![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9E0aEqCVxk7NBQ9fmSsb7DHW3dP05NQ9yF0p9rzfEnv5Ykgjxy4avbB6HOQox9M2QkJ2UUXrUSGU4isqBqI6Optuy-ayKdows0XOGAzFpCqf5gc6ggrs9X9JKxAbXs-EymW7GIpv7yrE/s400/first+OpenGL.jpg)
OpenGL добавили еще в Windows NT. Если кто-то собирается изучать OpenGL, то для начала хорошо бы посмотреть самую простую программу поддерживающую OpenGL:
#define WIN32_LEAN_AND_MEANЭта апликация не более, чем шаблон. Она ничего не рисует, а просто создает окно и готовит рабочую среду для использования OpenGL. Рисование должно быть добавлено в функцию RenderScene:
#include <windows.h>
#include <WinGDI.h>
#include <GL/gl.h>
#pragma comment(lib, "opengl32.lib")
LPCWSTR s_szWndClassName = L"Window for Open GL Test application";
ATOM RegisterWndClass(HINSTANCE, LPCWSTR);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void ChangeSize(int cx, int cy);
BOOL SetPixelFormat(HDC);
void RenderScene();
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HWND hWnd = NULL;
MSG msg = { 0 };
RegisterWndClass(hInstance, s_szWndClassName);
hWnd = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
s_szWndClassName, s_szWndClassName,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);
if (hWnd != NULL)
{
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
ATOM RegisterWndClass(HINSTANCE hInstance, LPCWSTR lpszWndClassName)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = lpszWndClassName;
return RegisterClassEx(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC;
static HDC hDC;
switch (message)
{
case WM_CREATE:
hDC = GetDC(hWnd);
SetPixelFormat(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
break;
case WM_PAINT:
RenderScene();
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
break;
case WM_DESTROY:
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd, hDC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
BOOL SetPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pfd = { 0 };
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 32;
pfd.iLayerType = PFD_MAIN_PLANE;
int nPixelFormat = ChoosePixelFormat(hDC, &pfd);
if (nPixelFormat == 0)
return FALSE;
BOOL bResult = SetPixelFormat(hDC, nPixelFormat, &pfd);
return bResult;
}
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void RenderScene()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(0.0f, 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(0.87f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(-0.87f, -0.5f);
glEnd();
glPopMatrix();
}
Можна реагировать на изменения размеров окна:
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;
Ну и сама ChangeSize:
void ChangeSize(int cx, int cy)
{
glViewport(0, 0, cx, cy);
}
Можно добавить таймер и заставить нарисованый треугольник крутиться - SetTimer в обработку WM_CREATE сообщения, KillTimer в WM_DESTROY, добавить обработку WM_TIMER - просто вызвать InvalidateRect.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
static HGLRC hRC; // Save the rendering context between calls
static HDC hDC; // Save the device context between calls
switch (message)
{
case WM_CREATE:
hDC = GetDC(hWnd);
SetPixelFormat(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
SetTimer(hWnd, 123, 100, NULL);
break;
case WM_PAINT:
RenderScene();
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);
break;
case WM_TIMER:
InvalidateRect(hWnd, NULL, FALSE);
break;
case WM_SIZE:
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;
case WM_DESTROY:
KillTimer(hWnd, 123);
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
ReleaseDC(hWnd, hDC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
И изменить функцию рисования:
void RenderScene()
{
static GLfloat angle = 0;
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(0.87f, -0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(-0.87f, -0.5f);
glEnd();
glPopMatrix();
angle += 1.0f;
}
И абсолютно без всякого смысла можно сделать окно полупрозрачным - WS_EX_LAYERED в вызов CreateWindowEx и вызвать SetLayeredWindowAttributes для дескриптора окна:
SetLayeredWindowAttributes(hWnd, 0, (255 * 70) / 100, LWA_ALPHA);
MSDN:OpenGL I: Quick Start
OpenGL Win32 Tutorial
No comments:
Post a Comment