#include "tkogl.h" #include "tkoglparse.h" #include "feedback.h" typedef int PrintVtx (Tcl_DString *, GLfloat* ); static int ProcessBuffer (Tcl_Interp *interp, int size, GLfloat* buffer, PrintVtx * proc) { Tcl_DString list; int i, j, n; char buf [80]; Tcl_DStringInit (&list); for (i = 0; i < size; i++) { int nvtx = 0; if (*buffer == GL_POINT_TOKEN) { Tcl_DStringAppendElement (&list, "-point"); nvtx = 1; } else if (*buffer == GL_BITMAP_TOKEN) { Tcl_DStringAppendElement (&list, "-bitmap"); nvtx = 1; } else if (*buffer == GL_DRAW_PIXEL_TOKEN) { Tcl_DStringAppendElement (&list, "-drawpixel"); nvtx = 1; } else if (*buffer == GL_COPY_PIXEL_TOKEN) { Tcl_DStringAppendElement (&list, "-copypixel"); nvtx = 1; } else if (*buffer == GL_LINE_TOKEN) { Tcl_DStringAppendElement (&list, "-line"); nvtx = 2; } else if (*buffer == GL_LINE_RESET_TOKEN) { Tcl_DStringAppendElement (&list, "-linereset"); nvtx = 2; } else if (*buffer == GL_POLYGON_TOKEN) { Tcl_DStringAppendElement (&list, "-polygon"); buffer++; i++; nvtx = (int) *buffer; } else if (*buffer == GL_PASS_THROUGH_TOKEN) { Tcl_DStringAppendElement (&list, "-passthrough"); buffer++; i++; sprintf (buf, "%d", (int) *buffer); Tcl_DStringAppendElement (&list, buf); } if (nvtx > 0) { ++buffer; for (j = 0; j < nvtx; j++) { n = (*proc) (&list, buffer); buffer += n; i += n; } } } Tcl_DStringResult (interp, &list); Tcl_DStringFree (&list); return TCL_OK; } static int PrintVtx2D (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 2; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 2; } static int PrintVtx3D (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 3; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 3; } static int PrintVtx3DColor (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 3; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-color"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 7; } static int PrintVtx3DColorTexture (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 3; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-color"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-texture"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 11; } static int PrintVtx4DColorTexture (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-color"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-texture"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 12; } int Feedback (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; int narg; int len; int size; PrintVtx * proc; GLenum type; GLfloat *buffer; if (argc < 4) { Tcl_AppendResult (interp, "Not enough args", (char*) NULL); return TCL_ERROR; } /* Parse 'size' */ if (Tcl_GetInt (interp, argv [2], &size) != TCL_OK || size <= 0) { Tcl_AppendResult (interp, "invalid hit buffer size", argv [2], NULL); return TCL_ERROR; } /* Parse 'type' */ len = strlen (argv [3]); if (strncasecmp (argv [3], "2d", len) == 0) { type = GL_2D; proc = PrintVtx2D; } else if (strncasecmp (argv [3], "3d", len) == 0) { type = GL_3D; proc = PrintVtx3D; } else if (strncasecmp (argv [3], "3dColor", len) == 0) { type = GL_3D_COLOR; proc = PrintVtx3DColor; } else if (strncasecmp (argv [3], "3dColorTexture", len) == 0) { type = GL_3D_COLOR_TEXTURE; proc = PrintVtx3DColorTexture; } else if (strncasecmp (argv [3], "4dColorTexture", len) == 0) { type = GL_4D_COLOR_TEXTURE; proc = PrintVtx4DColorTexture; } else { Tcl_AppendResult (interp, "Unknown type:", argv [3]); return TCL_ERROR; } /* Allocate feedback 'buffer' */ buffer = (GLfloat*) malloc (sizeof (GLfloat)*size); assert (buffer != NULL); /* Render in feedback mode */ glFeedbackBuffer (size, type, buffer); (void) glRenderMode (GL_FEEDBACK); argc -= 4; argv += 4; while (result == TCL_OK && argc > 0) { result = ParseGLFunc (interp, argc, argv, &narg); argc -= narg; argv += narg; } glFlush (); /* Generate feedback string */ size = glRenderMode (GL_RENDER); if (result == TCL_OK) { result = ProcessBuffer (interp, size, buffer, proc); } free (buffer); return result; }