00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_VISX_TCLPKG_GL_CC_UTC20050628171008_DEFINED
00035 #define GROOVX_VISX_TCLPKG_GL_CC_UTC20050628171008_DEFINED
00036
00037 #include "visx/tclpkg-gl.h"
00038
00039
00040
00041
00042
00043
00044 #include "geom/rect.h"
00045
00046 #include "gfx/canvas.h"
00047 #include "gfx/glcanvas.h"
00048
00049 #include "tcl/list.h"
00050 #include "tcl/pkg.h"
00051
00052 #include "rutz/arrays.h"
00053 #include "rutz/error.h"
00054
00055 #include <cmath>
00056 #include <map>
00057
00058 #if defined(GVX_GL_PLATFORM_GLX)
00059 # include <GL/gl.h>
00060 # include <GL/glu.h>
00061 # include <GL/glx.h>
00062 #elif defined(GVX_GL_PLATFORM_AGL)
00063 # include <AGL/gl.h>
00064 # include <AGL/glu.h>
00065 #endif
00066
00067 #include "rutz/trace.h"
00068
00070
00071
00072
00074
00075 namespace GLTcl
00076 {
00077 void loadMatrix(nub::soft_ref<GLCanvas> canvas, tcl::list entries);
00078 void lookAt(tcl::list args);
00079 void antialias(bool on_off);
00080 void drawOneLine(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
00081 void drawThickLine(GLdouble x1, GLdouble y1,
00082 GLdouble x2, GLdouble y2, GLdouble thickness);
00083 tcl::list lineInfo();
00084
00085
00086 const char* getString(GLenum name)
00087 {
00088 return reinterpret_cast<const char*>(glGetString(name));
00089 }
00090
00091 #define NAMEVAL(x) #x, x
00092
00093
00094
00095
00096
00097
00098 struct AttribInfo
00099 {
00100 const char* param_name;
00101 GLenum param_tag;
00102 int num_values;
00103 };
00104
00105 static std::map<GLenum, const AttribInfo*> theAttribMap;
00106
00107 void loadGet(tcl::pkg* pkg)
00108 {
00109 static const AttribInfo theAttribs[] =
00110 {
00111 { NAMEVAL(GL_ACCUM_CLEAR_VALUE), 4 },
00112 { NAMEVAL(GL_ACCUM_ALPHA_BITS), 1 },
00113 { NAMEVAL(GL_ACCUM_BLUE_BITS), 1 },
00114 { NAMEVAL(GL_ACCUM_GREEN_BITS), 1 },
00115 { NAMEVAL(GL_ACCUM_RED_BITS), 1 },
00116 { NAMEVAL(GL_ALPHA_BITS), 1 },
00117 { NAMEVAL(GL_BLUE_BITS), 1 },
00118 { NAMEVAL(GL_COLOR_CLEAR_VALUE), 4 },
00119 { NAMEVAL(GL_CURRENT_COLOR), 4 },
00120 { NAMEVAL(GL_CURRENT_INDEX), 1 },
00121 { NAMEVAL(GL_DEPTH_BITS), 1 },
00122 { NAMEVAL(GL_DEPTH_CLEAR_VALUE), 1 },
00123 { NAMEVAL(GL_INDEX_BITS), 1 },
00124 { NAMEVAL(GL_INDEX_CLEAR_VALUE), 1 },
00125 { NAMEVAL(GL_GREEN_BITS), 1 },
00126 { NAMEVAL(GL_LINE_WIDTH), 1 },
00127 { NAMEVAL(GL_LINE_WIDTH_GRANULARITY), 1 },
00128 { NAMEVAL(GL_LINE_WIDTH_RANGE), 2 },
00129 { NAMEVAL(GL_LIST_BASE), 1 },
00130 { NAMEVAL(GL_LIST_INDEX), 1 },
00131 { NAMEVAL(GL_MATRIX_MODE), 1 },
00132 { NAMEVAL(GL_MODELVIEW_MATRIX), 16 },
00133 { NAMEVAL(GL_POLYGON_MODE), 2 },
00134 { NAMEVAL(GL_PROJECTION_MATRIX), 16 },
00135 { NAMEVAL(GL_RED_BITS), 1 },
00136 { NAMEVAL(GL_RGBA_MODE), 1 },
00137 { NAMEVAL(GL_SUBPIXEL_BITS), 1 },
00138 { NAMEVAL(GL_STENCIL_BITS), 1 },
00139 { NAMEVAL(GL_STENCIL_CLEAR_VALUE), 1 },
00140 { NAMEVAL(GL_VIEWPORT), 4 },
00141 };
00142
00143 int num_params = sizeof(theAttribs) / sizeof(AttribInfo);
00144 for (int i = 0; i < num_params; ++i)
00145 {
00146 pkg->link_var_copy(theAttribs[i].param_name,
00147 static_cast<int>(theAttribs[i].param_tag));
00148 theAttribMap[theAttribs[i].param_tag] = &(theAttribs[i]);
00149 }
00150 }
00151
00152 struct NameVal
00153 {
00154 const char* name;
00155 int val;
00156 };
00157
00158 void loadEnums(tcl::pkg* pkg)
00159 {
00160 NameVal theEnums [] =
00161 {
00162
00163 { NAMEVAL(GL_POINTS) },
00164 { NAMEVAL(GL_LINES) },
00165 { NAMEVAL(GL_LINE_STRIP) },
00166 { NAMEVAL(GL_LINE_LOOP) },
00167 { NAMEVAL(GL_TRIANGLES) },
00168 { NAMEVAL(GL_TRIANGLE_STRIP) },
00169 { NAMEVAL(GL_TRIANGLE_FAN) },
00170 { NAMEVAL(GL_QUADS) },
00171 { NAMEVAL(GL_QUAD_STRIP) },
00172 { NAMEVAL(GL_POLYGON) },
00173
00174
00175 { NAMEVAL(GL_ZERO) },
00176 { NAMEVAL(GL_ONE) },
00177 { NAMEVAL(GL_DST_COLOR) },
00178 { NAMEVAL(GL_ONE_MINUS_DST_COLOR) },
00179 { NAMEVAL(GL_SRC_COLOR) },
00180 { NAMEVAL(GL_ONE_MINUS_SRC_COLOR) },
00181 { NAMEVAL(GL_SRC_ALPHA) },
00182 { NAMEVAL(GL_ONE_MINUS_SRC_ALPHA) },
00183 { NAMEVAL(GL_DST_ALPHA) },
00184 { NAMEVAL(GL_ONE_MINUS_DST_ALPHA) },
00185 { NAMEVAL(GL_SRC_ALPHA_SATURATE) },
00186
00187
00188 { NAMEVAL(GL_COLOR_BUFFER_BIT) },
00189 { NAMEVAL(GL_DEPTH_BUFFER_BIT) },
00190 { NAMEVAL(GL_ACCUM_BUFFER_BIT) },
00191 { NAMEVAL(GL_STENCIL_BUFFER_BIT) },
00192
00193
00194 { NAMEVAL(GL_NONE) },
00195 { NAMEVAL(GL_FRONT_LEFT) },
00196 { NAMEVAL(GL_FRONT_RIGHT) },
00197 { NAMEVAL(GL_BACK_LEFT) },
00198 { NAMEVAL(GL_BACK_RIGHT) },
00199 { NAMEVAL(GL_FRONT) },
00200 { NAMEVAL(GL_BACK) },
00201 { NAMEVAL(GL_LEFT) },
00202 { NAMEVAL(GL_RIGHT) },
00203 { NAMEVAL(GL_FRONT_AND_BACK) },
00204
00205
00206 { NAMEVAL(GL_ALPHA_TEST) },
00207 { NAMEVAL(GL_BLEND) },
00208 { NAMEVAL(GL_FOG) },
00209 { NAMEVAL(GL_LIGHTING) },
00210 { NAMEVAL(GL_LINE_STIPPLE) },
00211 { NAMEVAL(GL_POLYGON_STIPPLE) },
00212 { NAMEVAL(GL_CULL_FACE) },
00213 { NAMEVAL(GL_INDEX_LOGIC_OP) },
00214 { NAMEVAL(GL_COLOR_LOGIC_OP) },
00215 { NAMEVAL(GL_DITHER) },
00216 { NAMEVAL(GL_STENCIL_TEST) },
00217 { NAMEVAL(GL_DEPTH_TEST) },
00218 { NAMEVAL(GL_MAP1_VERTEX_3) },
00219 { NAMEVAL(GL_MAP1_VERTEX_4) },
00220 { NAMEVAL(GL_MAP1_COLOR_4) },
00221 { NAMEVAL(GL_MAP1_INDEX) },
00222 { NAMEVAL(GL_MAP1_NORMAL) },
00223 { NAMEVAL(GL_POINT_SMOOTH) },
00224 { NAMEVAL(GL_LINE_SMOOTH) },
00225 { NAMEVAL(GL_POLYGON_SMOOTH) },
00226 { NAMEVAL(GL_SCISSOR_TEST) },
00227 { NAMEVAL(GL_COLOR_MATERIAL) },
00228 { NAMEVAL(GL_NORMALIZE) },
00229 { NAMEVAL(GL_AUTO_NORMAL) },
00230 { NAMEVAL(GL_VERTEX_ARRAY) },
00231 { NAMEVAL(GL_NORMAL_ARRAY) },
00232 { NAMEVAL(GL_COLOR_ARRAY) },
00233 { NAMEVAL(GL_INDEX_ARRAY) },
00234 { NAMEVAL(GL_TEXTURE_COORD_ARRAY) },
00235 { NAMEVAL(GL_EDGE_FLAG_ARRAY) },
00236 { NAMEVAL(GL_POLYGON_OFFSET_POINT) },
00237 { NAMEVAL(GL_POLYGON_OFFSET_LINE) },
00238 { NAMEVAL(GL_POLYGON_OFFSET_FILL) },
00239 #ifdef GVX_GL_PLATFORM_GLX
00240 { NAMEVAL(GL_RESCALE_NORMAL_EXT) },
00241 #endif
00242
00243
00244 { NAMEVAL(GL_MODELVIEW) },
00245 { NAMEVAL(GL_PROJECTION) },
00246 { NAMEVAL(GL_TEXTURE) },
00247
00248
00249 { NAMEVAL(GL_COMPILE) },
00250 { NAMEVAL(GL_COMPILE_AND_EXECUTE) },
00251
00252
00253 { NAMEVAL(GL_POINT) },
00254 { NAMEVAL(GL_LINE) },
00255 { NAMEVAL(GL_FILL) },
00256 };
00257
00258 int num_enums = sizeof(theEnums) / sizeof(NameVal);
00259 for (int i = 0; i < num_enums; ++i)
00260 {
00261 pkg->link_var_copy(theEnums[i].name, theEnums[i].val);
00262 }
00263 }
00264
00265 #undef NAMEVAL
00266
00267 void extractValues(GLenum tag, GLboolean* vals_out)
00268 { glGetBooleanv(tag, vals_out); }
00269
00270 void extractValues(GLenum tag, GLdouble* vals_out)
00271 { glGetDoublev(tag, vals_out); }
00272
00273 void extractValues(GLenum tag, GLint* vals_out)
00274 { glGetIntegerv(tag, vals_out); }
00275
00276 template <class T>
00277 tcl::list get(GLenum param_tag
00278 #ifdef GVX_BROKEN_TEMPLATE_FUNCTIONS
00279 , T* =0
00280 #endif
00281 )
00282 {
00283 const AttribInfo* theInfo = theAttribMap[param_tag];
00284 if ( theInfo == 0 )
00285 {
00286 throw rutz::error("invalid or unsupported enumerant", SRC_POS);
00287 }
00288
00289 rutz::fixed_block<T> theVals(theInfo->num_values);
00290 extractValues(theInfo->param_tag, &(theVals[0]));
00291 tcl::list result;
00292 result.append_range(theVals.begin(), theVals.end());
00293 return result;
00294 }
00295
00296 #ifdef GVX_BROKEN_TEMPLATE_FUNCTIONS
00297 tcl::list getBoolean(GLenum param_tag)
00298 { return get<GLboolean>(param_tag, (GLboolean*) 0); }
00299
00300 tcl::list getDouble(GLenum param_tag)
00301 { return get<GLdouble>(param_tag, (GLdouble*) 0); }
00302
00303 tcl::list getInt(GLenum param_tag)
00304 { return get<GLint>(param_tag, (GLint*) 0); }
00305 #endif
00306 }
00307
00308
00309
00310
00311
00312
00313
00314 void GLTcl::loadMatrix(nub::soft_ref<GLCanvas> canvas, tcl::list entries)
00315 {
00316 rutz::fixed_block<GLdouble> matrix(entries.begin<GLdouble>(),
00317 entries.end<GLdouble>());
00318
00319 if (matrix.size() != 16)
00320 {
00321 throw rutz::error("matrix must have 16 entries "
00322 "in column-major order", SRC_POS);
00323 }
00324
00325 glLoadMatrixd(&matrix[0]);
00326
00327 canvas->throwIfError("loadMatrix", SRC_POS);
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 void GLTcl::lookAt(tcl::list args)
00337 {
00338 gluLookAt(args.get<GLdouble>(0),
00339 args.get<GLdouble>(1),
00340 args.get<GLdouble>(2),
00341 args.get<GLdouble>(3),
00342 args.get<GLdouble>(4),
00343 args.get<GLdouble>(5),
00344 args.get<GLdouble>(6),
00345 args.get<GLdouble>(7),
00346 args.get<GLdouble>(8));
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 void GLTcl::antialias(bool on_off)
00360 {
00361 GVX_TRACE("GLTcl::antialias");
00362 if (on_off)
00363 {
00364 glEnable(GL_BLEND);
00365 glEnable(GL_POLYGON_SMOOTH);
00366 glEnable(GL_LINE_SMOOTH);
00367 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00368 }
00369 else
00370 {
00371 glDisable(GL_BLEND);
00372 glDisable(GL_LINE_SMOOTH);
00373 glDisable(GL_POLYGON_SMOOTH);
00374 }
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 void GLTcl::drawOneLine(GLdouble x1, GLdouble y1,
00387 GLdouble x2, GLdouble y2)
00388 {
00389 glBegin(GL_LINES);
00390 glVertex3d(x1, y1, 0.0);
00391 glVertex3d(x2, y2, 0.0);
00392 glEnd();
00393 glFlush();
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 void GLTcl::drawThickLine(GLdouble x1, GLdouble y1,
00406 GLdouble x2, GLdouble y2, GLdouble thickness)
00407 {
00408
00409 double a, b, c, d, norm;
00410 a = x2 - x1;
00411 b = y2 - y1;
00412
00413 norm = sqrt(a*a + b*b);
00414 c = -b/norm*thickness/2;
00415 d = a/norm*thickness/2;
00416
00417 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00418 glBegin(GL_POLYGON);
00419 glVertex3d( x1+c, y1+d, 0.0);
00420 glVertex3d( x1-c, y1-d, 0.0);
00421
00422 glVertex3d( x2-c, y2-d, 0.0);
00423 glVertex3d( x2+c, y2+d, 0.0);
00424 glEnd();
00425 glFlush();
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 tcl::list GLTcl::lineInfo()
00438 {
00439 GLdouble range[2] = {-1.0,-1.0};
00440 GLdouble gran=-1.0;
00441 glGetDoublev(GL_LINE_WIDTH_RANGE, &range[0]);
00442 glGetDoublev(GL_LINE_WIDTH_GRANULARITY, &gran);
00443
00444 tcl::list result;
00445 result.append("range");
00446 result.append(range[0]);
00447 result.append(range[1]);
00448 result.append("granularity");
00449 result.append(gran);
00450 return result;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459 extern "C"
00460 int Gl_Init(Tcl_Interp* interp)
00461 {
00462 GVX_TRACE("Gl_Init");
00463
00464 GVX_PKG_CREATE(pkg, interp, "GL", "4.$Revision: 10065 $");
00465 GLTcl::loadGet(pkg);
00466 GLTcl::loadEnums(pkg);
00467
00468 using rutz::bind_first;
00469
00470 pkg->def( "::glBegin", "mode", glBegin, SRC_POS );
00471 pkg->def( "::glBlendFunc", "sfactor dfactor", glBlendFunc, SRC_POS );
00472 pkg->def( "::glCallList", "list", glCallList, SRC_POS );
00473 pkg->def( "::glClear", "mask_bits", glClear, SRC_POS );
00474 pkg->def( "::glClearColor", "red green blue alpha", glClearColor, SRC_POS );
00475 pkg->def( "::glClearIndex", "index", glClearIndex, SRC_POS );
00476 pkg->def( "::glColor", "red green blue", glColor3d, SRC_POS );
00477 pkg->def( "::glColor", "red green blue alpha", glColor4d, SRC_POS );
00478 pkg->def( "::glDeleteLists", "list_id range", glDeleteLists, SRC_POS );
00479 pkg->def( "::glDisable", "capability", glDisable, SRC_POS );
00480 pkg->def( "::glDrawBuffer", "mode", glDrawBuffer, SRC_POS );
00481 pkg->def( "::glEnable", "capability", glEnable, SRC_POS );
00482 pkg->def( "::glEnd", 0, glEnd, SRC_POS );
00483 pkg->def( "::glEndList", 0, glEndList, SRC_POS );
00484 pkg->def( "::glExtensions", 0, bind_first(GLTcl::getString, GL_EXTENSIONS), SRC_POS);
00485 pkg->def( "::glFinish", 0, glFinish, SRC_POS );
00486 pkg->def( "::glFlush", 0, glFlush, SRC_POS );
00487 pkg->def( "::glFrustum", "left right bottom top zNear zFar", glFrustum, SRC_POS );
00488 pkg->def( "::glGenLists", "range", glGenLists, SRC_POS );
00489 pkg->def( "::glIndexi", "index", glIndexi, SRC_POS );
00490 pkg->def( "::glIsList", "list_id", glIsList, SRC_POS );
00491 pkg->def( "::glLineWidth", "width", glLineWidth, SRC_POS );
00492 pkg->def( "::glListBase", "base", glListBase, SRC_POS );
00493 pkg->def( "::glLoadIdentity", 0, glLoadIdentity, SRC_POS );
00494 pkg->def( "::glLoadMatrix", "glcanvas 4x4_column_major_matrix", GLTcl::loadMatrix, SRC_POS );
00495 pkg->def( "::glMatrixMode", "mode", glMatrixMode, SRC_POS );
00496 pkg->def( "::glNewList", "list_id mode", glNewList, SRC_POS );
00497 pkg->def( "::glOrtho", "left right bottom top zNear zFar", glOrtho, SRC_POS );
00498 pkg->def( "::glPolygonMode", "face mode", glPolygonMode, SRC_POS );
00499 pkg->def( "::glPointSize", "size", glPointSize, SRC_POS );
00500 pkg->def( "::glPopMatrix", 0, glPopMatrix, SRC_POS );
00501 pkg->def( "::glPushMatrix", 0, glPushMatrix, SRC_POS );
00502 pkg->def( "::glRasterPos2d", "x y", glRasterPos2d, SRC_POS );
00503 pkg->def( "::glRenderer", 0, bind_first(GLTcl::getString, GL_RENDERER), SRC_POS);
00504 pkg->def( "::glRotate", "angle_in_degrees x y z", glRotated, SRC_POS );
00505 pkg->def( "::glScale", "x y z", glScaled, SRC_POS );
00506 pkg->def( "::glTranslate", "x y z", glTranslated, SRC_POS );
00507 pkg->def( "::glVendor", 0, bind_first(GLTcl::getString, GL_VENDOR), SRC_POS);
00508 pkg->def( "::glVersion", 0, bind_first(GLTcl::getString, GL_VERSION), SRC_POS);
00509 pkg->def( "::glVertex2", "x y", glVertex2d, SRC_POS );
00510 pkg->def( "::glVertex3", "x y z", glVertex3d, SRC_POS );
00511 pkg->def( "::glVertex4", "x y z w", glVertex4d, SRC_POS );
00512 #if defined(GVX_GL_PLATFORM_GLX)
00513 pkg->def( "::glXWaitX", 0, glXWaitX, SRC_POS );
00514 pkg->def( "::glXWaitGL", 0, glXWaitGL, SRC_POS );
00515 #endif
00516 pkg->def( "::gluLookAt", "eyeX eyeY eyeZ targX targY targZ upX upY upZ",
00517 GLTcl::lookAt, SRC_POS );
00518 pkg->def( "::gluPerspective", "field_of_view_y aspect zNear zFar",
00519 gluPerspective, SRC_POS );
00520
00521 #ifndef GVX_BROKEN_TEMPLATE_FUNCTIONS
00522 pkg->def( "::glGetBoolean", "param_name", GLTcl::get<GLboolean>, SRC_POS );
00523 pkg->def( "::glGetDouble", "param_name", GLTcl::get<GLdouble>, SRC_POS );
00524 pkg->def( "::glGetInteger", "param_name", GLTcl::get<GLint>, SRC_POS );
00525 #else
00526 pkg->def( "::glGetBoolean", "param_name", GLTcl::getBoolean, SRC_POS );
00527 pkg->def( "::glGetDouble", "param_name", GLTcl::getDouble, SRC_POS );
00528 pkg->def( "::glGetInteger", "param_name", GLTcl::getInt, SRC_POS );
00529 #endif
00530
00531 pkg->def( "::antialias", "on_off", GLTcl::antialias, SRC_POS );
00532 pkg->def( "::drawOneLine", "x1 y1 x2 y2", GLTcl::drawOneLine, SRC_POS );
00533 pkg->def( "::drawThickLine", "x1 y1 x2 y2 thickness", GLTcl::drawThickLine, SRC_POS );
00534 pkg->def( "::lineInfo", 0, GLTcl::lineInfo, SRC_POS );
00535
00536 GVX_PKG_RETURN(pkg);
00537 }
00538
00539 static const char __attribute__((used)) vcid_groovx_visx_tclpkg_gl_cc_utc20050628171008[] = "$Id: tclpkg-gl.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00540 #endif // !GROOVX_VISX_TCLPKG_GL_CC_UTC20050628171008_DEFINED