/*
fullscreen.c
Nate Robins, 1997.
An example of rendering OpenGL fullscreen using Win32. Use the
mouse to select a mode. Modes that are highlighted in green are
modes that can be changed to dynamically. Those in red can't be
changed to dynamically (they require a reboot). If you change to a
mode that has the wrong refresh rate, you can press the right mouse
button which will take you to the default display mode. The mode
that is highlighted in yellow is the current display mode. Press
'Esc' to quit. The program returns to the defalt display mode on
exit.
*/
#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>
HDC hDC;
int win_width, win_height;
int row = 0, col = 0;
int num_modes = 0;
int row_size = 10, col_size = 0;
int num_cols = 3, num_rows = 0;
int current = -1;
int cant = 0;
DEVMODE devmode;
DEVMODE *devmodes;
/*
general purpose text routine. draws a string according to the
format in a stroke font at x, y after scaling it by the scale
specified. x, y and scale are all in window-space [i.e., pixels]
with origin at the lower-left.
*/
void
text(GLuint x, GLuint y, GLuint scale, char* format, ...)
{
va_list args;
char buffer[255], *p;
GLfloat font_scale = 119.05F + 33.33F;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, win_width, 0, win_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef((GLfloat) x, (GLfloat) y, 0.0F);
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
for(p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, *p);
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void
display()
{
int i, x, y;
glViewport(0, 0, win_width, win_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, win_width, 0, win_height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPolygonMode(GL_FRONT, GL_LINE);
glClear(GL_COLOR_BUFFER_BIT);
for (i = 0; i < num_modes; i++) {
x = i / num_rows * col_size;
y = i % num_rows * row_size;
glColor3f(1.0F, 1.0F, 1.0F);
if (current == i)
glColor3f(1.0F, 1.0F, 0.0F);
if (row*row_size == y && col*col_size == x) {
/* test to see if the mode that the mouse pointer is above
is dynamic. */
if (ChangeDisplaySettings(&devmodes[i], CDS_TEST) ==
DISP_CHANGE_SUCCESSFUL) {
glColor3f(0.0F, 1.0F, 0.0F);
} else {
glColor3f(1.0F, 0.0F, 0.0F);
}
/* draw a box around the current choice. */
glRecti(x, y-2, x+col_size, y+row_size-1);
}
text(x, y, row_size, "%3d: %4dx%4d %2d bps %3dhz\n", i,
devmodes[i].dmPelsWidth, devmodes[i].dmPelsHeight,
devmodes[i].dmBitsPerPel, devmodes[i].dmDisplayFrequency);
}
/* let the user know that they can't choose that one. "cant"
decrements so that a few frames of the message are seen
(otherwise it blinks off too quickly to read). */
if (cant) {
glColor3f(1.0F, 0.0F, 0.0F);
text(0, win_height-20, 20, "Can't dynamically resize to that format.");
cant--;
}
glFlush();
SwapBuffers(hDC);
}
LONG WINAPI
WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i;
static PAINTSTRUCT ps;
switch(uMsg) {
case WM_PAINT:
display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
return 0;
case WM_SIZE:
win_width = LOWORD(lParam);
win_height = HIWORD(lParam);
num_rows = win_height / row_size;
col_size = win_width / num_cols;
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
switch (wParam) {
case 27: /* ESC key */
PostQuitMessage(0);
break;
}
return 0;
case WM_LBUTTONDOWN:
i = col * num_rows + row;
if (i < num_modes) {
/* test first, then change, just in case. */
if (ChangeDisplaySettings(&devmodes[i], CDS_TEST) ==
DISP_CHANGE_SUCCESSFUL)
{
ChangeDisplaySettings(&devmodes[i], 0);
current = i;
} else {
cant = 5;
PostMessage(hWnd, WM_PAINT, 0, 0);
}
}
return 0;
case WM_RBUTTONDOWN:
/* click your heels three times...hang on toto. */
ChangeDisplaySettings(NULL, 0);
return 0;
case WM_MOUSEMOVE:
col = LOWORD(lParam) / col_size;
row = (win_height - HIWORD(lParam)) / row_size;
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
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 pf;
HDC hDC;
HWND hWnd;
WNDCLASS wc;
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_POPUP | WS_MAXIMIZE |
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);
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 */
hWnd = CreateOpenGLWindow("minimal", 0, 0, win_width, win_height,
PFD_TYPE_RGBA, PFD_DOUBLEBUFFER);
if (hWnd == NULL)
exit(1);
hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
ShowWindow(hWnd, SW_SHOW);
/* get the total number of modes so we can allocate memory for all
of 'em. */
num_modes = 0;
while (EnumDisplaySettings(NULL, num_modes, &devmode))
num_modes++;
/* fill an array with all the devmodes so we don't have to keep
grabbing 'em. */
devmodes = (DEVMODE*)malloc(sizeof(DEVMODE)*num_modes);
num_modes = 0;
while (EnumDisplaySettings(NULL, num_modes, &devmodes[num_modes]))
num_modes++;
while(GetMessage(&msg, hWnd, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
/* free the array of devmodes, and click our heels to come back
from Oz...don't forget Toto. */
free(devmodes);
ChangeDisplaySettings(NULL, 0);
wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
return msg.wParam;
}
OpenGL全屏显示
最新推荐文章于 2021-01-27 11:46:16 发布