Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00032 #include "RAS_VAOpenGLRasterizer.h" 00033 #include <stdlib.h> 00034 00035 #include "GL/glew.h" 00036 #include "GPU_extensions.h" 00037 00038 #include "STR_String.h" 00039 #include "RAS_TexVert.h" 00040 #include "MT_CmMatrix4x4.h" 00041 #include "RAS_IRenderTools.h" // rendering text 00042 00043 RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock) 00044 : RAS_OpenGLRasterizer(canvas), 00045 m_Lock(lock && GLEW_EXT_compiled_vertex_array), 00046 m_last_texco_num(0), 00047 m_last_attrib_num(0) 00048 { 00049 } 00050 00051 RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer() 00052 { 00053 } 00054 00055 bool RAS_VAOpenGLRasterizer::Init(void) 00056 { 00057 00058 bool result = RAS_OpenGLRasterizer::Init(); 00059 00060 if (result) 00061 { 00062 glEnableClientState(GL_VERTEX_ARRAY); 00063 glEnableClientState(GL_NORMAL_ARRAY); 00064 glDisableClientState(GL_COLOR_ARRAY); 00065 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00066 00067 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00068 } 00069 00070 return result; 00071 } 00072 00073 void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode) 00074 { 00075 m_drawingmode = drawingmode; 00076 00077 switch (m_drawingmode) 00078 { 00079 case KX_BOUNDINGBOX: 00080 case KX_WIREFRAME: 00081 //glDisableClientState(GL_COLOR_ARRAY); 00082 //glDisable(GL_CULL_FACE); 00083 break; 00084 case KX_SOLID: 00085 //glDisableClientState(GL_COLOR_ARRAY); 00086 break; 00087 case KX_TEXTURED: 00088 case KX_SHADED: 00089 case KX_SHADOW: 00090 //glEnableClientState(GL_COLOR_ARRAY); 00091 default: 00092 break; 00093 } 00094 } 00095 00096 void RAS_VAOpenGLRasterizer::Exit() 00097 { 00098 glDisableClientState(GL_VERTEX_ARRAY); 00099 glDisableClientState(GL_NORMAL_ARRAY); 00100 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00101 glDisableClientState(GL_COLOR_ARRAY); 00102 00103 RAS_OpenGLRasterizer::Exit(); 00104 } 00105 00106 void RAS_VAOpenGLRasterizer::IndexPrimitives(RAS_MeshSlot& ms) 00107 { 00108 static const GLsizei stride = sizeof(RAS_TexVert); 00109 bool wireframe = m_drawingmode <= KX_WIREFRAME; 00110 RAS_MeshSlot::iterator it; 00111 GLenum drawmode; 00112 00113 if (ms.m_pDerivedMesh) { 00114 // cannot be handled here, pass to RAS_OpenGLRasterizer 00115 RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, false); 00116 return; 00117 } 00118 00119 if(!wireframe) 00120 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00121 00122 // use glDrawElements to draw each vertexarray 00123 for(ms.begin(it); !ms.end(it); ms.next(it)) { 00124 if(it.totindex == 0) 00125 continue; 00126 00127 // drawing mode 00128 if(it.array->m_type == RAS_DisplayArray::TRIANGLE) 00129 drawmode = GL_TRIANGLES; 00130 else if(it.array->m_type == RAS_DisplayArray::QUAD) 00131 drawmode = GL_QUADS; 00132 else 00133 drawmode = GL_LINES; 00134 00135 // colors 00136 if (drawmode != GL_LINES && !wireframe) { 00137 if (ms.m_bObjectColor) { 00138 const MT_Vector4& rgba = ms.m_RGBAcolor; 00139 00140 glDisableClientState(GL_COLOR_ARRAY); 00141 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); 00142 } 00143 else { 00144 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); 00145 glEnableClientState(GL_COLOR_ARRAY); 00146 } 00147 } 00148 else 00149 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); 00150 00151 glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); 00152 glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); 00153 if(!wireframe) { 00154 glTexCoordPointer(2, GL_FLOAT, stride, it.vertex->getUV1()); 00155 if(glIsEnabled(GL_COLOR_ARRAY)) 00156 glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); 00157 } 00158 00159 // here the actual drawing takes places 00160 glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); 00161 } 00162 00163 if(!wireframe) { 00164 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00165 glDisableClientState(GL_COLOR_ARRAY); 00166 } 00167 } 00168 00169 void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) 00170 { 00171 static const GLsizei stride = sizeof(RAS_TexVert); 00172 bool wireframe = m_drawingmode <= KX_WIREFRAME; 00173 RAS_MeshSlot::iterator it; 00174 GLenum drawmode; 00175 00176 if (ms.m_pDerivedMesh) { 00177 // cannot be handled here, pass to RAS_OpenGLRasterizer 00178 RAS_OpenGLRasterizer::IndexPrimitivesInternal(ms, true); 00179 return; 00180 } 00181 00182 if(!wireframe) 00183 EnableTextures(true); 00184 00185 // use glDrawElements to draw each vertexarray 00186 for(ms.begin(it); !ms.end(it); ms.next(it)) { 00187 if(it.totindex == 0) 00188 continue; 00189 00190 // drawing mode 00191 if(it.array->m_type == RAS_DisplayArray::TRIANGLE) 00192 drawmode = GL_TRIANGLES; 00193 else if(it.array->m_type == RAS_DisplayArray::QUAD) 00194 drawmode = GL_QUADS; 00195 else 00196 drawmode = GL_LINES; 00197 00198 // colors 00199 if (drawmode != GL_LINES && !wireframe) { 00200 if (ms.m_bObjectColor) { 00201 const MT_Vector4& rgba = ms.m_RGBAcolor; 00202 00203 glDisableClientState(GL_COLOR_ARRAY); 00204 glColor4d(rgba[0], rgba[1], rgba[2], rgba[3]); 00205 } 00206 else { 00207 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); 00208 glEnableClientState(GL_COLOR_ARRAY); 00209 } 00210 } 00211 else 00212 glColor4f(0.0f, 0.0f, 0.0f, 1.0f); 00213 00214 glVertexPointer(3, GL_FLOAT, stride, it.vertex->getXYZ()); 00215 glNormalPointer(GL_FLOAT, stride, it.vertex->getNormal()); 00216 if(!wireframe) { 00217 TexCoordPtr(it.vertex); 00218 if(glIsEnabled(GL_COLOR_ARRAY)) 00219 glColorPointer(4, GL_UNSIGNED_BYTE, stride, it.vertex->getRGBA()); 00220 } 00221 00222 // here the actual drawing takes places 00223 glDrawElements(drawmode, it.totindex, GL_UNSIGNED_SHORT, it.index); 00224 } 00225 00226 if(!wireframe) { 00227 glDisableClientState(GL_COLOR_ARRAY); 00228 EnableTextures(false); 00229 } 00230 } 00231 00232 void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv) 00233 { 00234 /* note: this function must closely match EnableTextures to enable/disable 00235 * the right arrays, otherwise coordinate and attribute pointers from other 00236 * materials can still be used and cause crashes */ 00237 int unit; 00238 00239 if(GLEW_ARB_multitexture) 00240 { 00241 for(unit=0; unit<m_texco_num; unit++) 00242 { 00243 glClientActiveTextureARB(GL_TEXTURE0_ARB+unit); 00244 if(tv->getFlag() & RAS_TexVert::SECOND_UV && (int)tv->getUnit() == unit) { 00245 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00246 glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2()); 00247 continue; 00248 } 00249 switch(m_texco[unit]) 00250 { 00251 case RAS_TEXCO_ORCO: 00252 case RAS_TEXCO_GLOB: 00253 glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getXYZ()); 00254 break; 00255 case RAS_TEXCO_UV1: 00256 glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1()); 00257 break; 00258 case RAS_TEXCO_NORM: 00259 glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal()); 00260 break; 00261 case RAS_TEXTANGENT: 00262 glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent()); 00263 break; 00264 case RAS_TEXCO_UV2: 00265 glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2()); 00266 break; 00267 default: 00268 break; 00269 } 00270 } 00271 00272 glClientActiveTextureARB(GL_TEXTURE0_ARB); 00273 } 00274 00275 if(GLEW_ARB_vertex_program) { 00276 for(unit=0; unit<m_attrib_num; unit++) { 00277 switch(m_attrib[unit]) { 00278 case RAS_TEXCO_ORCO: 00279 case RAS_TEXCO_GLOB: 00280 glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getXYZ()); 00281 break; 00282 case RAS_TEXCO_UV1: 00283 glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV1()); 00284 break; 00285 case RAS_TEXCO_NORM: 00286 glVertexAttribPointerARB(unit, 3, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getNormal()); 00287 break; 00288 case RAS_TEXTANGENT: 00289 glVertexAttribPointerARB(unit, 4, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getTangent()); 00290 break; 00291 case RAS_TEXCO_UV2: 00292 glVertexAttribPointerARB(unit, 2, GL_FLOAT, GL_FALSE, sizeof(RAS_TexVert), tv->getUV2()); 00293 break; 00294 case RAS_TEXCO_VCOL: 00295 glVertexAttribPointerARB(unit, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(RAS_TexVert), tv->getRGBA()); 00296 break; 00297 default: 00298 break; 00299 } 00300 } 00301 } 00302 } 00303 00304 void RAS_VAOpenGLRasterizer::EnableTextures(bool enable) 00305 { 00306 TexCoGen *texco, *attrib; 00307 int unit, texco_num, attrib_num; 00308 00309 /* we cache last texcoords and attribs to ensure we disable the ones that 00310 * were actually last set */ 00311 if(enable) { 00312 texco = m_texco; 00313 texco_num = m_texco_num; 00314 attrib = m_attrib; 00315 attrib_num = m_attrib_num; 00316 00317 memcpy(m_last_texco, m_texco, sizeof(TexCoGen)*m_texco_num); 00318 m_last_texco_num = m_texco_num; 00319 memcpy(m_last_attrib, m_attrib, sizeof(TexCoGen)*m_attrib_num); 00320 m_last_attrib_num = m_attrib_num; 00321 } 00322 else { 00323 texco = m_last_texco; 00324 texco_num = m_last_texco_num; 00325 attrib = m_last_attrib; 00326 attrib_num = m_last_attrib_num; 00327 } 00328 00329 if(GLEW_ARB_multitexture) { 00330 for(unit=0; unit<texco_num; unit++) { 00331 glClientActiveTextureARB(GL_TEXTURE0_ARB+unit); 00332 00333 switch(texco[unit]) 00334 { 00335 case RAS_TEXCO_ORCO: 00336 case RAS_TEXCO_GLOB: 00337 case RAS_TEXCO_UV1: 00338 case RAS_TEXCO_NORM: 00339 case RAS_TEXTANGENT: 00340 case RAS_TEXCO_UV2: 00341 if(enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00342 else glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00343 break; 00344 default: 00345 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00346 break; 00347 } 00348 } 00349 00350 glClientActiveTextureARB(GL_TEXTURE0_ARB); 00351 } 00352 else { 00353 if(texco_num) { 00354 if(enable) glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00355 else glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00356 } 00357 } 00358 00359 if(GLEW_ARB_vertex_program) { 00360 for(unit=0; unit<attrib_num; unit++) { 00361 switch(attrib[unit]) { 00362 case RAS_TEXCO_ORCO: 00363 case RAS_TEXCO_GLOB: 00364 case RAS_TEXCO_UV1: 00365 case RAS_TEXCO_NORM: 00366 case RAS_TEXTANGENT: 00367 case RAS_TEXCO_UV2: 00368 case RAS_TEXCO_VCOL: 00369 if(enable) glEnableVertexAttribArrayARB(unit); 00370 else glDisableVertexAttribArrayARB(unit); 00371 break; 00372 default: 00373 glDisableVertexAttribArrayARB(unit); 00374 break; 00375 } 00376 } 00377 } 00378 00379 if(!enable) { 00380 m_last_texco_num = 0; 00381 m_last_attrib_num = 0; 00382 } 00383 } 00384