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.
Related
I'm using the following code to draw a green line at some specified coordinates
GLfloat colors[] = {0,1,0,1, 0,1,0,0.5};
CGPoint v[] = {{p1.x, p1.y}, {p2.x, p2.y}};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_LINE_SMOOTH);
glLineWidth(10);
glVertexPointer(2, GL_FLOAT, 0, &v);
glColorPointer(4, GL_FLOAT, 0, &colors);
glDrawArrays(GL_LINE_LOOP, 0, 2);
glDisableClientState(GL_LINE_SMOOTH);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
The problem is that once in a while even if the draw method gets called, the line turns black or does not get drawn entirely. i've checked the coordinates i pass and they seem fine.
Is there something that i'm missing?
GL_LINE_SMOOTH has never been an acceptable argument to glEnableClientState().
It might not be the source of the problem, and you might have noticed it already, but isn't it correct to pass arrays to the functions without '&' or with '[0]'? i.e.
glVertexPointer(2, GL_FLOAT, 0, &v); // --> &v should be v, or &v[0]
glColorPointer(4, GL_FLOAT, 0, &colors); // --> colors, or &colors[0]
Also, glEnable(GL_LINE_SMOOTH); seems the correct syntax.
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.
I'm working on an iPhone project in Xcode 3.2.4 for which I'd like to display textures using OpenGL ES 2.0. I don't have much previous experience working with OpenGL, but so far it doesn't seem too awful. So far I've mainly been referring to The OpenGL ES 2.0 Programming Guide (gold book).
Right now I've got a project based on Xcode's default OpenGL template, with the drawFrame function replaced with my texture-displaying code, which in turn is based on the Simple_Texture2D project from the gold book. However, the square I should be drawing my texture onto does not display it; it's black instead, and I'm not sure why this is happening.
Here are the contents of drawFrame:
[(EAGLView *)self.view setFramebuffer];
GLuint textureID;
static const GLfloat squareVertices[] =
{
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f
};
// Generate a 2 x 2 rgb image at 3 bytes per pixel.
GLubyte image[4 * 3] =
{
255, 0, 0,
0, 255, 0,
0, 0, 255,
255, 255, 0
};
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
GLushort indices[] = {0, 1, 2, 3, 2, 1};
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
[(EAGLView *)self.view presentFramebuffer];
Perhaps to an experienced OpenGL user it'll be obvious what I'm doing wrong. Otherwise, any suggestions, guesses, or constructive comments of any kind are great too.
Thanks in advance!
You need not only vertex positions but also texture coordinates. As it stands you're only specifying vertex positions, so you're only going to vertices with whatever color was set last, no texture.
Try setting up a texCoord array and doing another glVertexAttribPointer(ATTRIB_TEXCOORD, ...) and a glEnableVertexArray(ATTRIB_TEXCOORD).
(If you're lighting you may want normals as well.)
There's sample code off songho's OpenGL Vertex Array page (glDrawElements section). See the draw3 function and prior setup.
Note that vertex buffer objects (and other buffer objects) are generally replacing vertex arrays (and other arrays) as the preferred solution for rendering batches of data at once. VBOs have more opportunity to be stored in a high-performance way by the driver.
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);
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.