/* An example of an OpenGL animation loop using the Win32 API. Also
demonstrates palette management for RGB and color index modes and
general strategies for message handling. */
#include <windows.h> /* must include this before GL/gl.h */
#include <windowsx.h>
#include <GL/gl.h> /* OpenGL header file */
#include <stdio.h>
#pragma comment(lib, "opengl32.lib")
HDC hDC; /* device context */
HPALETTE hPalette = 0; /* custom palette (if needed) */
GLboolean animate = GL_TRUE; /* animation flag */
#define IDT_TIMER1 1000
float fZoom = 1.0f;
POINT m_lastPos = {0, 0};
float m_xMove;
float m_yMove;
bool in_drag = false;//是否处于拖动模式
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glClearColor(1, 1, 1, 1);
glScalef(fZoom, fZoom, 0);
glTranslatef(m_xMove, m_yMove, -10.0);
/*
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(0.2, 0.2, 0.5);
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();
*/
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(0.2f, 0.2f, 0.5f);
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();
glFlush();
SwapBuffers(hDC); /* nop if singlebuffered */
}
LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
int delta = 0;
char strLog[64];
switch (uMsg) {
case WM_CREATE:
//SetTimer(hWnd, IDT_TIMER1, 1, NULL);
break;
case WM_PAINT:
BeginPaint(hWnd, &ps);
display();
EndPaint(hWnd, &ps);
return 0;
case WM_TIMER:
switch (wParam)
{
case IDT_TIMER1:
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
}
break;
case WM_MOUSEWHEEL:
if ((wParam & MK_CONTROL) == MK_CONTROL)
{
delta += (short)HIWORD(wParam); // 120 or -120
if (delta >= 120)
{
fZoom += 0.03f;
}
else if (delta <= -120)
{
fZoom -= 0.03f;
}
if (fZoom < 0.00001f)
fZoom = 0.01f;
}
if (HIBYTE(GetKeyState(VK_MENU)) & 0x80)
{
OutputDebugString("alt is press\n");
}
// PostMessage(hWnd, WM_PAINT, 0, 0);
SendMessage(hWnd, WM_PAINT, 0, 0);
snprintf(strLog, sizeof(strLog), "%f\n", fZoom);
OutputDebugString(strLog);
break;
case WM_MBUTTONUP:
break;
case WM_LBUTTONDOWN:
if ((wParam & MK_CONTROL) == MK_CONTROL)
{
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
snprintf(strLog, sizeof(strLog), "press: %d,%d\n", pt.x, pt.y);
OutputDebugString(strLog);
m_lastPos = pt;
in_drag = true;
}
break;
case WM_LBUTTONUP:
POINT pt2;
pt2.x = GET_X_LPARAM(lParam);
pt2.y = GET_Y_LPARAM(lParam);
snprintf(strLog, sizeof(strLog), "release: %d,%d\n", pt2.x, pt2.y);
OutputDebugString(strLog);
in_drag = false;
break;
case WM_MOUSEMOVE:
if (((wParam & MK_CONTROL) == MK_CONTROL) && in_drag)
{
POINT pt3;
int dx, dy;
float dx_scale, dy_scale;
pt3.x = GET_X_LPARAM(lParam);
pt3.y = GET_Y_LPARAM(lParam);
snprintf(strLog, sizeof(strLog), "move: %d,%d\n", pt3.x, pt3.y);
OutputDebugString(strLog);
dx = pt3.x - m_lastPos.x;
dy = pt3.y - m_lastPos.y;
dx_scale = dx * (1 / (float)800);
dy_scale = -dy * (1 / (float)640);
m_xMove = m_xMove + dx_scale;
m_yMove = m_yMove + dy_scale;
m_lastPos = pt3;
SendMessage(hWnd, WM_PAINT, 0, 0);
}
break;
case WM_SIZE:
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
switch (wParam) {
case 27: /* ESC key */
PostQuitMessage(0);
break;
case ' ':
animate = !animate;
break;
}
return 0;
#if 0
case WM_ACTIVATE:
if (IsIconic(hWnd))
animate = GL_FALSE;
else
animate = GL_TRUE;
return 0;
#endif
case WM_PALETTECHANGED:
if (hWnd == (HWND)wParam)
break;
/* fall through to WM_QUERYNEWPALETTE */
case WM_QUERYNEWPALETTE:
if (hPalette) {
UnrealizeObject(hPalette);
SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
return TRUE;
}
return FALSE;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
HWND CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
int n, pf;
HWND hWnd;
WNDCLASS wc;
LOGPALETTE* lpPal;
PIXELFORMATDESCRIPTOR pfd;
static HINSTANCE hInstance = 0;
/* only register the window class once - use hInstance as a flag. */
if (!hInstance) {
hInstance = GetModuleHandle(NULL);
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
if (!RegisterClass(&wc)) {
MessageBox(NULL, "RegisterClass() failed: "
"Cannot register window class.", "Error", MB_OK);
return NULL;
}
}
hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, width, height, NULL, NULL, hInstance, NULL);
if (hWnd == NULL) {
MessageBox(NULL, "CreateWindow() failed: Cannot create a window.",
"Error", MB_OK);
return NULL;
}
hDC = GetDC(hWnd);
/* there is no guarantee that the contents of the stack that become
the pfd are zeroed, therefore _make sure_ to clear these bits. */
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
pfd.iPixelType = type;
pfd.cColorBits = 32;
pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0) {
MessageBox(NULL, "ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", "Error", MB_OK);
return 0;
}
if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
MessageBox(NULL, "SetPixelFormat() failed: "
"Cannot set format specified.", "Error", MB_OK);
return 0;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
if (pfd.dwFlags & PFD_NEED_PALETTE ||
pfd.iPixelType == PFD_TYPE_COLORINDEX) {
n = 1 << pfd.cColorBits;
if (n > 256) n = 256;
lpPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * n);
memset(lpPal, 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * n);
lpPal->palVersion = 0x300;
lpPal->palNumEntries = n;
GetSystemPaletteEntries(hDC, 0, n, &lpPal->palPalEntry[0]);
/* if the pixel type is RGBA, then we want to make an RGB ramp,
otherwise (color index) set individual colors. */
if (pfd.iPixelType == PFD_TYPE_RGBA) {
int redMask = (1 << pfd.cRedBits) - 1;
int greenMask = (1 << pfd.cGreenBits) - 1;
int blueMask = (1 << pfd.cBlueBits) - 1;
int i;
/* fill in the entries with an RGB color ramp. */
for (i = 0; i < n; ++i) {
lpPal->palPalEntry[i].peRed =
(((i >> pfd.cRedShift) & redMask) * 255) / redMask;
lpPal->palPalEntry[i].peGreen =
(((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
lpPal->palPalEntry[i].peBlue =
(((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
lpPal->palPalEntry[i].peFlags = 0;
}
}
else {
lpPal->palPalEntry[0].peRed = 0;
lpPal->palPalEntry[0].peGreen = 0;
lpPal->palPalEntry[0].peBlue = 0;
lpPal->palPalEntry[0].peFlags = PC_NOCOLLAPSE;
lpPal->palPalEntry[1].peRed = 255;
lpPal->palPalEntry[1].peGreen = 0;
lpPal->palPalEntry[1].peBlue = 0;
lpPal->palPalEntry[1].peFlags = PC_NOCOLLAPSE;
lpPal->palPalEntry[2].peRed = 0;
lpPal->palPalEntry[2].peGreen = 255;
lpPal->palPalEntry[2].peBlue = 0;
lpPal->palPalEntry[2].peFlags = PC_NOCOLLAPSE;
lpPal->palPalEntry[3].peRed = 0;
lpPal->palPalEntry[3].peGreen = 0;
lpPal->palPalEntry[3].peBlue = 255;
lpPal->palPalEntry[3].peFlags = PC_NOCOLLAPSE;
}
hPalette = CreatePalette(lpPal);
if (hPalette) {
SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
}
free(lpPal);
}
ReleaseDC(hWnd, hDC);
return hWnd;
}
int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
LPSTR lpszCmdLine, int nCmdShow)
{
HGLRC hRC; /* opengl context */
HWND hWnd; /* window */
MSG msg; /* message */
DWORD buffer = PFD_DOUBLEBUFFER; /* buffering type */
BYTE color = PFD_TYPE_RGBA; /* color type */
if (strstr(lpszCmdLine, "-sb")) {
buffer = 0;
}
if (strstr(lpszCmdLine, "-ci")) {
color = PFD_TYPE_COLORINDEX;
}
if (strstr(lpszCmdLine, "-h")) {
MessageBox(NULL, "animate [-ci] [-sb]\n"
" -sb single buffered\n"
" -ci color index\n",
"Usage help", MB_ICONINFORMATION);
exit(0);
}
hWnd = CreateOpenGLWindow((char*)"opengl test ---- https://whycan.com", 0, 0, 800, 640, color, buffer);
if (hWnd == NULL)
exit(1);
hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
if (hPalette)
DeleteObject(hPalette);
return 0;
}
不依赖任何第三方库, 可执行文件下载: win32_opengl_test_1.7z
离线
按住 CTRL 键, 可以平移和缩放。
离线
搬出我多年前的收藏给楼主助威吧,NEHE OpenGL 教学例程,例程个个精美:
nehegl.zip
大哥! 太强大了!
整整48个例程啊, 我直接用VC2017编译了最后一个例程, 改了两三行就编译运行了, 真不依赖任何第三方库.
顺便请教一个问题, 现在我们公司的软件有点变态, 里面最多可能有一百万条线段的连接, OpenGL渲染可能要好几十微秒,
这种情况下鼠标还要能继续画线, 如果一起渲染的画感觉有点卡了,
请问OpenGL有没有增量渲染呢?或者说局部渲染? 这样感觉可以提高流畅度.
离线