OpenGL deform matrix at initialization

Started by
2 comments, last by Vorel512 12 years, 1 month ago
[color=#222222]Hi Experts!

[color=#222222]First of all:
[color=#222222]- Developing on OSX with Xcode 4.3.1.
[color=#222222]- For iOS 5.1.
[color=#222222]- With OpenGL ES 2.0/GLUT.
[color=#222222]- Language: Objective-C.

[color=#222222]I've run into a very strange error when learning programming in opengl es.
[color=#222222]I've made a class which stores every information belongs to a sprite (vectors, normals, tex coords, textures and an ID).
[color=#222222]The first two sprites are loaded successfully, but after them the top-right point of my squares starts to move/deform.
[color=#222222]At firts I've tried to NSLog the coordinates, and they are fine, AAAND the 3. object is being drawn right. I've figured out, that if I insert for cycles (objects count-2), then every object drawn right, no matter how the for cycles are written.

[color=#222222]My corresponding code (for 4 objects):
[color=#222222]
GLfloat gCubeVertexData[48];
for (unsigned int i = 0; 48>i;i++)
{
gCubeVertexData = [tempSprite getVector:i];
}

for (unsigned int i = 1; 2>i;i++)
{
}

for (unsigned int i = 1; 2>i;i++)
{
}

GLuint vertexArrayPointer;
GLuint vertexBufferPointer;

glGenVertexArraysOES(objectArray.count, &vertexArrayPointer);

[tempSprite setVertexArray:vertexArrayPointer];
[tempSprite setVertexBuffer:vertexBufferPointer];
vertexBufferPointer = [tempSprite getVertexBuffer];

glBindVertexArrayOES([tempSprite getVertexArray]);

glGenBuffers(objectArray.count, &vertexBufferPointer);

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferPointer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0));

glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(12));

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24));

glActiveTexture(GL_TEXTURE0);

glBindVertexArrayOES(objectArray.count-1);


[color=#222222]I had also tried sleep (maybe it just needs time), but the error still there.

[color=#222222]Thanks for any kind of help!
Advertisement
I've done further testing, and it seems to be, that I am doing something wrong when I want to copy a pointer.


Sprites *myModelObject = [[Sprites alloc] init];
[objectArray addObject: myModelObject];

Sprites *tempSprite;
tempSprite = [objectArray objectAtIndex:objectArray.count-1];
//------------------------------------------------------
[tempSprite loadSprite:objName textureType:@"txt"];

[tempSprite setName:objName];

/*
for (unsigned int a = 0; 1>a;a++)
{
}
for (unsigned int b = 0; 1>b;b++)
{
}
for (unsigned int c = 0; 1>c;c++)
{
}

for (unsigned int d = 0; 1>d;d++)
{
}

for (unsigned int e = 0; 1>e;e++)
{
}
*/
GLuint vertexArrayPointer;
GLuint vertexBufferPointer;

glGenVertexArraysOES(objectArray.count, &vertexArrayPointer);

[tempSprite setVertexArray:vertexArrayPointer]; // the problem is here after the first call (Error: BAD_ACCESS)
[tempSprite setVertexBuffer:vertexBufferPointer];

vertexBufferPointer = [tempSprite getVertexBuffer];
vertexArrayPointer = [tempSprite getVertexArray];

glBindVertexArrayOES(vertexArrayPointer);

glGenBuffers(objectArray.count, &vertexBufferPointer);

glBindBuffer(GL_ARRAY_BUFFER, vertexBufferPointer);


GLfloat gCubeVertexData[48];
for (unsigned int i = 0; 48>i;i++)
{
gCubeVertexData = [tempSprite getVector:i];
}


glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0));

glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(12));

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24));

glActiveTexture(GL_TEXTURE0);

glBindVertexArrayOES(objectArray.count-1);

tempAttrib.effect.texture2d0.name = [tempSprite getChildTexture:0];


In my sprite object .m:
- (void) setVertexArray:(GLuint) index
{
_vertexArray = index;
}
- (GLuint) getVertexArray
{
return _vertexArray;
}


object .h:
@interface Sprites : NSObject
{
GLfloat VectorArray[48];

GLuint _vertexArray;
GLuint _vertexBuffer;
}
- (void) setVertexArray:(GLuint) index;
- (GLuint) getVertexArray;


I think, that I pass the pointers in a wrong way, but I do not know how to fix it / do it in the right way.
Your interpretation of how to address a vertex array object is wrong. A vertex array object isn't addressed by a pointer, so using names like "vertexArrayPointer" and "vertexBufferPointer" is at least misleading.

However, the main problem is probably your use of glGenVertexArrays. Its first argument defines how many array objects the current invocation should allocate, and its second argument is a pointer to an array where the addresses of the allocated VAOs should be stored. E.g.

GLuint addr[3];
glGenVertexArraysOES( 3, addr );

would allocate 3 VAOs and store the belonging addresses into addr[0], addr[1], and addr[2], resp.

You are using

GLuint vertexArrayPointer;
glGenVertexArraysOES(objectArray.count, &vertexArrayPointer);

what should probably be replaced by

GLuint vertexArrayPointer;
glGenVertexArraysOES(1, &vertexArrayPointer);

or, IMHO even better with some renaming e.g.

GLuint vertexArrayAddress;
glGenVertexArraysOES(1, &vertexArrayAddress);


If you ignore this, and objectArray.count is greater than 1, then glGenVertexArrays will write more than 1 address although you have reserved only memory place for a single address, meaning you accidentally override memory! This kind of error is very dangerous, because it isn't detected at compile time and may lead to sporadic and unrelated errors at runtime.

Please notice that the above scheme is valid for (AFAIK) each and every kind of object in OpenGL (VBO, VAO, FBO, ...)
Awww.
That's solved my problem.
Thank you very much haegarr!!

This topic is closed to new replies.

Advertisement