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