r_array.c
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00083 if (mask & R_ARRAY_VERTEX)
00084 R_BindArray(GL_VERTEX_ARRAY, GL_FLOAT, mod->bsp.verts);
00085
00086
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
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
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) {
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
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) {
00124 if (mask & R_ARRAY_NORMAL)
00125 R_BindBuffer(GL_NORMAL_ARRAY, GL_FLOAT, mod->bsp.normal_buffer);
00126
00127
00128 if (r_bumpmap->value && (mask & R_ARRAY_TANGENT))
00129 R_BindBuffer(GL_TANGENT_ARRAY, GL_FLOAT, mod->bsp.tangent_buffer);
00130 }
00131
00132
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
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) {
00153 r_array_state.model = NULL;
00154 r_array_state.arrays = 0xFFFF;
00155 r_vertexbuffers->modified = qfalse;
00156 }
00157
00158
00159 mask = 0xFFFF, arrays = R_ArraysMask();
00160
00161
00162 if (r_array_state.model == mod) {
00163 const int xor = r_array_state.arrays ^ arrays;
00164 if (!xor)
00165 return;
00166
00167
00168 mask = arrays & xor;
00169 }
00170
00171 if (r_vertexbuffers->integer && qglGenBuffers)
00172 R_SetVertexBufferState(mod, mask);
00173 else
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
00186 R_BindBuffer(0, 0, 0);
00187
00188
00189 R_BindDefaultArray(GL_VERTEX_ARRAY);
00190
00191
00192 if (r_state.color_array_enabled)
00193 R_BindDefaultArray(GL_COLOR_ARRAY);
00194
00195
00196 if (r_state.lighting_enabled) {
00197 R_BindDefaultArray(GL_NORMAL_ARRAY);
00198
00199
00200 if (r_bumpmap->value && r_state.active_program == r_state.world_program)
00201 R_BindDefaultArray(GL_TANGENT_ARRAY);
00202 }
00203
00204
00205 if (texunit_diffuse.enabled)
00206 R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
00207
00208
00209 if (texunit_lightmap.enabled) {
00210 R_SelectTexture(&texunit_lightmap);
00211 R_BindDefaultArray(GL_TEXTURE_COORD_ARRAY);
00212 R_SelectTexture(&texunit_diffuse);
00213 }
00214 }