Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/post/src/graphics/gutil1.c
3203 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 2
10
* of the License, or (at your option) any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program (in file fem/GPL-2); if not, write to the
19
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
* Boston, MA 02110-1301, USA.
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* Graphics utilities part 1. OpenGL is called heavily by routines in this file.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 26 Sep 1995
40
*
41
* Modified by:
42
*
43
* Date of modification:
44
*
45
* $Id: gutil1.c,v 1.4 2003/02/06 09:37:50 jpr Exp $
46
*
47
* $Log: gutil1.c,v $
48
* Revision 1.4 2003/02/06 09:37:50 jpr
49
* *** empty log message ***
50
*
51
* Revision 1.3 2001/07/02 11:21:44 jpr
52
* *** empty log message ***
53
*
54
* Revision 1.2 1998/07/31 13:36:56 jpr
55
*
56
* Added id, started log.
57
*
58
*
59
******************************************************************************/
60
61
#include "../elmerpost.h"
62
63
static colormap_t *CurrentColormap = NULL;
64
65
void vsetcolori( int ncolor )
66
{
67
float r,g,b;
68
69
if ( CurrentColormap )
70
{
71
r = CurrentColormap->Values[ncolor].r / 255.0;
72
g = CurrentColormap->Values[ncolor].g / 255.0;
73
b = CurrentColormap->Values[ncolor].b / 255.0;
74
glColor4f( r,g,b,1.0 );
75
}
76
}
77
78
void vsetcolor( double color )
79
{
80
float r,g,b;
81
int ncolor;
82
83
if ( CurrentColormap )
84
{
85
ncolor = (CurrentColormap->NumberOfEntries-1) * color + 0.5;
86
r = CurrentColormap->Values[ncolor].r / 255.0;
87
g = CurrentColormap->Values[ncolor].g / 255.0;
88
b = CurrentColormap->Values[ncolor].b / 255.0;
89
glColor4f( r,g,b,1.0 );
90
}
91
}
92
93
/*******************************************************************************
94
*
95
* Name: gra_set_material
96
*
97
* Purpose: set current material
98
*
99
* Parameters:
100
*
101
* Input: (material_t *) pointer to material
102
*
103
* Output: none
104
*
105
* Return value: void
106
*
107
******************************************************************************/
108
void gra_set_material( material_t *Material )
109
{
110
static material_t *CurrentMaterial = NULL;
111
112
if ( !Material ) return;
113
114
/*
115
* if ( Material == CurrentMaterial && !Material->Changed ) return;
116
*/
117
118
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, Material->Shininess );
119
glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, Material->Specular );
120
121
#if 0
122
if ( Material->Specular[0] != 0.0 ||
123
Material->Specular[1] != 0.0 ||
124
Material->Specular[2] != 0.0
125
) glEnable( GL_NORMALIZE ); else glDisable( GL_NORMALIZE );
126
#endif
127
128
glColor4fv( Material->Diffuse );
129
130
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
131
132
if ( Material->Diffuse[3] < 1 )
133
{
134
glDisable( GL_DEPTH_TEST );
135
glEnable( GL_BLEND );
136
} else
137
{
138
glEnable( GL_DEPTH_TEST );
139
}
140
141
Material->Changed = FALSE;
142
CurrentMaterial = Material;
143
}
144
145
/*******************************************************************************
146
*
147
* Name: gra_set_colormap
148
*
149
* Purpose: set current colormap
150
*
151
* Parameters:
152
*
153
* Input: (colormap_t *) pointer to colormap
154
*
155
* Output: none
156
*
157
* Return value: void
158
*
159
******************************************************************************/
160
void gra_set_colormap( colormap_t *ColorMap )
161
{
162
static rgb_t v = { 255,255,255 };
163
int N;
164
static colormap_t ctr;
165
colormap_t *ct = ColorMap;
166
167
if ( !ct || !ct->Values || ct->NumberOfEntries <= 1 )
168
{
169
/* { glDisable( GL_TEXTURE_1D ); return } */
170
171
ct = &ctr;
172
ct->Changed = TRUE;
173
ct->Values = &v;
174
ct->NumberOfEntries = 1;
175
}
176
177
glEnable( GL_TEXTURE_1D );
178
179
if ( ct == CurrentColormap && !ct->Changed ) return;
180
181
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &N );
182
183
if ( ct->NumberOfEntries > N )
184
{
185
fprintf( stderr, "gra_set_colormap: Colormap size [%d] too "
186
"big for this OpenGL-implementation\n", ct->NumberOfEntries );
187
return;
188
}
189
190
glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
191
glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
192
glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP );
193
194
glTexEnvf( GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE );
195
196
glTexImage1D( GL_TEXTURE_1D, 0, 3, ct->NumberOfEntries, 0,
197
GL_RGB, GL_UNSIGNED_BYTE, ct->Values );
198
199
glEnable( GL_TEXTURE_1D );
200
201
ct->Changed = FALSE;
202
CurrentColormap = ct;
203
}
204
205
colormap_t *gra_get_colormap()
206
{
207
return CurrentColormap;
208
}
209
210
/*******************************************************************************
211
*
212
* Name: gra_triangle
213
*
214
* Purpose: draw one triangle, glBegin() should have been called,
215
* glEnd() should be called...
216
*
217
* Parameters:
218
*
219
* Input: (float [3][3]) vertex coordinates
220
* (float [3][3]) normal vectors
221
* (float [3]) vertex colors
222
*
223
* Output: graphics
224
*
225
* Return value: void
226
*
227
******************************************************************************/
228
static void gra_output_triangle( float coords[3][3],float normal[3][3],int ncolor )
229
{
230
int i,j;
231
double x0,y0,z0,x1,y1,z1,n0,n1,n2;
232
233
234
x0 = coords[1][0] - coords[0][0];
235
y0 = coords[1][1] - coords[0][1];
236
z0 = coords[1][2] - coords[0][2];
237
238
x1 = coords[2][0] - coords[0][0];
239
y1 = coords[2][1] - coords[0][1];
240
z1 = coords[2][2] - coords[0][2];
241
242
n0 = y0*z1 - y1*z0;
243
n1 = z0*x1 - z1*x0;
244
n2 = x0*y1 - x1*y0;
245
246
vsetcolori( ncolor );
247
248
if ( n0*normal[0][0] + n1*normal[0][1] + n2*normal[0][2] > 0 ) {
249
glNormal3fv( normal[0] );
250
glVertex3fv( coords[0] );
251
252
glNormal3fv( normal[1] );
253
glVertex3fv( coords[1] );
254
255
glNormal3fv( normal[2] );
256
glVertex3fv( coords[2] );
257
} else {
258
glNormal3fv( normal[2] );
259
glVertex3fv( coords[2] );
260
261
glNormal3fv( normal[1] );
262
glVertex3fv( coords[1] );
263
264
glNormal3fv( normal[0] );
265
glVertex3fv( coords[0] );
266
}
267
268
glNormal3f( 0.0,0.0,1.0 );
269
}
270
271
static void gra_internal_triangle( float coords[3][3],float normal[3][3],float color[3], int ncolor )
272
{
273
float ncoord[3][3], nnorma[3][3], ccolor[3];
274
double x[2], y[2], z[2], u[2], v[2], w[2], c[2];
275
276
double c0=color[0],c1=color[1],c2=color[2],t,K;
277
int i,n=0,k;
278
279
int S, S0, S1, S2;
280
281
if ( ncolor >= CurrentColormap->NumberOfEntries-1 )
282
{
283
gra_output_triangle( coords, normal, ncolor );
284
return;
285
}
286
287
K = (double)(ncolor+1) / (double)CurrentColormap->NumberOfEntries;
288
289
S0 = color[0] > K;
290
S1 = color[1] > K;
291
S2 = color[2] > K;
292
S = S0 + S1 + S2;
293
294
if ( S==0 )
295
{
296
gra_output_triangle( coords, normal, ncolor );
297
return;
298
}
299
300
if ( S==3 )
301
{
302
gra_internal_triangle( coords, normal, color, ncolor+1 );
303
return;
304
}
305
306
n = 0;
307
if (S0 ^ S1)
308
{
309
t = (K - c0) / (c1 - c0);
310
311
x[n] = t * ( coords[1][0] - coords[0][0] ) + coords[0][0];
312
y[n] = t * ( coords[1][1] - coords[0][1] ) + coords[0][1];
313
z[n] = t * ( coords[1][2] - coords[0][2] ) + coords[0][2];
314
u[n] = t * ( normal[1][0] - normal[0][0] ) + normal[0][0];
315
v[n] = t * ( normal[1][1] - normal[0][1] ) + normal[0][1];
316
w[n] = t * ( normal[1][2] - normal[0][2] ) + normal[0][2];
317
n++;
318
}
319
320
if (S0 ^ S2)
321
{
322
t = (K - c0) / (c2 - c0);
323
324
x[n] = t * ( coords[2][0] - coords[0][0] ) + coords[0][0];
325
y[n] = t * ( coords[2][1] - coords[0][1] ) + coords[0][1];
326
z[n] = t * ( coords[2][2] - coords[0][2] ) + coords[0][2];
327
u[n] = t * ( normal[2][0] - normal[0][0] ) + normal[0][0];
328
v[n] = t * ( normal[2][1] - normal[0][1] ) + normal[0][1];
329
w[n] = t * ( normal[2][2] - normal[0][2] ) + normal[0][2];
330
n++;
331
}
332
333
if (S1 ^ S2)
334
{
335
t = (K - c1) / (c2 - c1);
336
337
x[n] = t * ( coords[2][0] - coords[1][0] ) + coords[1][0];
338
y[n] = t * ( coords[2][1] - coords[1][1] ) + coords[1][1];
339
z[n] = t * ( coords[2][2] - coords[1][2] ) + coords[1][2];
340
u[n] = t * ( normal[2][0] - normal[1][0] ) + normal[1][0];
341
v[n] = t * ( normal[2][1] - normal[1][1] ) + normal[1][1];
342
w[n] = t * ( normal[2][2] - normal[1][2] ) + normal[1][2];
343
n++;
344
}
345
346
k = 3;
347
if ( (S0 ^ S1) && (S0 ^ S2) ) k = 0;
348
if ( (S0 ^ S1) && (S1 ^ S2) ) k = 1;
349
if ( (S0 ^ S2) && (S1 ^ S2) ) k = 2;
350
351
for( i=0; i<2; i++ )
352
{
353
ncoord[i][0] = x[i];
354
ncoord[i][1] = y[i];
355
ncoord[i][2] = z[i];
356
nnorma[i][0] = u[i];
357
nnorma[i][1] = v[i];
358
nnorma[i][2] = w[i];
359
ccolor[i] = K;
360
}
361
362
ncoord[2][0] = coords[k][0];
363
ncoord[2][1] = coords[k][1];
364
ncoord[2][2] = coords[k][2];
365
nnorma[2][0] = normal[k][0];
366
nnorma[2][1] = normal[k][1];
367
nnorma[2][2] = normal[k][2];
368
ccolor[2] = color[k];
369
if ( color[k] > K )
370
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
371
else
372
gra_output_triangle( ncoord, nnorma, ncolor );
373
374
switch( k )
375
{
376
case 2:
377
for( i=0; i<3; i++ )
378
{
379
ncoord[2][i] = coords[0][i];
380
nnorma[2][i] = normal[0][i];
381
}
382
ccolor[2] = color[0];
383
if ( color[k] > K )
384
gra_output_triangle( ncoord, nnorma, ncolor );
385
else
386
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
387
388
for( i=0; i<3; i++ )
389
{
390
ncoord[0][i] = coords[1][i];
391
nnorma[0][i] = normal[1][i];
392
}
393
ccolor[0] = color[1];
394
if ( color[k] > K )
395
gra_output_triangle( ncoord, nnorma, ncolor );
396
else
397
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
398
break;
399
400
case 1:
401
for( i=0; i<3; i++ )
402
{
403
ncoord[2][i] = coords[0][i];
404
nnorma[2][i] = normal[0][i];
405
}
406
ccolor[2] = color[0];
407
if ( color[k] > K )
408
gra_output_triangle( ncoord, nnorma, ncolor );
409
else
410
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
411
412
for( i=0; i<3; i++ )
413
{
414
ncoord[0][i] = coords[2][i];
415
nnorma[0][i] = normal[2][i];
416
}
417
ccolor[0] = color[2];
418
if ( color[k] > K )
419
gra_output_triangle( ncoord, nnorma, ncolor );
420
else
421
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
422
break;
423
424
case 0:
425
for( i=0; i<3; i++ )
426
{
427
ncoord[2][i] = coords[1][i];
428
nnorma[2][i] = normal[1][i];
429
}
430
ccolor[2] = color[1];
431
if ( color[k] > K )
432
gra_output_triangle( ncoord, nnorma, ncolor );
433
else
434
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
435
436
for( i=0; i<3; i++ )
437
{
438
ncoord[0][i] = coords[2][i];
439
nnorma[0][i] = normal[2][i];
440
}
441
ccolor[0] = color[2];
442
if ( color[k] > K )
443
gra_output_triangle( ncoord, nnorma, ncolor );
444
else
445
gra_internal_triangle( ncoord, nnorma, ccolor, ncolor+1 );
446
break;
447
}
448
}
449
450
void gra_triangle( float coords[3][3],float normal[3][3],float color[3] )
451
{
452
int i;
453
454
if ( GlobalOptions.OutputPS ) {
455
gra_internal_triangle( coords, normal, color, 0 );
456
} else {
457
for( i=0; i<3; i++ )
458
{
459
glTexCoord1f( color[i] );
460
glNormal3fv( normal[i] );
461
glVertex3fv( coords[i] );
462
}
463
}
464
glNormal3f( 0.0, 0.0, 1.0 );
465
}
466
467
/*******************************************************************************
468
*
469
* Name: gra_poly
470
*
471
* Purpose: draw one polygon
472
*
473
* Parameters:
474
*
475
* Input: int n
476
* (float *) x,y,z vertices
477
* (float *) u,v,w normals
478
* (float *) c color
479
*
480
* Output: graphics
481
*
482
* Return value: void
483
*
484
******************************************************************************/
485
void gra_poly3( int n,float *x,float *y,float *z,float *u,float *v,float *w,float *c)
486
{
487
float coords[3][3], normal[3][3];
488
int i;
489
490
for( i=0; i<n; i++ )
491
{
492
normal[i][0] = u[i];
493
normal[i][1] = v[i];
494
normal[i][2] = w[i];
495
496
coords[i][0] = x[i];
497
coords[i][1] = y[i];
498
coords[i][2] = z[i];
499
}
500
gra_triangle( coords,normal,c );
501
glNormal3f( 0.0, 0.0, 0.0 );
502
}
503
504
505
/*******************************************************************************
506
*
507
* Name: gra_flat_quad
508
*
509
* Purpose: draw one flat quad, glBegin() should have been called,
510
* glEnd() should be called...
511
*
512
* Parameters:
513
*
514
* Input: (float [4][3]) vertex coordinates
515
* (float [1]) face color
516
*
517
* Output: graphics
518
*
519
* Return value: void
520
*
521
******************************************************************************/
522
void gra_flat_quad( float coords[4][3],double color )
523
{
524
int j;
525
526
glNormal3f( 0.0,0.0,1.0 );
527
528
if ( GlobalOptions.OutputPS )
529
vsetcolor( color );
530
else
531
glTexCoord1f( color );
532
533
glVertex3fv( coords[0] );
534
glVertex3fv( coords[1] );
535
glVertex3fv( coords[2] );
536
glVertex3fv( coords[3] );
537
}
538
539
/*******************************************************************************
540
*
541
* Name: gra_line
542
*
543
* Purpose: draw a line with line style given, if style is
544
* line_style_line glBegin() should have been called,
545
* glEnd() should be called...
546
*
547
* Parameters:
548
*
549
* Input: (float [3]) coordinates of the first endpoint
550
* (double) color of the first endpoint (0-1)
551
* (float [3]) coordinates of the second endpoint
552
* (double) color of the second endpoint
553
* (line_style_t) line_style_line or line_style_cylinder
554
* (double) line width, cylinder radius
555
*
556
* Output: graphics
557
*
558
* Return value: void
559
*
560
******************************************************************************/
561
void gra_line(float *x0,double c0,float *x1,double c1,line_style_t style,double width)
562
{
563
void gra_cylinder();
564
if ( style == line_style_line )
565
{
566
if ( GlobalOptions.OutputPS )
567
vsetcolor( c0 );
568
else
569
glTexCoord1f( c0 );
570
glVertex3fv( x0 );
571
572
if ( GlobalOptions.OutputPS )
573
vsetcolor( c1 );
574
else
575
glTexCoord1f( c1 );
576
glVertex3fv( x1 );
577
} else
578
{
579
if ( GlobalOptions.OutputPS ) vsetcolor( c1 );
580
gra_cylinder( x0[0],x0[1],x0[2],c0,x1[0],x1[1],x1[2],c1,width );
581
}
582
}
583
584
585
/*******************************************************************************
586
*
587
* Name: gra_arrow
588
*
589
* Purpose: draw one arrow
590
*
591
* Parameters:
592
*
593
* Input: (float [3]) coordinate of the arrow base
594
* (float [3]) vector components x,y,z
595
* (double) color (0-1)
596
* (line_style_t) line_style_line or line_style_cylinder
597
* (arrow_style_t) arrow_style_stick or arrow_style_arrow
598
* (double) cylinder radius, line width
599
*
600
* Output: graphics
601
*
602
* Return value: void
603
*
604
******************************************************************************/
605
void gra_arrow(float From[3],float Vector[3],double color,line_style_t line_style,arrow_style_t arrow_style,double width)
606
{
607
double x = Vector[0], y = Vector[1], z = Vector[2];
608
double xo = From[0], yo = From[1], zo = From[2];
609
610
double xa = xo + 0.65*x;
611
double ya = yo + 0.65*y;
612
double za = zo + 0.65*z;
613
614
float r,g,b;
615
int ncolor;
616
void gra_cone(), gra_cylinder();
617
618
x += xo;
619
y += yo;
620
z += zo;
621
622
if ( GlobalOptions.OutputPS ) vsetcolor( color );
623
624
if ( line_style == line_style_cylinder )
625
{
626
if ( arrow_style == arrow_style_arrow )
627
{
628
gra_cylinder( xo,yo,zo,color,xa,ya,za,color,width );
629
gra_cone( xa,ya,za,color,2.0*width,x,y,z,color,0.0 );
630
} else {
631
gra_cylinder( xo,yo,zo,color,x,y,z,color,width );
632
}
633
} else
634
{
635
glDisable( GL_LIGHTING );
636
glTexCoord1f( color );
637
638
glBegin(GL_LINE_STRIP);
639
glVertex3f( xo,yo,zo );
640
glVertex3f( x,y,z );
641
glEnd();
642
643
if ( arrow_style == arrow_style_arrow )
644
{
645
double xp,yp,zp;
646
647
xp = 0.75 * ( x - xo ) + xo;
648
yp = 0.75 * ( y - yo ) + yo;
649
zp = 0.75 * ( z - zo ) + zo;
650
xa = xp + ( y - yp );
651
ya = yp - ( x - xp );
652
za = zp;
653
654
glBegin(GL_LINE_STRIP);
655
glVertex3f(x,y,z);
656
glVertex3f(xa,ya,za);
657
glVertex3f(xp,yp,zp);
658
xa = xp - ( y - yp );
659
ya = yp + ( x - xp );
660
za = zp;
661
glVertex3f(xa,ya,za);
662
glVertex3f(x,y,z);
663
glEnd();
664
665
glBegin(GL_LINE_STRIP);
666
xa = xp + ( z - zp );
667
ya = yp;
668
za = zp - ( x - xp );
669
glVertex3f(x,y,z);
670
glVertex3f(xa,ya,za);
671
glVertex3f(xp,yp,zp);
672
xa = xp - ( y - yp );
673
ya = yp;
674
za = zp + ( x - xp );
675
glVertex3f(xa,ya,za);
676
glVertex3f(x,y,z);
677
glEnd();
678
}
679
glEnable( GL_LIGHTING );
680
}
681
}
682
683