diff options
Diffstat (limited to 'intern/ghost/test/gears')
-rw-r--r-- | intern/ghost/test/gears/GHOST_C-Test.c | 543 | ||||
-rwxr-xr-x | intern/ghost/test/gears/GHOST_Test.cpp | 745 | ||||
-rwxr-xr-x | intern/ghost/test/gears/Makefile | 48 |
3 files changed, 1336 insertions, 0 deletions
diff --git a/intern/ghost/test/gears/GHOST_C-Test.c b/intern/ghost/test/gears/GHOST_C-Test.c new file mode 100644 index 00000000000..16d8b421d5b --- /dev/null +++ b/intern/ghost/test/gears/GHOST_C-Test.c @@ -0,0 +1,543 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * + * Simple test file for the GHOST library. + * The OpenGL gear code is taken from the Qt sample code which, + * in turn, is probably taken from somewhere as well. + * @author Maarten Gribnau + * @date May 31, 2001 + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include "GHOST_C-api.h" + +#if defined(WIN32) || defined(__APPLE__) + #ifdef WIN32 + #include <windows.h> + #include <GL/gl.h> + #else /* WIN32 */ + /* __APPLE__ is defined */ + #include <AGL/gl.h> + #endif /* WIN32 */ +#else /* defined(WIN32) || defined(__APPLE__) */ + #include <GL/gl.h> +#endif /* defined(WIN32) || defined(__APPLE__) */ + + +static void gearsTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time); + +static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0; +static GLfloat fAngle = 0.0; +static int sExitRequested = 0; +static GHOST_SystemHandle shSystem = NULL; +static GHOST_WindowHandle sMainWindow = NULL; +static GHOST_WindowHandle sSecondaryWindow = NULL; +static GHOST_TStandardCursor sCursor = GHOST_kStandardCursorFirstCursor; +static GHOST_WindowHandle sFullScreenWindow = NULL; +static GHOST_TimerTaskHandle sTestTimer; +static GHOST_TimerTaskHandle sGearsTimer; + + +static void testTimerProc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) +{ + printf("timer1, time=%d\n", (int)time); +} + + +static void gearGL(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; + const double pi = 3.14159264; + + r0 = inner_radius; + r1 = (float)(outer_radius - tooth_depth/2.0); + r2 = (float)(outer_radius + tooth_depth/2.0); + + da = (float)(2.0*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 = (float)(i * 2.0*pi / teeth); + glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5)); + glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5)); + glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5)); + glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5)); + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = (float)(2.0*pi / teeth / 4.0); + for (i=0;i<teeth;i++) { + angle = (float)(i * 2.0*pi / teeth); + glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5)); + glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5)); + glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5)); + glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(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 = (float)(i * 2.0*pi / teeth); + glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5)); + glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5)); + glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5)); + glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5)); + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = (float)(2.0*pi / teeth / 4.0); + for (i=0;i<teeth;i++) { + angle = (float)(i * 2.0*pi / teeth); + glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5)); + glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5)); + glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5)); + glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5)); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i=0;i<teeth;i++) { + angle = (float)(i * 2.0*pi / teeth); + glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(width*0.5)); + glVertex3f((float)(r1*cos(angle)), (float)(r1*sin(angle)), (float)(-width*0.5)); + u = (float)(r2*cos(angle+da) - r1*cos(angle)); + v = (float)(r2*sin(angle+da) - r1*sin(angle)); + len = (float)(sqrt(u*u + v*v)); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(width*0.5)); + glVertex3f((float)(r2*cos(angle+da)), (float)(r2*sin(angle+da)), (float)(-width*0.5)); + glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0); + glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(width*0.5)); + glVertex3f((float)(r2*cos(angle+2*da)), (float)(r2*sin(angle+2*da)), (float)(-width*0.5)); + u = (float)(r1*cos(angle+3*da) - r2*cos(angle+2*da)); + v = (float)(r1*sin(angle+3*da) - r2*sin(angle+2*da)); + glNormal3f(v, -u, 0.0); + glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(width*0.5)); + glVertex3f((float)(r1*cos(angle+3*da)), (float)(r1*sin(angle+3*da)), (float)(-width*0.5)); + glNormal3f((float)(cos(angle)), (float)(sin(angle)), 0.0); + } + glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(width*0.5)); + glVertex3f((float)(r1*cos(0.0)), (float)(r1*sin(0.0)), (float)(-width*0.5)); + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i=0;i<=teeth;i++) { + angle = (float)(i * 2.0*pi / teeth); + glNormal3f((float)(-cos(angle)), (float)(-sin(angle)), 0.0); + glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(-width*0.5)); + glVertex3f((float)(r0*cos(angle)), (float)(r0*sin(angle)), (float)(width*0.5)); + } + glEnd(); +} + + + +static void drawGearGL(int id) +{ + static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f }; + static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f }; + static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f }; + static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f }; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + switch (id) + { + case 1: + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared); + gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f); + break; + case 2: + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen); + gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f); + break; + case 3: + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue); + gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f); + break; + default: + break; + } + glEnable(GL_NORMALIZE); +} + + +static void drawGL(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(fAngle, 0.0, 0.0, 1.0); + drawGearGL(1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1f, -2.0f, 0.0f); + glRotatef((float)(-2.0*fAngle-9.0), 0.0, 0.0, 1.0); + drawGearGL(2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1f, 2.2f, -1.8f); + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + glRotatef((float)(2.0*fAngle-2.0), 0.0, 0.0, 1.0); + drawGearGL(3); + glPopMatrix(); + + glPopMatrix(); +} + + +static void setViewPortGL(GHOST_WindowHandle hWindow) +{ + GHOST_RectangleHandle hRect = NULL; + GLfloat w, h; + + GHOST_ActivateWindowDrawingContext(hWindow); + hRect = GHOST_GetClientBounds(hWindow); + + w = (float)GHOST_GetWidthRectangle(hRect) / (float)GHOST_GetHeightRectangle(hRect); + h = 1.0; + + glViewport(0, 0, GHOST_GetWidthRectangle(hRect), GHOST_GetHeightRectangle(hRect)); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-w, w, -h, h, 5.0, 60.0); + /* glOrtho(0, bnds.getWidth(), 0, bnds.getHeight(), -10, 10); */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); + + glClearColor(.2f,0.0f,0.0f,0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + GHOST_DisposeRectangle(hRect); +} + + + +int processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData) +{ + int handled = 1; + int cursor; + int visibility; + GHOST_TEventKeyData* keyData = NULL; + GHOST_DisplaySetting setting; + GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent); + + switch (GHOST_GetEventType(hEvent)) + { + /* + case GHOST_kEventUnknown: + break; + case GHOST_kEventCursorButton: + break; + case GHOST_kEventCursorMove: + break; + */ + case GHOST_kEventKeyUp: + break; + + case GHOST_kEventKeyDown: + { + keyData = (GHOST_TEventKeyData*)GHOST_GetEventData(hEvent); + switch (keyData->key) + { + case GHOST_kKeyC: + { + cursor = sCursor; + cursor++; + if (cursor >= GHOST_kStandardCursorNumCursors) + { + cursor = GHOST_kStandardCursorFirstCursor; + } + sCursor = (GHOST_TStandardCursor)cursor; + GHOST_SetCursorShape(window, sCursor); + } + break; + case GHOST_kKeyF: + if (!GHOST_GetFullScreen(shSystem)) + { + /* Begin fullscreen mode */ + setting.bpp = 24; + setting.frequency = 85; + setting.xPixels = 640; + setting.yPixels = 480; + + /* + setting.bpp = 16; + setting.frequency = 75; + setting.xPixels = 640; + setting.yPixels = 480; + */ + + sFullScreenWindow = GHOST_BeginFullScreen(shSystem, &setting, + false /* stereo flag */); + } + else + { + GHOST_EndFullScreen(shSystem); + sFullScreenWindow = 0; + } + break; + case GHOST_kKeyH: + { + visibility = GHOST_GetCursorVisibility(window); + GHOST_SetCursorVisibility(window, !visibility); + } + break; + case GHOST_kKeyQ: + if (GHOST_GetFullScreen(shSystem)) + { + GHOST_EndFullScreen(shSystem); + sFullScreenWindow = 0; + } + sExitRequested = 1; + case GHOST_kKeyT: + if (!sTestTimer) + { + sTestTimer = GHOST_InstallTimer(shSystem, 0, 1000, testTimerProc, NULL); + } + else + { + GHOST_RemoveTimer(shSystem, sTestTimer); + sTestTimer = 0; + } + break; + case GHOST_kKeyW: + { + if (sMainWindow) + { + char *title = GHOST_GetTitle(sMainWindow); + char *ntitle = malloc(strlen(title)+2); + + sprintf(ntitle, "%s-", title); + GHOST_SetTitle(sMainWindow, ntitle); + + free(ntitle); + free(title); + } + } + break; + default: + break; + } + } + break; + + case GHOST_kEventWindowClose: + { + GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent); + if (window == sMainWindow) + { + sExitRequested = 1; + } + else + { + if (sGearsTimer) + { + GHOST_RemoveTimer(shSystem, sGearsTimer); + sGearsTimer = 0; + } + GHOST_DisposeWindow(shSystem, window); + } + } + break; + + case GHOST_kEventWindowActivate: + handled = 0; + break; + case GHOST_kEventWindowDeactivate: + handled = 0; + break; + case GHOST_kEventWindowUpdate: + { + GHOST_WindowHandle window = GHOST_GetEventWindow(hEvent); + if (!GHOST_ValidWindow(shSystem, window)) + break; + //if (!m_fullScreenWindow) + { + setViewPortGL(window); + drawGL(); + GHOST_SwapWindowBuffers(window); + } + } + break; + + default: + handled = 0; + break; + } + return handled; +} + + +int main(int argc, char** argv) +{ + char* title1 = "gears - main window"; + char* title2 = "gears - secondary window"; + GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(processEvent, NULL); + + /* Create the system */ + shSystem = GHOST_CreateSystem(); + GHOST_AddEventConsumer(shSystem, consumer); + + if (shSystem) + { + /* Create the main window */ + sMainWindow = GHOST_CreateWindow(shSystem, + title1, + 10, + 64, + 320, + 200, + GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL); + if (!sMainWindow) + { + printf("could not create main window\n"); + exit(-1); + } + + /* Create a secondary window */ + sSecondaryWindow = GHOST_CreateWindow(shSystem, + title2, + 340, + 64, + 320, + 200, + GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL); + if (!sSecondaryWindow) + { + printf("could not create secondary window\n"); + exit(-1); + } + + /* Install a timer to have the gears running */ + sGearsTimer = GHOST_InstallTimer(shSystem, + 0, + 10, + gearsTimerProc, + sMainWindow); + + /* Enter main loop */ + while (!sExitRequested) + { + if (!GHOST_ProcessEvents(shSystem, 0)) + { +#ifdef WIN32 + /* If there were no events, be nice to other applications */ + Sleep(10); +#endif + } + GHOST_DispatchEvents(shSystem); + } + } + + /* Dispose windows */ + if (GHOST_ValidWindow(shSystem, sMainWindow)) + { + GHOST_DisposeWindow(shSystem, sMainWindow); + } + if (GHOST_ValidWindow(shSystem, sSecondaryWindow)) + { + GHOST_DisposeWindow(shSystem, sSecondaryWindow); + } + + /* Dispose the system */ + GHOST_DisposeSystem(shSystem); + GHOST_DisposeEventConsumer(consumer); + + return 0; +} + + +static void gearsTimerProc(GHOST_TimerTaskHandle hTask, GHOST_TUns64 time) +{ + GHOST_WindowHandle hWindow = NULL; + fAngle += 2.0; + view_roty += 1.0; + hWindow = (GHOST_WindowHandle)GHOST_GetTimerTaskUserData(hTask); + if (GHOST_GetFullScreen(shSystem)) + { + /* Running full screen */ + GHOST_InvalidateWindow(sFullScreenWindow); + } + else + { + if (GHOST_ValidWindow(shSystem, hWindow)) + { + GHOST_InvalidateWindow(hWindow); + } + } +} diff --git a/intern/ghost/test/gears/GHOST_Test.cpp b/intern/ghost/test/gears/GHOST_Test.cpp new file mode 100755 index 00000000000..a5459c9da9b --- /dev/null +++ b/intern/ghost/test/gears/GHOST_Test.cpp @@ -0,0 +1,745 @@ +/** + * $Id$ + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/** + + * $Id$ + * Copyright (C) 2001 NaN Technologies B.V. + * Simple test file for the GHOST library. + * The OpenGL gear code is taken from the Qt sample code which, + * in turn, is probably taken from somewhere as well. + * @author Maarten Gribnau + * @date May 31, 2001 + * Stereo code by Raymond de Vries, januari 2002 + */ + +#include <iostream> +#include <math.h> + +#if defined(WIN32) || defined(__APPLE__) + #ifdef WIN32 + #include <windows.h> + #include <atlbase.h> + + #include <GL/gl.h> + #else // WIN32 + // __APPLE__ is defined + #include <AGL/gl.h> + #endif // WIN32 +#else // defined(WIN32) || defined(__APPLE__) + #include <GL/gl.h> +#endif // defined(WIN32) || defined(__APPLE__) + +#include "STR_String.h" +#include "GHOST_Rect.h" + +#include "GHOST_ISystem.h" +#include "GHOST_IEvent.h" +#include "GHOST_IEventConsumer.h" + + +#define LEFT_EYE 0 +#define RIGHT_EYE 1 + +static bool nVidiaWindows; // very dirty but hey, it's for testing only + +static void gearsTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time); + +static class Application* fApp; +static GLfloat view_rotx=20.0, view_roty=30.0, view_rotz=0.0; +static GLfloat fAngle = 0.0; +static GHOST_ISystem* fSystem = 0; + + +void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane, + float zero_plane, float dist, + float eye); + + +static void testTimerProc(GHOST_ITimerTask* /*task*/, GHOST_TUns64 time) +{ + std::cout << "timer1, time=" << (int)time << "\n"; +} + + +static void gearGL(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; + + const double pi = 3.14159264; + da = 2.0*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*pi / teeth; + glVertex3f(r0*cos(angle), r0*sin(angle), width*0.5); + glVertex3f(r1*cos(angle), r1*sin(angle), width*0.5); + 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*pi / teeth / 4.0; + for (i=0;i<teeth;i++) { + angle = i * 2.0*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*pi / teeth; + glVertex3f(r1*cos(angle), r1*sin(angle), -width*0.5); + glVertex3f(r0*cos(angle), r0*sin(angle), -width*0.5); + 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*pi / teeth / 4.0; + for (i=0;i<teeth;i++) { + angle = i * 2.0*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*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.0), r1*sin(0.0), width*0.5); + glVertex3f(r1*cos(0.0), r1*sin(0.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*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 drawGearGL(int id) +{ + static GLfloat pos[4] = { 5.0f, 5.0f, 10.0f, 1.0f }; + static GLfloat ared[4] = { 0.8f, 0.1f, 0.0f, 1.0f }; + static GLfloat agreen[4] = { 0.0f, 0.8f, 0.2f, 1.0f }; + static GLfloat ablue[4] = { 0.2f, 0.2f, 1.0f, 1.0f }; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + switch (id) + { + case 1: + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared); + gearGL(1.0f, 4.0f, 1.0f, 20, 0.7f); + break; + case 2: + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen); + gearGL(0.5f, 2.0f, 2.0f, 10, 0.7f); + break; + case 3: + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue); + gearGL(1.3f, 2.0f, 0.5f, 10, 0.7f); + break; + default: + break; + } + glEnable(GL_NORMALIZE); +} + + +void RenderCamera() +{ + 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); +} + + +void RenderScene() +{ + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(fAngle, 0.0, 0.0, 1.0); + drawGearGL(1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1f, -2.0f, 0.0f); + glRotatef(-2.0 * fAngle - 9.0, 0.0, 0.0, 1.0); + drawGearGL(2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1f, 2.2f, -1.8f); + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + glRotatef(2.0 * fAngle - 2.0, 0.0, 0.0, 1.0); + drawGearGL(3); + glPopMatrix(); +} + + +static void View(GHOST_IWindow* window, bool stereo, int eye = 0) +{ + window->activateDrawingContext(); + GHOST_Rect bnds; + int noOfScanlines = 0, lowerScanline; + int verticalBlankingInterval = 32; // hard coded for testing purposes, display device dependant + float left, right, bottom, top; + float nearplane, farplane, zeroPlane, distance; + float eyeSeparation = 0.62; + window->getClientBounds(bnds); + GLfloat w = float(bnds.getWidth()) / float(bnds.getHeight()); + GLfloat h = 1.0; + + // viewport + if(stereo) + { + if(nVidiaWindows) + { + // handled by nVidia driver so act as normal (explicitly put here since + // it -is- stereo) + glViewport(0, 0, bnds.getWidth(), bnds.getHeight()); + } + else + { // generic cross platform above-below stereo + noOfScanlines = (bnds.getHeight() - verticalBlankingInterval) / 2; + switch(eye) + { + case LEFT_EYE: + // upper half of window + lowerScanline = bnds.getHeight() - noOfScanlines; + break; + case RIGHT_EYE: + // lower half of window + lowerScanline = 0; + break; + } + } + } + else + { + noOfScanlines = bnds.getHeight(); + lowerScanline = 0; + } + + glViewport(0, lowerScanline, bnds.getWidth(), noOfScanlines); + + // projection + left = -6.0; + right = 6.0; + bottom = -4.8; + top = 4.8; + nearplane = 5.0; + farplane = 60.0; + + if(stereo) + { + zeroPlane = 0.0; + distance = 14.5; + switch(eye) + { + case LEFT_EYE: + StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, -eyeSeparation / 2.0); + break; + case RIGHT_EYE: + StereoProjection(left, right, bottom, top, nearplane, farplane, zeroPlane, distance, eyeSeparation / 2.0); + break; + } + } + else + { +// left = -w; +// right = w; +// bottom = -h; +// top = h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(left, right, bottom, top, 5.0, 60.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); + + } + + glClearColor(.2f,0.0f,0.0f,0.0f); +} + + +void StereoProjection(float left, float right, float bottom, float top, float nearplane, float farplane, + float zero_plane, float dist, + float eye) +/* Perform the perspective projection for one eye's subfield. +The projection is in the direction of the negative z axis. + +-6.0, 6.0, -4.8, 4.8, +left, right, bottom, top = the coordinate range, in the plane of zero +parallax setting, which will be displayed on the screen. The +ratio between (right-left) and (top-bottom) should equal the aspect +ratio of the display. + +6.0, -6.0, +near, far = the z-coordinate values of the clipping planes. + +0.0, +zero_plane = the z-coordinate of the plane of zero parallax setting. + +14.5, +dist = the distance from the center of projection to the plane +of zero parallax. + +-0.31 +eye = half the eye separation; positive for the right eye subfield, +negative for the left eye subfield. +*/ +{ + float xmid, ymid, clip_near, clip_far, topw, bottomw, leftw, rightw, + dx, dy, n_over_d; + + dx = right - left; + dy = top - bottom; + + xmid = (right + left) / 2.0; + ymid = (top + bottom) / 2.0; + + clip_near = dist + zero_plane - nearplane; + clip_far = dist + zero_plane - farplane; + + n_over_d = clip_near / dist; + + topw = n_over_d * dy / 2.0; + bottomw = -topw; + rightw = n_over_d * (dx / 2.0 - eye); + leftw = n_over_d *(-dx / 2.0 - eye); + + /* Need to be in projection mode for this. */ + glLoadIdentity(); + glFrustum(leftw, rightw, bottomw, topw, clip_near, clip_far); + + glTranslatef(-xmid - eye, -ymid, -zero_plane - dist); + return; +} /* stereoproj */ + + +class Application : public GHOST_IEventConsumer { +public: + Application(GHOST_ISystem* system); + ~Application(void); + virtual bool processEvent(GHOST_IEvent* event); + + GHOST_ISystem* m_system; + GHOST_IWindow* m_mainWindow; + GHOST_IWindow* m_secondaryWindow; + GHOST_IWindow* m_fullScreenWindow; + GHOST_ITimerTask* m_gearsTimer, *m_testTimer; + GHOST_TStandardCursor m_cursor; + bool m_exitRequested; + + bool stereo; +}; + + +Application::Application(GHOST_ISystem* system) + : m_system(system), m_mainWindow(0), m_secondaryWindow(0), m_fullScreenWindow(0), + m_gearsTimer(0), m_testTimer(0), m_cursor(GHOST_kStandardCursorFirstCursor), + m_exitRequested(false), stereo(false) +{ + fApp = this; + + // Create the main window + STR_String title1 ("gears - main window"); + m_mainWindow = system->createWindow(title1, 10, 64, 320, 200, GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, true /* stereo flag */); + + if (!m_mainWindow) { + std::cout << "could not create main window\n"; + exit(-1); + } + + // Create a secondary window + STR_String title2 ("gears - secondary window"); + m_secondaryWindow = system->createWindow(title2, 340, 64, 320, 200, GHOST_kWindowStateNormal, + GHOST_kDrawingContextTypeOpenGL, false /* stereo flag */); + if (!m_secondaryWindow) { + cout << "could not create secondary window\n"; + exit(-1); + } + + // Install a timer to have the gears running + m_gearsTimer = system->installTimer(0 /*delay*/, 20/*interval*/, gearsTimerProc, m_mainWindow); +} + + +Application::~Application(void) +{ + // Dispose windows + if (m_system->validWindow(m_mainWindow)) { + m_system->disposeWindow(m_mainWindow); + } + if (m_system->validWindow(m_secondaryWindow)) { + m_system->disposeWindow(m_secondaryWindow); + } +} + + +bool Application::processEvent(GHOST_IEvent* event) +{ + GHOST_IWindow* window = event->getWindow(); + bool handled = true; + + switch (event->getType()) { +/* case GHOST_kEventUnknown: + break; + case GHOST_kEventCursorButton: + std::cout << "GHOST_kEventCursorButton"; break; + case GHOST_kEventCursorMove: + std::cout << "GHOST_kEventCursorMove"; break; +*/ + case GHOST_kEventKeyUp: + break; + + case GHOST_kEventKeyDown: + { + GHOST_TEventKeyData* keyData = (GHOST_TEventKeyData*) event->getData(); + switch (keyData->key) { + case GHOST_kKeyC: + { + int cursor = m_cursor; + cursor++; + if (cursor >= GHOST_kStandardCursorNumCursors) { + cursor = GHOST_kStandardCursorFirstCursor; + } + m_cursor = (GHOST_TStandardCursor)cursor; + window->setCursorShape(m_cursor); + } + break; + + case GHOST_kKeyE: + { + int x = 200, y= 200; + m_system->setCursorPosition(x,y); + break; + } + + case GHOST_kKeyF: + if (!m_system->getFullScreen()) { + // Begin fullscreen mode + GHOST_DisplaySetting setting; + + setting.bpp = 16; + setting.frequency = 50; + setting.xPixels = 640; + setting.yPixels = 480; + m_system->beginFullScreen(setting, &m_fullScreenWindow, false /* stereo flag */); + } + else { + m_system->endFullScreen(); + m_fullScreenWindow = 0; + } + break; + + case GHOST_kKeyH: + window->setCursorVisibility(!window->getCursorVisibility()); + break; + + case GHOST_kKeyM: + { + bool down = false; + m_system->getModifierKeyState(GHOST_kModifierKeyLeftShift,down); + if (down) { + std::cout << "left shift down\n"; + } + m_system->getModifierKeyState(GHOST_kModifierKeyRightShift,down); + if (down) { + std::cout << "right shift down\n"; } + m_system->getModifierKeyState(GHOST_kModifierKeyLeftAlt,down); + if (down) { + std::cout << "left Alt down\n"; + } + m_system->getModifierKeyState(GHOST_kModifierKeyRightAlt,down); + if (down) { + std::cout << "right Alt down\n"; + } + m_system->getModifierKeyState(GHOST_kModifierKeyLeftControl,down); + if (down) { + std::cout << "left control down\n"; + } + m_system->getModifierKeyState(GHOST_kModifierKeyRightControl,down); + if (down) { + std::cout << "right control down\n"; + } + } + break; + + case GHOST_kKeyQ: + if (m_system->getFullScreen()) + { + m_system->endFullScreen(); + m_fullScreenWindow = 0; + } + m_exitRequested = true; + break; + + case GHOST_kKeyS: // toggle mono and stereo + if(stereo) + stereo = false; + else + stereo = true; + break; + + case GHOST_kKeyT: + if (!m_testTimer) { + m_testTimer = m_system->installTimer(0, 1000, testTimerProc); + } + + else { + m_system->removeTimer(m_testTimer); + m_testTimer = 0; + } + + break; + + case GHOST_kKeyW: + if (m_mainWindow) + { + STR_String title; + m_mainWindow->getTitle(title); + title += "-"; + m_mainWindow->setTitle(title); + + } + break; + + default: + break; + } + } + break; + + case GHOST_kEventWindowClose: + { + GHOST_IWindow* window = event->getWindow(); + if (window == m_mainWindow) { + m_exitRequested = true; + } + else { + m_system->disposeWindow(window); + } + } + break; + + case GHOST_kEventWindowActivate: + handled = false; + break; + + case GHOST_kEventWindowDeactivate: + handled = false; + break; + + case GHOST_kEventWindowUpdate: + { + GHOST_IWindow* window = event->getWindow(); + if(!m_system->validWindow(window)) + break; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if(stereo) + { + View(window, stereo, LEFT_EYE); + glPushMatrix(); + RenderCamera(); + RenderScene(); + glPopMatrix(); + + View(window, stereo, RIGHT_EYE); + glPushMatrix(); + RenderCamera(); + RenderScene(); + glPopMatrix(); + } + else + { + View(window, stereo); + glPushMatrix(); + RenderCamera(); + RenderScene(); + glPopMatrix(); + } + window->swapBuffers(); + } + break; + + default: + handled = false; + break; + } + return handled; +} + + +int main(int /*argc*/, char** /*argv*/) +{ + nVidiaWindows = false; +// nVidiaWindows = true; + +#ifdef WIN32 + /* Set a couple of settings in the registry for the nVidia detonator driver. + * So this is very specific... + */ + if(nVidiaWindows) + { + LONG lresult; + HKEY hkey = 0; + DWORD dwd = 0; + unsigned char buffer[128]; + + CRegKey regkey; + DWORD keyValue; +// lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable"); + lresult = regkey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable", + KEY_ALL_ACCESS ); + + if(lresult == ERROR_SUCCESS) + printf("Succesfully opened key\n"); +#if 0 + lresult = regkey.QueryValue(&keyValue, "StereoEnable"); + if(lresult == ERROR_SUCCESS) + printf("Succesfully queried key\n"); +#endif + lresult = regkey.SetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\NVIDIA Corporation\\Global\\Stereo3D\\StereoEnable", + "1"); + if(lresult == ERROR_SUCCESS) + printf("Succesfully set value for key\n"); + regkey.Close(); + if(lresult == ERROR_SUCCESS) + printf("Succesfully closed key\n"); +// regkey.Write("2"); + } +#endif // WIN32 + + // Create the system + GHOST_ISystem::createSystem(); + fSystem = GHOST_ISystem::getSystem(); + + if (fSystem) { + // Create an application object + Application app (fSystem); + + // Add the application as event consumer + fSystem->addEventConsumer(&app); + + // Enter main loop + while (!app.m_exitRequested) { + //printf("main: loop\n"); + fSystem->processEvents(true); + fSystem->dispatchEvents(); + } + } + + // Dispose the system + GHOST_ISystem::disposeSystem(); + + return 0; +} + + +static void gearsTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 /*time*/) +{ + fAngle += 2.0; + view_roty += 1.0; + GHOST_IWindow* window = (GHOST_IWindow*)task->getUserData(); + if (fApp->m_fullScreenWindow) { + // Running full screen + fApp->m_fullScreenWindow->invalidate(); + } + else { + if (fSystem->validWindow(window)) { + window->invalidate(); + } + } +} diff --git a/intern/ghost/test/gears/Makefile b/intern/ghost/test/gears/Makefile new file mode 100755 index 00000000000..b7966b4d157 --- /dev/null +++ b/intern/ghost/test/gears/Makefile @@ -0,0 +1,48 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): none yet. +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# GHOST gears test application Makefile +# + +LIBNAME = gearstest +DIR = $(OCGDIR)/intern/ghost/test + +# we don't want a library here, only object files: +ALLTARGETS = $(OBJS) + +include nan_compile.mk + +CFLAGS += $(LEVEL_2_C_WARNINGS) +CCFLAGS += $(LEVEL_2_CPP_WARNINGS) + +CPPFLAGS += -I$(OPENGL_HEADERS) +CPPFLAGS += -I$(NAN_STRING)/include +CPPFLAGS += -I../.. + |