Jump to content
  • Advertisement
Sign in to follow this  
Specchum

OpenGL Mixing the Ortho and Perspective views: issues

This topic is 4683 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Yep, me again with yet another OGLES issue. :) Following on from the help I had from here with the view matrix last time, I have a camera that I can move around and rotate etc. Now I'm trying to render some sprites on the screen to display fonts and other 2d effects. I have a sprite class for this purpose that sets up a quad with u, v co-ords and has a render method to render the sprite, like this:
CSprite::CSprite(igInt32 id, CVector3 pos, CVector3 size)
{
 imageId = id;
 position = pos;
 scale = size;
	
 //build a quad centered on position
 vertex[0] = CVector3(-scale.x + position.x, position.y + scale.y,  position.z);
 vertex[1] = CVector3(-scale.x + position.x, position.y - scale.y, position.z);
 vertex[2] = CVector3(scale.x + position.x, position.y + scale.y, position.z);
 vertex[3] = CVector3(scale.x + position.x, position.y - scale.y, position.z);
};

//more stuff to set up tex-coords skipped here

//not the most efficient render method but I thought I'll start simple ;)
void CSprite::Render()
{
 igInt16 indices[6] = {0,1,2,2,1,3};
 glVertexPointer (3, GL_FIXED, 0,  vertex);
 glTexCoordPointer(3, GL_FIXED, 0, texCoord);
 glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_SHORT, indices);
};

My camera view matrix is being set up like this:
void CCamera::SetView()
{
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 igFixed viewmatrix[16]=
 {
  right.x, up.x, -forward.x, 0,
  right.y, up.y, -forward.y, 0,
  right.z, up.z, -forward.z, 0,
  -(FixMul(right.x,position.x) + FixMul(right.y,position.y) +  FixMul(right.z,position.z)),
  -(FixMul(up.x, position.x) + FixMul(up.y , position.y) + FixMul(up.z , position.z)), 
  (FixMul(forward.x, position.x) + FixMul(forward.y, position.y) + FixMul(forward.z, position.z)), 
  ITOX(1)
};

 glMultMatrixx(viewmatrix);
 glTranslatex(-position.x, -position.y, -position.z);
};
FixMul is a function that multiplies two fixed point values together. I'm using OpenGL ES with BREW and so I'm using fix point mathematics. Which is why some GL functions have the 'x' suffix. Anyway, no problems with the view matrix. Everything looks and works fine. Now then when it's time to render something I do tell my render class to render a model viz (bear with me!):
void CRenderer::Render(CModel* model)
{
 glEnableClientState(GL_VERTEX_ARRAY);
 glEnableClientState(GL_NORMAL_ARRAY);
 glEnableClientState(GL_COLOR_ARRAY);
 glEnableClientState(GL_TEXTURE_COORD_ARRAY);   
 glEnable(GL_TEXTURE_2D);

 //cache the vertex size
 const igInt32 CVERTEX_SIZE = sizeof(CVertex);

 for(igInt32 i = 0; i < model->nMaterials; ++i)
 {
  igFixed mat_col[] = {model->materialBuffer.diffuse.r,
			model->materialBuffer.diffuse.g,
			model->materialBuffer.diffuse.b,
			model->materialBuffer.diffuse.a};
		
  glMaterialxv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_col);
  glBindTexture(GL_TEXTURE_2D, model->materialBuffer.texture->id);
  for (igInt32 j = 0; j < model->nMeshes; ++j)
  {
	if (model->mesh[j].materialId == model->materialBuffer.id)
	{
  		glVertexPointer (3, GL_FIXED,	CVERTEX_SIZE, (void *)  &model->mesh[j].renderBuffer->position);
 		glNormalPointer  (GL_FIXED,		CVERTEX_SIZE, (void *) &model->mesh[j].renderBuffer->normal);
		glColorPointer   (4, GL_FIXED,	CVERTEX_SIZE, (void *) &model->mesh[j].renderBuffer->diffuse);
		glTexCoordPointer(2, GL_FIXED,  CVERTEX_SIZE, (void *) &model->mesh[j].renderBuffer->u);
			
		glDrawElements(GL_TRIANGLES, model->mesh[j].nIndices * 3, GL_UNSIGNED_SHORT, model->mesh[j].indexBuffer);
	}
  } //mesh loop
 }	//material loop
	
 glFlush();
	
 glDisableClientState(GL_VERTEX_ARRAY);
 glDisableClientState(GL_NORMAL_ARRAY);
 glDisableClientState(GL_COLOR_ARRAY);
 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
Works well enough. Need to optimise it later on. When it's time to render the world and the sprite I do this (the last bit of code, really):
void CGame::ShowDisplay(void)
{
	renderer->BeginFrame();
	camera->SetView();

	renderer->Render(world);
	
        //setup ortho mode for sprite rendering	
	glMatrixMode(GL_PROJECTION);
	renderer->LoadIdentity();
	glOrthox(0,0,240,320,0,1);
	renderer->RenderSprites();
	
	//switch back to perspective mode
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
	renderer->EndFrame();
}
The above bit doesn't work though. If I comment the SetView call, then my sprites render correctly, but uncommenting it shows nothing on the screen. To render only the world I need to comment the entire ortho mode setting up process and not call the RenderSprites function. Can anyone tell me what I'm doing wrong here? Why am I not able to switch between the modes cleanly?

Share this post


Link to post
Share on other sites
Advertisement
To render the sprites, your need to switch back to the MODELVIEW matrix mode after setting ortho mode (before rendering the sprites). Then, when done with the sprites, you need to go back to projection mode with a glMatrixMode(GL_PROJECTION) and glFrustum() call. Once back in projection mode, don't forget to set the matrix mode back to MODELVIEW again.

As far as I know, setting ortho mode overrides the old projection mode, and therefor it needs to be reinstated again. Also, you should always be in MODELVIEW matrix mode when actually rendering. The other modes are for setting up perspective.

Share this post


Link to post
Share on other sites

void Begin2D ( void )
{
glDisable ( GL_DEPTH_TEST );
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, Width, 0, Height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}

void End2D ( void )
{
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glEnable ( GL_DEPTH_TEST );
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!