/* $Id: index.c,v 1.13 2007/08/03 16:48:50 gregcouch Exp $ */ /* * Togl - a Tk OpenGL widget * Copyright (C) 1996-1997 Brian Paul and Ben Bederson * Copyright (C) 2006-2007 Greg Couch * See the LICENSE file for copyright details. */ /* * An example Togl program using color-index mode. */ #define USE_TOGL_STUBS #include "togl.h" #include #include #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT /* Our color indexes: */ static unsigned long black, red, green, blue; /* Rotation angle */ static float Angle = 0; /* * Togl widget create callback. This is called by Tcl/Tk when the widget has * been realized. Here's where one may do some one-time context setup or * initializations. */ static int create_cb(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Togl *togl; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName"); return TCL_ERROR; } if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) { return TCL_ERROR; } /* allocate color indexes */ black = Togl_AllocColor(togl, 0, 0, 0); red = Togl_AllocColor(togl, 1, 0, 0); green = Togl_AllocColor(togl, 0, 1, 0); blue = Togl_AllocColor(togl, 0, 0, 1); /* If we were using a private read/write colormap we'd setup our color * table with something like this: */ /* * black = 1; Togl_SetColor( togl, black, 0, 0, 0 ); red = 2; * Togl_SetColor( togl, red, 1, 0, 0 ); green = 3; Togl_SetColor( * togl, green, 0, 1, 0 ); blue = 4; Togl_SetColor( togl, blue, 0, * 0, 1 ); */ glShadeModel(GL_FLAT); glDisable(GL_DITHER); return TCL_OK; } /* * Togl widget reshape callback. This is called by Tcl/Tk when the widget * has been resized. Typically, we call glViewport and perhaps setup the * projection matrix. */ static int reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { int width; int height; float aspect; Togl *togl; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName"); return TCL_ERROR; } if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) { return TCL_ERROR; } width = Togl_Width(togl); height = Togl_Height(togl); aspect = (float) width / (float) height; glViewport(0, 0, width, height); /* Set up projection transform */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-aspect, aspect, -1, 1, -1, 1); /* Change back to model view transform for rendering */ glMatrixMode(GL_MODELVIEW); return TCL_OK; } /* * Togl widget display callback. This is called by Tcl/Tk when the widget's * contents have to be redrawn. Typically, we clear the color and depth * buffers, render our objects, then swap the front/back color buffers. */ static int display_cb(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Togl *togl; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName"); return TCL_ERROR; } if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) { return TCL_ERROR; } glClearIndex((float) black); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(0.3f, -0.3f, 0); glRotatef(Angle, 0, 0, 1); glIndexi(red); glBegin(GL_TRIANGLES); glVertex2f(-0.5f, -0.3f); glVertex2f(0.5f, -0.3f); glVertex2f(0, 0.6f); glEnd(); glPopMatrix(); glPushMatrix(); glRotatef(Angle, 0, 0, 1); glIndexi(green); glBegin(GL_TRIANGLES); glVertex2f(-0.5f, -0.3f); glVertex2f(0.5f, -0.3f); glVertex2f(0, 0.6f); glEnd(); glPopMatrix(); glPushMatrix(); glTranslatef(-0.3f, 0.3f, 0); glRotatef(Angle, 0, 0, 1); glIndexi(blue); glBegin(GL_TRIANGLES); glVertex2f(-0.5f, -0.3f); glVertex2f(0.5f, -0.3f); glVertex2f(0, 0.6f); glEnd(); glPopMatrix(); glFlush(); Togl_SwapBuffers(togl); return TCL_OK; } static int timer_cb(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Togl *togl; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "pathName"); return TCL_ERROR; } if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) { return TCL_ERROR; } Angle += 5.0; Togl_PostRedisplay(togl); return TCL_OK; } EXTERN int Index_Init(Tcl_Interp *interp) { /* * Initialize Tcl and the Togl widget module. */ if (Tcl_InitStubs(interp, "8.1", 0) == NULL || Togl_InitStubs(interp, "2.0", 0) == NULL) { return TCL_ERROR; } /* * Specify the C callback functions for widget creation, display, * and reshape. */ Tcl_CreateObjCommand(interp, "::index::create_cb", create_cb, NULL, NULL); Tcl_CreateObjCommand(interp, "::index::display_cb", display_cb, NULL, NULL); Tcl_CreateObjCommand(interp, "::index::reshape_cb", reshape_cb, NULL, NULL); Tcl_CreateObjCommand(interp, "::index::timer_cb", timer_cb, NULL, NULL); /* * Make a new Togl widget command so the Tcl code can set a C variable. */ /* NONE */ /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ return TCL_OK; }