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;
}