Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: upside-down textures in OpenGL  (Read 25247 times)

0 Members and 1 Guest are viewing this topic.

Tabasco

  • Newbie
  • *
  • Posts: 8
    • View Profile
upside-down textures in OpenGL
« on: May 25, 2009, 07:34:47 pm »
I've been moving one of my projects from GLFW to SFML.  The transition has been relatively simple, but with SFML when I load my models the textures are upside-down.

I have some models that I've made and UV-mapped in blender as well as some procedurally generated terrain meshes and the behavior has been the same.  I've tried storing the textures as jpg and png instead of tga, but as of yet, the only way I can get it looking right is to go into gimp and mirror the image.

This is what I'm getting:
The textures, original and flipped: http://tyranny.ckt.net/tabasco/kilntex.jpg

The results:
http://tyranny.ckt.net/tabasco/kiln1.jpg
http://tyranny.ckt.net/tabasco/kiln2.jpg

(I'm not particularly artistic, but there it is)

I'm loading textures almost exactly like I did in GLFW and SDL before that.  There are only a few minor differences:

Code: [Select]

    sf::Image Image;

    if (!Image.LoadFromFile(texname)) { return(0); }

    glGenTextures(1, &texid);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glBindTexture(GL_TEXTURE_2D, texid);

    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Image.GetWidth(), Image.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, Image.GetPixelsPtr());


I've compiled it in Windows XP and Ubuntu 9.04 with no visible difference.
Any ideas?

Tabasco

  • Newbie
  • *
  • Posts: 8
    • View Profile
upside-down textures in OpenGL
« Reply #1 on: May 25, 2009, 08:22:21 pm »
Just to be thorough, I made some adjustments to the OpenGL demo program bundled with SFML1.4.

The rotation has been removed and all of the quads but one have been commented out.

Code: [Select]

glTexCoord2f(0, 0); glVertex3f(-50.f, -50.f, 50.f);
glTexCoord2f(0, 1); glVertex3f(-50.f,  50.f, 50.f);
glTexCoord2f(1, 1); glVertex3f( 50.f,  50.f, 50.f);
glTexCoord2f(1, 0); glVertex3f( 50.f, -50.f, 50.f);


http://tyranny.ckt.net/tabasco/smile.jpg

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
upside-down textures in OpenGL
« Reply #2 on: May 25, 2009, 09:55:26 pm »
The OpenGL demo uses a perspective projection with the Y axis pointing upwards. The result is just as expected.
Laurent Gomila - SFML developer

Tabasco

  • Newbie
  • *
  • Posts: 8
    • View Profile
upside-down textures in OpenGL
« Reply #3 on: May 25, 2009, 10:27:31 pm »
Quote from: "Laurent"
The OpenGL demo uses a perspective projection with the Y axis pointing upwards. The result is just as expected.


