Log in or register to post comments

glVertexAttribPointer issue

April 16, 2013 - 12:39am #1

Hi, I have created object data and store them in vector array (in C++). Thus,  can I passed object data such as vertex, colors, or normals to  glVertexAttribPointer() using vector array in c++?

Before that, I have used pointer to point the address of my vector array

vector<float> v;

float* vertex =  &v[0];

and I passed the vertex pointer to  glVertexAttribPointer last arguments.

When I compiled the program, everthing works fine. But when I tested  the ImageTargets apps (I used this sample apps), and aimed to target, I got the following error 

fatal signal 11 (SIGSEGV) at 0x0040a00

I searched this issue from google, and some said that the problem is caused by dereferencing a null pointer in native code.

Does anybody know how to solve this issue?

Thanks

 

 

glVertexAttribPointer issue

April 17, 2013 - 8:31am #15

Hi,

Ah I see.. thank you for discussion. I will try to find another approach..

glVertexAttribPointer issue

April 17, 2013 - 7:16am #14

Hi,

the fact that you use for instance only 200 elements out of the total 10,000, is not a problem, because you are using this line at the end:

glDrawArrays(GL_TRIANGLES, 0, genData.cubeNumVerts);

Theat line tells OpenGL to only use the first "genData.cubeNumVerts" vertices, and ignore everything after that (so no need to worry about the content of the arrays after the first 200 elements).

I would try this approach.

glVertexAttribPointer issue

April 17, 2013 - 5:12am #13

Hi AlessandroB, 

I've tried using dynamic arrays, but I got the error similar like the first error "Fatal Signal 11 (SIGSEGV)"

                int vertsSize = genData.cubeVerts.size();
		int colorsSize = genData.cubeColors.size();
		int normalsSize = genData.cubeNormals.size();


		float *vertex = new float[vertsSize];
		float *colors = new float[colorsSize];
		float *normals = new float[normalsSize];

		for(int i = 0 ; i < vertsSize ; i++) vertex[i] = genData.cubeVerts.at(i);
		for(int i = 0 ; i < colorsSize ; i++) colors[i] = genData.cubeColors.at(i);
		for(int i = 0 ; i < normalsSize ; i++) normals[i] = genData.cubeNormals.at(i);


	  glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
	                              (const GLvoid*) vertex);
	  glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
	                              (const GLvoid*) normals);
	    
	  glVertexAttribPointer(mColorHandle, 4, GL_FLOAT, GL_FALSE, 0,
	                            (const GLvoid*) colors);


	        glEnableVertexAttribArray(vertexHandle);
	        glEnableVertexAttribArray(normalHandle);
	        glEnableVertexAttribArray(mColorHandle);
	       

	      

	      glDrawArrays(GL_TRIANGLES, 0, genData.cubeNumVerts);
	      SampleUtils::checkGlError("ImageTargets renderFrame");

	      delete [] vertex;
	      delete [] colors;
	      delete [] normals;
                

a much simpelr approach would be to just create your arrays large enough up-front (for instance, if you know in advance that you will never have more than 10,000 vertices, you could just create those arrays as global variables with 10,000 elements).

yeah, that's might be the easiest way. But btw, when we create arrays with 10.000 elements, and we just store for instance 200 elements, then the rest elements  will be considered as 0 value, thus glVertexAttribPointer will use the 0 values as object data.

Thanks for your kind of helps. 

 

 

glVertexAttribPointer issue

April 17, 2013 - 3:52am #12

Hi,

you can obtain the size of your vector with:

int vertsSize = cubeVerts.size();
int normSize = cubeNormals.size();
int colSize = cubeColors.size();

Then, instead of using stack arrays, you can allocate them dynamically, for instance:

float *vertex = new float[ vertsSize ];
float *normals = new float[ normSize ];
float *colors = new float[ colSize ];

Then, once you are done with it (before exiting the renderFrame() function), deallocate them with:

delete[] vertex;
delete[] colors;
delete[] normals;

Note however that this approach might result in some performance degradation (you need to test it);

