Incorrect colors implementation OpenGL ES2 - IOS - ios5

I have very simple OpenGL ES example similar to Hehe's example : http://nehe.gamedev.net/tutorial/ios_lesson_02__first_triangle/50001/
As shown above triangle filled with three colors - red, blue, green.
Instead in my app i always get triangle almost completely filled with black color, only small area around top vertex filled with green and small area around right bottom filled with red ... and there is no blue at all.
The first question is : why do the colors not interpolate in the middle of my triangle and why does blue color is not visible at all?
Any changes in my colors array affect nothing, e.g. when i try to make triangle white the colors do not change anyway ... in the meantime if i change Z coordinate in positions array then i can see the blue color.
The second question is : why any changes in colors do nothing and changes in positions change the color instead?
Seems like somewhere here i made one stupid mistake but i can't catch it.
This is Vertex / Color arrays :
const float colors[] = { // this does not work, triangle still black-green-red
1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0
};
const float positions[] = { // if i change 3rd index to 1.0 then i will see blue color
-0.5, -0.5, 0.0, 1.0,
0.0, 0.5, 0.0, 1.0,
0.5, -0.5, 0.0, 1.0
};
This is VBO :
- (BOOL)setupVBO
{
BOOL success = YES;
glGenBuffers(1, &_positionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _positionBuffer);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(positions) * sizeof(float),
&positions[0],
GL_STATIC_DRAW);
glGenBuffers(1, &_colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);
glBufferData(
GL_ARRAY_BUFFER,
sizeof(colors) * sizeof(float),
&colors[0],
GL_STATIC_DRAW);
return success;
}
Render :
- (void)render:(CADisplayLink*)displayLink
{
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, _positionBuffer);
glVertexAttribPointer(_positionSlot, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, _colorRenderBuffer);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays(GL_TRIANGLES, 0, 3);
[_glContext presentRenderbuffer:GL_RENDERBUFFER];
}
Thanks for any advice ...

Ok, i found where was the issue :)
As far as i am beginner in Open GL i just copypasted the code from example and renamed some variables ... and did not catch that i renamed ColorBuffer (VBO color, i.e. actual color data of drawing object) variable to ColorRenderBuffer variable (place in memory where GL processes actual color data)
Stupid mistake and i hope nobody will do the same :)

Related

Can I create Vertex Buffer Objects without color information?

