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.



11 comments:

Noel said...

Jeff,
I believe the problem is that you're telling OpenGL you're using 3 uvs. It should be: glTexCoordPointer(2, GL_FLOAT, 0, tex);

Also, you should consider using triangle strips to save two verts.

Hope that helps.

pyroka said...
This comment has been removed by the author.
Wendell Hicken said...

Just wanted to let you know I'm looking forward to seeing the final code/tutorial. I'd be happy to beat on the project some if the full code is available somewhere. Otherwise I'll just have to bide my time until you're ready.

Thanks for all the great posts.

noxa said...

Darn, Noel beat me to it ;)
That 3 is most likely the issue.

Jeff LaMarche said...

Noel:

Thank you! That was it. The texture mapping is now working. The texture is rotated 90° from what I was expecting, but that's minor and easy enough to deal with. I think that's in my "aiming" function where I convert yaw and pitch to x,y, and z.

I feel a little sheepish about such a stupid mistake, but you know what it's like when you've been staring at the same chunk of code too long. All the late nights at Macworld last week didn't help, either.

Anyway, if you want the free copy of the book, just drop me an e-mail to jeff underscore lamarche at mac dot com and it'll be on its way to you.

Man, I love that smart people read my blog. I probably won't be able to finish up the particle post until the weekend, but at least now I know I'll be able to finish it.

Jeff

Alex said...

Jeff,

Have you tried using point sprites?
This extension allows you to use textures with points, mapping the whole texture inside the point. With this, and setting an appropriate point size and blending, you could get very good looking particles.

glEnable(GL_POINT_SPRITE_OES);

This technique is used in engines such as the oolong engine (http://oolongengine.com/) and Cocos2D (http://code.google.com/p/cocos2d-iphone/)

Also, check the OpenGL ES tutorial #6 here:
http://www.typhoonlabs.com/

Thank you for all your great articles!

Jeff LaMarche said...

Alex

Yep, I've experimented with both triangle strips and point sprites (I settled on triangle strips). My problem with point sprites was that they didn't seem to change in size based on their Z position. Now, it's altogether possible that I was doing something wrong, but in my experiments, the particle system lost it's 3D feel.

Thanks for the links..

Jeff

Manpreet Singh said...

Hi Jeff,

I am assuming that you are using "glEnableClientState(GL_VERTEX_ARRAY)" also somewhere to be able to use glDrawElements or glDrawArrays.

Also, looking forward to your particle system tutorial !

Edwin said...

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

JeansPilot said...

JeansPilot offers the chance to buy a large variety of men’s and women’s jeans clothing from the world famous Italian Brands.
Online jeans clothing store looks for original fashion clothing sales and clearances of worldwide known designers. We participate in fashion auctions to get the lowest possible price for Top quality Clothes, Shoes and Accessories.
Buy Jeans

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels