Understanding the use of texcoords in opengl/spring

Understanding the use of texcoords in opengl/spring

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Post Reply
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Understanding the use of texcoords in opengl/spring

Post by SpliFF »

I'm having a bit of trouble finishing the texturing for the assimp importer. I think it's related to broken or invalid usage of UV mapping.

Could somebody please explain the relationship between texcoords, sTangents and tTangents. I think it would be useful if somebody could walk me through the following code (in laymans terms) so I can really understand what's going on:

Code: Select all

	if (!so->sTangents.empty()) {
		glClientActiveTexture(GL_TEXTURE5);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(3, GL_FLOAT, sizeof(float3), &so->sTangents[0].x);

		glClientActiveTexture(GL_TEXTURE6);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(3, GL_FLOAT, sizeof(float3), &so->tTangents[0].x);
	}

	glClientActiveTextureARB(GL_TEXTURE1_ARB);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glTexCoordPointer(2, GL_FLOAT, sizeof(SS3OVertex), &s3ov->textureX);

	glClientActiveTexture(GL_TEXTURE0);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glTexCoordPointer(2, GL_FLOAT, sizeof(SS3OVertex), &s3ov->textureX);

	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(3, GL_FLOAT, sizeof(SS3OVertex), &s3ov->pos.x);

	glEnableClientState(GL_NORMAL_ARRAY);
	glNormalPointer(GL_FLOAT, sizeof(SS3OVertex), &s3ov->normal.x);

	glDrawElements(GL_TRIANGLES, so->vertexDrawOrder.size(), GL_UNSIGNED_INT, &so->vertexDrawOrder[0]);

	if (!so->sTangents.empty()) {
		glClientActiveTexture(GL_TEXTURE6);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);

		glClientActiveTexture(GL_TEXTURE5);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	}

	glClientActiveTextureARB(GL_TEXTURE1_ARB);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glClientActiveTexture(GL_TEXTURE0);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Understanding the use of texcoords in opengl/spring

Post by Tobi »

It looks like it's doing the following:

Code: Select all

   if (!so->sTangents.empty()) {
      glClientActiveTexture(GL_TEXTURE5);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      glTexCoordPointer(3, GL_FLOAT, sizeof(float3), &so->sTangents[0].x);

      glClientActiveTexture(GL_TEXTURE6);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      glTexCoordPointer(3, GL_FLOAT, sizeof(float3), &so->tTangents[0].x);
   }
If the model (piece?) has tangents available, those are passed to the shader by putting them into texture coordinates. Such tangent vectors are often needed / wanted when doing e.g. normal mapping.

It looks as if it just 'mis-uses' texture coordinates to pass this data. I don't think it are actual texture coordinates.

Code: Select all

   glClientActiveTextureARB(GL_TEXTURE1_ARB);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glTexCoordPointer(2, GL_FLOAT, sizeof(SS3OVertex), &s3ov->textureX);

   glClientActiveTexture(GL_TEXTURE0);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   glTexCoordPointer(2, GL_FLOAT, sizeof(SS3OVertex), &s3ov->textureX);
Then, it sets texture coordinates for texture 0 and 1. Both sets of coordinates are identical. These are the texture coordinates for S3O texture 1 and texture 2. (I wonder why it doesn't simply refer to texture 0 texture coordinates in the shader; maybe this wasn't possible yet in the used shader language?)

Code: Select all

   glEnableClientState(GL_VERTEX_ARRAY);
   glVertexPointer(3, GL_FLOAT, sizeof(SS3OVertex), &s3ov->pos.x);

   glEnableClientState(GL_NORMAL_ARRAY);
   glNormalPointer(GL_FLOAT, sizeof(SS3OVertex), &s3ov->normal.x);
OpenGL is told about the vertex and normal data.

Code: Select all

   glDrawElements(GL_TRIANGLES, so->vertexDrawOrder.size(), GL_UNSIGNED_INT, &so->vertexDrawOrder[0]);
And finally the triangles are rendered, using vertex indices in vertexDrawOrder.

