Reputation: 3175
Here's an illustration of what I am currently doing with two functions.
In both cases I am creating a local copies: either an instance of std::vector<GLfloat>
or of std::vector<GLdouble>
.
Isn't there a shortcut not involving copies, where I could go from Rcpp::NumericMatrix
to GLfloat *
/GLdouble *
in a more direct way?
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;
//' @export
// [[Rcpp::export("glLoadMatrixf")]]
void gl_load_matrixf(Rcpp::NumericMatrix m) {
std::vector<GLfloat> float_v = Rcpp::as<std::vector<GLfloat> >(m);
const GLfloat * _float_v = &float_v[0];
glLoadMatrixf(_float_v);
}
//' @export
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {
std::vector<GLdouble> double_v = Rcpp::as<std::vector<GLdouble> >(m);
const GLdouble * _double_v = &double_v[0];
glLoadMatrixd(_double_v);
}
Upvotes: 4
Views: 336
Reputation: 26823
On my system GLfloat
and GLdouble
are defined as:
typedef float GLfloat;
typedef double GLdouble;
And R's numeric data type is always a double
. So you can use &m[0]
or m.begin()
directly to get something convertible to a GLdouble *
without the need to copy the data. For GLfloat
this is not possible, since it requires a (lossy) cast to go from the (64 bit) double
used by R to a (32 bit) float
.
Some code as illustration:
Sys.setenv(PKG_LIBS="-lGL -lglfw")
Rcpp::sourceCpp(code = '
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {
const GLdouble * _double_v = &m[0];
glLoadMatrixd(_double_v);
}
')
glLoadMatrixd(matrix(runif(10), 2, 5))
BTW, I have no idea what dimensions such a matrix should have. 2x5 is probably incorrect ...
Upvotes: 3