use BCOPY macro on FreeBSD
[mesa.git] / src / mesa / main / feedback.c
index 4251aae01a308a14ee15c164ddd1ec4f1370ba80..3a38db1d62ca727f205eb7eedf9cccfa7be258fa 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: feedback.c,v 1.1 1999/08/19 00:55:41 jtg Exp $ */
+/* $Id: feedback.c,v 1.9 2000/03/03 17:47:39 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.1
+ * Version:  3.3
  * 
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  */
 
 
-
-
-
 #ifdef PC_HEADER
 #include "all.h"
 #else
-#include <assert.h>
-#include <stdio.h>
+#include "glheader.h"
 #include "context.h"
 #include "enums.h"
 #include "feedback.h"
 #include "macros.h"
+#include "mmath.h"
 #include "types.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
+#include "triangle.h"
 #endif
 
 
@@ -54,8 +49,9 @@
 
 
 void
-gl_FeedbackBuffer( GLcontext *ctx, GLsizei size, GLenum type, GLfloat *buffer )
+_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx, "glFeedbackBuffer" );
 
    if (ctx->RenderMode==GL_FEEDBACK) {
@@ -111,8 +107,10 @@ gl_FeedbackBuffer( GLcontext *ctx, GLsizei size, GLenum type, GLfloat *buffer )
 
 
 
-void gl_PassThrough( GLcontext *ctx, GLfloat token )
+void
+_mesa_PassThrough( GLfloat token )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPassThrough");
 
    if (ctx->RenderMode==GL_FEEDBACK) {
@@ -127,20 +125,22 @@ void gl_PassThrough( GLcontext *ctx, GLfloat token )
  * Put a vertex into the feedback buffer.
  */
 void gl_feedback_vertex( GLcontext *ctx,
-                         GLfloat x, GLfloat y, GLfloat z, GLfloat w,
-                        const GLfloat color[4], GLfloat index,
+                         const GLfloat win[4],
+                        const GLfloat color[4], 
+                        GLuint index,
                         const GLfloat texcoord[4] )
 {
-   FEEDBACK_TOKEN( ctx, x );
-   FEEDBACK_TOKEN( ctx, y );
+   FEEDBACK_TOKEN( ctx, win[0] );
+   FEEDBACK_TOKEN( ctx, win[1] );
    if (ctx->Feedback.Mask & FB_3D) {
-      FEEDBACK_TOKEN( ctx, z );
+      printf("FB %g\n", win[2]);
+      FEEDBACK_TOKEN( ctx, win[2] );
    }
    if (ctx->Feedback.Mask & FB_4D) {
-      FEEDBACK_TOKEN( ctx, w );
+      FEEDBACK_TOKEN( ctx, win[3] );
    }
    if (ctx->Feedback.Mask & FB_INDEX) {
-      FEEDBACK_TOKEN( ctx, index );
+      FEEDBACK_TOKEN( ctx, (GLfloat) index );
    }
    if (ctx->Feedback.Mask & FB_COLOR) {
       FEEDBACK_TOKEN( ctx, color[0] );
@@ -158,6 +158,100 @@ void gl_feedback_vertex( GLcontext *ctx,
 
 
 
+static void feedback_vertex( GLcontext *ctx, GLuint v, GLuint pv )
+{
+   GLfloat win[4];
+   GLfloat color[4];
+   GLfloat tc[4];
+   GLuint texUnit = ctx->Texture.CurrentTransformUnit;
+   const struct vertex_buffer *VB = ctx->VB;
+   GLuint index;
+
+   win[0] = VB->Win.data[v][0];
+   win[1] = VB->Win.data[v][1];
+   win[2] = VB->Win.data[v][2] / ctx->Visual->DepthMaxF;
+   win[3] = 1.0 / VB->Win.data[v][3];
+
+   if (ctx->Light.ShadeModel == GL_SMOOTH)
+      pv = v;
+
+   UBYTE_RGBA_TO_FLOAT_RGBA( color, VB->ColorPtr->data[pv] );
+
+   if (VB->TexCoordPtr[texUnit]->size == 4 &&     
+       VB->TexCoordPtr[texUnit]->data[v][3] != 0.0) {
+      GLfloat invq = 1.0F / VB->TexCoordPtr[texUnit]->data[v][3];
+      tc[0] = VB->TexCoordPtr[texUnit]->data[v][0] * invq;
+      tc[1] = VB->TexCoordPtr[texUnit]->data[v][1] * invq;
+      tc[2] = VB->TexCoordPtr[texUnit]->data[v][2] * invq;
+      tc[3] = VB->TexCoordPtr[texUnit]->data[v][3];
+   }
+   else {
+      ASSIGN_4V(tc, 0,0,0,1);
+      COPY_SZ_4V(tc, 
+                VB->TexCoordPtr[texUnit]->size,
+                VB->TexCoordPtr[texUnit]->data[v]);
+   }
+
+   if (VB->IndexPtr)
+      index = VB->IndexPtr->data[v];
+   else
+      index = 0;
+
+   gl_feedback_vertex( ctx, win, color, index, tc );
+}
+
+
+
+/*
+ * Put triangle in feedback buffer.
+ */
+void gl_feedback_triangle( GLcontext *ctx,
+                          GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+{
+   if (gl_cull_triangle( ctx, v0, v1, v2, 0 )) {
+      FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN );
+      FEEDBACK_TOKEN( ctx, (GLfloat) 3 );        /* three vertices */
+      
+      feedback_vertex( ctx, v0, pv );
+      feedback_vertex( ctx, v1, pv );
+      feedback_vertex( ctx, v2, pv );
+   }
+}
+
+
+void gl_feedback_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv )
+{
+   GLenum token = GL_LINE_TOKEN;
+
+   if (ctx->StippleCounter==0) 
+      token = GL_LINE_RESET_TOKEN;
+
+   FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) token );
+
+   feedback_vertex( ctx, v1, pv );
+   feedback_vertex( ctx, v2, pv );
+
+   ctx->StippleCounter++;
+}
+
+
+void gl_feedback_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   const struct vertex_buffer *VB = ctx->VB;
+   GLuint i;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
+        feedback_vertex( ctx, i, i );
+      }
+   }
+}
+
+
+
+
+
 /**********************************************************************/
 /*                              Selection                             */
 /**********************************************************************/