The rest is clean up.
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Re: Understanding the use of texcoords in opengl/spring

Post by SpliFF »

Maybe a bit too layman. I should add some questions to that:

1.) Why tangents and not texcoords. Assimp can give me both and if assimp can calculate tangents why can't opengl? I still don't really get what the tangents actually are.

2.) What's the relationship between s / t and u / v ?

Not in the code above but:

3.) If what we're doing here is "multi-texturing", should we be using glMultiTexCoord1fARB like i've seen in other examples or is that another thing entirely?

4.) Is there any functional difference between GL_TEXTURE0 and GL_TEXTURE0_ARB?

5.) I thought glVertexAttribPointer was used to add tangents. Am I wrong is is that just another way of do this?
Tobi
Spring Developer
Posts: 4598
Joined: 01 Jun 2005, 11:36

Re: Understanding the use of texcoords in opengl/spring

Post by Tobi »

SpliFF wrote:1.) Why tangents and not texcoords. Assimp can give me both and if assimp can calculate tangents why can't opengl? I still don't really get what the tangents actually are.
In OpenGL, only 1 vertex or fragment is processed at once. I.e. you don't have access to other vertices in the shader for one vertex. Therefore you can not calculate tangents in OpenGL. If however you can acccess all data, like on CPU, then it isn't too hard to calculate tangents.

Tangents are vectors tangent to the surface, i.e. pependicular to the normal of the surface. Sometimes this data is needed for e.g. normal mapping.
2.) What's the relationship between s / t and u / v ?
Usually just different names for same things.
Not in the code above but:

3.) If what we're doing here is "multi-texturing", should we be using glMultiTexCoord1fARB like i've seen in other examples or is that another thing entirely?
glMultiTexCoord1fARB is function for sending a single texture coordinate, i.e. for use in combination with glVertex3f, glColor3ub, etc.

In this case an entire set of data is passed at once.
4.) Is there any functional difference between GL_TEXTURE0 and GL_TEXTURE0_ARB?
No.
5.) I thought glVertexAttribPointer was used to add tangents. Am I wrong is is that just another way of do this?
That would be the better way.
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Understanding the use of texcoords in opengl/spring

Post by Kloot »

1) Tangents are vectors needed for a particular variant of normal mapping. They are just passed as texture coordinates because that was the easiest way (at the time I wrote this code) to integrate them with Spring's rendering pipeline. You probably don't need to know the details.

2) You can consider them equivalent.

3) glMultiTexCoord* isn't meant for batch data transfers.

4) No

5) See 1; using glVertexAttribPointer cleanly would require the attribute data to be part of SS3OVertex, which wasn't possible without altering the S3O format definition.
Last edited by Kloot on 17 Jan 2010, 13:24, edited 1 time in total.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Understanding the use of texcoords in opengl/spring

Post by jK »

