1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
/* $Id: overlay.c,v 1.2 2009/05/14 20:43:34 vareille 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 an overlay.
*/
#define USE_TOGL_STUBS
#include "togl.h"
#include <stdlib.h>
#include <string.h>
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
/* Overlay color indexes: */
static unsigned long Red, Green;
/*
* 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 overlay color indexes */
Red = Togl_AllocColorOverlay(togl, 1, 0, 0);
Green = Togl_AllocColorOverlay(togl, 0, 1, 0);
/* in this demo we always show the overlay */
if (Togl_ExistsOverlay(togl)) {
Togl_ShowOverlay(togl);
printf("Red and green lines are in the overlay\n");
} else {
printf("Sorry, this display doesn't support overlays\n");
}
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;
/* Set up viewing for normal plane's context */
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-aspect, aspect, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
/* Set up viewing for overlay plane's context */
if (Togl_ExistsOverlay(togl)) {
Togl_UseLayer(togl, TOGL_OVERLAY);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
Togl_UseLayer(togl, TOGL_NORMAL);
}
return TCL_OK;
}
/*
* Togl widget overlay display callback. This is called by Tcl/Tk when the
* overlay has to be redrawn.
*/
static int
overlay_display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
Tcl_Obj *const *objv)
{
glClear(GL_COLOR_BUFFER_BIT);
glIndexi(Red);
glBegin(GL_LINES);
glVertex2f(-1, -1);
glVertex2f(1, 1);
glVertex2f(-1, 1);
glVertex2f(1, -1);
glEnd();
glIndexi(Green);
glBegin(GL_LINE_LOOP);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.5f, -0.5f);
glVertex2f(0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
glFlush();
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)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 1);
glVertex2f(-0.5f, -0.3f);
glVertex2f(0.5f, -0.3f);
glVertex2f(0, 0.6f);
glColor3f(1, 1, 0);
glVertex2f(-0.5f + 0.2f, -0.3f - 0.2f);
glVertex2f(0.5f + 0.2f, -0.3f - 0.2f);
glVertex2f(0 + 0.2f, 0.6f - 0.2f);
glColor3f(0, 1, 1);
glVertex2f(-0.5f + 0.4f, -0.3f - 0.4f);
glVertex2f(0.5f + 0.4f, -0.3f - 0.4f);
glVertex2f(0 + 0.4f, 0.6f - 0.4f);
glEnd();
glFlush();
return TCL_OK;
}
/*
* Called by Tcl to let me initialize the modules (Togl) I will need.
*/
EXTERN int
Overlay_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, "create_cb", create_cb, NULL, NULL);
Tcl_CreateObjCommand(interp, "display_cb", display_cb, NULL, NULL);
Tcl_CreateObjCommand(interp, "reshape_cb", reshape_cb, NULL, NULL);
Tcl_CreateObjCommand(interp, "overlay_display_cb", overlay_display_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;
}
|