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