Monday, January 12, 2009

A Little Help

I'm having a problem with OpenGL ES, and it's keeping me from finishing my particle engine post. I was hoping someone here could see what I'm doing. Here's the code that I have to draw a texture mapped particle. This version uses GL_TRIANGLES and glDrawArrays(), but I've had similar problems using GL_TRIANGLE_STRIP and glDrawElements()..

    case ParticleEmitter3DDrawTextureMap:
{
static const GLfloat squareStrip[18] = {
+0.01f, +0.01f, +0.0f,
-0.01f, +0.01f, +0.0f,
-0.01f, -0.01f, +0.0f,

+0.01f, +0.01f, +0.0f,
-0.01f, -0.01f, +0.0f,
+0.01f, -0.01f, +0.0f,
};
static const GLfloat tex[12] = {

1.0, 1.0,
0.0, 1.0,
0.0, 0.0,

1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
};

//static const GLfloat squareNormals[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

glScalef(oneParticle->particleSize, oneParticle->particleSize, oneParticle->particleSize);

[texture bind];
glEnable(GL_TEXTURE);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, squareStrip);
//glNormalPointer(GL_FLOAT, 0, squareNormals);
glTexCoordPointer(3, GL_FLOAT, 0, tex);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisable(GL_TEXTURE);
//glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
}

As a test, I was mapping this image onto the sprites:

But, what I get is this:

My guess, this is either a texture coordinate issue or a blending function issue. I've tried many, many permutations, both with triangle strips and triangles, and using glDrawArrays() and glDrawElements(), and I've tried every permutation of texture coordinates I can think of, yet I've never been able to get both triangles mapped right.

Here's a slightly different version that gives the same result:
            case ParticleEmitter3DDrawTextureMap:
{
static const GLfloat squareVertices[12] = {
+0.01f, +0.01f, +0.0f,
-0.01f, +0.01f, +0.0f,
-0.01f, -0.01f, +0.0f,
+0.01f, -0.01f, +0.0f,
};
static const GLfloat tex[8] = {
1.0, 0.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
};
static const GLushort triangle1[3] = {0,2,1};
static const GLushort triangle2[3] = {2,3,0};

//static const GLfloat squareNormals[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

glScalef(oneParticle->particleSize, oneParticle->particleSize, oneParticle->particleSize);

[texture bind];
glEnable(GL_TEXTURE);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, squareVertices);
//glNormalPointer(GL_FLOAT, 0, squareNormals);
glTexCoordPointer(3, GL_FLOAT, 0, tex);
//glDrawArrays(GL_TRIANGLES, 0, 6);

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, &triangle1);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, &triangle2);
glDisable(GL_TEXTURE);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
break;
}

The thing is, I know that these texture coordinates are right. I've copied verbatim the coordinates and drawing code from probably a half-dozen code samples and tutorials I found on the web. That, combined with the fact that I can't find any set of texture coordinates that works, makes me thing I'm doing something terribly wrong somewhere else. I tried switching the winding order of the triangle vertices, and that had no visible effect. I also played with the blending functions with no success.

If there's anyone out there who's pretty good with OpenGL who can point out the boneheaded thing I'm doing here, I would really appreciate it. I think it's possible that it's the same thing that was keeping me from getting the UV-mapped OBJ files to display correctly.

If you're the first person to figure out what I'm doing wrong, you're welcome to a free copy of Beginning iPhone Development, though if you can figure this out, you've probably no need of it. Unfortunately, I can't afford to spend more time on this right now, so unless someone can figure this out, the particle tutorial is probably going to go on a shelf for a few weeks while I dig out from the Macworld backlog.

No comments:

Post a Comment