Ivan Ermolaev
Ivan Ermolaev

Reputation: 1032

What data GLSL takes?

What data GLSL takes? For example I have a matrix 4x4, which is following kind:

float **matrix = new float*[4];
for(int i = 0; i < 4; i++)
    matrix[i] = new matrix[4];

Can the GLSL to take this, as mat4x4?

Or, better to use following:

float *matrix = new float[16];

I haven't found this information in specification of GLSL 1.30(I have use particularly this version)

Upvotes: 2

Views: 339

Answers (3)

datenwolf
datenwolf

Reputation: 162164

What data GLSL takes? For example I have a matrix 4x4, which is following kind:

float **matrix = new float*[4];
for(int i = 0; i < 4; i++)
    matrix[i] = new matrix[4];

That's not a 4×4 matrix. That's an array of pointers to arrays of 4 float elements.

Can the GLSL to take this, as mat4x4?

No, because it's not a matrix.

A 4×4 matrix would be a region of contiguous memory that contains 4·4 = 16 values (floats if you will) of which you denote, that each n-tuple (n=4) of values forms a vector and the m-tuple (m=4) of vectors forms a matrix.

Or, better to use following:

float *matrix = new float[16];

That would be a contiguous region of memory holding 16 = 4·4 float values, which by denotion can be interpreted as a 4×4 matrix of floats. So yes, this can be interpreted by OpenGL / GLSL as a 4×4 matrix of floats mat4.

However if you make this part of some class don't use dynamic memory.

class foo {
    foo() { matrix = new float[16]; }
    float *matrix;
};

Is bad, because you create some unnecessary overhead. If the class is dynamically allocated (with new) that will trigger another dynamic memory allocation, which creates overhead. If the instances are on automatic memory (stack, i.e. no new), it also imposes unnecessary overhead.

class foo {
    foo() { … }
    float matrix[16];
};

is much better, because if the class instances are created with new that also covers the memory for the matrix. And if it's on automatic memory it completely avoids the overhead of dynamic allocation.

Upvotes: 3

Celestis
Celestis

Reputation: 535

You can't use the first variant, because the 16 floats of the matrix data will be allocated in different memory areas. You store array of 4 pointers, each pointing to separate 4xfloat array. OpenGL expects data to be located sequentially, so either use the second variant or use struct/static 2d array:

GLfloat[4][4]

It may be convenient to use the existing library for that, fore example gl matrix

Upvotes: 3

Jack
Jack

Reputation: 133577

First of all you should make use of GLfloat instead that float, since it's there exactly to represent GL data which is used by your program and the GPU.

Regarding your specific question glUniform has many flavours used to send what you need. You have both

void glUniformMatrix2f(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
void glUniformMatrix4f(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

You can use them easily by passing the pointer to your data:

GLint location = glGetUniformLocation(variable,"variable_name");
glUniformMatrix4f(location, 1, false, &matrix);

Upvotes: 3

Related Questions