SpliFF wrote:1.) Why tangents and not texcoords. Assimp can give me both and if assimp can calculate tangents why can't opengl? I still don't really get what the tangents actually are.
http://jerome.jouvie.free.fr/OpenGl/Lessons/Lesson8.php
Tangents are NOT TexCoords. As Tobi already said you just misuse the texcoords attributes to send such data to the shader. Tangents are VECTORS as a normal is. Tangent, Bitagent/Binormal and Normal define the tangent space which is needed for per-pixel lighting computations (-> normalmapping).
Also OpenGL is nothing except an API, it's NOT a framework, so it won't calculate tangents for you. Direct3D instead is a framework and can calculate tangents for you, but does this in a suboptimal way.
SpliFF wrote:2.) What's the relationship between s / t and u / v ?
GLSLSpec wrote:The component names supported are:
{x, y, z, w} Useful when accessing vectors that represent points or normals
{r, g, b, a} Useful when accessing vectors that represent colors
{s, t, p, q} Useful when accessing vectors that represent texture coordinates
The component names x, r, and s are, for example, synonyms for the same (first) component in a vector.
u,v are just a different naming convention, but isn't official used in OpenGL. -> u:=s, v:=t
SpliFF wrote:3.) If what we're doing here is "multi-texturing", should we be using glMultiTexCoord1fARB like i've seen in other examples or is that another thing entirely?
The old definitions of MultiTexturing doesn't fit anymore. The term is bound the usage of multiple textures, with the FixedFunctionPipeline (pre-shaders times) you had to give for each of those textures its own texcoords via glMultiTextCoord, but with shaders you can now creat the TexCoords yourself in the shader and e.g. reuse one glTexCoord call for all your textures.
So glBindTexture is what defines if MultiTexturing is used (+ the shader code), but such texture bindings aren't done in the DisplayList creation (where your code example is from), it's done in the UnitDrawer.cpp. But as I already told you in the other thread it is perhaps useful to compile those texture bindings in the DisplayList, but that needs some changes in the UnitDrawer.cpp code.
SpliFF wrote:4.) Is there any functional difference between GL_TEXTURE0 and GL_TEXTURE0_ARB?
ARB ~= optional extensions not yet part of the official OpenGL spec.
When it's included in the official OpenGL tree, those "ARB" postfixes are redundant and can be removed.
SpliFF wrote:5.) I thought glVertexAttribPointer was used to add tangents. Am I wrong is is that just another way of do this?
Generic Vertex Attributes are new and introduced with GLSL, but the shader code was written for ARB shaders, so it had to misuse default vertex attributes to send the data.
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Re: Understanding the use of texcoords in opengl/spring

Post by SpliFF »

Thanks for all replies. It's apparent now i'm trying to build a ferrari with the plans for a Model-T Ford. There's clearly a lot of legacy stuff going on in the s3o rendering process that is a symptom of the format itself and the time it was written (pre-glsl, pre-opengl 3).

I actually understand most of what you guys said so what i really need to do now is go through some modern shader code (like the advshaders stuff in Spring) and see how things are being done today. Then backdate as required for older cards.

Is there a generally agreed upon minimum specification for Spring graphics?
Kloot
Spring Developer
Posts: 1867
Joined: 08 Oct 2006, 16:58

Re: Understanding the use of texcoords in opengl/spring

Post by Kloot »

The minimum spec is whatever the code dictates; that roughly corresponds to OGL 1.4 (which will be checked for explicitly as of the next release) when most graphical features are disabled by a client.
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Re: Understanding the use of texcoords in opengl/spring

Post by SpliFF »

Well I'm going ahead and writing the assimp model handler to the GL2.0 spec; largely because it's much faster and because GL3.0 won't support the existing methods anyway. Unless there is a massive uproar from owners of GeForce 2/3 cards (assuming spring even runs on them) I see no major harm. A GeForce 4, which is the minimum spec for shaders goes for $5-10 assuming you can't just find one in a dumpster.

http://www.opengl.org/wiki/GlVertexAttribPointer
User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Understanding the use of texcoords in opengl/spring

Post by hoijui »

the problem there would be, for low tech notebooks and netbooks, as they often have graphics with OpenGL 1.4 only (eg. Intel 945G).
This would only be a problem of course, if spring would not run anymore without OpenGL 2. if it will only fail for high tech mods/games that use your model format, it wont be a problem (as long as BA still works ;-) ).
User avatar
SpliFF
Posts: 1224
Joined: 28 Jul 2008, 06:51

Re: Understanding the use of texcoords in opengl/spring

Post by SpliFF »

hoijui wrote:the problem there would be, for low tech notebooks and netbooks, as they often have graphics with OpenGL 1.4 only (eg. Intel 945G).
This would only be a problem of course, if spring would not run anymore without OpenGL 2. if it will only fail for high tech mods/games that use your model format, it wont be a problem (as long as BA still works ;-) ).
Yeah older laptops and onboard graphics are an issue. I guess i'll keep the GL 1.4 pipeline around for now but only enable it via user setting or when GL 2.0 extensions aren't supported by the hardware (which is what happens now anyway).
Post Reply

Return to “Engine”