I want to create a grid of rectangles for a simulation, where we colorize the rectangles based on calculation results.
Initially I would just want to build the VBO to define the grid. And then in every frame simply assign colors to the rectangles.
Is this possible or is a VBO always "hard-wired" with a set of colors? Because all examples I find online do it like this. They initialize the VBO together with colors and not just the vertex position data, like this:
// allocate a new buffer
glGenBuffers(1, &cubeVBO);
// bind the buffer object to use
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
const GLsizeiptr vertex_size = NUMBER_OF_CUBE_VERTICES*NUMBER_OF_CUBE_COMPONENTS_PER_VERTEX*sizeof(GLfloat);
const GLsizeiptr color_size = NUMBER_OF_CUBE_COLORS*NUMBER_OF_CUBE_COMPONENTS_PER_COLOR*sizeof(GLubyte);
// allocate enough space for the VBO
glBufferData(GL_ARRAY_BUFFER, vertex_size + color_size, 0, GL_STATIC_DRAW);
A VBO is just a piece of memory, you use it to make things run faster by having the data reside in the graphics card. (Some hardware uses system memory for VBO, so not really much to gain in this case)
I also find it cleaner to always use VBOs, but that's a bit of a personal preference.
Anyway you can create VBOs, and then change the data inside them, same as piece of RAM, if you need to change everything on VBO every frame again no performance benefit, but if you only need to change stuff from time to time, or some of the data is fixed (say your vertex data), then you start to get some benefits...
for example:
glGenBuffers(1, &vboObjects[vboGroupBeaver]);
glBindBuffer(GL_ARRAY_BUFFER, vboObjects[vboGroupBeaver]);
glBufferData(GL_ARRAY_BUFFER, beaverVerts*8*sizeof(GLfloat), 0, GL_STATIC_DRAW);
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
NSString *path;
path = [[NSBundle mainBundle] pathForResource:#"beaver01" ofType:#"bin"];
NSFileHandle *model = [NSFileHandle fileHandleForReadingAtPath:path];
float vertice[8];
int counter = 0;
while (read([model fileDescriptor], &vertice, 8*sizeof(float))) {
memcpy(vbo_buffer, vertice, 8*sizeof(GLfloat)); // 0
vbo_buffer += 8*sizeof(GLfloat);
counter++;
}
NSLog(#"Vertices %1i",counter);
glUnmapBufferOES(GL_ARRAY_BUFFER);
This bit of code loads a model into a VBO (vboGroupBeaver), in this example it's the first keyframe of a animation.
All the data is now in the VBO, if I do this after:
glVertexPointer(3, GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 8*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glTexCoordPointer(2, GL_FLOAT,8*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);
I get a beaver drawn... (Notice that I'm using interleaved vertex data, that's why the pointer calls have the extra info).
In your case you would have a Color Pointer instead of a Texture pointer.
Now, if you want to change stuff all you have to do is glMapBufferOES to a buffer var, and interate thru it to change only the parts you need.
Something like:
vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
for (int i = start; i < end; i++) {
vbo_buffer += 6*sizeof(GLfloat); // offset to position
memcpy(vbo_buffer, whatYouWantToChange, 2*sizeof(GLfloat)); // change what you want, watch the size
}
EDIT give an example with color
First some example data, in this case a triangle with per vertex data interleaved:
static const ColoredTriangle vertexData[] = {
{
{0.0, 0.0, 0.0}, // Vertex 0
{0.0, 0.0, 1.0}, // Normal
{1.0, 0.0, 0.0, 1.0} // Color
},
{
{0.0, 480.0, 0.0}, // Vertex 1
{0.0, 0.0, 1.0}, // Normal
{1.0, 1.0, 0.0, 1.0} // Color
},
{
{320.0, 0.0, 0.0}, // Vertex 2
{0.0, 0.0, 1.0}, // Normal
{1.0, 1.0, 1.0, 1.0} // Color
}
Copy the thing to the vbo (after creating/binding/MapBuffer.
memcpy(vbo_buffer, vertexData, 10*3*sizeof(float));
draw the thing
glVertexPointer(3, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL));
glNormalPointer(GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+3*sizeof(GLfloat)));
glColorPointer(4, GL_FLOAT, 10*sizeof(GLfloat), (GLvoid*)((char*)NULL+6*sizeof(GLfloat)))
glDrawArrays(GL_TRIANGLES, 0, beaverVerts);
So now you have a triangle being draw with interleaved data from the VBO.
Now on each frame you want to do something just change the data.
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
vbo_buffer += 6*sizeof(GLfloat); // position the buffer at the first vertex color data
for (int i = 0; i < 3; i++) {
memcpy(vbo_buffer, newColor, 4*sizeof(GLfloat));
vbo_buffer += 10*sizeof(GLfloat); // skip the stripe
}
glUnmapBufferOES(GL_ARRAY_BUFFER);
Then draw again, and you just changed the color info.
Depending on the number of changes you're going to be making it might be better to change GL_STATIC_DRAW to something else also...
Disclaimer
This was made on the fly, so beware of dragons.
You can define the vertex coordinates in a VBO and the vertex colors in another, then you can use glVertexAttribPointer (or glVertexPointer, glColorPointer) to set up the vertex attributes for rendering.

How to dynamically create vertices in glVertexPointer() in openGLES

I have a set of textures which I need to draw at different vertices such that every texture is visible.I cannot define a static set of vertices since I load the textures dynamically and I dont know how many textures will be loaded everytime ( i choose them based on a condition).
This is how my code looks as of now.
for(int i=0;i<num_img;i++)
{
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
glRotatef(rot, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, texture[i]);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
Is there anyway to dynamically generate vertices that can be passed as final argument of glVertexPointer() ?
Do you know the maximum number of vertices that you will use? Maybe you could create the vertices array to be that maximum size then in the first parameter of glVertexPointer you only pass the number of vertices that you actually use.

Corrupted image if variable is not static

I'm doing the following:
static GLfloat vertices[3][3] =
{
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0}
};
glColor4ub(255, 0, 0, 255);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 9);
glDisableClientState(GL_VERTEX_ARRAY);
This works ok:
http://dl.dropbox.com/u/41764/posts/Screen%20shot%202010-03-28%20at%2020.04.56.png
However, if I remove static from vertices and therefore re-create the data on the stack on each rendering, I get the following:
http://dl.dropbox.com/u/41764/posts/Screen%20shot%202010-03-28%20at%2020.06.38.png
This happens both on the simulator and on the device.
Should I be keeping the variables around after I call glDrawArrays?
The reason you're seeing weird results is because you're not drawing what you think you are.
glDrawArrays(GL_TRIANGLES, 0, 9);
This means draw 9 vertices, hence 3 triangles. You only have 3 vertices declared in your array, so what the other 2 triangles will end up being is anybody's guess. You can see in the second picture that you indeed have more than 1 triangle... The data it ends up using is whatever else is on the stack at that time.
glDrawArrays does transfer on call, and I seriously doubt the iPhone would not be compliant on this. It's really basic GL, that (I believe) gets tested for conformance.
You are rendering uninitialized data in both cases. It just happens to look correct in the static case.
The third parameter to glDrawArrays is the number of vertices (which should be 3 in your case because you are trying to draw a single triangle).
You already told the GL that you are specifying 3 GLfloat per vertex (the first parameter of glVertexPointer). So the GL can figure out the total number of GLfloat to expect.
This should work:
GLfloat vertices[3][3] =
{
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0}
};
glColor4ub(255, 0, 0, 255);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);

Why does this Drawing glitch happen with GL_TRIANGLE_STRIP in OpenGL ES 1.1

So I'm starting to work with openGL, been following the tutorials over at Jeff LaMarche's blog and I've run into a problem when trying to draw a square using the GL_TRIANGLE_STRIP mode with glDrawArrays.
It works, by that I mean that I can draw a square, but I get this weird drawing glitch. You can see it here:
Drawing glitch http://img10.imageshack.us/img10/1631/picture1io.png
I'm using the xcode template that's provided by Jeff, so I assume the setup is all proper. The code I'm using in the drawView function is as follows:
Square2D *square = malloc(sizeof(Square2D));
Square2DSet(square, -0.25, -0.25, -20.0, 0.5, 0.5);
glLoadIdentity();
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0, 0.0, 0.0, 1.0);
glVertexPointer(3, GL_FLOAT, 0, square);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 12);
glDisableClientState(GL_VERTEX_ARRAY);
if(square != NULL)
free(square);
here's the code for Square2d and Square2DSet:
typedef struct {
Vertex3D tl;
Vertex3D bl;
Vertex3D tr;
Vertex3D br;
} Square2D;
static inline void Square2DSet(Square2D *sq, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
{
sq->tl = Vertex3DMake(x, y, z);
sq->bl = Vertex3DMake(x, y + height, z);
sq->tr = Vertex3DMake(x + width, y, z);
sq->br = Vertex3DMake(x + width, y + height, z);
}
I'm sure I'm doing something wrong, just not sure what. Eventually the glitch will go away after the program has run for a little bit.
Any ideas?
Cheers
glDrawArrays(GL_TRIANGLE_STRIP, 0, 12);
is drawing 12 vertices. You want 4. Its asking how many indices, not how many values to look at. It will multiply the index by the number of values at each index.
The reason why its going crazy is because its drawing junk, then it disappears because I assume that junk gets filled with 0s or something and it just goes away.

OpenGL to OpenGL-ES - glRectf()

I am trying to learn OpenGL on the iPhone using the "Super Bible" but am having trouble porting from OpenGLto OpenGL ES. My understanding is that the glRectf() function is not available in the latter. What is the substitute approach? Any relevant conceptual information would be appreciated as well.
The substitute approach is to draw a triangle strip:
GLfloat texture[] =
{
0, 0,
0, 1,
1, 0,
1, 1
};
GLfloat model[] =
{
0, 0, // lower left
0, h, // upper left
w, 0, // lower right
w, h // upper right
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, model);
glTexCoordPointer(2, GL_FLOAT, 0, texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
This draws a textured rectangle with width w and height h.
Rather than doing a rect, you just do two triangles.
This is really irrelevant though since GL-ES on the iPhone does not support immediate mode. You need to define all your vertices in an array and use one of the vertex array rendering functions to draw them rather than using the immediate mode functions.