OpenGL全屏显示

/* 

   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;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值