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)
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);
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
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.
Related
I have to create a matrix with the width and height determined by two parameters obtained from the writing of a file. But, in some cases when the matrix is too big, I've got a segmentation fault. I think is probably because I'm creating the matrix in a static way, so I need to create it dynamically, but is here where my problem appears, because I don't know how to do it.
My code right now is this:
FILE * fp;
unsigned int width=0;
unsigned int height=0;
//Open the file. argv[4] parameter contains the file
fp=fopen (argv[4],"r");
//Go to the last position which indicates the size
fseek(fp, 0, SEEK_END);
//Return to the start:
rewind(fp);
//The value of the first 4 bytes represent the width
size_t return1 = fread(&width,4,1,fp);
//The value of the next 4 bytes represent the height
size_t return2 = fread(&height,4,1,fp);
//Matrix creation
if (return1 > 0 && return2 > 0) {
unsigned int matrix[width][height];
If you are having trouble figuring out how to create arrays dynamically, I would definitely advise you to use the vector class instead.
Vectors are dynamically allocated, and can scale.
std::vector<unsigned int> matrix{width * height};
Notice that I made the vector a single dimension, since it really simplifies a lot when allocating the vector.
To access a specific coordinate you could use:
matrix.at(w * width + h);
Where w and h are the coordinates, h should obviously be in the range 0 <= h < height.
If you were to dynamically allocate your array you would have to use the new operator, and then have to remember to clean up afterwards as well using the proper delete[] operator. There is a better answer for that here on Stack Overflow: How do I declare a 2d array in C++ using new?
Basically it would boil down to:
unsigned int** matrix = new unsigned int*[width];
for (int w = 0; w < width; ++w) {
matrix[w] = new unsigned int[height];
}
Then you would have to remember to delete the matrix again, using something like this:
for (int w = 0; w < width; ++w) {
delete [] matrix[w];
}
delete [] matrix;
So, in other words, I recommend that you use the vector class instead.
Of course with sufficiently large values of width and height, even vector can fail, simply because you are trying to allocate too much memory. If that is the case I think you should revisit your design, and reconsider how it is made.
Remember to include the vector header when using vectors:
#include <vector>
unsigned int matrix[width][height];
This has two problems.
Firstly, width and height are not compile time constants, which is required by the C++ standard for the size of the array. Therefore your program is ill-formed. Your compiler might support variable length arrays (VLA) as a language extension, so it might work with your compiler anyway.
Secondly, VLA may be stored on the stack, and stack space is limited. Indeed, with a large array you can easily overflow the stack. You are correct, that you'll need to allocate the array dynamically. Both because the size is dynamic (assuming you want your program to work with other, standard compliant compilers that do not support VLA) and because it prevents the stack from overflowing.
The simplest way to create a dynamic array is std::vector. Tommy Andersen goes more into depth on how to use vectors in his answer.
I am developing a program in which one of the task is to read points (x,y and z) from a text file and then store them in an array. Now the text file may contain 10^2 or even 10^6 points, depending upon the text file user selects. Therefore I am defining a dynamic array.
For allocating a dynamic 2D array, I wrote as below and it works fine:
const int array_size = 100000;
float** array = new float* [array_size];
for(int i = 0; i < array_size; ++i){
ary[i] = new float[2]; // 0,1,2 being the columns for x,y,z co-ordinates
}
After the points are saved in the array, I write the following to deallocate the unallocated memory :
for (int i = 0; i < array_size; i++){
delete [] array[i];
}
delete [] array;
and then my program stops working and shows "Project.exe stopped working".
If I don't deallocate, the program works just fine.
In your comment you say 0,1,2 being the columns for x,y,z co-ordinates, if that's the case, you need to be allocating as float[3]. When you allocate an array of float[N], you are allocating a chunk of the memory of the size N * sizeof(float), and you will index them in the array from 1 to N - 1. Therefore if you need indeces 0,1,2, you will need to allocate a memory of the size 3 * sizeof(float), which makes it float[3].
Because other than that, I can compile and run the code without an error. If you fix it and still get an error, it might be your compiler problem. Then try to decrease 100000 to a small number and try again.
You are saying that you are trying to implement a dynamic array, this is what std::vector does and I would highly recommend that you use it. This way you are using something from the standard library that's extremely well tested and you won't run into issues by essentially trying to roll your own version of std::vector. Additionally this approach wraps memory better as it uses RAII which leverages the language to solve a lot of memory management issues. This has other benefits too like making your code more exception safe.
Also if you are storing x,y,z coordinates consider using a struct or a tuple, I think that enhances readability a lot. You can typedef the coordinate type too. Something like std::vector< coord_t > is more readable to me.
(Thanx a lot for suggestions!!)
Finally I am using vectors for the stated problem for reasons as below:
1.Unlike Arrays (not array object ofcourse), I don't need to manually deallocate unallocated memory.
2.There are numerous built in methods defined under vector class
Vector size can be extended at later stages
Below is how I used 2D Vector to store points (x,y,z co-ordinates)
Initialized (allocated memory) a 2D vector:
vector<vector<float>> array (1000, vector<float> array (3));
Where 1000 is the number of rows, and 3 is the number of columns
Once declared, values can be passed simply as:
array[i][j] = some value;
Also, at later stage I declared functions taking vector arguments and returning vectors as:
vector <vector <float>> function_name ( vector <vector <float>>);
vector <vector <float>> function_name ( vector <vector <float>> input_vector_name)
{
return output_vector_name_created_inside_function
}
Note: This method crates a copy of vector while returning, use pointer to return by reference. Even though mine is not working when I return vector by reference :(
For multi arrays I recommended use boost::multi_array.
Example:
typedef boost::multi_array<double, 3> array_type;
array_type A(boost::extents[3][4][2]);
A[0][0][0] = 3.14;
I have a 4x4 matrix class that holds the values as 2d float array : float mat[4][4]; and I overloaded the [] operator
inline float *Matrix4::operator[](int row)
{
return mat[row];
}
and I have an uniform mat4 in my shader (uniform mat4 Bones[64];) which i will upload my data onto. And I hold the bones as a Matrix4 pointer (Matrix4 *finalBones) which is a matrix array, containing numJoints elements. and this is what i use to upload the data :
glUniformMatrix4fv(shader.getLocation("Bones"),numJoints,false,finalBones[0][0]);
I am totally unsure about what is going to happen, so i need to ask that if this will work or i need to extract everything into 16*numJoints sized float arrays which seems to be expensive for each tick.
edit
this is what i have done which seems really expensive for each draw operation
void MD5Loader::uploadToGPU()
{
float* finalmat=new float[16*numJoints];
for (int i=0; i < numJoints; i++)
for (int j=0; j < 4; j++)
for(int k=0; k < 4; k++)
finalmat[16*i + j*4 + k] = finalBones[i][j][k];
glUniformMatrix4fv(shader.getLocation("Bones"),numJoints,false,finalmat);
delete[] finalmat;
}
It depends on two things. Assuming your compiler is C++03, (and you care about standards compliance), then your Matrix class must be a POD type. It must, in particular, have no constructors. C++11 relaxes these rules significantly.
The other thing is that your matrix appears to be row-major. I say this because your operator[] seems to think that your 2D array is row-major. The first coordinate is the row rather than the column, so it's row-major storage order.
If you're going to give OpenGL row-major matrices, you need to tell it that they are row-major:
glUniformMatrix4fv(shader.getLocation("Bones"), numJoints, GL_TRUE, finalBones[0][0]);
With C++11, a class with standard layout can be cast to a pointer, addressing its first member, and back again. With a sizeof check, you then have a guarantee of contiguous matrix data:
#include <type_traits>
static_assert((sizeof(Matrix4) == (sizeof(GLfloat) * 16)) &&
(std::is_standard_layout<Matrix4>::value),
"Matrix4 does not satisfy contiguous storage requirements");
Trivial (or POD) layouts are just too restrictive once you have non-trivial constructors, etc. Your post suggests you will need to set the transpose parameter to GL_TRUE.
I need to have a 2D array of double.
Its width is around 900. Its height as well (the same width value).
Dealing with two loops (one for the width and one for the height), I really need to get access to all the pixels of the 900X900 image that I will process.
The size of the array is too big (error when specifying the number of raw and column).
I thought about establishing that with a dynamic array to optimize the time of calculation and to free the memory everytime I deal with one pixel on the two loops.
But I really cannot find the syntax I would like to have to declare a 2D dynamic array (malloc, setting array element values and freeing the memory).
Wrap it in a class:
class Matrix2D {
typedef std::vector<double> Column;
std::vector<Column> columns;
public:
Matrix2D(unsigned int width, unsigned int height) :
columns(width, Column(height)) {
}
double& at(unsigned int i, unsigned int j) {
return columns[i][j];
}
};
Matrix2D matrix(900, 900);
matrix.at(45, 65) = 1234.5678;
I need to have a 2D array of double
Since you are using C++ you should use STL classes that will take care of ugly memory management for you. So you are actually looking for std::vector< std::vector<double> >, or for the sake of the readability of your code:
#include <vector>
typedef std::vector<double> DVector; // row represented by vector of doubles
typedef std::vector<DVector> MyVector; // 2D array as a vector of these rows
And then avoid using dynamic allocation wherever it's possible to do so. Take advantage of RAII idiom:
{
MyVectorarr; // vector object with automatic storage duration
} // <-- vector is automatically destructed when execution goes out of scope
Questions that might help you:
Multi-dimensional vector
Initialization of a vector of vectors?
vector of vector
I associate malloc with pure C, not C++ (as the prior answer points yout, you should use std::vector). However, if you really want to:
// allocate the memory in a block
double* block = (double *) malloc(sizeof(double) * xSize * ySize);
// allocate memory for the accessor array
double* accessor = (double*) malloc(sizeof(double*) * xSize);
// assign memory addresses
double* curPtr = block;
for (int i = 0; i < xSize; ++i) {
accessor[i] = curPtr;
curPtr += ySize;
}
// you can now access the array via accessor[x][y]
// now need to free malloced memory:
free(accessor);
free(block);
If you do it this way, I highly suggest tying it to the RAII pattern, otherwise you'll eventually get a memory leak. Using the STL's containers is a better approach.
Hey guys. Thanks for clicking.
This is a problem that I'm encountering while coding OpenGL, but it's a pretty general problem overall - so nothing graphics specific.
I have a struct (not a class, just a simply struct), Particle.
typedef struct
{
float x;
float y;
float z;
}float3;
typedef struct
{
float3 position;
float3 velocity;
//...other stuff
}Particle;
And I am working with a bunch of particles (Particle* particles[]), but I have a function that requires a float* of positions packed in an x, y, z order.
Thus a summary of my problem:
My data:
//I have this in a bunch of encapsulated structs
[... {1.0f, 2.0f, 3.0f,} ... {4.0f, 5.0f, 6.0f} ...]
//I want...
[1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f]
My problem is...I have all the data there already! I don't want to have to malloc/memcpy around again. Is there a way to use the data that is already there? Any C pointer acrobatics? I am also worrying about things like alignment/padding.
(float3 is a struct defined in CUDA, if anyone is curious).
glVertexAttribPointer has a stride parameter that is designed for just this situation.
Typically you will load an array of Particle objects into a VBO, and then, with the VBO bound:
glVertexAttribPointer(shader_arg_position, 3, GL_FLOAT, GL_FALSE, sizeof (Particle), offsetof(Particle, position));
My solution is more C oriented.
The thing with pointers,you can use them to walk freely from one memory address to another with the idea "don't care what data is there". Combine that with the fact that when you allocate structs they are aligned in the order they are declared and you have yourself an easy solution to access your data without too much hassle.
Just make a float* index to point at the beginning of your vector structure where you hold all the points. Using index now you can traverse it how you please, however be careful where you stop with the pointer movement.
To explain a bit:
struct {
float3 position;
float3 velocity;
float3 more_data;
} Particle;
When you allocate this structure the memory will look like this:
3 floats for position || 3 floats for velocity || 3 floats for whatever data
Take a float* at the address position.x and increment it through you particles taking in consideration what data you want to process (position, velocity, etc).
Concerning alignment, it depends what alignment do you want your structure to have.
What about a reinterpret cast and a lot of care here?
Particle* pP[];
// Fill your array of particles
// And now at your own risk (memory accesses and so on... :)
float* pF = reinterpret_cast<float*>(&pP[0]);
float x = pF[0];
float y = pF[1];
float z = pF[2];
pF = reinterpret_cast<float*>(&pP[1]);
// ..
If you have your Particle* array, but you want to work with it as if it were an array of float positions, you could write something like this:
float getNthFloat(size_t n)
{
size_t i = n / 3;
size_t j = n % 3;
float* pF = reinterpret_cast<float*>(&pP[i]);
return pF[j];
}
// This would get 6th element in your virtual float array
// That is, second z position
size_t foo = 5;
float blah = getNthFloat(5);
And going one step further; you could probably rewrite this so it actually looks like accessing an array instead of calling a function.
The ideal solution is to fire whoever designed float3 and replace this structure with simple arrays across the board.
If you can't do that, you can try simply casting the pointer, but you might find your compiler refuses to generate working code since this is a violation of the aliasing rules.
And one more solution:
typedef struct {
float elem[3];
} float3;
#define x elem[0]
#define y elem[1]
#define z elem[2]
Unfortunately the names x, y, and z could be problematic to define as macros like this. That's one reason many classic C structures use prefixed names for struct elements, like st_dev, tv_sec, si_uid, etc...