1 // OGL_PLANE.CPP
2
3 // Copyright (C) 1998 Tommi Hassinen.
4
5 // This package is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9
10 // This package is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with this package; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 /*################################################################################################*/
20
21 #include "ogl_plane.h" // config.h is here -> we get ENABLE-macros here...
22
23 #ifdef WIN32
24 #include <windows.h> // need to have this before GL stuff...
25 #endif // WIN32
26
27 #include <GL/gl.h>
28
29 #include <cstring>
30 #include <fstream>
31 #include <sstream>
32 using namespace std;
33
34 #include <oglappth/base_app.h>
35
36 #include "project.h"
37 #include "appdefine.h"
38
39 /*################################################################################################*/
40
ogl_color_plane(ogl_cp_param & p1)41 ogl_color_plane::ogl_color_plane(ogl_cp_param & p1)
42 {
43 prj = p1.prj;
44 data = p1.data;
45
46 my_glname = p1.my_glname;
47
48 transparent = p1.transparent;
49 automatic_cv2 = p1.automatic_cv2;
50
51 np = p1.np;
52
53 // now we can allocate memory...
54
55 dist = new fGL[np];
56
57 color4 = new fGL[np * np * 4];
58 point3 = new fGL[np * np * 3];
59
60 // we must do these settings...
61 // we must do these settings...
62 // we must do these settings...
63
64 ref = p1.ref;
65 GetValue = p1.vf;
66 GetColor = p1.cf;
67
68 cvalue1 = p1.cvalue1;
69 cvalue2 = p1.cvalue2;
70 alpha = p1.alpha;
71
72 // ...before trying to do this!!!
73 // ...before trying to do this!!!
74 // ...before trying to do this!!!
75
76 SetDimension(p1.dim);
77 Update();
78
79 // add the primitives, if this is a transparent object...
80 // add the primitives, if this is a transparent object...
81 // add the primitives, if this is a transparent object...
82
83 base_app * app = base_app::GetAppB();
84
85 if (transparent)
86 {
87 for (i32s n1 = 0;n1 < np - 1;n1++)
88 {
89 for (i32s n2 = 0;n2 < np - 1;n2++)
90 {
91 i32s tmp1, tmp2, tmp3;
92
93 tmp1 = n1 + 0; tmp2 = n2 + 0; tmp3 = tmp1 * np + tmp2;
94 fGL * c1 = & color4[tmp3 * 4]; fGL * p1 = & point3[tmp3 * 3];
95
96 tmp1 = n1 + 1; tmp2 = n2 + 0; tmp3 = tmp1 * np + tmp2;
97 fGL * c2 = & color4[tmp3 * 4]; fGL * p2 = & point3[tmp3 * 3];
98
99 tmp1 = n1 + 1; tmp2 = n2 + 1; tmp3 = tmp1 * np + tmp2;
100 fGL * c3 = & color4[tmp3 * 4]; fGL * p3 = & point3[tmp3 * 3];
101
102 tmp1 = n1 + 0; tmp2 = n2 + 1; tmp3 = tmp1 * np + tmp2;
103 fGL * c4 = & color4[tmp3 * 4]; fGL * p4 = & point3[tmp3 * 3];
104
105 tpd_quad_4c * tmp4;
106 tmp4 = new tpd_quad_4c(c1, p1, c2, p2, c3, p3, c4, p4);
107
108 transparent_primitive * tmp5;
109 tmp5 = new transparent_primitive((void *) this, * tmp4);
110
111 app->AddTP((void *) this, (* tmp5));
112
113 // tmp4, the tpd_quad_4c-object, will be deleted when
114 // prj->RemoveAllTPs() is called for this object...
115
116 delete tmp5;
117 }
118 }
119 }
120 }
121
~ogl_color_plane(void)122 ogl_color_plane::~ogl_color_plane(void)
123 {
124 if (transparent) base_app::GetAppB()->RemoveAllTPs((void *) this);
125
126 delete[] dist;
127
128 delete[] color4;
129 delete[] point3;
130 }
131
Update(void)132 void ogl_color_plane::Update(void)
133 {
134 xdir = data->ydir.vpr(data->zdir);
135
136 i32s tmp1[2]; // point indices...
137 fGL * tmp2 = new fGL[np * np]; // color values...
138
139 for (tmp1[0] = 0;tmp1[0] < np;tmp1[0]++)
140 {
141 for (tmp1[1] = 0;tmp1[1] < np;tmp1[1]++)
142 {
143 i32s index = tmp1[0] * np + tmp1[1];
144 GetCRD(tmp1, & point3[index * 3]);
145
146 tmp2[tmp1[0] * np + tmp1[1]] = GetValue(ref, & point3[index * 3], NULL);
147 }
148 }
149
150 if (automatic_cv2)
151 {
152 f64 avrg = 0.0;
153 for (i32s n1 = 0;n1 < np * np;n1++)
154 {
155 avrg += tmp2[n1];
156 }
157
158 // AUTO makes only partial correction -> just looks better and one can estimate the "bias".
159 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
160
161 cvalue2 = -0.80 * avrg / (f64) (np * np);
162 }
163
164 for (tmp1[0] = 0;tmp1[0] < np;tmp1[0]++)
165 {
166 for (tmp1[1] = 0;tmp1[1] < np;tmp1[1]++)
167 {
168 i32s index = tmp1[0] * np + tmp1[1];
169 fGL tmp3 = tmp2[tmp1[0] * np + tmp1[1]] + cvalue2;
170 GetColor((tmp3 / cvalue1), alpha, & color4[index * 4]);
171 }
172 }
173
174 delete[] tmp2;
175
176 // update the primitives, if this is a transparent object...
177 // update the primitives, if this is a transparent object...
178 // update the primitives, if this is a transparent object...
179
180 if (transparent) base_app::GetAppB()->UpdateMPsForAllTPs((void *) this);
181 }
182
Render(void)183 void ogl_color_plane::Render(void)
184 {
185 glPushMatrix();
186
187 glPushName(GLNAME_OBJECT);
188 glPushName(my_glname);
189
190 // if this is a transparent object, we will not render the quads here.
191 // instead, the quads get rendered at project::Render(), like all other
192 // transparent primitives.
193
194 if (!transparent)
195 {
196 glBegin(GL_QUADS);
197
198 for (i32s n1 = 0;n1 < np - 1;n1++)
199 {
200 for (i32s n2 = 0;n2 < np - 1;n2++)
201 {
202 i32s tmp1, tmp2, tmp3;
203
204 tmp1 = n1 + 0; tmp2 = n2 + 0; tmp3 = tmp1 * np + tmp2;
205 glColor4fv(& color4[tmp3 * 4]); glVertex3fv(& point3[tmp3 * 3]);
206
207 tmp1 = n1 + 1; tmp2 = n2 + 0; tmp3 = tmp1 * np + tmp2;
208 glColor4fv(& color4[tmp3 * 4]); glVertex3fv(& point3[tmp3 * 3]);
209
210 tmp1 = n1 + 1; tmp2 = n2 + 1; tmp3 = tmp1 * np + tmp2;
211 glColor4fv(& color4[tmp3 * 4]); glVertex3fv(& point3[tmp3 * 3]);
212
213 tmp1 = n1 + 0; tmp2 = n2 + 1; tmp3 = tmp1 * np + tmp2;
214 glColor4fv(& color4[tmp3 * 4]); glVertex3fv(& point3[tmp3 * 3]);
215 }
216 }
217
218 glEnd();
219 }
220
221 SetModelView(data);
222
223 fGL tmp1 = -0.55 * dim;
224 fGL tmp2 = -0.45 * dim;
225
226 glBegin(GL_LINES);
227 glColor3f(1.0, 1.0, 1.0); glVertex3f(tmp1, tmp1, 0.0);
228 glColor3f(0.0, 0.0, 1.0); glVertex3f(tmp2, tmp1, 0.0);
229
230 glColor3f(1.0, 1.0, 1.0); glVertex3f(tmp1, tmp1, 0.0);
231 glColor3f(0.0, 0.0, 1.0); glVertex3f(tmp1, tmp2, 0.0);
232
233 glColor3f(1.0, 1.0, 1.0); glVertex3f(tmp1, tmp1, 0.0);
234 glColor3f(0.0, 0.0, 1.0); glVertex3f(tmp1, tmp1, 0.1 * dim);
235 glEnd();
236
237 glPopName();
238 glPopName();
239
240 glPopMatrix();
241 }
242
SetDimension(fGL p1)243 void ogl_color_plane::SetDimension(fGL p1)
244 {
245 dim = p1; fGL tmp1 = np - 1;
246 for (i32s n1 = 0;n1 < np;n1++)
247 {
248 fGL tmp2 = (fGL) n1 / tmp1;
249 dist[n1] = dim * (tmp2 - 0.5);
250 }
251 }
252
GetCRD(i32s * p1,fGL * p2)253 void ogl_color_plane::GetCRD(i32s * p1, fGL * p2)
254 {
255 for (i32s n1 = 0;n1 < 3;n1++)
256 {
257 fGL tmp1 = xdir[n1] * dist[p1[0]];
258 fGL tmp2 = data->ydir[n1] * dist[p1[1]];
259 p2[n1] = data->crd[n1] + tmp1 + tmp2;
260 }
261 }
262
263 /*################################################################################################*/
264
ogl_color_plane_object(const ogl_object_location & p1,ogl_cp_param & p2,const char * p3)265 ogl_color_plane_object::ogl_color_plane_object(const ogl_object_location & p1, ogl_cp_param & p2, const char * p3) :
266 ogl_smart_object(p1)
267 {
268 p2.data = GetSafeLD();
269 p2.my_glname = base_app::GetAppB()->RegisterGLName((ogl_dummy_object *) this);
270
271 cp = new ogl_color_plane(p2);
272
273 ostringstream str;
274 str << p3 << "plane" << ends;
275
276 object_name = new char[strlen(str.str().c_str()) + 1];
277 strcpy(object_name, str.str().c_str());
278
279 copy_of_ref = p2.ref;
280 }
281
~ogl_color_plane_object(void)282 ogl_color_plane_object::~ogl_color_plane_object(void)
283 {
284 delete cp;
285 delete[] object_name;
286
287 // TODO : unregister my_glname???
288 }
289
OrbitObject(const fGL * p1,const ogl_camera & p2)290 void ogl_color_plane_object::OrbitObject(const fGL * p1, const ogl_camera & p2)
291 {
292 ogl_dummy_object::RotateObject(p1, p2);
293 Update();
294 }
295
RotateObject(const fGL * p1,const ogl_camera & p2)296 void ogl_color_plane_object::RotateObject(const fGL * p1, const ogl_camera & p2)
297 {
298 ogl_dummy_object::OrbitObject(p1, p2);
299 Update();
300 }
301
TranslateObject(const fGL * p1,const ogl_obj_loc_data * p2)302 void ogl_color_plane_object::TranslateObject(const fGL * p1, const ogl_obj_loc_data * p2)
303 {
304 fGL tmp1[3] = { p1[0], p1[1], p1[2] };
305
306 if (p2 == GetSafeLD())
307 {
308 tmp1[0] = -tmp1[0];
309 tmp1[2] = -tmp1[2];
310 }
311
312 ogl_dummy_object::TranslateObject(tmp1, p2);
313 Update();
314 }
315
316 /*################################################################################################*/
317
ogl_volume_rendering_object(const ogl_object_location & p1,ogl_cp_param & p2,i32s p3,fGL p4,ogl_camera & p5,const char * p6)318 ogl_volume_rendering_object::ogl_volume_rendering_object(const ogl_object_location & p1, ogl_cp_param & p2, i32s p3, fGL p4, ogl_camera & p5, const char * p6) :
319 ogl_smart_object(p1)
320 {
321 for (i32s n1 = 0;n1 < p3;n1++)
322 {
323 data_vector.push_back(new ogl_obj_loc_data);
324
325 p2.data = data_vector.back();
326 p2.my_glname = base_app::GetAppB()->RegisterGLName((ogl_dummy_object *) this);
327
328 cp_vector.push_back(new ogl_color_plane(p2));
329 }
330
331 thickness = p4;
332 ConnectCamera(p5);
333
334 ostringstream str;
335 str << p6 << "VR" << ends;
336
337 object_name = new char[strlen(str.str().c_str()) + 1];
338 strcpy(object_name, str.str().c_str());
339
340 copy_of_ref = p2.ref;
341
342 CameraEvent(p5);
343 }
344
~ogl_volume_rendering_object(void)345 ogl_volume_rendering_object::~ogl_volume_rendering_object(void)
346 {
347 for (i32u n1 = 0;n1 < cp_vector.size();n1++)
348 {
349 delete cp_vector[n1];
350 delete data_vector[n1];
351
352 // TODO : unregister my_glname???
353 }
354
355 delete[] object_name;
356 }
357
CameraEvent(const ogl_camera & p1)358 void ogl_volume_rendering_object::CameraEvent(const ogl_camera & p1)
359 {
360 oglv3d<GLfloat> newz = oglv3d<GLfloat>(GetSafeLD()->crd, p1.GetSafeLD()->crd);
361 newz = newz / newz.len();
362
363 oglv3d<GLfloat> newx = newz.vpr(p1.GetSafeLD()->ydir);
364 newx = newx / newx.len();
365
366 oglv3d<GLfloat> newy = newx.vpr(newz);
367 newy = newy / newy.len();
368
369 GetLD()->zdir = newz;
370 GetLD()->ydir = newy;
371
372 for (i32u n1 = 0;n1 < cp_vector.size();n1++)
373 {
374 fGL z1 = (fGL) n1 / (fGL) (cp_vector.size() - 1);
375 fGL z2 = 2.0 * (z1 - 0.5) * thickness;
376
377 oglv3d<GLfloat> pv = oglv3d<GLfloat>(GetSafeLD()->crd);
378 pv = pv + (GetSafeLD()->zdir * z2);
379
380 data_vector[n1]->crd[0] = pv.data[0];
381 data_vector[n1]->crd[1] = pv.data[1];
382 data_vector[n1]->crd[2] = pv.data[2];
383
384 data_vector[n1]->zdir = GetSafeLD()->zdir;
385 data_vector[n1]->ydir = GetSafeLD()->ydir;
386 }
387
388 Update(); // update the planes!!!!!
389 }
390
OrbitObject(const fGL *,const ogl_camera &)391 void ogl_volume_rendering_object::OrbitObject(const fGL *, const ogl_camera &)
392 {
393 }
394
RotateObject(const fGL *,const ogl_camera &)395 void ogl_volume_rendering_object::RotateObject(const fGL *, const ogl_camera &)
396 {
397 }
398
TranslateObject(const fGL * p1,const ogl_obj_loc_data * p2)399 void ogl_volume_rendering_object::TranslateObject(const fGL * p1, const ogl_obj_loc_data * p2)
400 {
401 fGL tmp1[3] = { p1[0], p1[1], p1[2] };
402
403 if (p2 == GetSafeLD())
404 {
405 tmp1[0] = -tmp1[0];
406 tmp1[2] = -tmp1[2];
407 }
408
409 ogl_dummy_object::TranslateObject(tmp1, p2);
410 Update();
411 }
412
Render(void)413 void ogl_volume_rendering_object::Render(void)
414 {
415 for (i32u n1 = 0;n1 < cp_vector.size();n1++)
416 {
417 cp_vector[n1]->Render();
418 }
419 }
420
Update(void)421 void ogl_volume_rendering_object::Update(void)
422 {
423 for (i32u n1 = 0;n1 < cp_vector.size();n1++)
424 {
425 cp_vector[n1]->Update();
426 }
427 }
428
429 /*################################################################################################*/
430
431 // eof
432