@@ -166,8 +260,10 @@ void gl_feedback_vertex( GLcontext *ctx,
 /*
  * NOTE: this function can't be put in a display list.
  */
-void gl_SelectBuffer( GLcontext *ctx, GLsizei size, GLuint *buffer )
+void
+_mesa_SelectBuffer( GLsizei size, GLuint *buffer )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glSelectBuffer");
    if (ctx->RenderMode==GL_SELECT) {
       gl_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" );
@@ -201,6 +297,42 @@ void gl_update_hitflag( GLcontext *ctx, GLfloat z )
    }
 }
 
+void gl_select_triangle( GLcontext *ctx,
+                        GLuint v0, GLuint v1, GLuint v2, GLuint pv )
+{
+   const struct vertex_buffer *VB = ctx->VB;
+
+   if (gl_cull_triangle( ctx, v0, v1, v2, 0 )) {
+      const GLfloat zs = 1.0F / ctx->Visual->DepthMaxF;
+      gl_update_hitflag( ctx, VB->Win.data[v0][2] * zs );
+      gl_update_hitflag( ctx, VB->Win.data[v1][2] * zs );
+      gl_update_hitflag( ctx, VB->Win.data[v2][2] * zs );
+   }
+}
+
+
+void gl_select_line( GLcontext *ctx,
+                    GLuint v0, GLuint v1, GLuint pv )
+{
+   const struct vertex_buffer *VB = ctx->VB;
+   const GLfloat zs = 1.0F / ctx->Visual->DepthMaxF;
+   gl_update_hitflag( ctx, VB->Win.data[v0][2] * zs );
+   gl_update_hitflag( ctx, VB->Win.data[v1][2] * zs );
+}
+
+
+void gl_select_points( GLcontext *ctx, GLuint first, GLuint last )
+{
+   struct vertex_buffer *VB = ctx->VB;
+   const GLfloat zs = 1.0F / ctx->Visual->DepthMaxF;
+   GLuint i;
+
+   for (i=first;i<=last;i++) {
+      if (VB->ClipMask[i]==0) {
+         gl_update_hitflag( ctx, VB->Win.data[i][2] * zs );
+      }
+   }
+}
 
 
 static void write_hit_record( GLcontext *ctx )
