clip.c revision 7117f1b4
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg * Version:  6.3
47117f1b4Smrg *
57117f1b4Smrg * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
67117f1b4Smrg *
77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
87117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
97117f1b4Smrg * to deal in the Software without restriction, including without limitation
107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
127117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
137117f1b4Smrg *
147117f1b4Smrg * The above copyright notice and this permission notice shall be included
157117f1b4Smrg * in all copies or substantial portions of the Software.
167117f1b4Smrg *
177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
207117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
217117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
227117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg
267117f1b4Smrg#include "glheader.h"
277117f1b4Smrg#include "clip.h"
287117f1b4Smrg#include "context.h"
297117f1b4Smrg#include "macros.h"
307117f1b4Smrg#include "mtypes.h"
317117f1b4Smrg
327117f1b4Smrg#include "math/m_xform.h"
337117f1b4Smrg#include "math/m_matrix.h"
347117f1b4Smrg
357117f1b4Smrg
367117f1b4Smrg
377117f1b4Smrg/**********************************************************************/
387117f1b4Smrg/*                     Get/Set User clip-planes.                      */
397117f1b4Smrg/**********************************************************************/
407117f1b4Smrg
417117f1b4Smrg
427117f1b4Smrg
437117f1b4Smrgvoid GLAPIENTRY
447117f1b4Smrg_mesa_ClipPlane( GLenum plane, const GLdouble *eq )
457117f1b4Smrg{
467117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
477117f1b4Smrg   GLint p;
487117f1b4Smrg   GLfloat equation[4];
497117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
507117f1b4Smrg
517117f1b4Smrg   p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
527117f1b4Smrg   if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) {
537117f1b4Smrg      _mesa_error( ctx, GL_INVALID_ENUM, "glClipPlane" );
547117f1b4Smrg      return;
557117f1b4Smrg   }
567117f1b4Smrg
577117f1b4Smrg   equation[0] = (GLfloat) eq[0];
587117f1b4Smrg   equation[1] = (GLfloat) eq[1];
597117f1b4Smrg   equation[2] = (GLfloat) eq[2];
607117f1b4Smrg   equation[3] = (GLfloat) eq[3];
617117f1b4Smrg
627117f1b4Smrg   /*
637117f1b4Smrg    * The equation is transformed by the transpose of the inverse of the
647117f1b4Smrg    * current modelview matrix and stored in the resulting eye coordinates.
657117f1b4Smrg    *
667117f1b4Smrg    * KW: Eqn is then transformed to the current clip space, where user
677117f1b4Smrg    * clipping now takes place.  The clip-space equations are recalculated
687117f1b4Smrg    * whenever the projection matrix changes.
697117f1b4Smrg    */
707117f1b4Smrg   if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top))
717117f1b4Smrg      _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
727117f1b4Smrg
737117f1b4Smrg   _mesa_transform_vector( equation, equation,
747117f1b4Smrg                           ctx->ModelviewMatrixStack.Top->inv );
757117f1b4Smrg
767117f1b4Smrg   if (TEST_EQ_4V(ctx->Transform.EyeUserPlane[p], equation))
777117f1b4Smrg      return;
787117f1b4Smrg
797117f1b4Smrg   FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
807117f1b4Smrg   COPY_4FV(ctx->Transform.EyeUserPlane[p], equation);
817117f1b4Smrg
827117f1b4Smrg   /* Update derived state.  This state also depends on the projection
837117f1b4Smrg    * matrix, and is recalculated on changes to the projection matrix by
847117f1b4Smrg    * code in _mesa_update_state().
857117f1b4Smrg    */
867117f1b4Smrg   if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
877117f1b4Smrg      if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
887117f1b4Smrg         _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );
897117f1b4Smrg
907117f1b4Smrg      _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
917117f1b4Smrg			   ctx->Transform.EyeUserPlane[p],
927117f1b4Smrg			   ctx->ProjectionMatrixStack.Top->inv );
937117f1b4Smrg   }
947117f1b4Smrg
957117f1b4Smrg   if (ctx->Driver.ClipPlane)
967117f1b4Smrg      ctx->Driver.ClipPlane( ctx, plane, equation );
977117f1b4Smrg}
987117f1b4Smrg
997117f1b4Smrg
1007117f1b4Smrgvoid GLAPIENTRY
1017117f1b4Smrg_mesa_GetClipPlane( GLenum plane, GLdouble *equation )
1027117f1b4Smrg{
1037117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1047117f1b4Smrg   GLint p;
1057117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1067117f1b4Smrg
1077117f1b4Smrg   p = (GLint) (plane - GL_CLIP_PLANE0);
1087117f1b4Smrg   if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) {
1097117f1b4Smrg      _mesa_error( ctx, GL_INVALID_ENUM, "glGetClipPlane" );
1107117f1b4Smrg      return;
1117117f1b4Smrg   }
1127117f1b4Smrg
1137117f1b4Smrg   equation[0] = (GLdouble) ctx->Transform.EyeUserPlane[p][0];
1147117f1b4Smrg   equation[1] = (GLdouble) ctx->Transform.EyeUserPlane[p][1];
1157117f1b4Smrg   equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2];
1167117f1b4Smrg   equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3];
1177117f1b4Smrg}
1187117f1b4Smrg
1197117f1b4Smrgvoid GLAPIENTRY
1207117f1b4Smrg_mesa_CullParameterfvEXT (GLenum cap, GLfloat *v)
1217117f1b4Smrg{
1227117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
1237117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1247117f1b4Smrg
1257117f1b4Smrg   switch (cap) {
1267117f1b4Smrg   case GL_CULL_VERTEX_EYE_POSITION_EXT:
1277117f1b4Smrg      FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1287117f1b4Smrg      COPY_4FV(ctx->Transform.CullEyePos, v);
1297117f1b4Smrg
1307117f1b4Smrg      _mesa_transform_vector( ctx->Transform.CullObjPos,
1317117f1b4Smrg			      ctx->Transform.CullEyePos,
1327117f1b4Smrg			      ctx->ModelviewMatrixStack.Top->inv );
1337117f1b4Smrg      break;
1347117f1b4Smrg
1357117f1b4Smrg   case GL_CULL_VERTEX_OBJECT_POSITION_EXT:
1367117f1b4Smrg      FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1377117f1b4Smrg      COPY_4FV(ctx->Transform.CullObjPos, v);
1387117f1b4Smrg
1397117f1b4Smrg      _mesa_transform_vector( ctx->Transform.CullEyePos,
1407117f1b4Smrg			      ctx->Transform.CullObjPos,
1417117f1b4Smrg			      ctx->ModelviewMatrixStack.Top->m );
1427117f1b4Smrg     break;
1437117f1b4Smrg   default:
1447117f1b4Smrg      _mesa_error( ctx, GL_INVALID_ENUM, "glCullParameterfvEXT" );
1457117f1b4Smrg   }
1467117f1b4Smrg}
1477117f1b4Smrg
1487117f1b4Smrgvoid GLAPIENTRY
1497117f1b4Smrg_mesa_CullParameterdvEXT (GLenum cap, GLdouble *v)
1507117f1b4Smrg{
1517117f1b4Smrg   GLfloat f[4];
1527117f1b4Smrg
1537117f1b4Smrg   f[0] = (GLfloat)v[0];
1547117f1b4Smrg   f[1] = (GLfloat)v[1];
1557117f1b4Smrg   f[2] = (GLfloat)v[2];
1567117f1b4Smrg   f[3] = (GLfloat)v[3];
1577117f1b4Smrg
1587117f1b4Smrg   _mesa_CullParameterfvEXT(cap, f);
1597117f1b4Smrg}
1607117f1b4Smrg
161