mirror of
https://github.com/NGSolve/netgen.git
synced 2024-11-11 16:49:16 +05:00
281 lines
6.7 KiB
C
281 lines
6.7 KiB
C
|
/* $Id: double.c,v 1.14 2005/04/23 07:49:13 gregcouch Exp $ */
|
||
|
|
||
|
/*
|
||
|
* Togl - a Tk OpenGL widget
|
||
|
* Copyright (C) 1996-1997 Brian Paul and Ben Bederson
|
||
|
* See the LICENSE file for copyright details.
|
||
|
*/
|
||
|
|
||
|
#include "togl.h"
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
/*
|
||
|
* The following variable is a special hack that is needed in order for
|
||
|
* Sun shared libraries to be used for Tcl.
|
||
|
*/
|
||
|
#ifdef SUN
|
||
|
extern int matherr();
|
||
|
int *tclDummyMathPtr = (int *) matherr;
|
||
|
#endif
|
||
|
|
||
|
static GLuint FontBase;
|
||
|
static float xAngle = 0.0, yAngle = 0.0, zAngle = 0.0;
|
||
|
static GLfloat CornerX, CornerY, CornerZ; /* where to print strings */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
void
|
||
|
create_cb(Togl *togl)
|
||
|
{
|
||
|
|
||
|
FontBase = Togl_LoadBitmapFont(togl, TOGL_BITMAP_8_BY_13);
|
||
|
if (!FontBase) {
|
||
|
printf("Couldn't load font!\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
void
|
||
|
reshape_cb(Togl *togl)
|
||
|
{
|
||
|
int width = Togl_Width(togl);
|
||
|
int height = Togl_Height(togl);
|
||
|
float aspect = (float) width / (float) height;
|
||
|
|
||
|
glViewport(0, 0, width, height);
|
||
|
|
||
|
/* Set up projection transform */
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
glLoadIdentity();
|
||
|
glFrustum(-aspect, aspect, -1.0, 1.0, 1.0, 10.0);
|
||
|
|
||
|
CornerX = -aspect;
|
||
|
CornerY = -1.0;
|
||
|
CornerZ = -1.1;
|
||
|
|
||
|
/* Change back to model view transform for rendering */
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
static void
|
||
|
print_string(const char *s)
|
||
|
{
|
||
|
glCallLists(strlen(s), GL_UNSIGNED_BYTE, s);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
void
|
||
|
display_cb(Togl *togl)
|
||
|
{
|
||
|
static GLuint cubeList = 0;
|
||
|
const char *ident;
|
||
|
|
||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||
|
|
||
|
glLoadIdentity(); /* Reset modelview matrix to the identity
|
||
|
* matrix */
|
||
|
glTranslatef(0.0, 0.0, -3.0); /* Move the camera back three units */
|
||
|
glRotatef(xAngle, 1.0, 0.0, 0.0); /* Rotate by X, Y, and Z angles */
|
||
|
glRotatef(yAngle, 0.0, 1.0, 0.0);
|
||
|
glRotatef(zAngle, 0.0, 0.0, 1.0);
|
||
|
|
||
|
glEnable(GL_DEPTH_TEST);
|
||
|
|
||
|
if (!cubeList) {
|
||
|
cubeList = glGenLists(1);
|
||
|
glNewList(cubeList, GL_COMPILE);
|
||
|
|
||
|
/* Front face */
|
||
|
glBegin(GL_QUADS);
|
||
|
glColor3f(0.0, 0.7, 0.1); /* Green */
|
||
|
glVertex3f(-1.0, 1.0, 1.0);
|
||
|
glVertex3f(1.0, 1.0, 1.0);
|
||
|
glVertex3f(1.0, -1.0, 1.0);
|
||
|
glVertex3f(-1.0, -1.0, 1.0);
|
||
|
/* Back face */
|
||
|
glColor3f(0.9, 1.0, 0.0); /* Yellow */
|
||
|
glVertex3f(-1.0, 1.0, -1.0);
|
||
|
glVertex3f(1.0, 1.0, -1.0);
|
||
|
glVertex3f(1.0, -1.0, -1.0);
|
||
|
glVertex3f(-1.0, -1.0, -1.0);
|
||
|
/* Top side face */
|
||
|
glColor3f(0.2, 0.2, 1.0); /* Blue */
|
||
|
glVertex3f(-1.0, 1.0, 1.0);
|
||
|
glVertex3f(1.0, 1.0, 1.0);
|
||
|
glVertex3f(1.0, 1.0, -1.0);
|
||
|
glVertex3f(-1.0, 1.0, -1.0);
|
||
|
/* Bottom side face */
|
||
|
glColor3f(0.7, 0.0, 0.1); /* Red */
|
||
|
glVertex3f(-1.0, -1.0, 1.0);
|
||
|
glVertex3f(1.0, -1.0, 1.0);
|
||
|
glVertex3f(1.0, -1.0, -1.0);
|
||
|
glVertex3f(-1.0, -1.0, -1.0);
|
||
|
glEnd();
|
||
|
|
||
|
glEndList();
|
||
|
|
||
|
}
|
||
|
glCallList(cubeList);
|
||
|
|
||
|
glDisable(GL_DEPTH_TEST);
|
||
|
glLoadIdentity();
|
||
|
glColor3f(1.0, 1.0, 1.0);
|
||
|
glRasterPos3f(CornerX, CornerY, CornerZ);
|
||
|
glListBase(FontBase);
|
||
|
ident = Togl_Ident(togl);
|
||
|
if (strcmp(ident, "Single") == 0) {
|
||
|
print_string("Single buffered");
|
||
|
} else {
|
||
|
print_string("Double buffered");
|
||
|
}
|
||
|
Togl_SwapBuffers(togl);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int
|
||
|
setXrot_cb(Togl *togl, int argc, CONST84 char *argv[])
|
||
|
{
|
||
|
Tcl_Interp *interp = Togl_Interp(togl);
|
||
|
|
||
|
/* error checking */
|
||
|
if (argc != 3) {
|
||
|
Tcl_SetResult(interp,
|
||
|
"wrong # args: should be \"pathName setXrot ?angle?\"",
|
||
|
TCL_STATIC);
|
||
|
return TCL_ERROR;
|
||
|
}
|
||
|
|
||
|
xAngle = atof(argv[2]);
|
||
|
|
||
|
/* printf( "before %f ", xAngle ); */
|
||
|
|
||
|
if (xAngle < 0.0) {
|
||
|
xAngle += 360.0;
|
||
|
} else if (xAngle > 360.0) {
|
||
|
xAngle -= 360.0;
|
||
|
}
|
||
|
|
||
|
/* printf( "after %f \n", xAngle ); */
|
||
|
|
||
|
Togl_PostRedisplay(togl);
|
||
|
|
||
|
/* Let result string equal value */
|
||
|
strcpy(interp->result, argv[2]);
|
||
|
return TCL_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int
|
||
|
setYrot_cb(Togl *togl, int argc, CONST84 char *argv[])
|
||
|
{
|
||
|
Tcl_Interp *interp = Togl_Interp(togl);
|
||
|
|
||
|
/* error checking */
|
||
|
if (argc != 3) {
|
||
|
Tcl_SetResult(interp,
|
||
|
"wrong # args: should be \"pathName setYrot ?angle?\"",
|
||
|
TCL_STATIC);
|
||
|
return TCL_ERROR;
|
||
|
}
|
||
|
|
||
|
yAngle = atof(argv[2]);
|
||
|
|
||
|
if (yAngle < 0.0) {
|
||
|
yAngle += 360.0;
|
||
|
} else if (yAngle > 360.0) {
|
||
|
yAngle -= 360.0;
|
||
|
}
|
||
|
|
||
|
Togl_PostRedisplay(togl);
|
||
|
|
||
|
/* Let result string equal value */
|
||
|
strcpy(interp->result, argv[2]);
|
||
|
return TCL_OK;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
getXrot_cb(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
|
||
|
{
|
||
|
sprintf(interp->result, "%d", (int) xAngle);
|
||
|
return TCL_OK;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
getYrot_cb(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
|
||
|
{
|
||
|
sprintf(interp->result, "%d", (int) yAngle);
|
||
|
return TCL_OK;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Called by Tk_Main() to let me initialize the modules (Togl) I will need.
|
||
|
*/
|
||
|
TOGL_EXTERN int
|
||
|
Double_Init(Tcl_Interp *interp)
|
||
|
{
|
||
|
#ifdef USE_TCL_STUBS
|
||
|
if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
|
||
|
return TCL_ERROR;
|
||
|
}
|
||
|
#endif
|
||
|
#ifdef USE_TK_STUBS
|
||
|
if (Tk_InitStubs(interp, "8.1", 0) == NULL) {
|
||
|
return TCL_ERROR;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (Togl_Init(interp) == TCL_ERROR) {
|
||
|
return TCL_ERROR;
|
||
|
}
|
||
|
#ifdef macintosh
|
||
|
Togl_MacSetupMainInterp(interp);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Specify the C callback functions for widget creation, display,
|
||
|
* and reshape.
|
||
|
*/
|
||
|
Togl_CreateFunc(create_cb);
|
||
|
Togl_DisplayFunc(display_cb);
|
||
|
Togl_ReshapeFunc(reshape_cb);
|
||
|
|
||
|
/*
|
||
|
* Make a new Togl widget command so the Tcl code can set a C variable.
|
||
|
*/
|
||
|
|
||
|
Togl_CreateCommand("setXrot", setXrot_cb);
|
||
|
Togl_CreateCommand("setYrot", setYrot_cb);
|
||
|
|
||
|
/*
|
||
|
* Call Tcl_CreateCommand for application-specific commands, if
|
||
|
* they weren't already created by the init procedures called above.
|
||
|
*/
|
||
|
|
||
|
Tcl_CreateCommand(interp, "getXrot", (Tcl_CmdProc *) getXrot_cb,
|
||
|
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||
|
Tcl_CreateCommand(interp, "getYrot", (Tcl_CmdProc *) getYrot_cb,
|
||
|
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
|
||
|
return TCL_OK;
|
||
|
}
|