a much simpelr approach would be to just create your arrays large enough up-front (for instance, if you know in advance that you will never have more than 10,000 vertices, you could just create those arrays as global variables with 10,000 elements).

 

glVertexAttribPointer issue

April 17, 2013 - 2:44am #11

Hi AlesandroB,

genData.vertex, genData.normals and genData.colors correspond to the same number of vertices (note that the colors have 4 components per vertex); for example, if you have 6 vertices, you should have 6*3 (18) elements in genData.vertex, 6*3 (18) elements in genData.normals and 6*4 (24) elements in genData.colors

Yes, my genData.colors has 4 elements for each vertex. 

Then, as a further test, you could create a temporary float array for each of the vertex, normals, and colors, and make a copy of the elements into those array (i.e. iterate over your vectors and copy all the elements to thse temporary arrays), then use the temp arrays in the glVertexAttribPointer, and then deallocate them when done

Okay, I assume vertex, colors, and normals as temporary array, 

float vertex[108];

float colors[144];

float normals[108];

for(int i = 0 ; i < cubeVerts.size() ; i++) vertex[i] = cubeVerts.at(i);
for(int i = 0 ; i < cubeColors.size() ; i++) colors[i] = cubeColors.at(i);
for(int i = 0 ; i < cubeNormals.size() ; i++) normals[i] = cubeNormals.at(i);

It works..

But, when we intialize an array (in this case temporary array), we should declare the constant size for our array. In my case, the number of vertices will get updated, so how can I update the size of array?

Thanks

glVertexAttribPointer issue

April 17, 2013 - 2:09am #10

Hi, the code seems to be correct, however I would check (by using some Logs) that:

- genData.vertex, genData.normals and genData.colors correspond to the same number of vertices (note that the colors have 4 components per vertex); for example, if you have 6 vertices, you should have 6*3 (18) elements in genData.vertex, 6*3 (18) elements in genData.normals and 6*4 (24) elements in genData.colors

- genData.vertex, genData.normals and genData.colors are not NULL when calling glVertexAttribPointer

Then, as a further test, you could create a temporary float array for each of the vertex, normals, and colors, and make a copy of the elements into those array (i.e. iterate over your vectors and copy all the elements to thse temporary arrays), then use the temp arrays in the glVertexAttribPointer, and then deallocate them when done

 

glVertexAttribPointer issue

April 17, 2013 - 2:04am #9

Hi, 
Yes, the number of vertices is correct.

Actually the I declare constructor in global scope, and genCubeData in initRendering.

in renderFrame()

// I create class to generate object data (vertices, normals, and colors)
        GenData genData(3); // constructor 
        genData.genCubeData(); // Generate cube data 
 
	// Initialize required Matrix
	QCAR::Matrix44F modelViewProjections;

	  SampleUtils::translatePoseMatrix(0.0f, 0.0f, kObjectScale,
	                                             &modelViewMatrix.data[0]);
	  SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,
	                                                         &modelViewMatrix.data[0]);
	  SampleUtils::multiplyMatrix(&projectionMatrix.data[0],
	                                          &modelViewMatrix.data[0] ,
	                                          &modelViewProjection.data[0]);
          // pass the object data
	  glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
	                              (const GLvoid*) genData.vertex);
	  glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
	                              (const GLvoid*) genData.normals);
	  glVertexAttribPointer(mColorHandle, 4, GL_FLOAT, GL_FALSE, 0,
	                            (const GLvoid*) genData.colors);


	        glEnableVertexAttribArray(vertexHandle);
	        glEnableVertexAttribArray(normalHandle);
	        glEnableVertexAttribArray(mColorHandle);
	        //glEnableVertexAttribArray(textureCoordHandle);

	        //glActiveTexture(GL_TEXTURE0);
	        //glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);
	       // glUniform1i(texSampler2DHandle, 0 );
	      glUniformMatrix4fv(  mvpMatrixHandle , 1, GL_FALSE,
	                           (GLfloat*)&modelViewProjection.data[0]);
	      glUniformMatrix4fv( mMVMatrixHandle , 1, GL_FALSE,
	                                   (GLfloat*)&modelViewMatrix.data[0]);
	

	      glDrawArrays(GL_TRIANGLES, 0, genData.cubeNumVerts);
	      SampleUtils::checkGlError("ImageTargets renderFrame");
}

