Home » Community » Forums » OpenGL » Last post about 2D in OpenGL (so please stop!)
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic

Page:    «« 1 2

 Last Thread Next Thread 
 Last post about 2D in OpenGL (so please stop!)
Post New Topic  Post Reply 
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!

 User Rating: 1117   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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 =)

 User Rating: 1260   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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 2031

double* 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.com

There it is, Television, Look Listen Kneel Pray.

 User Rating: 1020   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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.

 User Rating: 1260   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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.com

There it is, Television, Look Listen Kneel Pray.

 User Rating: 1020   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Original post by Eber Kain

I would think that calling glLoadMatrix is faster than glOrtho or another function that has to re-calculate the matrix every frame.


Sure, but in the method you posted you call glOrtho as often as I do. :) So where's the performance loss ?

And while you're pointing correctly that glLoadMatrix may be faster than glOrtho, I'd like to point that glGetDoublev is much slower than any kind of matrix operation. In general, anything read back from the server side should be discarded when you look for the highest performance.

 User Rating: 1260   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Optimising this for speed is a complete waste of time. Unless you're switching between 2D and 3D thousands of times per frame, you won't see any noticeable increase in frame rate.

 User Rating: 1489   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

In the code I posted, you call Perspective#D once in your entire program. You then call Render#D before drawing to specify if you want 2D or 3D.

www.EberKain.com

There it is, Television, Look Listen Kneel Pray.

 User Rating: 1020   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

OKey GRATE so now how d0 I trun this into a gaeM?!?!?!????

(P.S. Thanks, that's awesome, and makes me almost wish I used OpenGL)

 User Rating: 1019   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Quote:
Original post by Eber Kain
In the code I posted, you call Perspective#D once in your entire program.

Yes it is called thousands of time during the game, but what's important is that it's called once PER FRAME. It's true that optimizing every part of the engine is always a gain, but it's also true that if the performance gain makes almost no difference you'd better spend your time on other optimization things that will significantly improve frame rate, and come back later (probably in the end) on such negligible improvements.

Quote:
Original post by Tube
OKey GRATE so now how d0 I trun this into a gaeM?!?!?!????

Sure, I have the three lines of code solution that makes anything a great game everyone would love. Mind me if I post it later ?

 User Rating: 1260   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Page:    «« 1 2
All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: