This patch spawns from this game engine issue:
[blender-staging.git] / source / gameengine / Rasterizer / RAS_OpenGLRasterizer / RAS_VAOpenGLRasterizer.cpp
1 /**
2  * $Id$
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  */
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include "RAS_VAOpenGLRasterizer.h"
36 #include <stdlib.h>
37
38 #ifdef WIN32
39 #include <windows.h>
40 #endif // WIN32
41 #ifdef __APPLE__
42 #define GL_GLEXT_LEGACY 1
43 #include <OpenGL/gl.h>
44 #else
45 #include <GL/gl.h>
46 #endif
47
48 #include "STR_String.h"
49 #include "RAS_TexVert.h"
50 #include "MT_CmMatrix4x4.h"
51 #include "RAS_IRenderTools.h" // rendering text
52
53 #include "RAS_GLExtensionManager.h"
54         
55
56 using namespace bgl;
57
58 RAS_VAOpenGLRasterizer::RAS_VAOpenGLRasterizer(RAS_ICanvas* canvas, bool lock)
59 :       RAS_OpenGLRasterizer(canvas),
60         m_Lock(lock && RAS_EXT_support._EXT_compiled_vertex_array)      
61 {
62 }
63
64
65
66 RAS_VAOpenGLRasterizer::~RAS_VAOpenGLRasterizer()
67 {
68 }
69
70 bool RAS_VAOpenGLRasterizer::Init(void)
71 {
72         
73         bool result = RAS_OpenGLRasterizer::Init();
74         
75         if (result)
76         {
77                 glEnableClientState(GL_VERTEX_ARRAY);
78                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
79                 glEnableClientState(GL_NORMAL_ARRAY);
80                 glDisableClientState(GL_COLOR_ARRAY);
81
82                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
83         }
84
85         return result;
86 }
87
88
89
90 void RAS_VAOpenGLRasterizer::SetDrawingMode(int drawingmode)
91 {
92         m_drawingmode = drawingmode;
93
94                 switch (m_drawingmode)
95         {
96         case KX_BOUNDINGBOX:
97                 {
98                 }
99         case KX_WIREFRAME:
100                 {
101                         glDisable (GL_CULL_FACE);
102                         break;
103                 }
104         case KX_TEXTURED:
105                 {
106                 }
107         case KX_SHADED:
108                 {
109                         glEnableClientState(GL_COLOR_ARRAY);
110                 }
111         case KX_SOLID:
112                 {
113                         break;
114                 }
115         default:
116                 {
117                 }
118         }
119 }
120
121
122
123 void RAS_VAOpenGLRasterizer::Exit()
124 {
125         glDisableClientState(GL_VERTEX_ARRAY);
126         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
127         glDisableClientState(GL_COLOR_ARRAY);
128         glDisableClientState(GL_NORMAL_ARRAY);
129
130         RAS_OpenGLRasterizer::Exit();
131 }
132
133
134
135 void RAS_VAOpenGLRasterizer::IndexPrimitives( const vecVertexArray& vertexarrays,
136                                                         const vecIndexArrays & indexarrays,
137                                                         int mode,
138                                                         class RAS_IPolyMaterial* polymat,
139                                                         class RAS_IRenderTools* rendertools,
140                                                         bool useObjectColor,
141                                                         const MT_Vector4& rgbacolor,
142                                                         class KX_ListSlot** slot)
143 {
144         static const GLsizei vtxstride = sizeof(RAS_TexVert);
145         GLenum drawmode;
146         switch (mode)
147         {
148         case 0:
149                 {
150                 drawmode = GL_TRIANGLES;
151                 break;
152                 }
153         case 2:
154                 {
155                 drawmode = GL_QUADS;
156                 break;
157                 }
158         case 1: //lines
159                 {
160                 }
161         default:
162                 {
163                 drawmode = GL_LINES;
164                 break;
165                 }
166         }
167         const RAS_TexVert* vertexarray;
168         unsigned int numindices, vt;
169         if (drawmode != GL_LINES)
170         {
171                 if (useObjectColor)
172                 {
173                         glDisableClientState(GL_COLOR_ARRAY);
174                         glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
175                 } else
176                 {
177                         glColor4d(0,0,0,1.0);
178                         glEnableClientState(GL_COLOR_ARRAY);
179                 }
180         }
181         else
182         {
183                 glColor3d(0,0,0);
184         }
185
186         // use glDrawElements to draw each vertexarray
187         for (vt=0;vt<vertexarrays.size();vt++)
188         {
189                 vertexarray = &((*vertexarrays[vt]) [0]);
190                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
191                 numindices = indexarray.size();
192
193                 if (!numindices)
194                         continue;
195                 
196                 glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ());
197                 glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1());
198                 glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA());
199                 glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal());
200
201                 //if(m_Lock)
202                 //      local->Begin(vertexarrays[vt]->size());
203
204                 // here the actual drawing takes places
205                 glDrawElements(drawmode,numindices,GL_UNSIGNED_SHORT,&(indexarray[0]));
206
207                 //if(m_Lock)
208                 //      local->End();
209
210
211         }
212 }
213
214
215 void RAS_VAOpenGLRasterizer::IndexPrimitivesMulti( const vecVertexArray& vertexarrays,
216                                                         const vecIndexArrays & indexarrays,
217                                                         int mode,
218                                                         class RAS_IPolyMaterial* polymat,
219                                                         class RAS_IRenderTools* rendertools,
220                                                         bool useObjectColor,
221                                                         const MT_Vector4& rgbacolor,
222                                                         class KX_ListSlot** slot)
223 {
224         static const GLsizei vtxstride = sizeof(RAS_TexVert);
225         GLenum drawmode;
226         switch (mode)
227         {
228         case 0:
229                 {
230                 drawmode = GL_TRIANGLES;
231                 break;
232                 }
233         case 2:
234                 {
235                 drawmode = GL_QUADS;
236                 break;
237                 }
238         case 1: //lines
239                 {
240                 }
241         default:
242                 {
243                 drawmode = GL_LINES;
244                 break;
245                 }
246         }
247         const RAS_TexVert* vertexarray;
248         unsigned int numindices, vt;
249         const unsigned int enabled = polymat->GetEnabled();
250
251         if (drawmode != GL_LINES)
252         {
253                 if (useObjectColor)
254                 {
255                         glDisableClientState(GL_COLOR_ARRAY);
256                         glColor4d(rgbacolor[0], rgbacolor[1], rgbacolor[2], rgbacolor[3]);
257                 } else
258                 {
259                         glColor4d(0,0,0,1.0);
260                         glEnableClientState(GL_COLOR_ARRAY);
261                 }
262         }
263         else
264         {
265                 glColor3d(0,0,0);
266         }
267
268         // use glDrawElements to draw each vertexarray
269         for (vt=0;vt<vertexarrays.size();vt++)
270         {
271                 vertexarray = &((*vertexarrays[vt]) [0]);
272                 const KX_IndexArray & indexarray = (*indexarrays[vt]);
273                 numindices = indexarray.size();
274
275                 if (!numindices)
276                         continue;
277                 
278                 glVertexPointer(3,GL_FLOAT,vtxstride,vertexarray->getLocalXYZ());
279                 TexCoordPtr(vertexarray, enabled);
280
281                 //glTexCoordPointer(2,GL_FLOAT,vtxstride,vertexarray->getUV1());
282                 glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,vertexarray->getRGBA());
283                 glNormalPointer(GL_FLOAT,vtxstride,vertexarray->getNormal());
284
285                 //if(m_Lock)
286                 //      local->Begin(vertexarrays[vt]->size());
287
288                 // here the actual drawing takes places
289                 glDrawElements(drawmode,numindices,GL_UNSIGNED_SHORT,&(indexarray[0]));
290                 
291                 //if(m_Lock)
292                 //      local->End();
293         }
294 }
295
296 void RAS_VAOpenGLRasterizer::TexCoordPtr(const RAS_TexVert *tv, int enabled)
297 {
298 #if defined(GL_ARB_multitexture) && defined(WITH_GLEXT)
299         if (!getenv("WITHOUT_GLEXT")) {
300                 if(bgl::RAS_EXT_support._ARB_multitexture)
301                 {
302                         for(int unit=0; unit<enabled; unit++)
303                         {
304                                 bgl::blClientActiveTextureARB(GL_TEXTURE0_ARB+unit);
305
306                                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
307                                 if( tv->getFlag() & TV_2NDUV && tv->getUnit() == unit ) {
308                                         glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert), tv->getUV2());
309                                         continue;
310                                 }
311                                 switch(m_texco[unit])
312                                 {
313                                 case RAS_TEXCO_DISABLE:
314                                 case RAS_TEXCO_OBJECT:
315                                 case RAS_TEXCO_GEN:
316                                         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
317                                         break;
318                                 case RAS_TEXCO_ORCO:
319                                 case RAS_TEXCO_GLOB:
320                                         glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getLocalXYZ());
321                                         break;
322                                 case RAS_TEXCO_UV1:
323                                         glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV1());
324                                         break;
325                                 case RAS_TEXCO_NORM:
326                                         glTexCoordPointer(3, GL_FLOAT, sizeof(RAS_TexVert),tv->getNormal());
327                                         break;
328                                 case RAS_TEXTANGENT:
329                                         glTexCoordPointer(4, GL_FLOAT, sizeof(RAS_TexVert),tv->getTangent());
330                                         break;
331                                 case RAS_TEXCO_UV2:
332                                         glTexCoordPointer(2, GL_FLOAT, sizeof(RAS_TexVert),tv->getUV2());
333                                         break;
334                                 }
335                         }
336                 }
337
338 #ifdef GL_ARB_vertex_program
339                 if(m_useTang && bgl::RAS_EXT_support._ARB_vertex_program)
340                         bgl::blVertexAttrib4fvARB(1/*tangent*/, tv->getTangent());
341 #endif
342         }
343 #endif
344 }
345
346
347 void RAS_VAOpenGLRasterizer::EnableTextures(bool enable)
348 {
349         if (enable)
350                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
351         else
352                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
353 }
354