netgen/ng/Togl2.1/overlay.c
2016-02-08 15:53:16 +01:00

215 lines
5.2 KiB
C

/* $Id: overlay.c,v 1.10 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 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;
}