📄 t_vb_program.c
字号:
/* * Mesa 3-D graphics library * Version: 7.1 * * Copyright (C) 1999-2007 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"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file tnl/t_vb_program.c * \brief Pipeline stage for executing vertex programs. * \author Brian Paul, Keith Whitwell */#include "main/glheader.h"#include "main/colormac.h"#include "main/context.h"#include "main/macros.h"#include "main/imports.h"#include "shader/prog_instruction.h"#include "shader/prog_statevars.h"#include "shader/prog_execute.h"#include "swrast/s_context.h"#include "swrast/s_texfilter.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"/*! * Private storage for the vertex program pipeline stage. */struct vp_stage_data { /** The results of running the vertex program go into these arrays. */ GLvector4f results[VERT_RESULT_MAX]; GLvector4f ndcCoords; /**< normalized device coords */ GLubyte *clipmask; /**< clip flags */ GLubyte ormask, andmask; /**< for clipping */};#define VP_STAGE_DATA(stage) ((struct vp_stage_data *)(stage->privatePtr))static voiduserclip( GLcontext *ctx, GLvector4f *clip, GLubyte *clipmask, GLubyte *clipormask, GLubyte *clipandmask ){ GLuint p; for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { GLuint nr, i; const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; GLfloat *coord = (GLfloat *)clip->data; GLuint stride = clip->stride; GLuint count = clip->count; for (nr = 0, i = 0 ; i < count ; i++) { GLfloat dp = (coord[0] * a + coord[1] * b + coord[2] * c + coord[3] * d); if (dp < 0) { nr++; clipmask[i] |= CLIP_USER_BIT; } STRIDE_F(coord, stride); } if (nr > 0) { *clipormask |= CLIP_USER_BIT; if (nr == count) { *clipandmask |= CLIP_USER_BIT; return; } } } }}static GLbooleando_ndc_cliptest(GLcontext *ctx, struct vp_stage_data *store){ TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; /* Cliptest and perspective divide. Clip functions must clear * the clipmask. */ store->ormask = 0; store->andmask = CLIP_FRUSTUM_BITS; if (tnl->NeedNdcCoords) { VB->NdcPtr = _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, &store->ndcCoords, store->clipmask, &store->ormask, &store->andmask ); } else { VB->NdcPtr = NULL; _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr, NULL, store->clipmask, &store->ormask, &store->andmask ); } if (store->andmask) { /* All vertices are outside the frustum */ return GL_FALSE; } /* Test userclip planes. This contributes to VB->ClipMask. */ /** XXX NEW_SLANG _Enabled ??? */ if (ctx->Transform.ClipPlanesEnabled && (!ctx->VertexProgram._Enabled || ctx->VertexProgram.Current->IsPositionInvariant)) { userclip( ctx, VB->ClipPtr, store->clipmask, &store->ormask, &store->andmask ); if (store->andmask) { return GL_FALSE; } } VB->ClipAndMask = store->andmask; VB->ClipOrMask = store->ormask; VB->ClipMask = store->clipmask; return GL_TRUE;}/** * XXX the texture sampling code in this module is a bit of a hack. * The texture sampling code is in swrast, though it doesn't have any * real dependencies on the rest of swrast. It should probably be * moved into main/ someday. */static voidvp_fetch_texel(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, GLuint unit, GLfloat color[4]){ GLchan rgba[4]; SWcontext *swrast = SWRAST_CONTEXT(ctx); /* XXX use a float-valued TextureSample routine here!!! */ swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 1, (const GLfloat (*)[4]) texcoord, &lambda, &rgba); color[0] = CHAN_TO_FLOAT(rgba[0]); color[1] = CHAN_TO_FLOAT(rgba[1]); color[2] = CHAN_TO_FLOAT(rgba[2]); color[3] = CHAN_TO_FLOAT(rgba[3]);}/** * Called via ctx->Driver.ProgramStringNotify() after a new vertex program * string has been parsed. */void_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program){ /* No-op. * If we had derived anything from the program that was private to this * stage we'd recompute/validate it here. */}/** * Initialize virtual machine state prior to executing vertex program. */static voidinit_machine(GLcontext *ctx, struct gl_program_machine *machine){ /* Input registers get initialized from the current vertex attribs */ MEMCPY(machine->VertAttribs, ctx->Current.Attrib, MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat)); if (ctx->VertexProgram._Current->IsNVProgram) { GLuint i; /* Output/result regs are initialized to [0,0,0,1] */ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); } /* Temp regs are initialized to [0,0,0,0] */ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); } for (i = 0; i < MAX_VERTEX_PROGRAM_ADDRESS_REGS; i++) { ASSIGN_4V(machine->AddressReg[i], 0, 0, 0, 0); } } machine->NumDeriv = 0; /* init condition codes */ machine->CondCodes[0] = COND_EQ; machine->CondCodes[1] = COND_EQ; machine->CondCodes[2] = COND_EQ; machine->CondCodes[3] = COND_EQ; /* init call stack */ machine->StackDepth = 0; machine->FetchTexelLod = vp_fetch_texel; machine->FetchTexelDeriv = NULL; /* not used by vertex programs */ machine->Samplers = ctx->VertexProgram._Current->Base.SamplerUnits;}/** * Map the texture images which the vertex program will access (if any). */static voidmap_textures(GLcontext *ctx, const struct gl_vertex_program *vp){ GLuint u; if (!ctx->Driver.MapTexture) return; for (u = 0; u < ctx->Const.MaxVertexTextureImageUnits; u++) { if (vp->Base.TexturesUsed[u]) { /* Note: _Current *should* correspond to the target indicated * in TexturesUsed[u]. */ ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[u]._Current); } }}/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -