soc-2008-mxcurioni: merged changes to revision 15441
[blender-staging.git] / source / blender / freestyle / intern / app_blender / api.cpp
1 #include "AppGLWidget.h"
2 #include "Controller.h"
3 #include "AppConfig.h"
4
5 #include <iostream>
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11 #include "DNA_camera_types.h"
12
13 #include "render_types.h"
14 #include "renderpipeline.h"
15
16 #include "BLI_blenlib.h"
17 #include "BPY_extern.h"
18
19 #ifdef __cplusplus
20 }
21 #endif
22
23 using namespace std;
24
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28
29         static Config::Path *pathconfig = NULL;
30         static Controller *controller = NULL;
31         static AppGLWidget *view = NULL;
32
33         
34         void FRS_initialize(){
35                 
36                 if( pathconfig == NULL )
37                         pathconfig = new Config::Path;
38                 
39                 if( controller == NULL )
40                         controller = new Controller;
41                 
42                 if( view == NULL )
43                         view = new AppGLWidget;
44                 
45                 controller->SetView(view);
46         }
47
48
49         void FRS_init_view(Render* re){
50                 view->setWidth( re->winx );
51                 view->setHeight( re->winy );
52                 view->_camera->setScreenWidthAndHeight( re->winx, re->winy);
53         }
54
55         void FRS_init_camera(Render* re){
56                 Object* maincam_obj = re->scene->camera;
57                 Camera *cam = (Camera*) maincam_obj->data;
58
59                 if(cam->type == CAM_PERSP){
60                         view->_camera->setType(AppGLWidget_Camera::PERSPECTIVE);
61                         view->_camera->setHorizontalFieldOfView( M_PI / 180.0f * cam->angle );
62                 }
63                 // else if (cam->type == CAM_ORTHO){
64                 //      view->_camera->setType(AppGLWidget_Camera::ORTHOGRAPHIC);
65                 //      // view->_camera->setFocusDistance does not seem to work
66                 //      // integrate cam->ortho_scale parameter
67                 // }
68                 
69                 Vec camPosition(maincam_obj->obmat[3][0], maincam_obj->obmat[3][1], maincam_obj->obmat[3][2]);
70                 Vec camUp( re->viewmat[0][1], re->viewmat[1][1], re->viewmat[2][1]);
71                 Vec camDirection( -re->viewmat[0][2], -re->viewmat[1][2], -re->viewmat[2][2]);
72                 view->_camera->setPosition(camPosition);
73                 view->_camera->setUpVector(camUp);      
74                 view->_camera->setViewDirection(camDirection);
75         }
76         
77         void FRS_scene_3ds_export(Render* re) {
78                 // export scene to 3ds format
79                 string script_3ds_export =      pathconfig->getProjectDir() + 
80                                                                         Config::DIR_SEP + "python" + 
81                                                                         Config::DIR_SEP + "3ds_export.py";
82                 BPY_run_python_script( const_cast<char *>(script_3ds_export.c_str()) );
83                 
84                 // load 3ds scene
85                 char btempdir[255];
86                 BLI_where_is_temp(btempdir,1);
87                 string exported_3ds_file =  btempdir;
88                 exported_3ds_file += Config::DIR_SEP + "tmp_scene_freestyle.3ds";
89                 if( BLI_exists( const_cast<char *>(exported_3ds_file.c_str()) ) ) {
90                         controller->Load3DSFile( exported_3ds_file.c_str() );
91                 }
92                 else {
93                         cout << "Cannot find" << exported_3ds_file << endl;
94                         return;
95                 }
96         }
97         
98         void FRS_prepare(Render* re) {
99                 FRS_initialize();
100                 
101                 FRS_init_view(re);
102                 FRS_init_camera(re);
103                 
104                 FRS_scene_3ds_export(re);
105         }
106
107         void FRS_render(Render* re, int render_in_layer) {
108                 
109                 if(render_in_layer) {
110                         view->workingBuffer = GL_COLOR_ATTACHMENT0_EXT;
111                 } else {
112                         view->workingBuffer = GL_BACK;
113                 }
114                 
115                 // add style module
116                 string style_module = pathconfig->getProjectDir() + 
117                                                                 Config::DIR_SEP + "style_modules" + 
118                                                                 Config::DIR_SEP + "contour.py";
119                 controller->InsertStyleModule( 0, const_cast<char *>(style_module.c_str())       );
120                 controller->toggleLayer(0, true);
121                 
122                 // compute view map
123                 controller->ComputeViewMap();
124                 
125                 // build strokes
126                 controller->DrawStrokes(); 
127                 
128                 // render final result
129                 view->draw(); 
130         }
131
132         void FRS_execute(Render* re, int render_in_layer) {
133                 
134                 GLuint framebuffer, renderbuffers[2];
135                 GLenum status;
136                 RenderLayer *rl;
137                 
138                 if(render_in_layer) {
139                         cout << "Freestyle as a render layer - SETUP" << endl;
140                 
141                         // set up frame buffer
142                         glGenFramebuffersEXT(1, &framebuffer);
143                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
144
145                         // set up render buffer: one color buffer, one depth buffer
146                         glGenRenderbuffersEXT(2, renderbuffers);
147                         
148                         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,      renderbuffers[0]);
149                         glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, re->winx, re->winy);
150                         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, renderbuffers[0]);
151                         
152                         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffers[1]);
153                         glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, re->winx, re->winy);
154                         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbuffers[1]);
155
156                         // status verification 
157                         status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
158                         if (status != GL_FRAMEBUFFER_COMPLETE_EXT){
159                                 cout << "Framebuffer setup error" << endl;
160                                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
161                                 glDeleteRenderbuffersEXT(2, renderbuffers);
162                                 glDeleteFramebuffersEXT(1, &framebuffer);
163                                 return;
164                         }
165                         
166                         glPushAttrib(GL_VIEWPORT_BIT); 
167                         glViewport(0, 0, re->winx, re->winy);
168                         glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // really needed ?
169                 }
170                 
171                 FRS_render(re, render_in_layer);
172                 
173                 if(render_in_layer) {
174                         for(rl = (RenderLayer *)re->result->layers.first; rl; rl= rl->next) {
175                                 if(rl->layflag & SCE_LAY_FRS) {
176                                         cout << "Freestyle as a render layer - RESULT" << endl;
177                                         
178                                         // transfer render to layer
179                                         glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
180                                         glReadPixels(0, 0, re->winx, re->winy, GL_RGBA, GL_FLOAT, rl->rectf );
181
182                                         // bind window
183                                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
184                                         glDrawBuffer(GL_BACK);
185                                         glPopAttrib();
186                                         glDeleteRenderbuffersEXT(2, renderbuffers);
187                                         glDeleteFramebuffersEXT(1, &framebuffer);
188                                 }
189                         }
190                 } else {
191                         // copy result into render window
192                         RenderResult rres;
193                         RE_GetResultImage(re, &rres);
194                         view->readPixels(0, 0, re->winx, re->winy, AppGLWidget::RGBA, rres.rectf );             
195                         re->result->renlay = render_get_active_layer(re, re->result);
196                         re->display_draw(re->result, NULL);
197                 }
198                 
199                 controller->CloseFile();
200         }
201         
202 #ifdef __cplusplus
203 }
204 #endif