Jump to content
  • Advertisement
Sign in to follow this  
Andybean9

OpenGL OpenGL Drawing with MFC Problem

This topic is 5397 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

Hi all, I have been working on a 3D level editor in openGL using the CSplitterWnd class to split the viewport. Now I know there have been a lot of posts on this issue, but that is not my problem. My problem to me seems to be completely random. I can draw to all viewports just fine, I can also manipulate the objects and move them around and they update in the views just fine. My problem comes in when I try to draw my textured models to the window. Everytime I run the program and import a model into it, it seems to only show the model textured in one viewport, and a random viewport it seems like. The other 3 viewports it just shows the model as grey. I have checked all openGL color calls to see if somewhere I was overriding the color call at some point and I'm not. The hard thing for me to understand is I use the same function to draw in all viewports. I also checked the color data that is supposed to be shown on the screen and from the one that is being drawn properly to the ones that aren't the color data is identical and valid. Here is my OpenGL initiation code
	//Get a DC for the Client Area
	m_pDC = new CClientDC(this);

	//Failure to Get DC
	if( m_pDC == NULL )
		return FALSE;

	if( !SetupPixelFormat() )
		return FALSE;

    //Create Rendering Context
	m_hRC = ::wglCreateContext( m_pDC->GetSafeHdc() );

    //Failure to Create Rendering Context
    if( m_hRC == 0 )
        return FALSE;

	//Make the RC Current
	if( ::wglMakeCurrent( m_pDC->GetSafeHdc(), m_hRC ) == FALSE )
		return FALSE;

	float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);

	// Usual OpenGL stuff
	glClearColor( 0.5f, 0.5f, 0.5f, 0.0f );
	glClearDepth(1.0f);
	glEnable( GL_DEPTH_TEST );
	glEnable( GL_TEXTURE_2D );
	glEnable(GL_LIGHTING);

	SetTimer(0, 30, 0);

	return TRUE;

Here is my draw code that is used for all windows:
	// Draw the models
	glPushMatrix();
		
		CLList<CBaseObj *>::CIterator iter;
		for (iter = CRenderFunctions::GetInstance()->DrawList.Front(); !iter.End(); iter++)
		{
			glPushMatrix();	
				// Object Transform
				glMultMatrixf(iter.Element()->RotMatrix);

				// A list of all the triangles
				CArray<Triangle> TriList;
				// A list that uses the TriList to reference which verts are part of a triangle
				CArray<Vertex> VertList;
				// Will hold the texture ID of a model
				int iTexID = 0;
				// Gets the triangle, vertex and texture ID of a model
				CModelManager::GetInstance()->GetMesh(TriList, VertList, iter.Element()->ModelTag, &iTexID);
				// Binds the texture to be drawn
				CTextureManager::GetInstance()->BindTexture(iTexID);

				// Draw the mesh
				glBegin(GL_TRIANGLES);
					for (int j = 0; j < TriList.Size(); j++)
					{
						// Change the color of the model to reflect it's been selected
						if(iter.Element()->Selected)
							glColor3f(0.0f,0.0f, 0.8f);
						// If it's not selected use the color data in the model file
						else
							glColor3fv(TriList[j].RGB);
						for (int k = 0; k < 3; k++)
						{
							glTexCoord3fv(VertList[TriList[j].points[k]].UV);
							glVertex3fv(VertList[TriList[j].points[k]].pos);
						}
					} // End iteration of triangle list for this object
				glEnd();
			glPopMatrix();
		} // End iteration of object

	glPopMatrix();

I hope someone can see any problems in this code, or if this is not enough information please let me know as I have been struggling with this problem for quite a while now. Thank you.

Share this post


Link to post
Share on other sites
Advertisement
At the moment, your textures are only being loaded into one rendering context. That's fine, but you need to use the wglShareLists function to allow the other rendering contexts to share those textures. With wglShareLists, you only load textures into one rendering context, but all your others have access to them, so you can use the same texture ID over multiple RCs. The best method I found was to have a global rendering context, created from your main CFrameWnd (the one the splitter is in) at the start of the program. Load that context when you load your textures, then call wglShareLists once for all the other rendering contexts in your program. Of course, you can just load the textures into the rendering context of one of your child windows, and get the others to share that, if it's easier. Whichever method you choose, you won't need to change your drawing code at all...

[Edited by - iNsAn1tY on September 29, 2004 5:38:29 PM]

Share this post


Link to post
Share on other sites
Hi,
Thanks for the reply. I tried what said to do and I couldn't quite get it to work. Now when I draw there are no textures in any of the windows. I made a global rendering context in my CProgramNameDoc class and created the context with wglCreateContext in the constructor. Then whenever I load a model I call wglMakeCurrent on that RC. Before I draw in any of the viewports I call the wglShareLists function. Can you think of any reason why this isn't working? Thank you.

-Andrew

Share this post


Link to post
Share on other sites
You might need to post the code to solve this one.

Things to check before you do that:

1. Is the hDC you use valid? I assume you're creating it from your main CFrameWnd?
2. Have you used the same setup code for the global RC as you have for all the others?
3. Are you calling wglShareLists with the arguments the wrong way round (happened to me :)?

Try creating the hRC in the OnCreate member of your main CFrameWnd, and having it as a global variable. This is the code I use, in CMainFrame::OnCreate() (there's no error checking or anything, haven't got round to that yet):


// Get a hDC...
g_hDC = ::GetDC(this->GetSafeHwnd());
::wglMakeCurrent(g_hDC, NULL);

// Get a hRC...
int iPixelFormat = ::ChoosePixelFormat(g_hDC, &pfd);
::SetPixelFormat(g_hDC, iPixelFormat, &pfd);
g_hRC = ::wglCreateContext(g_hDC);



Plus, you don't need to call wglShareLists before you render each window. You only need to call it once (I think), after the window and it's rendering context are created, so make sure the global hRC has been created by the time your child windows are created.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!