diff options
author | Brian Paul <brianp@vmware.com> | 2017-04-21 12:12:40 -0600 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2017-04-21 12:25:21 -0600 |
commit | 7f78480a4da37764f0e64c54ca6568861106c0e6 (patch) | |
tree | 461ba8b178748ba73a0c9e61f12d1b70a8056fa5 | |
parent | 6cb6cdfc71ce29b138f4ecdc763ba1d300311521 (diff) | |
download | mesa-demos-7f78480a4da37764f0e64c54ca6568861106c0e6.zip mesa-demos-7f78480a4da37764f0e64c54ca6568861106c0e6.tar.xz |
wgl: import the wglgears demo
Ben Skeggs ported gears to wgl many years ago. With Ben's blessing I'm
putting it in the demos repo.
Signed-off-by: Brian Paul <brianp@vmware.com>
-rw-r--r-- | src/wgl/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/wgl/wglgears.c | 512 |
2 files changed, 514 insertions, 0 deletions
diff --git a/src/wgl/CMakeLists.txt b/src/wgl/CMakeLists.txt index cb50cca..e4a72c1 100644 --- a/src/wgl/CMakeLists.txt +++ b/src/wgl/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable (wglinfo wglinfo.c ${CMAKE_SOURCE_DIR}/src/xdemos/glinfo_common.c add_executable (wglcontext wglcontext.c) add_executable (wincopy WIN32 wincopy.c wglutil.c) add_executable (wglfont wglfont.c) +add_executable (wglgears wglgears.c) install ( TARGETS @@ -25,6 +26,7 @@ install ( wglinfo wglcontext wglfont + wglgears wincopy DESTINATION wgl) diff --git a/src/wgl/wglgears.c b/src/wgl/wglgears.c new file mode 100644 index 0000000..28130e1 --- /dev/null +++ b/src/wgl/wglgears.c @@ -0,0 +1,512 @@ +/* + * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* $XFree86: xc/programs/glxgears/glxgears.c,v 1.3tsi Exp $ */ + +/* + * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT) + * Port by Brian Paul 23 March 2001 + * + * Command line options: + * -info print GL implementation information + * + */ + +/* Modified from X11/GLX to Win32/WGL by Ben Skeggs + * 25th October 2004 + */ + +#include <windows.h> +#include <GL/gl.h> +#include <GL/wglext.h> + + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <math.h> + +/* XXX this probably isn't very portable */ +#include <time.h> +#include <unistd.h> + +#ifndef M_PI +#define M_PI 3.14159265 +#endif /* !M_PI */ + +/* Turn a NULL pointer string into an empty string */ +#define NULLSTR(x) (((x)!=NULL)?(x):("")) +#define Log(x) { if(verbose) printf x; } + +#define Bool int +#define False 0 +#define True 1 + +#if 0 +/* wgl extensions */ +PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = 0; +#endif + +/* Global vars */ +static HDC hDC; +static HGLRC hRC; +static HWND hWnd; +static HINSTANCE hInst; +static RECT winrect; + +static const char *ProgramName; /* program name (from argv[0]) */ +static Bool verbose = False; /* verbose output what the program is doing */ + +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; +static GLint gear1, gear2, gear3; +static GLfloat angle = 0.0; + +static +void usage(void) +{ + fprintf (stderr, "usage: %s [options]\n", ProgramName); + fprintf (stderr, "-info\tPrint additional GL information.\n"); + fprintf (stderr, "-h\tPrint this help page.\n"); + fprintf (stderr, "-v\tVerbose output.\n"); + fprintf (stderr, "\n"); + exit(EXIT_FAILURE); +} + + +/* return current time (in seconds) */ +static int current_time(void) { + return (int)time(NULL); +} + +/* + * + * Draw a gear wheel. You'll probably want to call this function when + * building a display list since we do a lot of trig here. + * + * Input: inner_radius - radius of hole at center + * outer_radius - radius at center of teeth + * width - width of gear + * teeth - number of teeth + * tooth_depth - depth of tooth + */ +static void +gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, + GLint teeth, GLfloat tooth_depth) +{ + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + da = 2.0 * M_PI / teeth / 4.0; + + glShadeModel(GL_FLAT); + + glNormal3f(0.0, 0.0, 1.0); + + /* draw front face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + if (i < teeth) { + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + width * 0.5); + } + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * M_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + width * 0.5); + } + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + + /* draw back face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + if (i < teeth) { + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + } + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * M_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + -width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + -width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + u = r2 * cos(angle + da) - r1 * cos(angle); + v = r2 * sin(angle + da) - r1 * sin(angle); + len = sqrt(u * u + v * v); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + -width * 0.5); + u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); + v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); + glNormal3f(v, -u, 0.0); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + } + + glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5); + glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5); + + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glNormal3f(-cos(angle), -sin(angle), 0.0); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + } + glEnd(); +} + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + glCallList(gear1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1, -2.0, 0.0); + glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); + glCallList(gear2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1, 4.2, 0.0); + glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); + glCallList(gear3); + glPopMatrix(); + + glPopMatrix(); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + + glViewport(0, 0, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); +} + + +static void +init(void) +{ + static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 }; + static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; + static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; + static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + /* make the gears */ + gear1 = glGenLists(1); + glNewList(gear1, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear(1.0, 4.0, 1.0, 20, 0.7); + glEndList(); + + gear2 = glGenLists(1); + glNewList(gear2, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear(0.5, 2.0, 2.0, 10, 0.7); + glEndList(); + + gear3 = glGenLists(1); + glNewList(gear3, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear(1.3, 2.0, 0.5, 10, 0.7); + glEndList(); + + glEnable(GL_NORMALIZE); +} + +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch (uMsg) { + case WM_CLOSE: + PostQuitMessage(0); + return 0; + case WM_SIZE: + reshape(LOWORD(lParam), HIWORD(lParam)); + return 0; + case WM_KEYDOWN: + if (wParam == VK_LEFT) + view_roty += 5.0; + else if (wParam == VK_RIGHT) + view_roty -= 5.0; + else if (wParam == VK_UP) + view_rotx += 5.0; + else if (wParam == VK_DOWN) + view_rotx -= 5.0; + else if (wParam == VK_ESCAPE) + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +/* + * Create an RGB, double-buffered window. + * Return the window and context handles. + */ +static void make_window(const char *name, int x, int y, int width, int height) { + GLuint PixelFormat; + WNDCLASS wc; + DWORD dwExStyle, dwStyle; + static PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, + 24, + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 16, + 0, + 0, + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + winrect.left = (long)0; + winrect.right = (long)width; + winrect.top = (long) 0; + winrect.bottom = (long)height; + + hInst = GetModuleHandle(NULL); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = (WNDPROC)WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInst; + wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = name; + if (!RegisterClass(&wc)) { + printf("failed to register class\n"); + exit(0); + } + + dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + dwStyle = WS_OVERLAPPEDWINDOW; + AdjustWindowRectEx(&winrect, dwStyle, False, dwExStyle); + + if (!(hWnd = CreateWindowEx(dwExStyle, name, name, + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, 0, 0, + winrect.right - winrect.left, winrect.bottom - winrect.top, + NULL, NULL, hInst, NULL))) { + printf("failed to create window\n"); + exit(0); + } + + if (!(hDC = GetDC(hWnd)) || + !(PixelFormat = ChoosePixelFormat(hDC, &pfd)) || + !(SetPixelFormat(hDC, PixelFormat, &pfd)) || + !(hRC = wglCreateContext(hDC)) || + !(wglMakeCurrent(hDC, hRC))) { + printf("failed to initialise opengl\n"); + exit(0); + } + + ShowWindow(hWnd, SW_SHOW); + SetForegroundWindow(hWnd); + SetFocus(hWnd); +} + + +static void event_loop() { + MSG msg; + int t, t0 = current_time(); + int frames = 0; + + while(1) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) break;; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + angle += 2.0; + draw(); + SwapBuffers(hDC); + + /* calc framerate */ + t = current_time(); + frames++; + if (t - t0 >= 5.0) { + GLfloat s = t - t0; + GLfloat fps = frames / s; + printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, s, fps); + t0 = t; + frames = 0; + } + } +} + +int +main(int argc, char *argv[]) +{ + int i; + Bool printInfo = False; + + ProgramName = argv[0]; + + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + int len = strlen(arg); + + if (strcmp(argv[i], "-info") == 0) { + printInfo = GL_TRUE; + } + else if (!strncmp("-v", arg, len)) { + verbose = True; + printInfo = GL_TRUE; + } + else if (strcmp(argv[i], "-h") == 0) { + usage(); + } + else + { + fprintf(stderr, "%s: Unsupported option '%s'.\n", ProgramName, argv[i]); + usage(); + } + } + + + make_window("glxgears", 0, 0, 300, 300); + reshape(300, 300); + +/* force vsync off */ +#if 0 + wglSwapIntervalEXT = wglGetProcAddress("wglSwapIntervalEXT"); + if (!wglSwapIntervalEXT) { + printf("warning: wglSwapIntervalEXT missing, cannot force vsync off\n"); + } else if (!wglSwapIntervalEXT(0)) { + printf("warning: failed to force vsync off, it may still be on\n"); + } +#endif + + if (printInfo) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } + + init(); + + event_loop(); + +/* cleanup */ + wglMakeCurrent (NULL, NULL); + wglDeleteContext (hRC); + ReleaseDC (hWnd, hDC); + + return EXIT_SUCCESS; +} |