1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 6.5 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors: 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Keith Whitwell <keith@tungstengraphics.com> 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/mtypes.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "math/m_xform.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "t_context.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "t_pipeline.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct normal_stage_data { 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org normal_func NormalTransform; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvector4f normal; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define NORMAL_STAGE_DATA(stage) ((struct normal_stage_data *)stage->privatePtr) 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgrun_normal_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat *lengths; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!store->NormalTransform) 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We can only use the display list's saved normal lengths if we've 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * got a transformation matrix with uniform scaling. 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_math_matrix_is_general_scale(ctx->ModelviewMatrixStack.Top)) 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lengths = NULL; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lengths = VB->NormalLengthPtr; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform( ctx->ModelviewMatrixStack.Top, 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->_ModelViewInvScale, 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VB->AttribPtr[_TNL_ATTRIB_NORMAL], /* input normals */ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lengths, 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &store->normal ); /* resulting normals */ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count > 1) { 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->normal.stride = 4 * sizeof(GLfloat); 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->normal.stride = 0; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &store->normal; 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VB->NormalLengthPtr = NULL; /* no longer valid */ 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Examine current GL state and set the store->NormalTransform pointer 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to point to the appropriate normal transformation routine. 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvalidate_normal_stage(struct gl_context *ctx, struct tnl_pipeline_stage *stage) 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->VertexProgram._Current || 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (!ctx->Light.Enabled && 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org !(ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))) { 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = NULL; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->_NeedEyeCoords) { 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Eye coordinates are needed, for whatever reasons. 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do lighting in eye coordinates, as the GL spec says. 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint transform = NORM_TRANSFORM_NO_ROT; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_math_matrix_has_rotation(ctx->ModelviewMatrixStack.Top)) { 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* need to do full (3x3) matrix transform */ 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transform = NORM_TRANSFORM; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Transform.Normalize) { 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = _mesa_normal_tab[transform | NORM_NORMALIZE]; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (ctx->Transform.RescaleNormals && 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->_ModelViewInvScale != 1.0) { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE]; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = _mesa_normal_tab[transform]; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We don't need eye coordinates. 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do lighting in object coordinates. Thus, we don't need to fully 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * transform normal vectors (just leave them in object coordinates) 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * but we still need to do normalization/rescaling if enabled. 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->Transform.Normalize) { 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = _mesa_normal_tab[NORM_NORMALIZE]; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (!ctx->Transform.RescaleNormals && 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->_ModelViewInvScale != 1.0) { 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = _mesa_normal_tab[NORM_RESCALE]; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store->NormalTransform = NULL; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate stage's private data (storage for transformed normals). 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgalloc_normal_data(struct gl_context *ctx, struct tnl_pipeline_stage *stage) 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TNLcontext *tnl = TNL_CONTEXT(ctx); 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct normal_stage_data *store; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->privatePtr = malloc(sizeof(*store)); 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org store = NORMAL_STAGE_DATA(stage); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!store) 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 ); 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free stage's private data. 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfree_normal_data(struct tnl_pipeline_stage *stage) 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (store) { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_vector4f_free( &store->normal ); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free( store ); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stage->privatePtr = NULL; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst struct tnl_pipeline_stage _tnl_normal_transform_stage = 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "normal transform", /* name */ 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NULL, /* privatePtr */ 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alloc_normal_data, /* create */ 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free_normal_data, /* destroy */ 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org validate_normal_stage, /* validate */ 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org run_normal_stage /* run */ 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 188