* Make sure freestyle branch compiles with SCons/msvc9 on Windows. This was joint...
[blender.git] / source / blender / freestyle / intern / app_blender / AppCanvas.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
23 #ifdef WIN32
24 # include <GL/glew.h>
25 # include <windows.h>
26 #endif
27 #ifdef __MACH__
28 # include <OpenGL/gl.h>
29 #else
30 # include <GL/gl.h>
31 #endif
32
33 #include "AppGLWidget.h"
34 #include "../image/Image.h"
35 #include "../system/TimeStamp.h"
36 #include "Controller.h"
37 #include "../stroke/StrokeRenderer.h"
38 #include "AppCanvas.h"
39 #include "../rendering/GLRenderer.h"
40 #include "../rendering/GLStrokeRenderer.h"
41 #include "../rendering/GLUtils.h"
42 #include "AppConfig.h"
43
44 #include "../system/StringUtils.h"
45
46 AppCanvas::AppCanvas()
47 :Canvas()
48 {
49   _pViewer = 0;
50   _blendEquation = true;
51         _MapsPath = StringUtils::toAscii( Config::Path::getInstance()->getMapsDir() ).c_str();
52 }
53
54 AppCanvas::AppCanvas(AppGLWidget* iViewer)
55 :Canvas()
56 {
57   _pViewer = iViewer;
58   _blendEquation = true;
59 }
60
61 AppCanvas::AppCanvas(const AppCanvas& iBrother)
62 :Canvas(iBrother)
63 {
64   _pViewer = iBrother._pViewer;
65   _blendEquation = iBrother._blendEquation;
66 }
67
68 AppCanvas::~AppCanvas()
69 {
70   _pViewer = 0;
71 }
72
73 void AppCanvas::setViewer(AppGLWidget *iViewer)
74 {
75   _pViewer = iViewer;
76 }  
77
78 int AppCanvas::width() const 
79 {
80   return _pViewer->width();
81 }
82
83 int AppCanvas::height() const
84 {
85   return _pViewer->height();
86 }
87
88 BBox<Vec3r> AppCanvas::scene3DBBox() const 
89 {
90   return _pViewer->scene3DBBox();
91 }
92
93 void AppCanvas::preDraw()
94 {
95   Canvas::preDraw();
96
97   _pViewer->prepareCanvas();
98   glClearColor(0,0,0,0);
99         glClear(GL_COLOR_BUFFER_BIT);
100         glDisable(GL_LIGHTING);
101         glPolygonMode(GL_FRONT, GL_FILL);
102         glShadeModel(GL_SMOOTH);
103         glDisable(GL_DEPTH_TEST);
104         glEnable(GL_TEXTURE_2D);
105   glEnable(GL_BLEND);
106 }
107
108 void AppCanvas::init() 
109 {
110 #ifdef WIN32
111   static bool firsttime = true;
112   if (firsttime) {
113
114         GLenum err = glewInit();
115         if (GLEW_OK != err)
116         {
117                 cerr << "Error: problem occurred while initializing GLEW" << endl;      
118         }
119         cout << "GLEW initialized" << endl;
120
121         if(!glBlendEquation) {
122         _blendEquation = false;
123         cout << "glBlendEquation unavailable on this hardware -> switching to strokes basic rendering mode" << endl;
124      }
125     firsttime=false;
126    }
127 #endif
128
129   _Renderer = new GLStrokeRenderer;
130   if(!StrokeRenderer::loadTextures())
131     {
132       cerr << "unable to load stroke textures" << endl;
133       return;
134     }
135 }
136
137 void AppCanvas::postDraw()
138 {
139   //inverse frame buffer
140   glDisable(GL_TEXTURE_2D);
141   glDisable(GL_BLEND);
142   _pViewer->releaseCanvas();
143
144   Canvas::postDraw();
145 }
146
147 void AppCanvas::Erase()
148 {
149   Canvas::Erase();
150   //_pViewer->clear();
151 }
152
153 #include "../image/GaussianFilter.h"
154 void AppCanvas::readColorPixels(int x,int y,int w, int h, RGBImage& oImage) const
155 {
156   //static unsigned number = 0;
157   float *rgb = new float[3*w*h];
158   _pViewer->readPixels(x,y,w,h,AppGLWidget::RGB,rgb);
159   oImage.setArray(rgb, width(), height(), w,h, x, y, false);
160   // FIXME
161   //  QImage qtmp(w, h, 32);
162   //  for(unsigned py=0;py<h;++py){
163   //    for(unsigned px=0;px<w;++px){
164   //      int r = (int)255*(oImage.getR(x+px,y+py));
165   //      int g = (int)255*(oImage.getG(x+px,y+py));
166   //      int b = (int)255*(oImage.getB(x+px,y+py));
167   //      qtmp.setPixel(px,py,qRgb(r,g,b));
168   //    }
169   //  }
170   //  qtmp.save("densityQuery"+QString::number(number)+".png", "PNG");
171   //  if(number == 1090){
172   //    RGBImage img;
173   //    float *rgbtmp = new float[3*width()*height()];
174   //    _pViewer->readPixels(0,0,width(),height(),AppGLWidget::RGB,rgbtmp);
175   //    img.setArray(rgbtmp, width(), height(), width(), height(), 0, 0, false);
176   //    QImage qtmp(width(), height(), 32);
177   //    for(unsigned py=0;py<height();++py){
178   //      for(unsigned px=0;px<width();++px){
179   //        int r = (int)255*(img.getR(px,py));
180   //        int g = (int)255*(img.getG(px,py));
181   //        int b = (int)255*(img.getB(px,py));
182   //        qtmp.setPixel(px,height()-1-py,qRgb(r,g,b));
183   //      }
184   //    }
185   //    qtmp.save("densityQuery"+QString::number(number)+".png", "PNG");
186   //    
187   //    GaussianFilter filter;
188   //    filter.setSigma(4.0);
189   //    int bound = filter.getBound();
190   //    QImage qtmp2(width(), height(), 32);
191   //    for(int py2=0;py2<height();++py2){
192   //      for(int px2=0;px2<width();++px2){  
193   //        if( (px2-bound < 0) || (px2+bound>width())
194   //          || (py2-bound < 0) || (py2+bound>height()))
195   //          continue;
196   //        int g = 255*filter.getSmoothedPixel<RGBImage>(&img, px2,py2);
197   //        qtmp2.setPixel(px2,height()-1-py2,qRgb(g,g,g));
198   //      }
199   //    }
200   //    qtmp2.save("blurredCausalDensity"+QString::number(number)+".png", "PNG");
201   //  }
202   //  cout << number << endl;
203   //  ++number;
204 }
205
206 void AppCanvas::readDepthPixels(int x,int y,int w, int h, GrayImage& oImage) const
207 {
208   float *rgb = new float[w*h];
209   _pViewer->readPixels(x,y,w,h,AppGLWidget::DEPTH,rgb);
210   oImage.setArray(rgb, width(), height(), w,h, x, y, false);
211 }
212
213 void AppCanvas::update()
214 {
215 //  static int counter = 0;
216 //  char fileName[100] = "framebuffer";
217 //  char number[10];
218 //
219   _pViewer->updateGL();
220   //_pViewer->swapBuffers();
221   //QImage fb = _pViewer->grabFrameBuffer();
222   //  sprintf(number, "%3d", counter);
223   //  strcat(fileName, number);
224   //  strcat(fileName, ".bmp");
225   //  fb.save(fileName, "BMP");
226   //counter++;
227 }
228
229 void AppCanvas::Render(const StrokeRenderer *iRenderer)
230 {
231   if(!_blendEquation){
232     RenderBasic(iRenderer);
233     return;
234   }
235
236   glClearColor(1,1,1,1);
237   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
238   glDisable(GL_LIGHTING);
239   glPolygonMode(GL_FRONT, GL_FILL);
240   glShadeModel(GL_SMOOTH);
241   
242   if(_pViewer->draw3DsceneEnabled())
243   {
244     glClearColor(1,1,1,0);
245     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
246     glMatrixMode(GL_PROJECTION);
247     glPushMatrix();
248     glMatrixMode(GL_MODELVIEW);
249     glPushMatrix();
250     
251     glEnable(GL_LIGHTING);
252     glEnable(GL_DEPTH_TEST);
253     _pViewer->set3DContext();
254     _pViewer->DrawScene(_pViewer->glRenderer());
255     glDisable(GL_DEPTH_TEST);
256     glDisable(GL_LIGHTING);
257     glMatrixMode(GL_PROJECTION);
258     glPopMatrix();
259     glMatrixMode(GL_MODELVIEW);
260     glPopMatrix();
261   }
262   
263   
264   glDisable(GL_DEPTH_TEST);
265   glBlendEquation(GL_ADD);
266   
267   glBlendFunc(GL_DST_COLOR, GL_ZERO);
268   
269   if(_drawPaper)
270   {
271     glEnable(GL_BLEND);
272     glEnable(GL_TEXTURE_2D);
273     float zfar = _pViewer->zfar();
274     zfar = zfar+0.1*zfar;
275     //draw background paper // FIXME
276     //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
277     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
278     glBindTexture(GL_TEXTURE_2D, StrokeRenderer::_textureManager->getPaperTextureIndex(_paperTextureIndex)); 
279     glColor4f(1,1,1,0.0);
280     glBegin(GL_TRIANGLE_STRIP);
281     { 
282       glTexCoord2f(0,0); glVertex3f(0, 0, -1);
283       glTexCoord2f(4,0); glVertex3f(2048, 0, -1);
284       glTexCoord2f(0,4); glVertex3f(0, 2048, -1);
285       glTexCoord2f(4,4); glVertex3f(2048, 2048, -1);
286     } 
287     glEnd();
288   }
289   
290   glPushAttrib(GL_COLOR_BUFFER_BIT);
291   glBlendEquation(GL_FUNC_SUBTRACT);
292   glBlendFunc(GL_ONE, GL_ONE);
293   
294   glDisable(GL_TEXTURE_2D);
295   glEnable(GL_BLEND);
296   glColor4f(1,1,1,1);
297   glBegin(GL_TRIANGLE_STRIP);
298   {  
299     glVertex2f(0, 0);
300     glVertex2f(2048, 0);
301     glVertex2f(0, 2048);
302     glVertex2f(2048, 2048);
303   }  
304   glEnd();
305   glPopAttrib();
306   
307   glDisable(GL_DEPTH_TEST);
308   glBlendEquation(GL_ADD);
309   glBlendFunc(GL_SRC_ALPHA, GL_ONE);
310   
311   glEnable(GL_TEXTURE_2D);
312
313   Canvas::Render(iRenderer);
314   //  
315   glPushAttrib(GL_COLOR_BUFFER_BIT);
316   glBlendEquation(GL_FUNC_SUBTRACT);
317   glBlendFunc(GL_ONE, GL_ONE);
318   
319   glDisable(GL_TEXTURE_2D);
320   glEnable(GL_BLEND);
321   glColor3f(1,1,1);
322   glBegin(GL_TRIANGLE_STRIP);
323   { 
324     glVertex2f(0, 0);
325     glVertex2f(2048, 0);
326     glVertex2f(0, 2048);
327     glVertex2f(2048, 2048);
328   } 
329   glEnd();
330   glPopAttrib();
331   
332   glDisable(GL_TEXTURE_2D);
333   glDisable(GL_BLEND);
334 }
335
336 void AppCanvas::RenderBasic(const StrokeRenderer *iRenderer)
337 {
338   glClearColor(1,1,1,1);
339   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
340   glDisable(GL_LIGHTING);
341   glPolygonMode(GL_FRONT, GL_FILL);
342   glShadeModel(GL_SMOOTH);
343   
344   if(_pViewer->draw3DsceneEnabled())
345   {
346     glClearColor(1,1,1,0);
347     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
348     glMatrixMode(GL_PROJECTION);
349     glPushMatrix();
350     glMatrixMode(GL_MODELVIEW);
351     glPushMatrix();
352     
353     glEnable(GL_LIGHTING);
354     glEnable(GL_DEPTH_TEST);
355     _pViewer->set3DContext();
356     _pViewer->DrawScene(_pViewer->glRenderer());
357     glDisable(GL_DEPTH_TEST);
358     glDisable(GL_LIGHTING);
359     glMatrixMode(GL_PROJECTION);
360     glPopMatrix();
361     glMatrixMode(GL_MODELVIEW);
362     glPopMatrix();
363   }
364
365   glBlendFunc(GL_DST_COLOR, GL_ZERO);
366   if(_drawPaper)
367   {
368     glEnable(GL_BLEND);
369     glEnable(GL_TEXTURE_2D);
370     float zfar = _pViewer->zfar();
371     zfar = zfar+0.1*zfar;
372     //draw background paper // FIXME
373     //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
374     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
375     glBindTexture(GL_TEXTURE_2D, StrokeRenderer::_textureManager->getPaperTextureIndex(_paperTextureIndex)); 
376     glColor4f(1,1,1,0.0);
377     glBegin(GL_TRIANGLE_STRIP);
378     { 
379       glTexCoord2f(0,0); glVertex3f(0, 0, -1);
380       glTexCoord2f(4,0); glVertex3f(2048, 0, -1);
381       glTexCoord2f(0,4); glVertex3f(0, 2048, -1);
382       glTexCoord2f(4,4); glVertex3f(2048, 2048, -1);
383     } 
384     glEnd();
385   }
386
387   glDisable(GL_DEPTH_TEST);
388   glPushAttrib(GL_COLOR_BUFFER_BIT);
389   glEnable(GL_BLEND);
390   glPopAttrib();
391
392   glDisable(GL_DEPTH_TEST);
393   glBlendFunc(GL_SRC_ALPHA, GL_ONE);
394   
395   glEnable(GL_TEXTURE_2D);
396   Canvas::RenderBasic(iRenderer);
397
398   glDisable(GL_TEXTURE_2D);
399   glDisable(GL_BLEND);
400 }
401
402
403 void AppCanvas::RenderStroke(Stroke *iStroke) {
404   iStroke->Render(_Renderer);
405   if(_pViewer->getRecordFlag()){
406     //Sleep(1000);
407      _pViewer->saveSnapshot(true);
408   }
409 }