Привет! Вод код моего движка. Может чем поможет.
Движок пока в разработке.
Возможности на данный момент:
Загрузка ms3d,md2/bmp,pcx,tga,dds
Анимация
Управление костями ms3d
Туман
Создание нескольких камер
Управление объектами
//***************************************************************************
"Engine.h"
Код:
struct CDevice
{
int Width;
int Height;
float Near;
float Far;
float FOV;
bool FullScreen;
bool VSync;
bool Active;
HGLRC hRC;
HDC hDC;
HWND hWND;
HINSTANCE hInstance;
char *Title;
};
class CScene
{
public:
CDevice g_sScreenMode;
bool CreateGLWindow(int Width,int Height,int Bits,int Frequency,bool FullScreen,char* Title,bool VSync);
void CloseEngine();
void BeginScene(float r,float g,float b);
bool EndScene();
private:
void KillGLWindow(void);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DrawWin();
void InitGl();
};
//***********************************************************************************
"Engine.cpp"
bool CScene::CreateGLWindow(int Width,int Height,int Bits,int Frequency,bool FullScreen,char* Title,bool VSync)
{
int PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
g_sScreenMode.Active = true;
g_sScreenMode.Far = 10000.0f;
g_sScreenMode.Near = 0.01f;
g_sScreenMode.FOV = 60.0f;
g_sScreenMode.Width = Width;
g_sScreenMode.Height = Height;
g_sScreenMode.FullScreen = FullScreen;
g_sScreenMode.VSync = VSync;
g_sScreenMode.Title = Title;
RECT WindowRect;
WindowRect.left = (long)0;
WindowRect.right = (long)g_sScreenMode.Width;
WindowRect.top = (long)0;
WindowRect.bottom = (long)g_sScreenMode.Height;
g_sScreenMode.hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_sScreenMode.hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = g_sScreenMode.Title;
if(!RegisterClass(&wc))
{
MessageBox(NULL, "Failed To Register The Window Class.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
CloseEngine();
return false;
}
if(FullScreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = g_sScreenMode.Width;
dmScreenSettings.dmPelsHeight = g_sScreenMode.Height;
dmScreenSettings.dmBitsPerPel = Bits; // Ãëóáèíà öâåòà
dmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
dmScreenSettings.dmDisplayFrequency = Frequency;
if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL )
{
CloseEngine();
return false;
}
}
if(FullScreen)
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_POPUP;
ShowCursor(false);
}
else
{
dwExStyle = WS_EX_OVERLAPPEDWINDOW;
dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
}
AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle);
if(!(g_sScreenMode.hWND = CreateWindowEx(
dwExStyle,
g_sScreenMode.Title,
g_sScreenMode.Title,
WS_CLIPSIBLINGS |
WS_CLIPCHILDREN |
dwStyle,
0, 0,
WindowRect.right-WindowRect.left,
WindowRect.bottom-WindowRect.top,
NULL,
NULL,
g_sScreenMode.hInstance,
NULL)))
{
KillGLWindow();
MessageBox(NULL, "Window Creation Error.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
CloseEngine();
return false;
}
if(!(g_sScreenMode.hDC = GetDC(g_sScreenMode.hWND)))
{
KillGLWindow();
MessageBox( NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION );
CloseEngine();
return false;
}
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
Bits,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
if(!(PixelFormat = ChoosePixelFormat(g_sScreenMode.hDC, &pfd)))
{
KillGLWindow();
MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
CloseEngine();
return false;
}
if(!SetPixelFormat(g_sScreenMode.hDC, PixelFormat, &pfd))
{
KillGLWindow();
MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
CloseEngine();
return false;
}
if(!(g_sScreenMode.hRC = wglCreateContext(g_sScreenMode.hDC)))
{
KillGLWindow();
MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
CloseEngine();
return false;
}
if(!wglMakeCurrent(g_sScreenMode.hDC, g_sScreenMode.hRC))
{
KillGLWindow();
MessageBox(NULL, "Can't Activate The GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
CloseEngine();
return false;
}
ShowWindow(g_sScreenMode.hWND, SW_SHOW);
SetForegroundWindow(g_sScreenMode.hWND);
SetFocus(g_sScreenMode.hWND);
PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = NULL;
wglSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
if(wglSwapInterval)wglSwapInterval(VSync);
InitGl();
g_sScreenMode.Active = true;
return true;
}
LRESULT CALLBACK CScene::WndProc(HWND hWND, UINT imsg, WPARAM wParam, LPARAM lParam)
{
switch(imsg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWND,imsg,wParam,lParam);
}
void CScene::KillGLWindow(void)
{
if(g_sScreenMode.FullScreen)
{
ChangeDisplaySettings(NULL, 0);
ShowCursor(true);
}
if(g_sScreenMode.hRC)
{
if(!wglMakeCurrent(NULL, NULL))
{
MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
if(!wglDeleteContext(g_sScreenMode.hRC))
{
MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
g_sScreenMode.hRC = NULL;
}
if(g_sScreenMode.hDC && !ReleaseDC(g_sScreenMode.hWND, g_sScreenMode.hDC))
{
MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
g_sScreenMode.hDC = NULL;
}
if(g_sScreenMode.hWND && !DestroyWindow(g_sScreenMode.hWND))
{
MessageBox(NULL, "Could Not Release hWND.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
g_sScreenMode.hWND = NULL;
}
if( !UnregisterClass(g_sScreenMode.Title, g_sScreenMode.hInstance))
{
MessageBox(NULL, "Could Not Unregister Class.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
g_sScreenMode.hInstance = NULL;
}
}
void CScene::DrawWin()
{
MSG tmsg;
while (PeekMessage(&tmsg,NULL,0,0,PM_REMOVE))
{
if(tmsg.hwnd == g_sScreenMode.hWND)
WndProc(g_sScreenMode.hWND,tmsg.message,tmsg.wParam,tmsg.lParam);
else
DispatchMessage(&tmsg);
if(tmsg.message == WM_QUIT)
g_sScreenMode.Active = false;
}
}
void CScene::CloseEngine()
{
if(g_sScreenMode.FullScreen)
{
ChangeDisplaySettings(NULL, 0);
ShowCursor(true);
}
if(g_sScreenMode.hRC)
{
if(!wglMakeCurrent(NULL,NULL))
if(!wglDeleteContext(g_sScreenMode.hRC))
g_sScreenMode.hRC=NULL;
}
if(g_sScreenMode.hDC && !ReleaseDC(g_sScreenMode.hWND,g_sScreenMode.hDC)){g_sScreenMode.hDC=NULL;}
if(g_sScreenMode.hWND && !DestroyWindow(g_sScreenMode.hWND)){g_sScreenMode.hWND=NULL;}
if(!UnregisterClass(g_sScreenMode.Title,g_sScreenMode.hInstance)){g_sScreenMode.hInstance=NULL;}
}
void CScene::InitGl()
{
glClearColor(0.0,0.0,0.0,0.0);
glClearDepth(1.0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
SwapBuffers(g_sScreenMode.hDC);
}
void CScene::BeginScene(float r,float g,float b)
{
DrawWin();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(r,g,b,1.0);
glClearDepth(1.0);
}
bool CScene::EndScene()
{
SwapBuffers(g_sScreenMode.hDC);
return g_sScreenMode.Active;
}