r_array.c

Go to the documentation of this file.
00001 
00007 /*
00008 Copyright(c) 1997-2001 Id Software, Inc.
00009 Copyright(c) 2002 The Quakeforge Project.
00010 Copyright(c) 2006 Quake2World.
00011 
00012 This program is free software; you can redistribute it and/or
00013 modify it under the terms of the GNU General Public License
00014 as published by the Free Software Foundation; either version 2
00015 of the License, or(at your option) any later version.
00016 
00017 This program is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00020 
00021 See the GNU General Public License for more details.
00022 
00023 You should have received a copy of the GNU General Public License
00024 along with this program; if not, write to the Free Software
00025 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00026 */
00027 
00028 #include "r_local.h"
00029 
00030 #define R_ARRAY_VERTEX          0x1
00031 #define R_ARRAY_COLOR           0x2
00032 #define R_ARRAY_NORMAL          0x4
00033 #define R_ARRAY_TANGENT         0x8
00034 #define R_ARRAY_TEX_DIFFUSE     0x10
00035 #define R_ARRAY_TEX_LIGHTMAP    0x20
00036 
00037 typedef struct r_array_state_s {
00038     const model_t *model;
00039     int arrays;
00040 } r_array_state_t;
00041 
00042 static r_array_state_t r_array_state;
00043 
00044 
00051 static int R_ArraysMask (void)
00052 {
00053     int mask;
00054 
00055     mask = R_ARRAY_VERTEX;
00056 
00057     if (r_state.color_array_enabled)
00058         mask |= R_ARRAY_COLOR;
00059 
00060     if (r_state.lighting_enabled) {
00061         mask |= R_ARRAY_NORMAL;
00062 
00063         if (r_bumpmap->value)
00064             mask |= R_ARRAY_TANGENT;
00065     }
00066 
00067     if (texunit_diffuse.enabled)
00068         mask |= R_ARRAY_TEX_DIFFUSE;
00069 
00070     if (texunit_lightmap.enabled)
00071         mask |= R_ARRAY_TEX_LIGHTMAP;
00072 
00073     return mask;
00074 }
00075 
00080 static inline void R_SetVertexArrayState (const model_t* mod, int mask)
00081 {
00082     /* vertex array */
00083     if (mask & R_ARRAY_VERTEX)
00084         R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, mod->bsp.verts);
00085 
00086     /* normals and tangents for lighting */
00087     if (r_state.lighting_enabled) {
00088         if (mask & R_ARRAY_NORMAL)
00089             R_BindArray(GL_NORMAL_ARRAY, GL_FLOAT, mod->bsp.normals);
00090 
00091         /* tangent vectors for bump mapping */
00092         if (r_bumpmap->value && r_state.active_program == r_state.world_program)
00093             if (mask & R_ARRAY_TANGENT)
00094                 R_BindArray(GL_TANGENT_ARRAY, GL_FLOAT, mod->bsp.tangents);
00095     }
00096 
00097     /* diffuse texcoords */
00098     if (texunit_diffuse.enabled) {
00099         if (mask & R_ARRAY_TEX_DIFFUSE)
00100             R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->bsp.texcoords);
00101     }
00102 
00103     if (texunit_lightmap.enabled) {  /* lightmap texcoords */
00104         if (mask & R_ARRAY_TEX_LIGHTMAP) {
00105             R_SelectTexture(&texunit_lightmap);
00106             R_BindArray(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->bsp.lmtexcoords);
00107             R_SelectTexture(&texunit_diffuse);
00108         }
00109     }
00110 }
00111 
00117 static inline void R_SetVertexBufferState (const model_t* mod, int mask)
00118 {
00119     /* vertex array */
00120     if (mask & R_ARRAY_VERTEX)
00121         R_BindBuffer(GL_VERTEX_ARRAY, GL_FLOAT, mod->bsp.vertex_buffer);
00122 
00123     if (r_state.lighting_enabled) { /* normals and tangents for lighting */
00124         if (mask & R_ARRAY_NORMAL)
00125             R_BindBuffer(GL_NORMAL_ARRAY, GL_FLOAT, mod->bsp.normal_buffer);
00126 
00127         /* tangent vectors for bump mapping */
00128         if (r_bumpmap->value && (mask & R_ARRAY_TANGENT))
00129             R_BindBuffer(GL_TANGENT_ARRAY, GL_FLOAT, mod->bsp.tangent_buffer);
00130     }
00131 
00132     /* diffuse texcoords */
00133     if (texunit_diffuse.enabled) {
00134         if (mask & R_ARRAY_TEX_DIFFUSE)
00135             R_BindBuffer(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->bsp.texcoord_buffer);
00136     }
00137 
00138     /* lightmap texcoords */
00139     if (texunit_lightmap.enabled) {
00140         if (mask & R_ARRAY_TEX_LIGHTMAP) {
00141             R_SelectTexture(&texunit_lightmap);
00142             R_BindBuffer(GL_TEXTURE_COORD_ARRAY, GL_FLOAT, mod->bsp.lmtexcoord_buffer);
00143             R_SelectTexture(&texunit_diffuse);
00144         }
00145     }
00146 }
00147 
00148 void R_SetArrayState (const model_t *mod)
00149 {
00150     int arrays, mask;
00151 
00152     if (r_vertexbuffers->modified) {  /* force a full re-bind */
00153         r_array_state.model = NULL;
00154         r_array_state.arrays = 0xFFFF;
00155         r_vertexbuffers->modified = qfalse;
00156     }
00157 
00158     /* resolve the desired arrays mask */
00159     mask = 0xFFFF, arrays = R_ArraysMask();
00160 
00161     /* try to save some binds */
00162     if (r_array_state.model == mod) {
00163         const int xor = r_array_state.arrays ^ arrays;
00164         if (!xor)  /* no changes, we're done */
00165             return;
00166 
00167         /* resolve what's left to turn on */
00168         mask = arrays & xor;
00169     }
00170 
00171     if (r_vertexbuffers->integer && qglGenBuffers)  /* use vbo */
00172         R_SetVertexBufferState(mod, mask);
00173     else  /* or arrays */
00174         R_SetVertexArrayState(mod, mask);
00175 
00176     r_array_state.model = mod;
00177     r_array_state.arrays = arrays;
00178 }
00179 
00180 void R_ResetArrayState (void)
00181 {
00182     r_array_state.model = NULL;
00183     r_array_state.arrays = 0;
00184 
00185     /* vbo */
00186     R_BindBuffer(0, 0, 0);
00187 
00188     /* vertex array */
00189     R_BindDefaultArray(GL_VERTEX_ARRAY);
00190 
00191     /* color array */
00192     if (r_state.color_array_enabled)
00193         R_BindDefaultArray(GL_COLOR_ARRAY);
00194 
00195     /* normals and tangents */
00196     if (r_state.lighting_enabled) {
00197         R_BindDefaultArray(GL_NORMAL_ARRAY);
00198 
00199         /* tangent vectors for bump mapping */
00200         if (r_bumpmap->value && r_state.active_program == r_state.world_program)
00201             R_BindDefaultArray(GL_TANGENT_ARRAY);
00202     }
00203 
00204     /* diffuse texcoords */
00205     if (texunit_diffuse.enabled)
00206         R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
00207 
00208     /* lightmap texcoords */
00209     if (texunit_lightmap.enabled) {
00210         R_SelectTexture(&texunit_lightmap);
00211         R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
00212         R_SelectTexture(&texunit_diffuse);
00213     }
00214 }

Generated by  doxygen 1.6.2