flip opengl viewport upside-down (-y)

Started by
8 comments, last by nimnimnim 13 years, 2 months ago
Hello. I'm building a Cairo app using the code from the gl-cairo-simple example found on the Cairo website.
The code where I pass opengl the image buffer is this:


glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClear (GL_COLOR_BUFFER_BIT);

glPushMatrix ();

glBindTexture (GL_TEXTURE_RECTANGLE_ARB, m_texture_id);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_cairo_surface_data);

glColor3f (0.0, 0.0, 0.0);
glBegin (GL_QUADS);
glTexCoord2f (0.0f, 0.0f);
glVertex2f (0.0f, 0.0f);
glTexCoord2f ((GLfloat) m_width, 0.0f);
glVertex2f (1.0f, 0.0f);
glTexCoord2f ((GLfloat) m_width, (GLfloat) m_height);
glVertex2f (1.0f, 1.0f);
glTexCoord2f (0.0f, (GLfloat) m_height);
glVertex2f (0.0f, 1.0f);
glEnd ();

glPopMatrix ();

SDL_GL_SwapBuffers();

how should I flip the entire viewport upside down?

any suggestions on how to change the code alltogether (perhaps glMatrixMode (GL_PROJECTION);?) would also be welcome.
Advertisement
If you want to control which direction is up, it's usually done with the projection matrix, for example when using glOrtho or gluOrtho2d you can switch the place of the top and bottom arguments (usually 0 and height, or 0 and 1).
If you just want to flip something you draw on the Y-axis, you can use glScalef(1.0f, -1.0f, 1.0f) to manipulate the matrix to flip around the current Y=0 axis.

If you want to control which direction is up, it's usually done with the projection matrix, for example when using glOrtho or gluOrtho2d you can switch the place of the top and bottom arguments (usually 0 and height, or 0 and 1).
If you just want to flip something you draw on the Y-axis, you can use glScalef(1.0f, -1.0f, 1.0f) to manipulate the matrix to flip around the current Y=0 axis.


thanks for the reply. however that just made my viewport blank. I tried inserting it everywhere... I've never programmed opengl before so I'm totally lost here and while it'd be good to read up on it this short piece of code is really all the related opengl code in my project and there won't be any more later either I should think... :-/

could you give me some short hints on how to alter the code to use projection instead of modelview and where to use glOrtho and glScalef?
What is the purpose of flipping the viewport?
If you want to display your texture upside down, then you can just change the tex-coords, so you set the tex-coord y to m_height when the vertex y is 0.0f, and change the m_height to a 0 where the vertex y is 1. This will make your texture flip vertically.

glTexCoord2f (0.0f, 0.0f/*change to m_height*/);
glVertex2f (0.0f, 0.0f);


As for the scaling, when you draw your quad from 0,0 to 1,1 like you do now, does it cover the entire screen your just the top right corner?
When you use glScale(1,-1,1) that quad will turn to 0,0 to 1,-1. Normally 0,0 is in the middle of the screen which makes this work fine, but otherwise your quad might be outside the screen with the scale.
In addition, you might need to use glDisable(GL_CULL_FACE) when scaling like that.

When you use a projection matrix, you can specify your vertex-coordinates in screen pixels instead of from 0.0f to 1.0f.

// To specify coordinates in exact pixels, have width/height match your window-size
// If you set width to 5.0, then 5.0f is the right side of the screen
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0, width, height, 0, 0, 1);

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();


In addition, you should only call glTexImage2d in init code, and not every frame, unless the texture is animated and the pixel values update every frame. glTexImage2d sets up the texture, and then it can be used extremely fast from video memory. Every time you call glTexImage2d it resets the texture and loads all the memory to the graphics card again, which is expensive. So once it is set up, you only need to call glBindTexture the next time, as OpenGL will remember the pixels.
[color="#1C2837"]the reason I'm calling glTexImage2d every frame is that I'm using opengl as a backend to a 2D graphics surface (Cairo vector graphics) like they do in http://cairographics.org/OpenGL/ gl-cairo-simple example at the Cairo website which is whence all of my gl code came.
the
[color="#1C2837"][color="#000000"]glMatrixMode [color="#666600"]([color="#000000"]GL_PROJECTION[color="#666600"]);[color="#000000"]
glLoadIdentity [color="#666600"]();[color="#000000"]
glOrtho[color="#666600"]([color="#006666"]0[color="#666600"],[color="#000000"] width[color="#666600"],[color="#000000"] height[color="#666600"], [color="#006666"]0[color="#666600"], [color="#006666"]0[color="#666600"], [color="#006666"]1[color="#666600"]);[color="#000000"]

glMatrixMode [color="#666600"]([color="#000000"]GL_MODELVIEW[color="#666600"]);[color="#000000"]
glLoadIdentity
code made my viewport go blank aswell. OTL

[color="#1c2837"]the reason I'm calling glTexImage2d every frame is that I'm using opengl as a backend to a 2D graphics surface (Cairo vector graphics) like they do in http://cairographics.org/OpenGL/ gl-cairo-simple example at the Cairo website which is whence all of my gl code came.
the
[color="#1c2837"][color="#000000"]glMatrixMode [color="#666600"]([color="#000000"]GL_PROJECTION[color="#666600"]);[color="#000000"]
glLoadIdentity [color="#666600"]();[color="#000000"]
glOrtho[color="#666600"]([color="#006666"]0[color="#666600"],[color="#000000"] width[color="#666600"],[color="#000000"] height[color="#666600"], [color="#006666"]0[color="#666600"], [color="#006666"]0[color="#666600"], [color="#006666"]1[color="#666600"]);[color="#000000"]

glMatrixMode [color="#666600"]([color="#000000"]GL_MODELVIEW[color="#666600"]);[color="#000000"]
glLoadIdentity
code made my viewport go blank aswell. OTL


You said earlier that something didn't work, but he gave you more than one option. What were you referring to there? Scaling it by -1 on the y axis should work fine.
Did you try disabling face culling?
When you switch the Y-axis direction every front-face becomes a back-face, so that means you need to either disable face-culling or change the winding of the front-face.
I tried glDisable(GL_CULL_FACE); and then glScalef(1,-1,1); but either way my viewport is blank. really appreciate the help :) I wish I'd have a better understanding of it!
Try the following.

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0.0, 100.0, 100.0, 0.0, -1.0, 1.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClear (GL_COLOR_BUFFER_BIT);

glPushMatrix ();

glBindTexture (GL_TEXTURE_RECTANGLE_ARB, m_texture_id);
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, m_cairo_surface_data);

glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glColor3f (1.0, 1.0, 1.0);
glBegin (GL_QUADS);
glTexCoord2f (0.0f, 0.0f);
glVertex2f (0.0f, 0.0f);
glTexCoord2f ((GLfloat) m_width, 0.0f);
glVertex2f (100.0f, 0.0f);
glTexCoord2f ((GLfloat) m_width, (GLfloat) m_height);
glVertex2f (100.0f, 100.0f);
glTexCoord2f (0.0f, (GLfloat) m_height);
glVertex2f (0.0f, 100.0f);
glEnd ();

glPopMatrix ();

SDL_GL_SwapBuffers();
Ah! great that worked fine! thanks a bundle!, Erik
Regards /Erik :P

This topic is closed to new replies.

Advertisement