PDA

View Full Version : ST co-ordinate clarification



Scotopik
05-21-2009, 03:07 AM
Hi,

I'm new to OpenGL (experienced D3D), and have a simple quick question I hope to clear up.

OpenGL ST co-ordinates use the Cartesian co-ordinate system, with (0,0) at the bottom left and (1,1) at the top right of texture space.

The trouble is whenever I see a texturing example in a book, it's always got some image looking correct (upright) with a ST axis in the bottom left, with S going left->right and T going bottom->top. However, the MEMORY representation is the opposite. My understanding is the first texel is at memory address 0, and the last texel is at the end of memory.

This means if you were to use the typical example of (i.e. 1 with v0=bl, v1=br, v2=tr):



glBegin(GL_TRIANGLES);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-0.5f, -0.5f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f( 0.5f, -0.5f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f( 0.5f, 0.5f);
glEnd();


it would mean the texture is flipped in Y. Just to be sure, I built a texture in memory like such (just a texture which starts at black at T=0 and increases in blue to T=1:



{
GLushort *imageData;

imageData =(GLushort *)malloc(kTestWidth * kTestHeight * 2);

for (int y=0; y<kTestHeight; ++y) {
for (int x=0; x<kTestWidth; ++x) {
imageData[y*kTestWidth+x] = MAKE_5551_F(0,0,(float)y/kTestHeight,1);
}
}

glGenTextures(1, &amp;texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTestWidth, kTestHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, imageData);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

free(imageData);
}


This produces:

http://img199.imageshack.us/img199/5656/opengly.jpg

Which is what I would expect. I either have to flip the texture in memory (upon create if code created, or on load if loaded from a file), or flip the T co-ordinates.

So why do I see so many examples with 0,0 used in the texture co-ordinates at the bottom left, yet still render right way up? Do people tend to flip the texture in memory or the T co-ordinates?

Why is this not mentioned with respect to physical memory in books? Are my assumptions correct?

Cheers.

Xmas
05-21-2009, 04:18 AM
OpenGL ST co-ordinates use the Cartesian co-ordinate system, with (0,0) at the bottom left and (1,1) at the top right of texture space.
No. Texture space has no physical orientation, therefore "bottom left" or "top right" simply have no meaning in that space.

All you need to know is the correspondence of memory layout, as used by glTexImage2D and similar functions, to the coordinate axes in texture space. The memory you pass to these functions forms an array of rows of texels. S increases inside each row, T increases from row to row.

More specifically:
Inside each row, the S coordinate goes from (0.5/texwidth) for the texel at the lowest address, to ((texwidth - 0.5)/texwidth) for the texel at the highest address.
The T coordinate goes from (0.5/texheight) for the row at the lowest address, to ((texheight - 0.5)/texheight) for the row at the highest address.

Scotopik
05-21-2009, 06:35 AM
Hi,

Fair call on my "top right" comment. I was just trying to be practical, in that it's 0-1 but at the end of the day the interpolator is working on data from memory, hence my question. Point taken though :)

In short, my assumption is right though, in that T is moving from 0->1 row by row, starting at the beginning of the texture memory, which will flip the image upside down if the ST(0,0) is placed on the bottom left vertex and ST(1,1) on the top right vertex. However, this still leaves me confused about what is happening in books etc.

The Red Book, for instance, doesn't mention memory addresses with respect to ST (well I can't see where anyway), and uses annoyingly symmetrical textures like checker boards ;), so the problem of displaying a flipped texture doesn't present itself. Also, most examples I see usually start with ST(0,0) at the bottom left vertex, and ST(1,1) top right vertex, yet the image is oriented correctly (as if rasterised top to bottom).

So to see what was happening, I put a single white line on a black background (as a .png and a .tga), and loaded the image into RAM and sure enough, the first row in memory was white 0xFF's, so the image was upside down. Unless they're using .bmp's which are flipped in the file format.

Anyway, so all of this just makes me think most people flip the texture on-load and leave the source texture and ST's alone. That's what I'd prefer to do, because I can leave all of my packed geometry alone. It just becomes one transparent flip-on-load (or even offline flip when I'm building my texture atlas's). Does this sound right? Is this the 'norm' for OpenGL programmers?

I'm probably thinking about it too much, but I just want this clear in my mind.

Thanks again.

ZbuffeR
05-21-2009, 11:36 AM
You are making this more complex than it is.
from the manpage, about texel data :
http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml


The first element corresponds to the lower left corner of the texture
image.
Subsequent elements progress left-to-right through the remaining texels
in the lowest row of the texture image, and then in successively higher
rows of the texture image.
The final element corresponds to the upper right corner of the texture
image.

This is coherent to the way axes and texture coordinates are oriented in opengl, ie left to right, bottom to top.

So yes, if the image is stored on disk in a different layout, it has to be adapted during load. And yes, this depends on the file format.

Scotopik
05-21-2009, 04:05 PM
Ok, cool, this is how I thought it worked. People must be flipping the image on-load.

Thanks for the clarification.