If it's the projection, wouldn't all of my geometry be upside-down as well, not just the texture assignment?
Based on how opengl views texture coordinates
( http://www.gamedev.net/reference/programming/features/ogltm/texcoord.jpg )
the texture should not be upside-down on the above quad.
The quad starts in the lower left corner, then the upper left, moving clockwise and the texture coordinate provided for the bottom corner of the quad would correlate to the bottom corner of the texture image.

After a little more reading I came across this:
http://www.devolution.com/pipermail/sdl/2005-February/067479.html

If the data provided by sf::Image uses a top-left origin, it would be upside down in OpenGL.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
upside-down textures in OpenGL
« Reply #4 on: May 25, 2009, 11:36:31 pm »
Quote
Based on how opengl views texture coordinates
( http://www.gamedev.net/reference/programming/features/ogltm/texcoord.jpg )
the texture should not be upside-down on the above quad.

This picture confuses me. I've always thought the origin for texture mapping was the top-left corner. And I never got flipped textures so far.

Unfortunately I can't find any reliable source other than this tutorial.
Laurent Gomila - SFML developer

Imbue

  • Full Member
  • ***
  • Posts: 104
    • View Profile
upside-down textures in OpenGL
« Reply #5 on: May 26, 2009, 12:27:53 am »
I think that texture coordinates go with the geometry coordinates. So if your geometry has the Y axis pointing down, your texture coordinates should too.

Tabasco

  • Newbie
  • *
  • Posts: 8
    • View Profile
upside-down textures in OpenGL
« Reply #6 on: May 26, 2009, 12:45:16 am »
I'm surprised this isn't explained better than it is.  So far the best I've found is point 12 here:
http://www.opengl.org/resources/features/KilgardTechniques/oglpitfall/

Quote
Another common pitfall related to 2D rendering APIs having an upper left-hand coordinate system is that 2D image file formats start the image at the top scan line, not the bottom scan line. OpenGL assumes images start at the bottom scan line by default.


The NeHe tutorials and other implementations I've found scattered across the Internet all flip the image so that the origin is at the lower-left corner as well, but they don't explain why.  :(

I guess my question now is, what's the fastest way to swap the row order in an sf::Image?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
upside-down textures in OpenGL
« Reply #7 on: May 26, 2009, 07:48:54 am »
Quote
I guess my question now is, what's the fastest way to swap the row order in an sf::Image?

You can't do it with sf::Image. The best solution is to do iy yourself, using GetPixelsPtr() and a temporary array to hold the flipped pixels.

However I'm going to look into this, maybe I can fix it directly in SFML.
Laurent Gomila - SFML developer

Tabasco

  • Newbie
  • *
  • Posts: 8
    • View Profile
upside-down textures in OpenGL
« Reply #8 on: May 28, 2009, 12:57:07 am »
Thanks!  I appreciate that you're really active on this project and I'm looking forward to seeing how it grows.

In the mean time I'm just flipping rows like this

Code: [Select]

    GLuint imgsize = (Image.GetWidth() * Image.GetHeight()) * 4;
    GLuint rowsize = Image.GetWidth() * 4;
    sf::Uint8 *newimg = (sf::Uint8*) malloc(imgsize+1);
    const sf::Uint8 *oimg = Image.GetPixelsPtr();

    GLuint x;
    for(x = 0; x < Image.GetHeight(); x++)
    {
        memcpy(newimg + (x * rowsize), (oimg + imgsize) - (rowsize + (rowsize * x)), rowsize);
    }
    //Is this necessary?
    newimg[imgsize+1] = '\0';

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
upside-down textures in OpenGL
« Reply #9 on: May 28, 2009, 07:57:36 am »
Quote
Code: [Select]
   //Is this necessary?
    newimg[imgsize+1] = '\0';

No, it's not a string :D

And you should really use std::vector instead of malloc (unless your code is pure C).
Laurent Gomila - SFML developer

vpoqol5

  • Newbie
  • *
  • Posts: 5
    • View Profile
upside-down textures in OpenGL
« Reply #10 on: May 30, 2009, 02:05:54 pm »
Yes, this should be fixed in sfml
I came across it few weeks ago when I was porting part of my framework for another project to sfml, but, because I have my own implementations for every operation I need, I fixed it as easy as changing variable v to -v, better explained

Code: [Select]

glTexCoord2f(pVertex->u,pVertex->v);

(obviously, I use triangles in my rendering code)

I found a number of "misunderstandings" but they hardly make me any problem, because I don't depend on sfml functions, but I'll post all of them when I find time for it,
anyway, it's a really good library, and I'm impressed, I hardly ever used another library than my knowledge for writing portable applications and "universal" functions but I could use half of them from sfml to change mine  

great work, keep up ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
upside-down textures in OpenGL
« Reply #11 on: May 31, 2009, 05:54:37 pm »
Well, I made more tests, very simple ones just displaying an OpenGL texture on a quad. They clearly demonstrate that the texture origin is at the top-left corner of the image. More researches on Google resulted in 50% messages saying it's top-left, and the 50 other % saying it's bottom-left.

What a confusion :lol:

Anyway, based on my tests I'm not going to change SFML's behaviour, unless someone clearly proves me I'm wrong.
Laurent Gomila - SFML developer

dabo

  • Sr. Member
  • ****
  • Posts: 260
    • View Profile
    • http://www.dabostudios.net
upside-down textures in OpenGL
« Reply #12 on: May 31, 2009, 06:53:15 pm »
I'm pretty sure it says in my OpenGL book it's bottom-left. I wish I had it with me so that I could check for sure.

vpoqol5

  • Newbie
  • *
  • Posts: 5
    • View Profile
upside-down textures in OpenGL
« Reply #13 on: May 31, 2009, 08:35:46 pm »
Ok, I'll put it this way
I'm programming in opengl for about five years now and this is my "job", so I'm pretty sure that origin is at bottom left,
you can see it in superbible 1,2,3 and 4th editiion, in beginning opengl game programming on page 151, the offical guide to learning opengl version 2.1 6th edition on page 378, OpenGL Graphics
Through Applications page 171, 175

But actually don't mind that, my question is, where have you seen it as being applied to top left? This is first time that I hear about that, truly :)

The mapping process involves moving from the texture space to the Cartesian space, and origin is defined as bottom left in both scenarios

Tabasco

  • Newbie
  • *
  • Posts: 8
    • View Profile
upside-down textures in OpenGL
« Reply #14 on: May 31, 2009, 11:34:37 pm »
It's been bottom left since I've been using opengl and every other engine or framework I've used treats it that way.  When I export models from blender, and presumably any other modeling software, the UV's are/would be all upside down.
The article I posted is from opengl.org and the author (http://en.wikipedia.org/wiki/Mark_Kilgard) is credible, so if that's not enough proof, I don't know what is.
It really is shocking to me that it isn't documented any better than it is but opengl clearly reads textures starting with the bottom row.