M
hat länger gedauert als gedacht
den source nicht so ernst nehmen es ging da nur ein "grobes" design, er ist auch
schon ziemlich als (März 04) und wird mit sicherheit einige fehler beinhalten
dich ich heute nicht mehr mache, aber das wirst du ja selber kennen.
es handelt sich hierbei nur um das (minimalste) framework, mit nur einen viewport, aber falls du noch fragen hast du weisst wie es geht.
#if(WINVER <= 0x0500)
#define WINVER 0x0500
#endif
#if(_WIN32_IE <= 0x0500)
#define _WIN32_IE 0x0500 // IE 5.0
#endif
#include <windows.h>
#include <commctrl.h>
#include <gl/gl.h>
#include "resource.h"
// D E F I N E S
#define SZWNDCLASS TEXT("FrameworkEditor") // fensterklasse
#define SZGLCLASS TEXT("OpenGLWnd") // klasse gl fenster
#define SZWNDTITLE TEXT("Framework") // fenstername
// F U N K T I O N E N
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL GLWindowCreate(HWND hwndParent); // opengl fenster erstellen
void InitEditor(HWND hwndParent); // editor mit standardwerten initialisieren
void Update(HWND hwndParent); // rendern
// G L O B A L E V A R I A B E L E N
BOOL g_bDone = FALSE; // mainloop
BOOL g_bAppActive = TRUE; // application aktiv
HDC g_hDC = NULL; // GDI device context
HGLRC g_hGLrc = NULL; // handle rendering context
int WINAPI WinMain(
HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
// überprüfen ob programm schon gestartet ist
CreateMutex(NULL, TRUE, "Framework Started");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
HWND hWndFirst;
hWndFirst = FindWindow(SZWNDCLASS, NULL);
BringWindowToTop(hWndFirst);
SetForegroundWindow(hWndFirst);
return -1;
}
// argumente benutzt das framework nicht
UNREFERENCED_PARAMETER(lpszArgument);
InitCommonControls();
HWND hwnd;
MSG msg;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = SZWNDCLASS;
wincl.lpfnWndProc = WindowProc;
wincl.style = CS_HREDRAW | CS_VREDRAW;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDI_MAIN));
wincl.hIconSm = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDI_MAIN));
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = "MAINMENU";
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW);
if(!RegisterClassEx(&wincl))
return -1;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = SZGLCLASS;
wincl.lpfnWndProc = GLWindowProc;
wincl.style = CS_HREDRAW | CS_VREDRAW;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = NULL;
wincl.hIconSm = NULL;
wincl.hCursor = LoadCursor(NULL, IDC_CROSS);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW);
if(!RegisterClassEx(&wincl))
return -1;
if(!(hwnd = CreateWindowEx(
WS_EX_APPWINDOW,
SZWNDCLASS,
SZWNDTITLE,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |WS_VISIBLE,
25,
25,
GetSystemMetrics(SM_CXSCREEN) - 50,
GetSystemMetrics(SM_CYSCREEN) - 100,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL)))
{
MessageBox(
NULL,
"Couldn't create Mainwindow",
"Error",
MB_OK | MB_ICONEXCLAMATION);
return -1;
}
ShowWindow(hwnd, nCmdShow);
while(!g_bDone)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if(g_bAppActive)
{
Update(hwnd);
SwapBuffers(g_hDC);
}
}
}
// aufräumen
if(g_hGLrc)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(g_hGLrc);
}
ReleaseDC(hwnd, g_hDC);
DestroyWindow(hwnd);
UnregisterClass(SZWNDCLASS, hThisInstance);
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static HWND hwndTabCtrl;
switch(msg)
{
case WM_CREATE:
{
// opengl fenster erstellen
if(!GLWindowCreate(hwnd))
DestroyWindow(hwnd);
// als beispiel habe ich ein tab control hinzugefügt
if(!(hwndTabCtrl = CreateWindowEx(
0,
WC_TABCONTROL,
TEXT(""),
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS |
TCS_FOCUSNEVER | TCS_SINGLELINE,
0, 0, 0, 0,
hwnd,
(HMENU)IDC_TAB,
((LPCREATESTRUCT)lParam)->hInstance,
NULL)))
{
MessageBox(
hwnd,
"Couldn't create Tabcontrol",
"Error",
MB_OK | MB_ICONEXCLAMATION);
DestroyWindow(hwnd);
}
TCITEM item;
item.pszText = TEXT("Edit1");
TabCtrl_InsertItem(hwndTabCtrl, 0, &item);
item.pszText = TEXT("Edit2");
TabCtrl_InsertItem(hwndTabCtrl, 1, &item);
InitEditor(hwnd);
}
break;
case WM_ACTIVATEAPP:
g_bAppActive = (BOOL)wParam;
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
// file --------------------------------------------------------
case IDM_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
// help --------------------------------------------------------
case IDM_\1:
MessageBox(
hwnd,
"Opengl Leveleditor Framework",
"About",
MB_OK);
break;
}
break;
case WM_NOTIFY:
// tab click abfangen
break;
case WM_SIZE:
if(wParam != SIZE_MINIMIZED)
{
RECT rc;
GetClientRect(hwnd, &rc);
int nGlWndWidth = rc.right - rc.left - 155;
int nGlWndHeight = rc.bottom - rc.top;
MoveWindow(
hwndTabCtrl,
0, 0, 150, nGlWndHeight, TRUE);
MoveWindow(
GetDlgItem(hwnd, IDC_GLWND),
155, 0, nGlWndWidth, nGlWndHeight, TRUE);
}
break;
case WM_GETMINMAXINFO:
((MINMAXINFO*)lParam)->ptMinTrackSize.x = 800;
((MINMAXINFO*)lParam)->ptMinTrackSize.y = 600;
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
g_bDone = TRUE;
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_MOUSEMOVE:
// tasten abfangen zb: strg, shift
// diff ausrechenen vom mauspunkt dann
// --> zoomen, panen, rotieren, etc
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
BOOL GLWindowCreate(HWND hwndParent)
{
HWND hwnd;
int nPixelformat;
if(!(hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
SZGLCLASS,
"",
WS_CHILD | WS_VISIBLE,
0, 0, 0, 0,
hwndParent,
(HMENU)IDC_GLWND,
(HINSTANCE)GetWindowLong(hwndParent, GWL_HINSTANCE),
NULL)))
return FALSE;
if(!(g_hDC = GetDC(hwnd)))
{
MessageBox(
hwndParent,
"Can't create a GL Device Context.",
"Error",
MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,
0, 0,
PFD_MAIN_PLANE,
0, 0, 0, 0
};
if(!(nPixelformat = ChoosePixelFormat(g_hDC, &pfd)))
{
MessageBox(
hwndParent,
"Can't find a suitable PixelFormat",
"Error",
MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if(!SetPixelFormat(g_hDC, nPixelformat, &pfd))
{
MessageBox(
hwndParent,
"Can't set the PixelFormat",
"Error",
MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if(!(g_hGLrc = wglCreateContext(g_hDC)))
{
MessageBox(
hwndParent,
"Can't create a GL Rendering Context",
"Error",
MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if(!wglMakeCurrent(g_hDC, g_hGLrc))
{
MessageBox(
hwndParent,
"Can't activate the GL Rendering Context",
"Error",
MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
return TRUE;
}
void InitEditor(HWND hwndParent)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
// gl init ...
}
void Update(HWND hwndParent)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}