1 #include <iostream>
2 #include <sstream>
3 #include "bstm_ocl_render_tableau.h"
4 //:
5 // \file
6 #include "vpgl/vpgl_perspective_camera.h"
7 #include "vgui/vgui_modifier.h"
8 #include "vgui/vgui_utils.h"
9 #ifdef _MSC_VER
10 # include "vcl_msvc_warnings.h"
11 #endif
12
13 #include <bocl/bocl_device.h>
14 #include <bocl/bocl_kernel.h>
15
16 #include <boxm2/view/boxm2_view_utils.h>
17
18 #include <brdb/brdb_value.h>
19 #include <brdb/brdb_selection.h>
20
21 #include <bprb/bprb_batch_process_manager.h>
22 #include <bprb/bprb_parameters.h>
23 #include <bprb/bprb_macros.h>
24 #include <bprb/bprb_func_process.h>
25
26 //: Constructor
bstm_ocl_render_tableau()27 bstm_ocl_render_tableau::bstm_ocl_render_tableau()
28 {
29 pbuffer_=0;
30 ni_=640;
31 nj_=480;
32 DECLARE_FUNC_CONS(bstm_ocl_render_gl_expected_image_process);
33 DECLARE_FUNC_CONS(bstm_ocl_render_gl_expected_color_process);
34 REG_PROCESS_FUNC_CONS(bprb_func_process, bprb_batch_process_manager, bstm_ocl_render_gl_expected_image_process, "bstmOclRenderGlExpectedImageProcess");
35 REG_PROCESS_FUNC_CONS(bprb_func_process, bprb_batch_process_manager, bstm_ocl_render_gl_expected_color_process, "bstmOclRenderGlExpectedColorProcess");
36
37 REGISTER_DATATYPE(bstm_opencl_cache_sptr);
38 REGISTER_DATATYPE(bstm_scene_sptr);
39 REGISTER_DATATYPE(bocl_mem_sptr);
40 REGISTER_DATATYPE(float);
41 }
42
43 //: initialize tableau properties
init(bocl_device_sptr device,bstm_opencl_cache_sptr opencl_cache,bstm_scene_sptr scene,unsigned ni,unsigned nj,vpgl_perspective_camera<double> * cam,vgui_slider_tableau_sptr slider)44 bool bstm_ocl_render_tableau::init(bocl_device_sptr device,
45 bstm_opencl_cache_sptr opencl_cache,
46 bstm_scene_sptr scene,
47 unsigned ni,
48 unsigned nj,
49 vpgl_perspective_camera<double> * cam,vgui_slider_tableau_sptr slider)
50 {
51 //set image dimensions, camera and scene
52 ni_ = ni;
53 nj_ = nj;
54
55
56 cam_ = (*cam);
57 default_cam_ = (*cam);
58
59 default_stare_point_.set(scene->bounding_box().centroid().x(),
60 scene->bounding_box().centroid().y(),
61 scene->bounding_box().min_z());
62 stare_point_=default_stare_point_;
63 scale_ =scene->bounding_box().height();
64 //create the scene
65 scene_ = scene;
66 opencl_cache_=opencl_cache;
67 device_=device;
68 do_init_ocl=true;
69 render_trajectory_ = true;
70 render_label_ = false;
71 vgl_box_3d<double> bb= scene_->bounding_box();
72 bb.set_centroid_z(bb.centroid_z() - bb.depth()/4 );
73 trajectory_ = new boxm2_trajectory(20.0, 20, -1.0, bb, ni, nj);
74 cam_iter_ = trajectory_->begin();
75
76 //set bb for time
77 scene->bounding_box_t(scene_min_t_,scene_max_t_);
78
79 slider_ = slider;
80
81 return true;
82 }
83
84
85 //: Handles tableau events (drawing and keys)
handle(vgui_event const & e)86 bool bstm_ocl_render_tableau::handle(vgui_event const &e)
87 {
88
89 //toggle color - this is a hack to get color models to show as grey
90 if (e.type == vgui_KEY_PRESS) {
91 if (e.key == vgui_key('p')) {
92 //play...
93 }
94 if (e.key == vgui_key('l')) {
95 render_label_ = !render_label_;
96 }
97 }
98 else if (e.type == vgui_DRAW) //draw handler - called on post_draw()
99 {
100
101 if (do_init_ocl) {
102 this->init_clgl();
103 do_init_ocl = false;
104 }
105 float gpu_time = this->render_frame();
106 this->setup_gl_matrices();
107 glClear(GL_COLOR_BUFFER_BIT);
108 glDisable(GL_DEPTH_TEST);
109 glRasterPos2i(0, 1);
110 vgui_utils::set_glPixelZoom(1,-1);
111 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbuffer_);
112 glDrawPixels(ni_, nj_, GL_RGBA, GL_UNSIGNED_BYTE, 0);
113 glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
114
115 //calculate and write fps to status
116 std::stringstream str;
117 str<<". rendering at ~ "<< (1000.0f / gpu_time) <<" fps ";
118 if (status_) {
119 status_->write(str.str().c_str());
120 }
121 return true;
122 }
123
124 if (bstm_cam_tableau::handle(e))
125 return true;
126
127
128 return false;
129 }
130
131 //: calls on ray manager to render frame into the pbuffer_
render_frame()132 float bstm_ocl_render_tableau::render_frame()
133 {
134 cl_int status = clEnqueueAcquireGLObjects( queue_, 1,&exp_img_->buffer(), 0, 0, 0);
135 exp_img_->zero_gpu_buffer( queue_ );
136 if (!check_val(status,CL_SUCCESS,"clEnqueueAcquireGLObjects failed. (gl_image)"+error_to_string(status)))
137 return -1.0f;
138
139 double scaled_time = scene_min_t_ + time_ * (scene_max_t_ - scene_min_t_);
140
141 //set up brdb_value_sptr arguments...
142 brdb_value_sptr brdb_device = new brdb_value_t<bocl_device_sptr>(device_);
143 brdb_value_sptr brdb_scene = new brdb_value_t<bstm_scene_sptr>(scene_);
144 brdb_value_sptr brdb_opencl_cache = new brdb_value_t<bstm_opencl_cache_sptr>(opencl_cache_);
145 vpgl_camera_double_sptr cam = new vpgl_perspective_camera<double>(cam_);
146 brdb_value_sptr brdb_cam = new brdb_value_t<vpgl_camera_double_sptr>(cam);
147 brdb_value_sptr brdb_ni = new brdb_value_t<unsigned>(ni_);
148 brdb_value_sptr brdb_nj = new brdb_value_t<unsigned>(nj_);
149 brdb_value_sptr exp_img = new brdb_value_t<bocl_mem_sptr>(exp_img_);
150 brdb_value_sptr exp_img_dim = new brdb_value_t<bocl_mem_sptr>(exp_img_dim_);
151 brdb_value_sptr brdb_time = new brdb_value_t<float>(scaled_time);
152 brdb_value_sptr brdb_render_label = new brdb_value_t<bool>(render_label_);
153
154
155 //if scene has RGB data type, use color render process
156 bool good = true;
157 if(scene_->has_data_type(bstm_data_traits<BSTM_GAUSS_RGB>::prefix()) )
158 good = bprb_batch_process_manager::instance()->init_process("bstmOclRenderGlExpectedColorProcess");
159 else
160 good = bprb_batch_process_manager::instance()->init_process("bstmOclRenderGlExpectedImageProcess");
161
162 //set process args
163 good = good && bprb_batch_process_manager::instance()->set_input(0, brdb_device); // device
164 good = good && bprb_batch_process_manager::instance()->set_input(1, brdb_scene); // scene
165 good = good && bprb_batch_process_manager::instance()->set_input(2, brdb_opencl_cache);
166 good = good && bprb_batch_process_manager::instance()->set_input(3, brdb_cam);// camera
167 good = good && bprb_batch_process_manager::instance()->set_input(4, brdb_ni); // ni for rendered image
168 good = good && bprb_batch_process_manager::instance()->set_input(5, brdb_nj); // nj for rendered image
169 good = good && bprb_batch_process_manager::instance()->set_input(6, exp_img); // exp image ( gl buffer)
170 good = good && bprb_batch_process_manager::instance()->set_input(7, exp_img_dim); // exp image dimensions
171 good = good && bprb_batch_process_manager::instance()->set_input(8, brdb_time); // time
172 good = good && bprb_batch_process_manager::instance()->set_input(9, brdb_render_label); // render_label?
173 good = good && bprb_batch_process_manager::instance()->run_process();
174
175
176 //grab float output from render gl process
177 unsigned int time_id = 0;
178 good = good && bprb_batch_process_manager::instance()->commit_output(0, time_id);
179 brdb_query_aptr Q = brdb_query_comp_new("id", brdb_query::EQ, time_id);
180 brdb_selection_sptr S = DATABASE->select("float_data", std::move(Q));
181 if (S->size()!=1){
182 std::cout << "in bprb_batch_process_manager::set_input_from_db(.) -"
183 << " no selections\n";
184 }
185 brdb_value_sptr value;
186 if (!S->get_value(std::string("value"), value)) {
187 std::cout << "in bprb_batch_process_manager::set_input_from_db(.) -"
188 << " didn't get value\n";
189 }
190 float time = value->val<float>();
191
192 //release gl buffer
193 status = clEnqueueReleaseGLObjects(queue_, 1, &exp_img_->buffer(), 0, 0, 0);
194 clFinish( queue_ );
195
196 return time;
197 }
198
199 //: private helper method to init_clgl stuff (gpu processor)
init_clgl()200 bool bstm_ocl_render_tableau::init_clgl()
201 {
202 //get relevant blocks
203 std::cout<<"Data Path: "<<scene_->data_path()<<std::endl;
204 device_->context() = boxm2_view_utils::create_clgl_context(*(device_->device_id()));
205 opencl_cache_->set_context(device_->context());
206
207 int status_queue=0;
208 queue_ = clCreateCommandQueue(device_->context(),*(device_->device_id()),CL_QUEUE_PROFILING_ENABLE,&status_queue);
209
210 // delete old buffer
211 if (pbuffer_) {
212 clReleaseMemObject(clgl_buffer_);
213 glDeleteBuffers(1, &pbuffer_);
214 }
215
216 ////generate glBuffer, and bind to ray_mgr->image_gl_buf_
217 glGenBuffers(1, &pbuffer_);
218 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbuffer_);
219 glBufferData(GL_PIXEL_UNPACK_BUFFER, ni_*nj_*sizeof(GLubyte)*4, 0, GL_STREAM_DRAW);
220 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
221
222 //create OpenCL buffer from GL PBO, and set kernel and arguments
223 int status = 0;
224 clgl_buffer_ = clCreateFromGLBuffer(device_->context(),
225 CL_MEM_WRITE_ONLY,
226 pbuffer_,
227 &status);
228 exp_img_ = new bocl_mem(device_->context(), NULL, RoundUp(ni_,8)*RoundUp(nj_,8)*sizeof(GLubyte)*4, "exp image (gl) buffer");
229 exp_img_->set_gl_buffer(clgl_buffer_);
230
231 int img_dim_buff[4];
232 img_dim_buff[0] = 0; img_dim_buff[2] = ni_;
233 img_dim_buff[1] = 0; img_dim_buff[3] = nj_;
234 exp_img_dim_=new bocl_mem(device_->context(), img_dim_buff, sizeof(int)*4, "image dims");
235 exp_img_dim_->create_buffer(CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR);
236 return true;
237 }
238