35 #include <libFreeWRL.h>
37 #include "../vrml_parser/Structs.h"
38 #include "../main/headers.h"
39 #include "../opengl/Frustum.h"
40 #include "../opengl/Material.h"
41 #include "../opengl/OpenGL_Utils.h"
42 #include "Component_Shape.h"
43 #include "../scenegraph/RenderFuncs.h"
44 #include "../scenegraph/Polyrep.h"
46 #define FW_MAXCLIPPLANES 4
50 Stack *clipplane_stack;
51 float clipplanes[4*FW_MAXCLIPPLANES];
53 void *Component_Rendering_constructor(){
58 void Component_Rendering_init(
struct tComponent_Rendering *t){
62 t->prv = Component_Rendering_constructor();
65 p->clipplane_stack = newStack(
usehit);
68 void Component_Rendering_clear(
struct tComponent_Rendering *t){
70 deleteVector(
struct X3D_Node*,p->clipplane_stack);
76 static void findExtentInCoord (
struct X3D_Node *node,
int count,
struct SFVec3f* coord) {
83 for (i=0; i<count; i++) {
84 if (coord->c[0] > node->EXTENT_MAX_X) node->EXTENT_MAX_X = coord->c[0];
85 if (coord->c[0] < node->EXTENT_MIN_X) node->EXTENT_MIN_X = coord->c[0];
86 if (coord->c[1] > node->EXTENT_MAX_Y) node->EXTENT_MAX_Y = coord->c[1];
87 if (coord->c[1] < node->EXTENT_MIN_Y) node->EXTENT_MIN_Y = coord->c[1];
88 if (coord->c[2] > node->EXTENT_MAX_Z) node->EXTENT_MAX_Z = coord->c[2];
89 if (coord->c[2] < node->EXTENT_MIN_Z) node->EXTENT_MIN_Z = coord->c[2];
97 COMPILE_POLY_IF_REQUIRED(node->coord, node->fogCoord, node->color, node->normal, node->texCoord)
98 CULL_FACE(node->solid)
103 COMPILE_POLY_IF_REQUIRED(node->coord, node->fogCoord, node->color, node->normal, node->texCoord)
104 CULL_FACE(node->solid)
105 render_polyrep(node);
110 COMPILE_POLY_IF_REQUIRED( node->coord, node->fogCoord, node->color, node->normal, NULL)
111 CULL_FACE(node->solid)
112 render_polyrep(node);
116 COMPILE_POLY_IF_REQUIRED (node->coord, node->fogCoord, node->color, node->normal, node->texCoord)
117 CULL_FACE(node->solid)
118 render_polyrep(node);
122 COMPILE_POLY_IF_REQUIRED(node->coord, node->fogCoord, node->color, node->normal, node->texCoord)
123 CULL_FACE(node->solid)
124 render_polyrep(node);
128 COMPILE_POLY_IF_REQUIRED(node->coord, node->fogCoord, node->color, node->normal, node->texCoord)
129 CULL_FACE(node->solid)
130 render_polyrep(node);
149 ushort *vertCountPtr;
150 ushort **indxStartPtr;
156 ushort * colorIndShort;
159 GLfloat defcolorRGBA[] = {1.0f, 1.0f, 1.0f,1.0f};
163 colorIndShort = NULL;
167 node->__segCount = 0;
180 dtmp = getCoordinate (node->coord,
"IndexedLineSet");
185 findExtentInCoord(X3D_NODE(node), npoints, points);
190 if (node->coordIndex.n == 0)
return;
193 maxCoordFound = -1000;
196 for (i=0; i<node->coordIndex.n; i++) {
198 if (node->coordIndex.p[i] < -1) {
199 ConsoleMessage (
"IndexedLineSet - coordIndex less than 0 at %d\n",i);
204 if (node->coordIndex.p[i] == -1) {
205 if (i!=((node->coordIndex.n)-1)) nSegments++;
209 if (node->coordIndex.p[i] > maxCoordFound) maxCoordFound = node->coordIndex.p[i];
211 if (maxCoordFound > npoints) {
223 FREE_IF_NZ (node->__vertArr);
224 node->__vertArr = MALLOC (ushort *,
sizeof(ushort)*(nVertices+1));
225 pt = (ushort *)node->__vertArr;
227 for (vtc = 0; vtc < nVertices; vtc++) {
236 FREE_IF_NZ (node->__vertIndx);
237 node->__vertIndx = MALLOC (ushort **,
sizeof(ushort*)*(nSegments));
239 FREE_IF_NZ (node->__vertices);
240 node->__vertices = MALLOC (
struct SFVec3f *,
sizeof(
struct SFVec3f)*(nVertices+1));
242 FREE_IF_NZ (node->__vertexCount);
243 node->__vertexCount = MALLOC (ushort *,
sizeof(ushort)*(nSegments));
246 indxStartPtr = (ushort **)node->__vertIndx;
247 newpoints = node->__vertices;
248 vertCountPtr = (ushort *) node->__vertexCount;
250 pt = (ushort *)node->__vertArr;
258 for (i=0; i<node->coordIndex.n; i++) {
260 if (node->coordIndex.p[i] == -1) {
261 if (i!=((node->coordIndex.n)-1)) {
267 *vertCountPtr = segLength;
273 oldpoint = &points[node->coordIndex.p[i]];
274 memcpy (newpoints, oldpoint,
sizeof(
struct SFColor));
285 FREE_IF_NZ (node->__xcolours);
287 newcolors = (
struct SFColorRGBA *) node->__xcolours;
288 POSSIBLE_PROTO_EXPANSION(
struct X3D_Color *, node->color,cc)
291 if ((cc->_nodeType != NODE_Color) && (cc->_nodeType != NODE_ColorRGBA)) {
292 ConsoleMessage (
"make_IndexedLineSet, color node, expected %d got %d\n", NODE_Color, cc->_nodeType);
298 if (node->colorPerVertex) {
300 colorIndInt = node->coordIndex.p;
302 if ((node->colorIndex.n)>0) {
303 if ((node->colorIndex.n) < (node->coordIndex.n)) {
304 ConsoleMessage (
"IndexedLineSet - expect more colorIndexes to match coords\n");
307 colorIndInt = node->colorIndex.p;
309 colorIndShort = node->__vertArr;
314 if ((node->colorIndex.n)>0) {
315 if ((node->colorIndex.n) < (nSegments)) {
316 ConsoleMessage (
"IndexedLineSet - expect more colorIndexes to match coords\n");
319 colorIndInt = node->colorIndex.p;
322 colorIndShort = node->__vertArr;
329 for (i=0; i<node->coordIndex.n; i++) {
330 if (node->coordIndex.p[i] != -1) {
332 if (node->colorPerVertex) {
333 if (colorIndInt != NULL)
334 curcolor = colorIndInt[i];
336 curcolor = colorIndShort[i];
338 if (colorIndInt != NULL)
339 curcolor = colorIndInt[curSeg];
341 curcolor = colorIndShort[curSeg];
344 if ((curcolor < 0) || (curcolor >= cc->color.n)) {
345 ConsoleMessage (
"IndexedLineSet, colorIndex %d (for vertex %d or segment %d) out of range (0..%d)\n",
346 curcolor, i, curSeg, cc->color.n);
350 oldcolor = (
struct SFColorRGBA *) &(cc->color.p[curcolor]);
353 if (cc->_nodeType == NODE_Color) {
354 memcpy (newcolors, defcolorRGBA,
sizeof (defcolorRGBA));
355 memcpy (newcolors, oldcolor,
sizeof(
struct SFColor));
357 memcpy (newcolors, oldcolor,
sizeof(
struct SFColorRGBA));
370 *vertCountPtr = segLength;
371 node->__segCount = nSegments;
375 ushort **indxStartPtr;
385 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X, node->EXTENT_MAX_Y,
386 node->EXTENT_MIN_Y, node->EXTENT_MAX_Z, node->EXTENT_MIN_Z,
391 if (node->__segCount > 0) {
392 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,node->__vertices);
394 if (node->__xcolours) {
395 FW_GL_COLOR_POINTER (4,GL_FLOAT,0,node->__xcolours);
398 indxStartPtr = (ushort **)node->__vertIndx;
399 count = node->__vertexCount;
401 for (i=0; i<node->__segCount; i++) {
404 sendElementsToGPU(GL_LINE_STRIP,count[i],indxStartPtr[i]);
410 struct SFColor *colors=0;
int ncolors=0;
413 if (node->_pointsVBO == 0) {
414 glGenBuffers(1,(GLuint *) &node->_pointsVBO);
424 dtmp = getCoordinate (node->coord,
"PointSet");
427 findExtentInCoord(X3D_NODE(node), dtmp->n, dtmp->p);
429 if (dtmp->n == 0)
return;
430 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, (GLuint) node->_pointsVBO);
431 glBufferData(GL_ARRAY_BUFFER,
sizeof(
struct SFVec3f)*dtmp->n, dtmp->p, GL_STATIC_DRAW);
432 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,0);
433 node->_npoints = dtmp->n;
437 POSSIBLE_PROTO_EXPANSION(
struct X3D_Color *, node->color,cc)
439 if ((cc->_nodeType != NODE_Color) && (cc->_nodeType != NODE_ColorRGBA)) {
440 ConsoleMessage (
"make_PointSet, expected %d got %d\n", NODE_Color, cc->_nodeType);
442 ncolors = cc->color.n;
443 colors = cc->color.p;
448 if(ncolors && ncolors < node->_npoints) {
449 ConsoleMessage (
"PointSet has less colors than points - removing color\n");
452 if (node->_coloursVBO == 0) {
453 glGenBuffers(1,(GLuint *)&node->_coloursVBO);
457 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, (GLuint) node->_coloursVBO);
458 if (cc->_nodeType == NODE_Color) {
459 glBufferData(GL_ARRAY_BUFFER,
sizeof(
struct SFColor)*ncolors, colors, GL_STATIC_DRAW);
460 node->_colourSize = 3;
462 glBufferData(GL_ARRAY_BUFFER,
sizeof(
struct SFColorRGBA)*ncolors, colors, GL_STATIC_DRAW);
463 node->_colourSize = 4;
465 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,0);
475 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X, node->EXTENT_MAX_Y,
476 node->EXTENT_MIN_Y, node->EXTENT_MAX_Z, node->EXTENT_MIN_Z,
482 if (node->_pointsVBO == 0)
return;
484 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->_pointsVBO);
485 FW_GL_VERTEX_POINTER(3,GL_FLOAT,0,0);
488 if (node->_coloursVBO != 0) {
489 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->_coloursVBO);
490 FW_GL_COLOR_POINTER(node->_colourSize,GL_FLOAT,0,0);
494 sendArraysToGPU(GL_POINTS,0,node->_npoints);
511 setExtent( node->EXTENT_MAX_X, node->EXTENT_MIN_X, node->EXTENT_MAX_Y,
512 node->EXTENT_MIN_Y, node->EXTENT_MAX_Z, node->EXTENT_MIN_Z,
516 if (node->__segCount > 0) {
520 if (cc->_nodeType == NODE_Color) {
521 FW_GL_COLOR_POINTER (3,GL_FLOAT,0,(
float *)cc->color.p);
523 FW_GL_COLOR_POINTER (4,GL_FLOAT,0,(
float *)cc->color.p);
526 points = getCoordinate(node->coord,
"LineSet");
528 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,(
float *)points->p);
530 indices = (ushort **)node->__vertIndx;
532 count = (GLsizei*) node->vertexCount.p;
534 for (i=0; i<node->__segCount; i++) {
544 sendElementsToGPU(GL_LINE_STRIP,count[i],indices[i]);
553 struct SFVec3f *coord=0;
int ncoord;
556 int *vertexC;
int nvertexc;
557 int totVertexRequired;
564 node->__segCount = 0;
567 nvertexc = (node->vertexCount).n; vertexC = (node->vertexCount).p;
568 if (nvertexc==0)
return;
569 totVertexRequired = 0;
575 for (c=0; c<nvertexc; c++) {
576 totVertexRequired += vertexC[c];
578 ConsoleMessage (
"make_LineSet, we have a vertexCount of %d, must be >=2,\n",vertexC[c]);
585 dtmp = getCoordinate (node->coord,
"IndexedLineSet");
590 findExtentInCoord(X3D_NODE(node), ncoord, coord);
596 if (totVertexRequired > ncoord) {
597 ConsoleMessage (
"make_LineSet, not enough points for vertexCount (vertices:%d points:%d)\n",
598 totVertexRequired, ncoord);
604 POSSIBLE_PROTO_EXPANSION(
struct X3D_Color *, node->color,cc)
606 if ((cc->_nodeType != NODE_Color) && (cc->_nodeType != NODE_ColorRGBA)) {
607 ConsoleMessage (
"make_LineSet, expected %d got %d\n", NODE_Color, cc->_nodeType);
609 ncolor = cc->color.n;
614 if (totVertexRequired > ncolor) {
615 ConsoleMessage (
"make_LineSet, not enough colors for vertexCount (vertices:%d colors:%d)\n",
616 totVertexRequired, ncolor);
624 FREE_IF_NZ (node->__vertArr);
625 node->__vertArr = MALLOC (GLuint *,
sizeof(GLuint)*(ncoord));
626 pt = (GLushort *)node->__vertArr;
627 for (vtc = 0; vtc < ncoord; vtc++) {
636 FREE_IF_NZ (node->__vertIndx);
637 node->__vertIndx = MALLOC (ushort **,
sizeof(ushort*)*(nvertexc));
639 pt = (GLushort *)node->__vertArr;
640 vpt = (ushort**) node->__vertIndx;
641 for (vtc=0; vtc<nvertexc; vtc++) {
643 vpt[vtc] = (ushort*) pt;
648 node->__segCount = nvertexc;
686 float *getTransformedClipPlanes(){
687 #define tactic_one_shot 1
688 #define tactic_point_plus_normal 2
690 double modelviewmatrix[16], meinv[16], u2me[16], me2u[16], me2ut[16], u2met[16], *M, *MIT;
693 nsend = min(FW_MAXCLIPPLANES,vectorSize(p->clipplane_stack));
700 tactic = tactic_point_plus_normal;
701 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewmatrix);
702 matinverseAFFINE(meinv,modelviewmatrix);
704 for(i=0;i<nsend;i++){
708 double dplane[4],dplane2[4];
710 uhit = vector_get(
usehit,p->clipplane_stack,i);
712 matmultiplyAFFINE(u2me,uhit.mvm,meinv);
713 mattranspose(u2met,u2me);
714 matinverseAFFINE(me2u,u2me);
715 mattranspose(me2ut,me2u);
719 for(j=0;j<4;j++) dplane[j] = cplane->plane.c[j];
720 if(tactic == tactic_one_shot){
722 transformFULL4d(dplane2,dplane,MIT);
728 double O4[4], N4[4], d;
729 vecscaled(O4,dplane,-dplane[3]);
735 transformAFFINEd(O4,O4,M);
737 transformAFFINEd(N4,N4,MIT);
739 veccopyd(dplane2,N4);
744 for(j=0;j<4;j++) p->clipplanes[i*4 + j] = (
float) dplane2[j];
746 return p->clipplanes;
748 int getClipPlaneCount(){
751 nsend = min(FW_MAXCLIPPLANES,vectorSize(p->clipplane_stack));
755 void popShaderFlags();
757 void sib_prep_ClipPlane(
struct X3D_Node *parent,
struct X3D_Node *sibAffector){
760 if(sibAffector && sibAffector->_nodeType == NODE_ClipPlane){
763 if(cplane->enabled == TRUE){
766 double modelviewmatrix[16];
770 shaderflags = getShaderFlags();
771 shaderflags.base |= CLIPPLANE_SHADER;
772 pushShaderFlags(shaderflags);
777 uhit.node = X3D_NODE(cplane);
778 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewmatrix);
779 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
780 stack_push(
usehit,p->clipplane_stack,uhit);
797 void sib_fin_ClipPlane(
struct X3D_Node *parent,
struct X3D_Node *sibAffector){
799 if(sibAffector && sibAffector->_nodeType == NODE_ClipPlane){
801 if(cplane->enabled == TRUE){
803 stack_pop(
usehit,p->clipplane_stack);