summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2017-04-21 12:12:40 -0600
committerBrian Paul <brianp@vmware.com>2017-04-21 12:25:21 -0600
commit7f78480a4da37764f0e64c54ca6568861106c0e6 (patch)
tree461ba8b178748ba73a0c9e61f12d1b70a8056fa5
parent6cb6cdfc71ce29b138f4ecdc763ba1d300311521 (diff)
downloadmesa-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.txt2
-rw-r--r--src/wgl/wglgears.c512
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;
+}