[英]OpenGL context creation in Windows
這是我的代碼。 我不想要一個用於設備上下文/rc 創建的庫。
什么都不會畫。 也許我設置了 DC 或 RC 錯誤?
我正在嘗試從頭開始制作游戲引擎。
#pragma once
#include <cstdlib>
#include <windows.h>
#include <GL/GL.h>
#pragma comment (lib, "opengl32.lib")
#include <iostream>
using namespace std;
class shadoeGE
{
public:
HWND s_Window = NULL;
int __cdecl Init(const char*, int, int);
private:
};
LRESULT __stdcall s_WindowEvent(HWND hWnd, unsigned int message, unsigned int wParam, long lParam)
{
switch (message)
{
default:
return DefWindowProc(hWnd, message, wParam, lParam);
};
};
int shadoeGE::Init(const char* title, int x, int y)
{
MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = s_WindowEvent;
wc.hInstance = GetModuleHandle(NULL);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = "sWindowClass";
wc.style = CS_OWNDC;
if (!RegisterClass(&wc))
{
return 0;
};
this->s_Window = CreateWindowA(wc.lpszClassName, title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, x, y, 0, 0, GetModuleHandle(NULL), 0);
while (GetMessage(&msg, NULL, 0, 0) > 0)
{
DispatchMessage(&msg);
};
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC deviceContextHandle = GetDC(this->s_Window);
int windowsChosen = ChoosePixelFormat(deviceContextHandle, &pfd);
SetPixelFormat(deviceContextHandle, windowsChosen, &pfd);
HGLRC ourOpenGLRenderingContext = wglCreateContext(deviceContextHandle);
wglMakeCurrent(deviceContextHandle, ourOpenGLRenderingContext);
glViewport(0, 0, 640, 480);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.2, 0.3);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 1, 0);
glEnd();
SwapBuffers(deviceContextHandle);
return 1;
};
你必須實現一個消息循環:
MSG msg;
while( ::GetMessage( &msg, 0, 0, 0 ) )
::DispatchMessage( &msg );
當發送WM_PAINT
消息時,您必須在消息循環中繪制場景:
LRESULT CALLBACK shadoeGE::s_WindowEvent( HWND hWnd, unsigned int msg, WPARAM wparam, LPARAM lparam )
{
switch(msg)
{
// [...]
case WM_PAINT:
wnd.Display();
break;
}
return DefWindowProc( hWnd, msg, wparam, lparam );
}
void shadoeGE::Display( void )
{
RECT clientRect;
::GetClientRect( hOGLWnd, &clientRect );
glViewport( 0, 0, clientRect.right-clientRect.left, clientRect.bottom-clientRect.top );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// [...]
HDC hDC = ::GetDC( hOGLWnd );
::SwapBuffers( hDC );
::ReleaseDC( hOGLWnd, hDC );
}
請參閱示例:
#include <windows.h>
#include <GL/gl.h>
#include <vector>
#include <stdexcept>
class shadoeGE
{
public:
static LRESULT CALLBACK s_WindowEvent( HWND hWnd, unsigned int msg, WPARAM wparam, LPARAM lparam );
HWND Init( int width, int height );
void DestroyWindow( void );
void MessageLoop( void );
void Display( void );
private:
HWND hOGLWnd = NULL;
HGLRC hOGLRenderContext = NULL;
};
std::wstring wnd_class( L"my_wnd_class" );
shadoeGE wnd;
int main()
{
int w = 800;
int h = 600;
HWND hWnd = wnd.Init( w, h );
if ( hWnd == 0 )
throw std::runtime_error( "error initializing window" );
wnd.MessageLoop();
wnd.DestroyWindow();
return 0;
}
HWND shadoeGE::Init( int width, int height )
{
// Get module handle
HMODULE hModule = ::GetModuleHandle( 0 );
if (!hModule)
return NULL;
// Create window class
WNDCLASSEX wndClassData;
memset( &wndClassData, 0, sizeof( WNDCLASSEX ) );
wndClassData.cbSize = sizeof( WNDCLASSEX );
wndClassData.style = CS_DBLCLKS;
wndClassData.lpfnWndProc = s_WindowEvent;
wndClassData.cbClsExtra = 0;
wndClassData.cbWndExtra = 0;
wndClassData.hInstance = hModule;
wndClassData.hIcon = ::LoadIcon(0,IDI_APPLICATION);
wndClassData.hCursor = ::LoadCursor(0,IDC_ARROW);
wndClassData.hbrBackground = ::CreateSolidBrush(COLOR_WINDOW+1);
wndClassData.lpszMenuName = 0;
wndClassData.lpszClassName = wnd_class.c_str();
wndClassData.hIconSm = 0;
if ( !::RegisterClassEx( &wndClassData ) )
return false;
// Creaate Window
hOGLWnd = ::CreateWindow( wnd_class.c_str(), NULL, WS_OVERLAPPEDWINDOW, 0, 0, width, height, NULL, NULL, hModule, NULL);
if ( hOGLWnd == NULL )
return NULL;
// Get device context
HDC hDC = ::GetDC( hOGLWnd );
// Create OpenGL context
DWORD pixelFormatFlags = PFD_SUPPORT_OPENGL | PFD_SUPPORT_COMPOSITION | PFD_GENERIC_ACCELERATED | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
pixelFormatFlags, //Flags
PFD_TYPE_RGBA, //The kind of framebuffer. RGBA or palette.
32, //Colordepth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, //Number of bits for the depthbuffer
8, //Number of bits for the stencilbuffer
0, //Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int pixelFormat = ::ChoosePixelFormat( hDC, &pfd );
::SetPixelFormat( hDC, pixelFormat, &pfd );
hOGLRenderContext = ::wglCreateContext( hDC );
// make OpenGL context the current context
::wglMakeCurrent( hDC, hOGLRenderContext );
// release device context
::ReleaseDC( hOGLWnd, hDC );
// show the window
::ShowWindow( hOGLWnd, SW_SHOWDEFAULT );
return hOGLWnd;
}
void shadoeGE::MessageLoop( void )
{
MSG msg;
while( ::GetMessage( &msg, 0, 0, 0 ) )
::DispatchMessage( &msg );
}
void shadoeGE::DestroyWindow(void)
{
::DestroyWindow( hOGLWnd );
::wglMakeCurrent( NULL, NULL );
::wglDeleteContext( hOGLRenderContext );
HMODULE hModule = ::GetModuleHandle( 0 );
if (!hModule)
return;
::UnregisterClass( wnd_class.c_str(), hModule );
}
LRESULT CALLBACK shadoeGE::s_WindowEvent( HWND hWnd, unsigned int msg, WPARAM wparam, LPARAM lparam )
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
wnd.Display();
break;
}
return DefWindowProc( hWnd, msg, wparam, lparam );
}
void shadoeGE::Display( void )
{
RECT clientRect;
::GetClientRect( hOGLWnd, &clientRect );
glViewport( 0, 0, clientRect.right-clientRect.left, clientRect.bottom-clientRect.top );
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(0.1, 0.2, 0.3);
glVertex3f(0, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(0, 1, 0);
glEnd();
HDC hDC = ::GetDC( hOGLWnd );
::SwapBuffers( hDC );
::ReleaseDC( hOGLWnd, hDC );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.