www.pudn.com > OglD3DMix.rar > dxogl.cpp


#include "dxogl.h" 
 
Dxogl        *g_dxogl = NULL; 
 
LRESULT CALLBACK WndProc(	HWND	hWnd,			// Handle For This Window 
							UINT	uMsg,			// Message For This Window 
							WPARAM	wParam,			// Additional Message Information 
							LPARAM	lParam)			// Additional Message Information 
{ 
	return g_dxogl->MsgProc(hWnd, uMsg, wParam, lParam); 
} 
 
Dxogl::Dxogl() 
:D3DFVF_TRIANGLE(D3DFVF_XYZ|D3DFVF_DIFFUSE) 
{ 
	g_dxogl = this; 
	mszClassName = _T("OpenGL"); 
    mszWinTitle  = _T("DirectX和OpenGL混合"); 
	mhWnd        = NULL; 
	mbActive     = TRUE; 
 
	mdwWidth  = 640; 
	mdwHeight = 480; 
 
	//OpenGL 
	PixelFormat  = 0xFF00ff00; 
	oglColorBits = 32;          //16bits 
	hDC          = NULL; 
	hRC          = NULL; 
 
	//Direct3D 
	hr           = NULL; 
	m_pd3dDevice = NULL; 
    m_pvb        = NULL; 
 
	RenderType   = DIRECT3D;           
} 
 
Dxogl::~Dxogl() 
{ 
 
} 
 
HRESULT Dxogl::Create() 
{ 
	WNDCLASSEX wc = {sizeof(WNDCLASSEX),0, WndProc,0,0, GetModuleHandle(NULL), 
	                 LoadIcon(NULL, IDI_WINLOGO),LoadCursor(NULL, IDC_ARROW), 
	                 (HBRUSH)CreateSolidBrush(RGB(0,0,255)),NULL,mszClassName,LoadIcon(NULL,IDI_WINLOGO)}; 
    RegisterClassEx(&wc); 
 
    mhWnd = CreateWindowEx(0, mszClassName, mszWinTitle, WS_OVERLAPPEDWINDOW, 10, 10,  
		                  mdwWidth, mdwHeight, NULL, NULL, wc.hInstance, NULL); 
    ShowWindow(mhWnd, SW_SHOW); 
     
	//初始化OpenGL 和 Direct3D  
	InitOgl(); 
    InitDx(); 
    InitiaResource(); 
 
	UpdateWindow(mhWnd); 
	return S_OK; 
} 
 
HRESULT Dxogl::InitDx() 
{ 
	 
	LPDIRECT3D9    td3d9 = Direct3DCreate9(D3D_SDK_VERSION); 
     
	D3DDISPLAYMODE d3ddm; 
    td3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); 
     
	D3DPRESENT_PARAMETERS  d3dpp; 
	ZeroMemory(&d3dpp, sizeof(d3dpp)); 
	d3dpp.BackBufferCount = 1; 
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
	d3dpp.Windowed = TRUE; 
	d3dpp.BackBufferFormat = d3ddm.Format; 
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; 
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 
    d3dpp.BackBufferWidth = mdwWidth; 
	d3dpp.BackBufferHeight = mdwHeight; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
	d3dpp.hDeviceWindow = mhWnd; 
	 
	hr = td3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mhWnd,  
		                D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_pd3dDevice); 
    if(FAILED(hr)) 
	{ 
		hr = td3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mhWnd,  
			                D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pd3dDevice); 
		if(FAILED(hr)) 
		{ 
          hr = td3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, mhWnd,  
		                D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pd3dDevice); 
		} 
	} 
    SAFE_RELEASE(td3d9); 
 
	m_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE); 
	m_pd3dDevice->SetRenderState(D3DRS_ZENABLE,TRUE); 
	return S_OK; 
} 
 
HRESULT Dxogl::UinitDx() 
{ 
	SAFE_RELEASE(m_pd3dDevice); 
	return S_OK; 
} 
 
