1 /* $Id: overlay.c,v 1.10 2007/08/03 16:48:50 gregcouch Exp $ */
2
3 /*
4 * Togl - a Tk OpenGL widget
5 * Copyright (C) 1996-1997 Brian Paul and Ben Bederson
6 * Copyright (C) 2006-2007 Greg Couch
7 * See the LICENSE file for copyright details.
8 */
9
10
11 /*
12 * An example Togl program using an overlay.
13 */
14
15 #define USE_TOGL_STUBS
16
17 #include "togl.h"
18 #include <stdlib.h>
19 #include <string.h>
20
21 #undef TCL_STORAGE_CLASS
22 #define TCL_STORAGE_CLASS DLLEXPORT
23
24
25 /* Overlay color indexes: */
26 static unsigned long Red, Green;
27
28
29 /*
30 * Togl widget create callback. This is called by Tcl/Tk when the widget has
31 * been realized. Here's where one may do some one-time context setup or
32 * initializations.
33 */
34 static int
create_cb(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * const * objv)35 create_cb(ClientData clientData, Tcl_Interp *interp, int objc,
36 Tcl_Obj *const *objv)
37 {
38 Togl *togl;
39
40 if (objc != 2) {
41 Tcl_WrongNumArgs(interp, 1, objv, "pathName");
42 return TCL_ERROR;
43 }
44
45 if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
46 return TCL_ERROR;
47 }
48
49 /* allocate overlay color indexes */
50 Red = Togl_AllocColorOverlay(togl, 1, 0, 0);
51 Green = Togl_AllocColorOverlay(togl, 0, 1, 0);
52
53 /* in this demo we always show the overlay */
54 if (Togl_ExistsOverlay(togl)) {
55 Togl_ShowOverlay(togl);
56 printf("Red and green lines are in the overlay\n");
57 } else {
58 printf("Sorry, this display doesn't support overlays\n");
59 }
60 return TCL_OK;
61 }
62
63
64 /*
65 * Togl widget reshape callback. This is called by Tcl/Tk when the widget
66 * has been resized. Typically, we call glViewport and perhaps setup the
67 * projection matrix.
68 */
69 static int
reshape_cb(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * const * objv)70 reshape_cb(ClientData clientData, Tcl_Interp *interp, int objc,
71 Tcl_Obj *const *objv)
72 {
73 int width;
74 int height;
75 float aspect;
76 Togl *togl;
77
78 if (objc != 2) {
79 Tcl_WrongNumArgs(interp, 1, objv, "pathName");
80 return TCL_ERROR;
81 }
82
83 if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) {
84 return TCL_ERROR;
85 }
86
87 width = Togl_Width(togl);
88 height = Togl_Height(togl);
89 aspect = (float) width / (float) height;
90
91 /* Set up viewing for normal plane's context */
92 glViewport(0, 0, width, height);
93 glMatrixMode(GL_PROJECTION);
94 glLoadIdentity();
95 glOrtho(-aspect, aspect, -1, 1, -1, 1);
96 glMatrixMode(GL_MODELVIEW);
97
98 /* Set up viewing for overlay plane's context */
99 if (Togl_ExistsOverlay(togl)) {
100 Togl_UseLayer(togl, TOGL_OVERLAY);
101 glViewport(0, 0, width, height);
102 glMatrixMode(GL_PROJECTION);
103 glLoadIdentity();
104 glOrtho(-1, 1, -1, 1, -1, 1);
105 glMatrixMode(GL_MODELVIEW);
106 Togl_UseLayer(togl, TOGL_NORMAL);
107 }
108 return TCL_OK;
109 }
110
111
112 /*
113 * Togl widget overlay display callback. This is called by Tcl/Tk when the
114 * overlay has to be redrawn.
115 */
116 static int
overlay_display_cb(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * const * objv)117 overlay_display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
118 Tcl_Obj *const *objv)
119 {
120 glClear(GL_COLOR_BUFFER_BIT);
121
122 glIndexi(Red);
123 glBegin(GL_LINES);
124 glVertex2f(-1, -1);
125 glVertex2f(1, 1);
126 glVertex2f(-1, 1);
127 glVertex2f(1, -1);
128 glEnd();
129
130 glIndexi(Green);
131 glBegin(GL_LINE_LOOP);
132 glVertex2f(-0.5f, -0.5f);
133 glVertex2f(0.5f, -0.5f);
134 glVertex2f(0.5f, 0.5f);
135 glVertex2f(-0.5f, 0.5f);
136 glEnd();
137 glFlush();
138 return TCL_OK;
139 }
140
141
142 /*
143 * Togl widget display callback. This is called by Tcl/Tk when the widget's
144 * contents have to be redrawn. Typically, we clear the color and depth
145 * buffers, render our objects, then swap the front/back color buffers.
146 */
147 static int
display_cb(ClientData clientData,Tcl_Interp * interp,int objc,Tcl_Obj * const * objv)148 display_cb(ClientData clientData, Tcl_Interp *interp, int objc,
149 Tcl_Obj *const *objv)
150 {
151 glClear(GL_COLOR_BUFFER_BIT);
152
153 glLoadIdentity();
154
155 glBegin(GL_TRIANGLES);
156
157 glColor3f(1, 0, 1);
158 glVertex2f(-0.5f, -0.3f);
159 glVertex2f(0.5f, -0.3f);
160 glVertex2f(0, 0.6f);
161
162 glColor3f(1, 1, 0);
163 glVertex2f(-0.5f + 0.2f, -0.3f - 0.2f);
164 glVertex2f(0.5f + 0.2f, -0.3f - 0.2f);
165 glVertex2f(0 + 0.2f, 0.6f - 0.2f);
166
167 glColor3f(0, 1, 1);
168 glVertex2f(-0.5f + 0.4f, -0.3f - 0.4f);
169 glVertex2f(0.5f + 0.4f, -0.3f - 0.4f);
170 glVertex2f(0 + 0.4f, 0.6f - 0.4f);
171
172 glEnd();
173
174 glFlush();
175 return TCL_OK;
176 }
177
178
179 /*
180 * Called by Tcl to let me initialize the modules (Togl) I will need.
181 */
182 EXTERN int
Overlay_Init(Tcl_Interp * interp)183 Overlay_Init(Tcl_Interp *interp)
184 {
185 /*
186 * Initialize Tcl and the Togl widget module.
187 */
188 if (Tcl_InitStubs(interp, "8.1", 0) == NULL
189 || Togl_InitStubs(interp, "2.0", 0) == NULL) {
190 return TCL_ERROR;
191 }
192
193 /*
194 * Specify the C callback functions for widget creation, display,
195 * and reshape.
196 */
197 Tcl_CreateObjCommand(interp, "create_cb", create_cb, NULL, NULL);
198 Tcl_CreateObjCommand(interp, "display_cb", display_cb, NULL, NULL);
199 Tcl_CreateObjCommand(interp, "reshape_cb", reshape_cb, NULL, NULL);
200
201 Tcl_CreateObjCommand(interp, "overlay_display_cb", overlay_display_cb, NULL,
202 NULL);
203
204 /*
205 * Make a new Togl widget command so the Tcl code can set a C variable.
206 */
207 /* NONE */
208
209 /*
210 * Call Tcl_CreateCommand for application-specific commands, if
211 * they weren't already created by the init procedures called above.
212 */
213 return TCL_OK;
214 }
215