here is the header file of GenData


#include <vector>
#include "ShapeBuilder.h"
using namespace std;

class GenData{

public:
	int cubeNumVerts;
	int mRequestCubeFactor;

	GenData(int requestCubeFactor);
	void GenCubeData();


	vector<float> cubeVerts;
	vector<float> cubeColors;
	vector<float> cubeNormals;

	float *vertex;
	float *colors ;
	float *normals ;

private:
	float minPosition;
	float maxPosition;


};







 

glVertexAttribPointer issue

April 17, 2013 - 1:05am #8

Another thing; are you always passing the correct number of vertices to the glDrawArray function ?

maybe if you could share your OpenGL code where you set the vertex attrib pointer and you draw, it would help.

 

glVertexAttribPointer issue

April 16, 2013 - 11:03pm #7

Hi

Ok, so, if you change the vector (number of vertices during runtime, as you say) dynamically, that probably explains the issue;

So, yup.. but to my knowledge

the declaration

float *vertex;

vertex = &v[0];

the pointer always change the address of what it points to. Is there any chances it will points to null array if my std::vector<float> v dynamically updates it's element? In fact, before I update the vector contents in run time, the fatal error 11 SIGSEGV was thrown..

also, you should only change the vertices in the same thread as the OpenGL rendering thread (for instance, it is safe to do that in the renderFrame function, but not in other places)

Yes, that's what I did.

 

 

glVertexAttribPointer issue

April 16, 2013 - 10:54am #6

Ok, so, if you change the vector (number of vertices during runtime, as you say) dynamically, that probably explains the issue;

also, you should only change the vertices in the same thread as the OpenGL rendering thread (for instance, it is safe to do that in the renderFrame function, but not in other places)

 

glVertexAttribPointer issue

April 16, 2013 - 8:35am #5

Hi AlesandroB, 

oh, I see.

I used vector because I want to change the number of my vertices during runtime.

That's why I used vector because I can dynamically reserve the space for  vertices and manage each of vertices easily.  

hm, for your information, actually sometimes my virtual object is rendered when target detected but in colorful (I don't know why because I just assignd one type of color for every vertex) and my real scene just vanished and replaced by some kind of virtual box. I could not get the screenshot, because it appeared less than about 1 second. After that, my AR scene was closed, but it did not force to close the app. Any Idea?

 

Thanks

glVertexAttribPointer issue

April 16, 2013 - 8:19am #4

No, you cannot pass an std::vector<float> directly to glVertexAttribPointer()

another question: are you changing the content of the vector during execution ?

(actually, the question is why are you using an std::vector for vertex coordinates...)

 

glVertexAttribPointer issue

April 16, 2013 - 2:34am #3

Hi, 

"assigning the pointer to the first element of the vector is acceptable only if you are sure that the vector won't change in size"

Yes, I have made sure that my vector did not change in size.

 

"Otherwise, a more proper way of obtaining an array from your vector is this:

float* vertex = v.data();"

it seems my ADT eclipse did not support c++11 since my vector array has no member of data. 

Is there a way to pass the vector array directly to the glVertexAttribPointer()?

 

Thanks

glVertexAttribPointer issue

April 16, 2013 - 1:37am #2

Hi,

this sounds like a genuine C++ issue (not really about Vuforia);

however, to my knowledge, assigning the pointer to the first element of the vector is acceptable only if you are sure that the vector won't change in size (otherwise at some point your float* pointer might end up pointing to a NULL or invalid value, as the vector<float> might internally be reset to a different area in memory if its internal array is reallocated).

So, the correct flow should be in this order:

  1. create your vector<float>, and fill it with all the elements (vertex coordinates)
  2. obtain the array (pointer) from your vector.

Otherwise, a more proper way of obtaining an array from your vector is this:

float* vertex = v.data();

Have you tried that ?

 

 

Log in or register to post comments