HRESULT Dxogl::InitiaResource() 
{ 
	m_pd3dDevice->CreateVertexBuffer(3 * sizeof(TRIANGLE),0,D3DFVF_TRIANGLE,D3DPOOL_DEFAULT,&m_pvb,NULL); 
     
	TRIANGLE g_verts[] = { 
		{-1.0f,-1.0f, 0.0f, 0x00ff0000}, 
		{0.0f, 1.0f, 0.0f, 0x00ffff00}, 
		{1.0f, -1.0f, 0.0f, 0x000000ff}, 
	}; 
	TRIANGLE *pverts = NULL; 
	m_pvb->Lock(0,0, (void**)&pverts, NULL); 
	memcpy(pverts, g_verts, sizeof(g_verts)); 
	m_pvb->Unlock(); 
 
 
	return S_OK; 
} 
 
HRESULT Dxogl::InitOgl() 
{ 
	static	PIXELFORMATDESCRIPTOR pfd =				// pfd Tells Windows How We Want Things To Be 
	{ 
		sizeof(PIXELFORMATDESCRIPTOR),				// Size Of This Pixel Format Descriptor 
		1,											// Version Number 
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,  
		PFD_TYPE_RGBA,								// Request An RGBA Format 
		oglColorBits,							    // 选择我们的颜色深度 
		0, 0, 0, 0, 0, 0,							// Color Bits Ignored 
		0,											// No Alpha Buffer 
		0,											// Shift Bit Ignored 
		0,											// No Accumulation Buffer 
		0, 0, 0, 0,									// Accumulation Bits Ignored 
		16,											// 16Bit Z-Buffer (Depth Buffer)   
		0,											// No Stencil Buffer 
		0,											// No Auxiliary Buffer 
		PFD_MAIN_PLANE,								// Main Drawing Layer 
		0,											// Reserved 
		0, 0, 0										// Layer Masks Ignored 
	}; 
     
	hDC = GetDC(mhWnd);                             //获取设备句柄 
	PixelFormat=ChoosePixelFormat(hDC,&pfd);        //选择更好的像素 
    SetPixelFormat(hDC,PixelFormat,&pfd);           //设置像素 
 
	//wgl设置 渲染上下文 
	hRC = wglCreateContext(hDC); 
	wglMakeCurrent(hDC,hRC); 
	 
	//Resize 
	glViewport(0,0,mdwWidth, mdwHeight);						// 设置当前视口 
	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix 
	glLoadIdentity();									// Reset The Projection Matrix 
	gluPerspective(45.0f, (GLfloat)mdwWidth/(GLfloat)mdwHeight, 0.1f, 100.0f); 
	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix 
	glLoadIdentity();				 
    //Resize 
 
	//InitGL 
	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading 
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background 
	glClearDepth(1.0f);									// Depth Buffer Setup 
	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing 
	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do 
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations 
 
	/* 
	BOOL	done=FALSE;								// Bool Variable To Exit Loop 
 
	fullscreen=FALSE; 
	 
	if (fullscreen)												// Attempt Fullscreen Mode? 
	{ 
		DEVMODE dmScreenSettings;								// Device Mode 
		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// Makes Sure Memory's Cleared 
		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// Size Of The Devmode Structure 
		dmScreenSettings.dmPelsWidth	= width;				// Selected Screen Width 
		dmScreenSettings.dmPelsHeight	= height;				// Selected Screen Height 
		dmScreenSettings.dmBitsPerPel	= bits;					// Selected Bits Per Pixel 
		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; 
 
		// Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. 
		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) 
		{ 
			// If The Mode Fails, Offer Two Options.  Quit Or Use Windowed Mode. 
			if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) 
			{ 
				fullscreen=FALSE;		// Windowed Mode Selected.  Fullscreen = FALSE 
			} 
			else 
			{ 
				// Pop Up A Message Box Letting User Know The Program Is Closing. 
				MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP); 
				return FALSE;									// Return FALSE 
			} 
		} 
	} 
    */ 
 
	return S_OK; 
} 
 