@@ -218,7 +350,7 @@ static void write_hit_record( GLcontext *ctx )
    WRITE_RECORD( ctx, ctx->Select.NameStackDepth );
    WRITE_RECORD( ctx, zmin );
    WRITE_RECORD( ctx, zmax );
-   for (i=0;i<ctx->Select.NameStackDepth;i++) {
+   for (i = 0; i < ctx->Select.NameStackDepth; i++) {
       WRITE_RECORD( ctx, ctx->Select.NameStack[i] );
    }
 
@@ -230,11 +362,13 @@ static void write_hit_record( GLcontext *ctx )
 
 
 
-void gl_InitNames( GLcontext *ctx )
+void
+_mesa_InitNames( void )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glInitNames");
    /* Record the hit before the HitFlag is wiped out again. */
-   if (ctx->RenderMode==GL_SELECT) {
+   if (ctx->RenderMode == GL_SELECT) {
       if (ctx->Select.HitFlag) {
          write_hit_record( ctx );
       }
@@ -247,20 +381,22 @@ void gl_InitNames( GLcontext *ctx )
 
 
 
-void gl_LoadName( GLcontext *ctx, GLuint name )
+void
+_mesa_LoadName( GLuint name )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLoadName");
-   if (ctx->RenderMode!=GL_SELECT) {
+   if (ctx->RenderMode != GL_SELECT) {
       return;
    }
-   if (ctx->Select.NameStackDepth==0) {
+   if (ctx->Select.NameStackDepth == 0) {
       gl_error( ctx, GL_INVALID_OPERATION, "glLoadName" );
       return;
    }
    if (ctx->Select.HitFlag) {
       write_hit_record( ctx );
    }
-   if (ctx->Select.NameStackDepth<MAX_NAME_STACK_DEPTH) {
+   if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) {
       ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name;
    }
    else {
@@ -269,16 +405,18 @@ void gl_LoadName( GLcontext *ctx, GLuint name )
 }
 
 
-void gl_PushName( GLcontext *ctx, GLuint name )
+void
+_mesa_PushName( GLuint name )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushName");
-   if (ctx->RenderMode!=GL_SELECT) {
+   if (ctx->RenderMode != GL_SELECT) {
       return;
    }
    if (ctx->Select.HitFlag) {
       write_hit_record( ctx );
    }
-   if (ctx->Select.NameStackDepth<MAX_NAME_STACK_DEPTH) {
+   if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) {
       ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name;
    }
    else {
@@ -288,16 +426,18 @@ void gl_PushName( GLcontext *ctx, GLuint name )
 
 
 
-void gl_PopName( GLcontext *ctx )
+void
+_mesa_PopName( void )
 {
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopName");
-   if (ctx->RenderMode!=GL_SELECT) {
+   if (ctx->RenderMode != GL_SELECT) {
       return;
    }
    if (ctx->Select.HitFlag) {
       write_hit_record( ctx );
    }
-   if (ctx->Select.NameStackDepth>0) {
+   if (ctx->Select.NameStackDepth > 0) {
       ctx->Select.NameStackDepth--;
    }
    else {
@@ -316,8 +456,10 @@ void gl_PopName( GLcontext *ctx )
 /*
  * NOTE: this function can't be put in a display list.
  */
-GLint gl_RenderMode( GLcontext *ctx, GLenum mode )
+GLint
+_mesa_RenderMode( GLenum mode )
 {
+   GET_CURRENT_CONTEXT(ctx);
    GLint result;
 
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glRenderMode", 0);
@@ -386,7 +528,6 @@ GLint gl_RenderMode( GLcontext *ctx, GLenum mode )
         return 0;
    }
 
-
    ctx->RenderMode = mode;
    ctx->NewState |= NEW_ALL;