soc-2008-mxcurioni: towards Freestyle compilation, removing Qt's QString and QImage...
[blender-staging.git] / source / blender / freestyle / intern / rendering / GLRenderer.cpp
1
2 //
3 //  Copyright (C) : Please refer to the COPYRIGHT file distributed 
4 //   with this source distribution. 
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 ///////////////////////////////////////////////////////////////////////////////
21
22 #include "../scene_graph/IndexedFaceSet.h"
23 #include "../scene_graph/NodeDrawingStyle.h"
24 #include "../scene_graph/NodeLight.h"
25 #include "../scene_graph/NodeCamera.h"
26 #include "../scene_graph/NodeTransform.h"
27 #include "../scene_graph/NodeShape.h"
28 #include "../scene_graph/OrientedLineRep.h"
29 #include "../scene_graph/VertexRep.h"
30 #include "../stroke/Stroke.h"
31
32 #include "../scene_graph/TriangleRep.h"
33
34 #include "GLRenderer.h"
35
36 static GLenum lights[8] = {GL_LIGHT0, 
37                     GL_LIGHT1, 
38                     GL_LIGHT2, 
39                     GL_LIGHT3, 
40                     GL_LIGHT4,
41                     GL_LIGHT5,
42                     GL_LIGHT6,
43                     GL_LIGHT7};
44
45 void GLRenderer::visitIndexedFaceSet(IndexedFaceSet& ifs)
46 {
47   /*GLuint dl = ifs.displayList();
48   if(dl != 0){
49     glCallList(dl);
50     return;
51   }*/
52   unsigned int fIndex = 0;
53   
54   const real * vertices = ifs.vertices();
55   const real * normals = ifs.normals();
56   const real * texCoords = ifs.texCoords();
57   const Material *const* materials = ifs.materials();
58   const unsigned *vindices = ifs.vindices();
59   const unsigned *nindices = ifs.nindices();
60   const unsigned *mindices = ifs.mindices();
61   const unsigned *tindices = ifs.tindices();
62   const unsigned numfaces = ifs.numFaces();
63   const IndexedFaceSet::TRIANGLES_STYLE * faceStyle = ifs.trianglesStyle();
64   const unsigned *numVertexPerFace = ifs.numVertexPerFaces();
65   
66
67   const unsigned* pvi = vindices;
68   const unsigned* pni = nindices;
69   const unsigned* pmi = mindices;
70   const unsigned* pti = tindices;
71
72   //dl = glGenLists(1);
73   //glNewList(dl, GL_COMPILE_AND_EXECUTE);
74   for(fIndex=0; fIndex<numfaces; fIndex++)
75   {
76     switch(faceStyle[fIndex])
77     {
78     case IndexedFaceSet::TRIANGLE_STRIP:
79       RenderTriangleStrip(vertices, normals, materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]);
80       break;
81     case IndexedFaceSet::TRIANGLE_FAN:
82       RenderTriangleFan(vertices, normals, materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]);
83       break;
84     case IndexedFaceSet::TRIANGLES:
85       RenderTriangles(vertices, normals, materials, texCoords, pvi, pni, pmi, pti, numVertexPerFace[fIndex]);
86       break;
87     }
88     pvi += numVertexPerFace[fIndex];
89     pni += numVertexPerFace[fIndex];
90                 if(pmi)
91                         pmi += numVertexPerFace[fIndex];
92     if(pti)
93         pti += numVertexPerFace[fIndex];
94   }
95   //glEndList();
96   //ifs.SetDisplayList(dl);
97 }
98
99 void GLRenderer::visitNodeTransform(NodeTransform& tn) {
100   if(tn.scaled())
101     glEnable(GL_NORMALIZE);
102 }
103
104 void GLRenderer::visitNodeTransformBefore(NodeTransform& tn) {
105   glPushMatrix();
106
107   // Now apply transform
108   applyTransform(tn.matrix());
109 }
110
111 void GLRenderer::visitNodeTransformAfter(NodeTransform& tn) {
112   glPopMatrix();
113 }
114
115 void GLRenderer::visitNodeLight(NodeLight& ln)  
116 {
117   if(true != ln.isOn())
118     return;
119
120   int number = ln.number();
121   
122   glLightfv(lights[number], GL_AMBIENT, ln.ambient());
123   glLightfv(lights[number], GL_DIFFUSE, ln.diffuse());
124   glLightfv(lights[number], GL_SPECULAR, ln.specular());
125   glLightfv(lights[number], GL_POSITION, ln.position());
126
127   glEnable(lights[number]);
128 }
129
130 void GLRenderer::visitNodeCamera(NodeCamera& cn)  
131 {
132     const double * mvm = cn.modelViewMatrix();
133     const double * pm = cn.projectionMatrix();
134
135     glMatrixMode(GL_PROJECTION);
136     glLoadIdentity();
137     glMultMatrixd(pm);
138
139     glMatrixMode(GL_MODELVIEW);
140     glLoadIdentity();
141     glMultMatrixd(mvm);
142
143
144 }
145
146 void GLRenderer::visitNodeDrawingStyleBefore(NodeDrawingStyle& ds) {
147   glPushAttrib(GL_ALL_ATTRIB_BITS);
148 }
149
150 void GLRenderer::visitNodeDrawingStyleAfter(NodeDrawingStyle&) {
151   glPopAttrib();
152 }
153
154 void GLRenderer::RenderTriangleStrip( const real *iVertices, 
155                                      const real *iNormals,
156                                      const Material *const* iMaterials,
157                                      const real *iTexCoords,
158                                      const unsigned* iVIndices, 
159                                      const unsigned* iNIndices,
160                                      const unsigned* iMIndices,
161                                      const unsigned* iTIndices,
162                                      const unsigned iNVertices) 
163 {
164   unsigned index = -1;
165   glBegin(GL_TRIANGLE_STRIP);
166   for(unsigned int i=0; i<iNVertices; i++)
167   {
168                 if(iMIndices){
169                         if(iMIndices[i] != index){
170                                 visitMaterial(*(iMaterials[iMIndices[i]]));
171                                 index = iMIndices[i];
172                         }
173                 }
174
175         if(iTIndices){
176             glTexCoord2f(   iTexCoords[iTIndices[i]],
177                             iTexCoords[iTIndices[i]+1]);
178                 }
179     
180     glNormal3r(iNormals[iNIndices[i]], 
181                iNormals[iNIndices[i]+1],
182                iNormals[iNIndices[i]+2]);
183
184     glVertex3r( iVertices[iVIndices[i]], 
185                 iVertices[iVIndices[i]+1],
186                 iVertices[iVIndices[i]+2]);
187   }
188   glEnd();
189 }
190
191 void GLRenderer::RenderTriangleFan( const real *iVertices, 
192                                     const real *iNormals,
193                                     const Material *const* iMaterials,
194                                     const real *iTexCoords,
195                                     const unsigned* iVIndices, 
196                                     const unsigned* iNIndices,
197                                     const unsigned* iMIndices,
198                                     const unsigned* iTIndices,
199                                     const unsigned iNVertices)  
200 {
201   unsigned index = -1;
202   glBegin(GL_TRIANGLE_FAN);
203   for(unsigned int i=0; i<iNVertices; i++)
204   {
205                 if(iMIndices){
206                         if(iMIndices[i] != index){
207                                 visitMaterial(*(iMaterials[iMIndices[i]]));
208                                 index = iMIndices[i];
209                         }
210                 }
211         if(iTIndices){
212             glTexCoord2f(   iTexCoords[iTIndices[i]],
213                             iTexCoords[iTIndices[i]+1]);
214                 }
215
216     glNormal3r(iNormals[iNIndices[i]], 
217                iNormals[iNIndices[i]+1],
218                iNormals[iNIndices[i]+2]);
219
220     glVertex3r( iVertices[iVIndices[i]], 
221                 iVertices[iVIndices[i]+1],
222                 iVertices[iVIndices[i]+2]);
223   }
224   glEnd();
225 }
226
227 void GLRenderer::RenderTriangles( const real *iVertices, 
228                                  const real *iNormals,
229                                  const Material *const* iMaterials,
230                                  const real *iTexCoords,
231                                  const unsigned* iVIndices, 
232                                  const unsigned* iNIndices,
233                                  const unsigned* iMIndices,
234                                  const unsigned* iTIndices,
235                                  const unsigned iNVertices)  
236 {
237   unsigned index = -1;
238   glBegin(GL_TRIANGLES);
239   for(unsigned int i=0; i<iNVertices; i++)
240   {
241                 if(iMIndices){
242                         if(iMIndices[i] != index){
243                                 visitMaterial(*(iMaterials[iMIndices[i]]));
244                                 index = iMIndices[i];
245                         }
246                 }
247         if(iTIndices){
248             glTexCoord2f(   iTexCoords[iTIndices[i]],
249                             iTexCoords[iTIndices[i]+1]);
250                 }
251
252     glNormal3r(iNormals[iNIndices[i]], 
253                iNormals[iNIndices[i]+1],
254                iNormals[iNIndices[i]+2]);
255
256     glVertex3r( iVertices[iVIndices[i]], 
257                 iVertices[iVIndices[i]+1],
258                 iVertices[iVIndices[i]+2]);
259   }
260   glEnd();
261 }
262
263 void GLRenderer::visitLineRep( LineRep& iLine) 
264 {
265   if(iLine.width() != 0)
266     glLineWidth(iLine.width());
267
268   switch(iLine.style())
269   {
270   case LineRep::LINES:
271     glBegin(GL_LINES);
272     break;
273   case LineRep::LINE_STRIP:
274     glBegin(GL_LINE_STRIP);
275     break;
276   case LineRep::LINE_LOOP:
277     glBegin(GL_LINE_LOOP);
278     break;
279   default:
280     return;
281   }
282
283  const vector<Vec3r>& vertices = iLine.vertices();
284   float step=1.f/vertices.size();
285   vector<Vec3r>::const_iterator v;
286
287   for(v=vertices.begin(); v!=vertices.end(); v++)
288     glVertex3r((*v)[0], (*v)[1], (*v)[2]);
289
290   glEnd();
291 }
292
293
294 void GLRenderer::visitTriangleRep( TriangleRep& iTriangle) 
295 {
296   glPushAttrib(GL_ALL_ATTRIB_BITS);
297   switch(iTriangle.style())
298   {
299   case TriangleRep::FILL:
300     glPolygonMode(GL_FRONT, GL_FILL);
301     break;
302   case TriangleRep::LINES:
303     glPolygonMode(GL_FRONT, GL_LINES);
304     break;
305   default:
306     return;
307   }
308
309   glBegin(GL_TRIANGLES);
310   for(int i=0; i<3; ++i)
311   {
312     glColor3f(iTriangle.color(i)[0], iTriangle.color(i)[1], iTriangle.color(i)[2]);
313     glVertex3r(iTriangle.vertex(i)[0], iTriangle.vertex(i)[1], iTriangle.vertex(i)[2]);
314   }
315
316   glEnd();
317
318
319
320   glPopAttrib();
321
322 }
323
324 void GLRenderer::visitOrientedLineRep(OrientedLineRep& iLine) 
325 {
326   switch(iLine.style())
327   {
328   case LineRep::LINES:
329     glBegin(GL_LINES);
330     break;
331   case LineRep::LINE_STRIP:
332     glBegin(GL_LINE_STRIP);
333     break;
334   case LineRep::LINE_LOOP:
335     glBegin(GL_LINE_LOOP);
336     break;
337   default:
338     return;
339   }
340
341   int i=0;
342   int ncolor = iLine.getId().getFirst()%3;
343   
344   const vector<Vec3r>& vertices = iLine.vertices();
345   float step=1.f/vertices.size();
346   vector<Vec3r>::const_iterator v;
347   for(v=vertices.begin(); v!=vertices.end(); v++)
348   {
349     switch(ncolor)
350     {
351     case 0:
352       glColor3f(i*step,0.f,0.f);
353       break;
354     case 1:
355       glColor3f(0.f, i*step, 0.f);
356       break;
357     case 2:
358       glColor3f(0.f, 0.f, i*step);
359       break;
360     default:
361       glColor3f(i*step, i*step,i*step);
362       break;
363     }
364     i++;
365     glVertex3r((*v)[0], (*v)[1], (*v)[2]);
366   }
367
368   glEnd();
369 }
370
371 void GLRenderer::visitVertexRep( VertexRep& iVertex) 
372 {
373   if(iVertex.pointSize() != 0.f)
374     glPointSize(iVertex.pointSize());
375   
376   glBegin(GL_POINTS);
377   glVertex3r(iVertex.x(), iVertex.y(), iVertex.z());
378   glEnd();
379 }
380
381 void GLRenderer::visitDrawingStyle(DrawingStyle& iDrawingStyle) 
382 {
383   
384   // Drawing Style management
385   switch(iDrawingStyle.style())
386   {
387   case DrawingStyle::FILLED:
388     glPolygonMode(GL_FRONT, GL_FILL);
389     glShadeModel(GL_SMOOTH);
390     break;
391
392   case DrawingStyle::LINES:
393     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
394     glEnable(GL_BLEND);
395     glEnable(GL_LINE_SMOOTH);
396     glPolygonMode(GL_FRONT, GL_LINE);
397     glLineWidth(iDrawingStyle.lineWidth());
398     break;
399
400   case DrawingStyle::POINTS:
401     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
402     glEnable(GL_BLEND);
403     glEnable(GL_POINT_SMOOTH);
404     glPolygonMode(GL_FRONT, GL_POINT);
405     glPointSize(iDrawingStyle.pointSize());
406     break;
407
408   case DrawingStyle::INVISIBLE:
409     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
410     glDepthMask(0);
411     break;
412
413   default:
414     break;
415   }
416
417   glLineWidth(iDrawingStyle.lineWidth());
418   glPointSize(iDrawingStyle.pointSize());
419
420   // FIXME
421   if(true == iDrawingStyle.lightingEnabled())
422     glEnable(GL_LIGHTING);
423   else
424     glDisable(GL_LIGHTING);
425 }
426
427 void GLRenderer::visitMaterial(Material& m) {
428   const float* diff = m.diffuse();
429   const float* amb = m.ambient();
430   const float* spec = m.specular();
431   const float* em = m.emission();
432
433   RenderColor(diff);
434   glMaterialfv(GL_FRONT, GL_AMBIENT, amb);
435   glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
436   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
437   glMaterialfv(GL_FRONT, GL_EMISSION, em);
438   glMaterialf(GL_FRONT, GL_SHININESS, m.shininess());
439 }
440
441 void GLRenderer::visitMaterial(const Material& m) {
442   const float* diff = m.diffuse();
443   const float* amb = m.ambient();
444   const float* spec = m.specular();
445   const float* em = m.emission();
446
447   RenderColor(diff);
448   glMaterialfv(GL_FRONT, GL_AMBIENT, amb);
449   glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
450   glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
451   glMaterialfv(GL_FRONT, GL_EMISSION, em);
452   glMaterialf(GL_FRONT, GL_SHININESS, m.shininess());
453 }
454 void GLRenderer::applyTransform( const Matrix44r &iMatrix)  
455 {
456   real m[16];
457   for(int lign=0; lign<4; lign++)
458     for(int column=0; column<4; column++)
459       m[column*4+lign] = iMatrix(lign, column);
460
461   glMultMatrixr(m);
462 }
463
464 void GLRenderer::RenderColor( const float *rgba)  
465 {
466   glColor4fv(rgba);
467