Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygent_vb_render.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 6.5 00004 * 00005 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 * 00024 * Authors: 00025 * Keith Whitwell <keith@tungstengraphics.com> 00026 */ 00027 00028 00029 /* 00030 * Render whole vertex buffers, including projection of vertices from 00031 * clip space and clipping of primitives. 00032 * 00033 * This file makes calls to project vertices and to the point, line 00034 * and triangle rasterizers via the function pointers: 00035 * 00036 * context->Driver.Render.* 00037 * 00038 */ 00039 00040 00041 #include "main/glheader.h" 00042 #include "main/context.h" 00043 #include "main/enums.h" 00044 #include "main/macros.h" 00045 #include "main/imports.h" 00046 #include "main/mtypes.h" 00047 00048 #include "t_pipeline.h" 00049 00050 00051 00052 /**********************************************************************/ 00053 /* Clip single primitives */ 00054 /**********************************************************************/ 00055 00056 00057 #define W(i) coord[i][3] 00058 #define Z(i) coord[i][2] 00059 #define Y(i) coord[i][1] 00060 #define X(i) coord[i][0] 00061 #define SIZE 4 00062 #define TAG(x) x##_4 00063 #include "t_vb_cliptmp.h" 00064 00065 00066 00067 /**********************************************************************/ 00068 /* Clip and render whole begin/end objects */ 00069 /**********************************************************************/ 00070 00071 #define NEED_EDGEFLAG_SETUP (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) 00072 #define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] 00073 #define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val 00074 00075 00076 /* This does NOT include the CLIP_USER_BIT! */ 00077 #define CLIPMASK (CLIP_FRUSTUM_BITS | CLIP_CULL_BIT) 00078 00079 00080 /* Vertices, with the possibility of clipping. 00081 */ 00082 #define RENDER_POINTS( start, count ) \ 00083 tnl->Driver.Render.Points( ctx, start, count ) 00084 00085 #define RENDER_LINE( v1, v2 ) \ 00086 do { \ 00087 GLubyte c1 = mask[v1], c2 = mask[v2]; \ 00088 GLubyte ormask = c1|c2; \ 00089 if (!ormask) \ 00090 LineFunc( ctx, v1, v2 ); \ 00091 else if (!(c1 & c2 & CLIPMASK)) \ 00092 clip_line_4( ctx, v1, v2, ormask ); \ 00093 } while (0) 00094 00095 #define RENDER_TRI( v1, v2, v3 ) \ 00096 do { \ 00097 GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \ 00098 GLubyte ormask = c1|c2|c3; \ 00099 if (!ormask) \ 00100 TriangleFunc( ctx, v1, v2, v3 ); \ 00101 else if (!(c1 & c2 & c3 & CLIPMASK)) \ 00102 clip_tri_4( ctx, v1, v2, v3, ormask ); \ 00103 } while (0) 00104 00105 #define RENDER_QUAD( v1, v2, v3, v4 ) \ 00106 do { \ 00107 GLubyte c1 = mask[v1], c2 = mask[v2]; \ 00108 GLubyte c3 = mask[v3], c4 = mask[v4]; \ 00109 GLubyte ormask = c1|c2|c3|c4; \ 00110 if (!ormask) \ 00111 QuadFunc( ctx, v1, v2, v3, v4 ); \ 00112 else if (!(c1 & c2 & c3 & c4 & CLIPMASK)) \ 00113 clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ 00114 } while (0) 00115 00116 00117 #define LOCAL_VARS \ 00118 TNLcontext *tnl = TNL_CONTEXT(ctx); \ 00119 struct vertex_buffer *VB = &tnl->vb; \ 00120 const GLuint * const elt = VB->Elts; \ 00121 const GLubyte *mask = VB->ClipMask; \ 00122 const GLuint sz = VB->ClipPtr->size; \ 00123 const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ 00124 const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ 00125 const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ 00126 const GLboolean stipple = ctx->Line.StippleFlag; \ 00127 (void) (LineFunc && TriangleFunc && QuadFunc); \ 00128 (void) elt; (void) mask; (void) sz; (void) stipple; 00129 00130 #define TAG(x) clip_##x##_verts 00131 #define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) 00132 #define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) 00133 #define PRESERVE_VB_DEFS 00134 #include "t_vb_rendertmp.h" 00135 00136 00137 00138 /* Elts, with the possibility of clipping. 00139 */ 00140 #undef ELT 00141 #undef TAG 00142 #define ELT(x) elt[x] 00143 #define TAG(x) clip_##x##_elts 00144 #include "t_vb_rendertmp.h" 00145 00146 /* TODO: do this for all primitives, verts and elts: 00147 */ 00148 static void clip_elt_triangles( GLcontext *ctx, 00149 GLuint start, 00150 GLuint count, 00151 GLuint flags ) 00152 { 00153 TNLcontext *tnl = TNL_CONTEXT(ctx); 00154 tnl_render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES]; 00155 struct vertex_buffer *VB = &tnl->vb; 00156 const GLuint * const elt = VB->Elts; 00157 GLubyte *mask = VB->ClipMask; 00158 GLuint last = count-2; 00159 GLuint j; 00160 (void) flags; 00161 00162 tnl->Driver.Render.PrimitiveNotify( ctx, GL_TRIANGLES ); 00163 00164 for (j=start; j < last; j+=3 ) { 00165 GLubyte c1 = mask[elt[j]]; 00166 GLubyte c2 = mask[elt[j+1]]; 00167 GLubyte c3 = mask[elt[j+2]]; 00168 GLubyte ormask = c1|c2|c3; 00169 if (ormask) { 00170 if (start < j) 00171 render_tris( ctx, start, j, 0 ); 00172 if (!(c1&c2&c3&CLIPMASK)) 00173 clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); 00174 start = j+3; 00175 } 00176 } 00177 00178 if (start < j) 00179 render_tris( ctx, start, j, 0 ); 00180 } 00181 00182 /**********************************************************************/ 00183 /* Render whole begin/end objects */ 00184 /**********************************************************************/ 00185 00186 #define NEED_EDGEFLAG_SETUP (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) 00187 #define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] 00188 #define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val 00189 00190 00191 /* Vertices, no clipping. 00192 */ 00193 #define RENDER_POINTS( start, count ) \ 00194 tnl->Driver.Render.Points( ctx, start, count ) 00195 00196 #define RENDER_LINE( v1, v2 ) \ 00197 LineFunc( ctx, v1, v2 ) 00198 00199 #define RENDER_TRI( v1, v2, v3 ) \ 00200 TriangleFunc( ctx, v1, v2, v3 ) 00201 00202 #define RENDER_QUAD( v1, v2, v3, v4 ) \ 00203 QuadFunc( ctx, v1, v2, v3, v4 ) 00204 00205 #define TAG(x) _tnl_##x##_verts 00206 00207 #define LOCAL_VARS \ 00208 TNLcontext *tnl = TNL_CONTEXT(ctx); \ 00209 struct vertex_buffer *VB = &tnl->vb; \ 00210 const GLuint * const elt = VB->Elts; \ 00211 const tnl_line_func LineFunc = tnl->Driver.Render.Line; \ 00212 const tnl_triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \ 00213 const tnl_quad_func QuadFunc = tnl->Driver.Render.Quad; \ 00214 const GLboolean stipple = ctx->Line.StippleFlag; \ 00215 (void) (LineFunc && TriangleFunc && QuadFunc); \ 00216 (void) elt; (void) stipple 00217 00218 #define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx ) 00219 #define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x ) 00220 #define RENDER_TAB_QUALIFIER 00221 #define PRESERVE_VB_DEFS 00222 #include "t_vb_rendertmp.h" 00223 00224 00225 /* Elts, no clipping. 00226 */ 00227 #undef ELT 00228 #define TAG(x) _tnl_##x##_elts 00229 #define ELT(x) elt[x] 00230 #include "t_vb_rendertmp.h" 00231 00232 00233 /**********************************************************************/ 00234 /* Helper functions for drivers */ 00235 /**********************************************************************/ 00236 00237 void _tnl_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ) 00238 { 00239 TNLcontext *tnl = TNL_CONTEXT(ctx); 00240 struct vertex_buffer *VB = &tnl->vb; 00241 GLuint *tmp = VB->Elts; 00242 00243 VB->Elts = (GLuint *)elts; 00244 tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); 00245 VB->Elts = tmp; 00246 } 00247 00248 void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) 00249 { 00250 TNLcontext *tnl = TNL_CONTEXT(ctx); 00251 tnl->Driver.Render.Line( ctx, ii, jj ); 00252 } 00253 00254 00255 00256 /**********************************************************************/ 00257 /* Clip and render whole vertex buffers */ 00258 /**********************************************************************/ 00259 00260 00261 static GLboolean run_render( GLcontext *ctx, 00262 struct tnl_pipeline_stage *stage ) 00263 { 00264 TNLcontext *tnl = TNL_CONTEXT(ctx); 00265 struct vertex_buffer *VB = &tnl->vb; 00266 tnl_render_func *tab; 00267 GLint pass = 0; 00268 00269 /* Allow the drivers to lock before projected verts are built so 00270 * that window coordinates are guarenteed not to change before 00271 * rendering. 00272 */ 00273 ASSERT(tnl->Driver.Render.Start); 00274 00275 tnl->Driver.Render.Start( ctx ); 00276 00277 ASSERT(tnl->Driver.Render.BuildVertices); 00278 ASSERT(tnl->Driver.Render.PrimitiveNotify); 00279 ASSERT(tnl->Driver.Render.Points); 00280 ASSERT(tnl->Driver.Render.Line); 00281 ASSERT(tnl->Driver.Render.Triangle); 00282 ASSERT(tnl->Driver.Render.Quad); 00283 ASSERT(tnl->Driver.Render.ResetLineStipple); 00284 ASSERT(tnl->Driver.Render.Interp); 00285 ASSERT(tnl->Driver.Render.CopyPV); 00286 ASSERT(tnl->Driver.Render.ClippedLine); 00287 ASSERT(tnl->Driver.Render.ClippedPolygon); 00288 ASSERT(tnl->Driver.Render.Finish); 00289 00290 tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); 00291 00292 if (VB->ClipOrMask) { 00293 tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; 00294 clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; 00295 } 00296 else { 00297 tab = (VB->Elts ? 00298 tnl->Driver.Render.PrimTabElts : 00299 tnl->Driver.Render.PrimTabVerts); 00300 } 00301 00302 do 00303 { 00304 GLuint i; 00305 00306 for (i = 0 ; i < VB->PrimitiveCount ; i++) 00307 { 00308 GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); 00309 GLuint start = VB->Primitive[i].start; 00310 GLuint length = VB->Primitive[i].count; 00311 00312 assert((prim & PRIM_MODE_MASK) <= GL_POLYGON); 00313 00314 if (MESA_VERBOSE & VERBOSE_PRIMS) 00315 _mesa_debug(NULL, "MESA prim %s %d..%d\n", 00316 _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK), 00317 start, start+length); 00318 00319 if (length) 00320 tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim ); 00321 } 00322 } while (tnl->Driver.Render.Multipass && 00323 tnl->Driver.Render.Multipass( ctx, ++pass )); 00324 00325 tnl->Driver.Render.Finish( ctx ); 00326 00327 return GL_FALSE; /* finished the pipe */ 00328 } 00329 00330 00331 /**********************************************************************/ 00332 /* Render pipeline stage */ 00333 /**********************************************************************/ 00334 00335 00336 00337 00338 00339 const struct tnl_pipeline_stage _tnl_render_stage = 00340 { 00341 "render", /* name */ 00342 NULL, /* private data */ 00343 NULL, /* creator */ 00344 NULL, /* destructor */ 00345 NULL, /* validate */ 00346 run_render /* run */ 00347 }; Generated on Fri May 25 2012 04:18:54 for ReactOS by
1.7.6.1
|