Last post about 2D in OpenGL (so please stop!)

Started by
33 comments, last by vincoof 19 years, 10 months ago
quote:Original post by Puzzler183
Also, the OpenGL PixelCopy functions are ridiculously slow.


You mean glReadPixels? Yes, it''s slow, but it''s not necesseraly OpenGL''s fault. The AGP bus is optimized for writing to the Video memory, not retrieving data from it so reading back pixels, which requires the driver to lock the framebuffer in video memory and send data back on the bus to system memory is slow. If you want software rendering, i think MesaGL is what you are looking for.

Advertisement
lol, i have almost the same exact functions in my game for drawing 2D UI stuff

- Voxelz
Great Job on the sticky.

One thing though - On the implementation example, can you change the last "glVertex2D(50, 50);" to "glVertex2d(50, 50);" so newbies like me won''t have to use their brains.
The same, essentially, except in lwjgl/java.

Haven''t tested it yet, but it compiles, so here it is. Licenced the same as the original.

(I was working on my snippet library and wanted to add this back to where it came from)

import org.lwjgl.opengl.GL11;public final class OpenGL2D extends java.lang.Object {	public static void glEnable2D() {		java.nio.IntBuffer vPort = java.nio.IntBuffer.allocate(4);		GL11.glGetInteger(GL11.GL_VIEWPORT, vPort);		GL11.glMatrixMode(GL11.GL_PROJECTION);		GL11.glPushMatrix();		GL11.glLoadIdentity();		GL11.glOrtho(0, vPort.get(2), 0, vPort.get(3), -1, 1);		GL11.glMatrixMode(GL11.GL_MODELVIEW);		GL11.glPushMatrix();		GL11.glLoadIdentity();	}	public static void glDisable2D() {		GL11.glMatrixMode(GL11.GL_PROJECTION);		GL11.glPopMatrix();   		GL11.glMatrixMode(GL11.GL_MODELVIEW);		GL11.glPopMatrix();		}}
Also, if you want to be able to access the screen in floating-point with the left side being -1.0 and the top being -1.0 (bottom and right still 1.0), you can do:

gluOrtho2D( 0.0, 0.0, 1.0, 1.0 );

[Edited by - fyhuang on August 31, 2005 11:25:03 AM]
- fyhuang [ site ]
I love you guys. All of you. You know that? I haven''t been here for over two years, and you still have that post. :tears in eyes: =D

You guys rock!
----------[Development Journal]
Nice tip.
May I point few enhancements ?

1- don't mandate viewport[0] and viewport[1] are null. In the generic case, it's better to call that instead :
glOrtho(vPort[0], vPort[0]+vPort[2], vPort[1], vPort[1]+vPort[3], -1, 1);

2- for pixel-exact positioning, the usage of a slight translation is mandatory, as explained in the opengl.org's FAQ :
glMatrixMode(GL_MODELVIEW);glPushMatrix();glLoadIdentity();glTranslatef(0.375, 0.375, 0.);


3- disable depth testing while rendering 2D. But this means 2D stuff has to be rendered AFTER all 3D stuff, in case 2D represents some kind of HUD (acronym of Heads Up Display).

So the new code becomes :
void glEnable2D(){   int vPort[4];   glGetIntegerv(GL_VIEWPORT, vPort);   glMatrixMode(GL_PROJECTION);   glPushMatrix();   glLoadIdentity();   glOrtho(vPort[0], vPort[0]+vPort[2], vPort[1], vPort[1]+vPort[3], -1, 1);   glMatrixMode(GL_MODELVIEW);   glPushMatrix();   glLoadIdentity();   glTranslatef(0.375, 0.375, 0.);   glPushAttrib(GL_DEPTH_BUFFER_BIT);   glDisable(GL_DEPTH_TEST);}void glDisable2D(){   glPopAttrib();   glMatrixMode(GL_PROJECTION);   glPopMatrix();      glMatrixMode(GL_MODELVIEW);   glPopMatrix();       }


Keep up the good work =)
For me the important thing is speed, I have 2D and 3D elements every frame and it is important that the framerate not suffer to bad. I came up with the idea of saving the matrix and reloading it, instead of recalculating it, I have not tested for a speed difference, but it seems as though it would have to be faster.

Basically, you would call both the Perspective#D functions at the start of the program and then call the Render#D function before you draw depending on what you want to draw.

#define RENDER_2D 2030#define RENDER_3D 2031double* matrix2D = new float[16];double* matrix3D = new float[16];short renderMode;void Perspective3D(float p_fov, float p_near, float p_far, float width, float height) {	renderMode = RENDER_3D;	float lw = (float)width, lh = (float)height;	if(height == 0) height = 1;	glViewport(0,0,width,height);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	gluPerspective(p_fov,lw/lh,p_near,p_far);	glMatrixMode(GL_MODELVIEW);	glGetDoublev(GL_PROJECTION_MATRIX , matrix3D);	glLoadIdentity();}void Render3D() {	if(renderMode==RENDER_3D) return;	renderMode = RENDER_3D;	glMatrixMode(GL_PROJECTION);	glLoadMatrixd(matrix3D);	glMatrixMode(GL_MODELVIEW);}void Perspective2D(RECT size) {	renderMode = RENDER_2D;	glViewport(size.left, size.bottom, size.right, size.top);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	gluOrtho2D(size.left, size.right, size.bottom, size.top);	glMatrixMode(GL_MODELVIEW);	glGetDoublev(GL_PROJECTION_MATRIX, matrix2D);	glLoadIdentity();}void Render2D() {	if(renderMode==RENDER_2D) return;	renderMode = RENDER_2D;	glMatrixMode(GL_PROJECTION);	glLoadMatrixd(matrix2D);	glMatrixMode(GL_MODELVIEW);}
www.EberKain.comThere it is, Television, Look Listen Kneel Pray.
my guess is that push/pop is faster than get/load, and it also saves memory. The only problem with push and pop is that you're limited in some (quite high, yet limited) stack depth.
Push / Pop would be faster, but thats not all you would be doing. Any way you look at it you have to get the new Matrix into the projection matrix stack. I would think that calling glLoadMatrix is faster than glOrtho or another function that has to re-calculate the matrix every frame. Memory... its 16 doubles, thats like 128 bytes, I dont think thats to much to sacrifice for a possible speed gain.
www.EberKain.comThere it is, Television, Look Listen Kneel Pray.

This topic is closed to new replies.

Advertisement