HRESULT Dxogl::UinitOgl() 
{ 
	wglMakeCurrent(NULL, NULL);     
	wglDeleteContext(hRC);         //释放wgl需要的RC 
	ReleaseDC(mhWnd, hDC);          //释放OpenGL需要的DC 
	return S_OK; 
} 
 
LRESULT Dxogl::MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
	switch (msg)									// Check For Windows Messages 
	{ 
	    case WM_ACTIVATEAPP: 
            mbActive = (BOOL)wParam; 
		break; 
 
		case WM_CLOSE:								// Did We Receive A Close Message? 
		{ 
			ReleaseResource(); 
			UinitDx(); 
			UinitOgl(); 
			PostQuitMessage(0);						// Send A Quit Message 
			return 0;								// Jump Back 
		} 
 
		case WM_KEYDOWN:							// Is A Key Being Held Down? 
		{ 
			switch(wParam) 
			{ 
			case VK_ESCAPE: 
				PostMessage(hWnd, WM_CLOSE, wParam, lParam); 
				break; 
			case VK_F1: 
				RenderType = RenderType ? DIRECT3D: OPENGL; 
				break; 
			case VK_F2: 
				break; 
			} 
			return 0; 
		}		 
	} 
 
	return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
 
HRESULT Dxogl::ReleaseResource() 
{ 
	return S_OK; 
} 
 
HRESULT Dxogl::RenderDx() 
{ 
	m_pd3dDevice->Clear(NULL, NULL ,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0),1.0f, 0); 
	if(SUCCEEDED(m_pd3dDevice->BeginScene())) 
	{ 
      m_pd3dDevice->SetFVF(D3DFVF_TRIANGLE); 
	  m_pd3dDevice->SetStreamSource(0, m_pvb, 0, sizeof(TRIANGLE)); 
	  m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); 
	  m_pd3dDevice->EndScene(); 
	} 
	return S_OK; 
} 
 
HRESULT Dxogl::RenderScene() 
{ 
	if(m_pd3dDevice == NULL) 
		return E_FAIL; 
	RenderDx(); 
	RenderOgl(); 
	 
  if(RenderType) 
	m_pd3dDevice->Present(0,0,0,0); 
  else 
	SwapBuffers(hDC);  
	return S_OK; 
} 
 
HRESULT Dxogl::RenderOgl() 
{ 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer 
			glLoadIdentity();									// Reset The Current Modelview Matrix 
			glTranslatef(-1.5f,0.0f,-6.0f);						// Move Left 1.5 Units And Into The Screen 6.0 
			 
			glBegin(GL_TRIANGLES);								// Drawing Using Triangles 
				glVertex3f( 0.0f, 1.0f, 0.0f);					// Top 
				glVertex3f(-1.0f,-1.0f, 0.0f);					// Bottom Left 
				glVertex3f( 1.0f,-1.0f, 0.0f);					// Bottom Right 
			glEnd();											// Finished Drawing The Triangle 
			glTranslatef(3.0f,0.0f,0.0f);						// Move Right 3 Units 
			glBegin(GL_QUADS);									// Draw A Quad 
				glVertex3f(-1.0f, 1.0f, 0.0f);					// Top Left 
				glVertex3f( 1.0f, 1.0f, 0.0f);					// Top Right 
				glVertex3f( 1.0f,-1.0f, 0.0f);					// Bottom Right 
				glVertex3f(-1.0f,-1.0f, 0.0f);					// Bottom Left 
			glEnd();			 
	return S_OK; 
} 
 
HRESULT Dxogl::Run() 
{ 
	BOOL bActive = TRUE; 
	MSG msg; 
	ZeroMemory(&msg, sizeof(msg)); 
	while(msg.message != WM_QUIT){ 
		if(mbActive) 
			bActive = PeekMessage(&msg, NULL ,0, 0, PM_REMOVE); 
		else 
            bActive = GetMessage(&msg, NULL, 0, 0); 
		if(bActive) 
		{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		} 
		else 
		{ 
            //渲染 
			RenderScene(); 
		} 
	} 
	return S_OK; 
}