34 #include <libFreeWRL.h>
36 #include "../vrml_parser/Structs.h"
37 #include "../main/headers.h"
38 #include "../scenegraph/Component_ProgrammableShaders.h"
41 #include "Collision.h"
42 #include "../scenegraph/quaternion.h"
44 #include "LinearAlgebra.h"
45 #include "../input/SensInterps.h"
46 #include "system_threads.h"
49 #include "../opengl/OpenGL_Utils.h"
50 #include "../opengl/Textures.h"
51 #include "../scenegraph/Component_Shape.h"
52 #include "RenderFuncs.h"
55 typedef float shaderVec4[4];
83 ushort *elements_indices;
89 int profile_entry_count;
92 float light_linAtten[MAX_LIGHT_STACK];
93 float light_constAtten[MAX_LIGHT_STACK];
94 float light_quadAtten[MAX_LIGHT_STACK];
95 float light_spotCutoffAngle[MAX_LIGHT_STACK];
96 float light_spotBeamWidth[MAX_LIGHT_STACK];
97 shaderVec4 light_amb[MAX_LIGHT_STACK];
98 shaderVec4 light_dif[MAX_LIGHT_STACK];
99 shaderVec4 light_pos[MAX_LIGHT_STACK];
100 shaderVec4 light_spec[MAX_LIGHT_STACK];
101 shaderVec4 light_spotDir[MAX_LIGHT_STACK];
102 float light_radius[MAX_LIGHT_STACK];
103 GLint lightType[MAX_LIGHT_STACK];
106 int refreshLightUniforms;
107 unsigned int currentLoop;
108 unsigned int lastLoop;
109 unsigned int sendCount;
112 GLint lightOnOff[MAX_LIGHT_STACK];
113 GLint lightChanged[MAX_LIGHT_STACK];
129 Stack *render_geom_stack;
132 Stack *shaderflags_stack;
134 Stack *localLight_stack;
139 Stack *usehits_stack;
140 Stack *usehitsB_stack;
141 Stack *pickablegroupdata_stack;
142 Stack *draw_call_params_stack;
144 void *RenderFuncs_constructor(){
149 void RenderFuncs_init(
struct tRenderFuncs *t){
152 t->BrowserAction = FALSE;
157 t->hypersensitive = 0;
159 t->have_transparency=FALSE;
162 t->last_texture_type = NOTEXTURE;
165 t->prv = RenderFuncs_constructor();
168 p->profile_entry_count = 0;
172 p->nextFreeLight = 0;
173 p->refreshLightUniforms = 0;
178 p->libraries=newVector(
void3 *,1);
179 p->AnchorsAnchor = NULL;
180 t->rayHit = (
void *)&p->rayHit;
185 p->lastLoop = 10000000;
187 p->render_geom_stack = newStack(
int);
188 p->sensor_stack = newStack(
struct currayhit);
190 p->usehits_stack = newStack(
usehit);
191 p->usehitsB_stack = newStack(
usehit);
192 p->pickablegroupdata_stack = newStack(
void*);
194 p->fog_stack = newStack(
struct X3D_Node*);
195 p->localLight_stack = newStack(
int);
198 t->hp = (
void *)&p->hp;
208 void usehit_add(
struct X3D_Node * node,
double *modelviewmatrix){
213 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
214 uhit.userdata = NULL;
215 vector_pushBack(
usehit,p->usehits_stack,uhit);
217 void usehit_add2(
struct X3D_Node * node,
double *modelviewmatrix,
void *userdata){
222 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
223 uhit.userdata = userdata;
224 vector_pushBack(
usehit,p->usehits_stack,uhit);
233 if(vectorSize(p->usehits_stack)>0){
244 istart = ((
char*)lasthit - (
char*)vector_get_ptr(
usehit,p->usehits_stack,0))/
sizeof(
usehit) + 1;
247 for(i=istart;i<p->usehits_stack->n;i++){
248 item = vector_get_ptr(
usehit,p->usehits_stack,i);
249 if(item->node == node){
261 p->usehits_stack->n = 0;
267 void usehitB_add(
struct X3D_Node * node,
double *modelviewmatrix){
272 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
273 uhit.userdata = NULL;
274 vector_pushBack(
usehit,p->usehitsB_stack,uhit);
276 void usehitB_add2(
struct X3D_Node * node,
double *modelviewmatrix,
void *userdata){
281 memcpy(uhit.mvm,modelviewmatrix,16*
sizeof(
double));
282 uhit.userdata = userdata;
283 vector_pushBack(
usehit,p->usehitsB_stack,uhit);
292 if(vectorSize(p->usehitsB_stack)>0){
303 istart = ((
char*)lasthit - (
char*)vector_get_ptr(
usehit,p->usehitsB_stack,0))/
sizeof(
usehit) + 1;
306 for(i=istart;i<p->usehitsB_stack->n;i++){
307 item = vector_get_ptr(
usehit,p->usehitsB_stack,i);
308 if(item->node == node){
316 void usehitB_clear(){
320 p->usehitsB_stack->n = 0;
322 Stack *getUseHitBStack(){
324 return p->usehitsB_stack;
330 void push_pickablegroupdata(
void *userdata){
332 stack_push(
void*,p->pickablegroupdata_stack,userdata);
334 void pop_pickablegroupdata(){
336 stack_pop(
void*,p->pickablegroupdata_stack);
338 void *getpickablegroupdata(){
342 if(vectorSize(p->pickablegroupdata_stack)>0)
343 ret = stack_top(
void*,p->pickablegroupdata_stack);
348 void unload_libraryscenes();
349 int gc_broto_instance(
struct X3D_Proto* node);
350 void RenderFuncs_clear(
struct tRenderFuncs *t){
352 unload_libraryscenes();
353 deleteVector(
void3 *,p->libraries);
354 deleteVector(
int,p->render_geom_stack);
355 deleteVector(
struct currayhit,p->sensor_stack);
357 deleteVector(
usehit,p->usehits_stack);
360 deleteVector(
struct X3D_Node*,p->fog_stack);
361 deleteVector(
int,p->localLight_stack);
364 void unload_libraryscenes(){
374 for(i=0;i<vectorSize(p->libraries);i++){
378 ul = vector_get(
struct void3*,p->libraries,i);
380 url = (
char *)ul->one;
383 gc_broto_instance(libscn);
384 deleteVector(
struct X3D_Node*,libscn->_parentVector);
385 freeMallocedNodeFields((
struct X3D_Node*)libscn);
390 vector_set(
struct void3*,p->libraries,i,NULL);
396 void clearLightTable(){
399 p->nextFreeLight = 0;
409 int rv = p->nextFreeLight;
410 if(rv == HEADLIGHT_LIGHT) {
413 p->lightChanged[rv] = 0;
419 void setLightType(GLint light,
int type) {
421 p->lightType[light] = type;
423 void setLightChangedFlag(GLint light) {
425 p->lightChanged[light] = 1;
429 void setLightState(GLint light,
int status) {
434 PRINT_GL_ERROR_IF_ANY(
"start lightState");
437 p->lightOnOff[light] = status;
438 PRINT_GL_ERROR_IF_ANY(
"end lightState");
442 void saveLightState2(
int *last) {
444 *last = p->nextFreeLight;
447 void restoreLightState2(
int last) {
449 p->nextFreeLight = last;
451 void refreshLightUniforms(){
453 p->refreshLightUniforms = TRUE;
455 int numberOfLights(){
457 int rv = p->nextFreeLight;
466 if(p->localLight_stack->n)
467 retval = stack_top(
int,p->localLight_stack);
470 void pushLocalLight(
int lastlight){
476 stack_push(
int,p->localLight_stack,lastlight);
478 void popLocalLight(){
482 stack_pop(
int,p->localLight_stack);
486 void transformLightToEye(
float *pos,
float* dir)
489 GLDOUBLE modelMatrix[16], *b;
491 shaderVec4 aux, auxt;
492 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
507 transformf(auxt,pos,modelMatrix);
521 aux[0] = (float) (b[0]*a[0] +b[4]*a[1] +b[8]*a[2] );
522 aux[1] = (float) (b[1]*a[0] +b[5]*a[1] +b[9]*a[2] );
523 aux[2] = (float) (b[2]*a[0] +b[6]*a[1] +b[10]*a[2]);
532 void fwglLightfv (
int light,
int pname, GLfloat *params) {
551 memcpy ((
void *)p->light_amb[light],(
void *)params,
sizeof(shaderVec4));
554 memcpy ((
void *)p->light_dif[light],(
void *)params,
sizeof(shaderVec4));
557 memcpy ((
void *)p->light_pos[light],(
void *)params,
sizeof(shaderVec4));
571 if (light != HEADLIGHT_LIGHT) transformLightToEye(p->light_pos[light], p->light_spotDir[light]);
574 memcpy ((
void *)p->light_spec[light],(
void *)params,
sizeof(shaderVec4));
576 case GL_SPOT_DIRECTION:
578 memcpy ((
void *)p->light_spotDir[light],(
void *)params,
sizeof(shaderVec4));
580 default: {printf (
"help, unknown fwgllightfv param %d\n",pname);}
584 void fwglLightf (
int light,
int pname, GLfloat param) {
588 printf (
"fwglLightf light: %d ",light);
590 case GL_CONSTANT_ATTENUATION: printf (
"GL_CONSTANT_ATTENUATION");
break;
591 case GL_LINEAR_ATTENUATION: printf (
"GL_LINEAR_ATTENUATION");
break;
592 case GL_QUADRATIC_ATTENUATION: printf (
"GL_QUADRATIC_ATTENUATION");
break;
593 case GL_SPOT_CUTOFF: printf (
"GL_SPOT_CUTOFF");
break;
594 case GL_SPOT_BEAMWIDTH: printf (
"GL_SPOT_BEAMWIDTH");
break;
596 printf (
" %f\n",param);
601 case GL_CONSTANT_ATTENUATION:
602 p->light_constAtten[light] = param;
604 case GL_LINEAR_ATTENUATION:
605 p->light_linAtten[light] = param;
607 case GL_QUADRATIC_ATTENUATION:
608 p->light_quadAtten[light] = param;
611 p->light_spotCutoffAngle[light] = param;
614 case GL_SPOT_BEAMWIDTH:
615 p->light_spotBeamWidth[light] = param;
619 case GL_LIGHT_RADIUS:
620 p->light_radius[light] = param;
623 default: {printf (
"help, unknown fwgllightfv param %d\n",pname);}
645 int i,j, lightcount, lightsChanged;
646 int lightIndexesToSend[MAX_LIGHTS];
649 if (me==NULL)
return;
651 PRINT_GL_ERROR_IF_ANY(
"BEGIN sendLightInfo");
656 lightsChanged = FALSE;
657 for(i=0;i<MAX_LIGHT_STACK;i++){
658 if(p->lightChanged[i]) lightsChanged = TRUE;
660 if(!lightsChanged && (p->currentShader == p->lastShader))
662 p->lastShader = p->currentShader;
667 profile_start(
"sendlight");
672 PRINT_GL_ERROR_IF_ANY(
"MIDDLE1 sendLightInfo");
679 lightsChanged = FALSE;
683 for(i=MAX_LIGHT_STACK-1;i>-1;i--){
684 if(i==HEADLIGHT_LIGHT || i<p->nextFreeLight){
685 if (p->lightOnOff[i]){
686 lightIndexesToSend[lightcount] = i;
688 lightsChanged = lightsChanged || p->lightChanged[i];
689 if(lightcount >= MAX_LIGHTS)
break;
693 if(!lightsChanged && (p->currentShader == p->lastShader) && !p->refreshLightUniforms)
695 p->refreshLightUniforms = FALSE;
696 p->lastShader = p->currentShader;
697 for (j=0;j<lightcount; j++) {
698 i = lightIndexesToSend[j];
699 p->lightChanged[i] = 0;
709 if(p->lightType[i]<2 ){
710 shaderVec4 light_Attenuations;
711 light_Attenuations[0] = p->light_constAtten[i];
712 light_Attenuations[1] = p->light_linAtten[i];
713 light_Attenuations[2] = p->light_quadAtten[i];
714 GLUNIFORM3FV(me->lightAtten[j],1,light_Attenuations);
719 if(p->lightType[i]==1 ){
720 GLUNIFORM1F(me->lightSpotCutoffAngle[j], p->light_spotCutoffAngle[i]);
721 GLUNIFORM1F(me->lightSpotBeamWidth[j], p->light_spotBeamWidth[i]);
723 if(p->lightType[i]==0){
724 GLUNIFORM1F(me->lightRadius[j],p->light_radius[i]);
726 GLUNIFORM4FV(me->lightSpotDir[j],1, p->light_spotDir[i]);
727 GLUNIFORM4FV(me->lightPosition[j],1,p->light_pos[i]);
728 GLUNIFORM4FV(me->lightAmbient[j],1,p->light_amb[i]);
729 GLUNIFORM4FV(me->lightDiffuse[j],1,p->light_dif[i]);
730 GLUNIFORM4FV(me->lightSpecular[j],1,p->light_spec[i]);
731 GLUNIFORM1I(me->lightType[j],p->lightType[i]);
733 GLUNIFORM1I(me->lightcount,lightcount);
735 profile_end(
"sendlight");
736 PRINT_GL_ERROR_IF_ANY(
"END sendLightInfo");
740 void finishedWithGlobalShader(
void) {
745 getAppearanceProperties()->currentShaderProperties = NULL;
746 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
748 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
757 void resetGlobalShader() {
763 p->currentShader = 0;
766 void restoreGlobalShader(){
768 if (p->currentShader)
769 USE_SHADER(p->currentShader);
777 if (myShader == NULL) {
778 finishedWithGlobalShader();
783 getAppearanceProperties()->currentShaderProperties = myShader;
784 if (myShader->myShaderProgram != p->currentShader) {
785 USE_SHADER(myShader->myShaderProgram);
786 p->currentShader = myShader->myShaderProgram;
792 void sendAttribToGPU(
int myType,
int dataSize,
int dataType,
int normalized,
int stride,
float *pointer,
int texID,
char *file,
int line){
797 if (me==NULL)
return;
801 ConsoleMessage (
"sendAttribToGPU, getAppearanceProperties()->currentShaderProperties %p\n",getAppearanceProperties()->currentShaderProperties);
802 ConsoleMessage (
"myType %d, dataSize %d, dataType %d, stride %d\n",myType,dataSize,dataType,stride);
805 case FW_NORMAL_POINTER_TYPE:
806 ConsoleMessage (
"glVertexAttribPointer Normals %d at %s:%d\n",me->Normals,file,line);
808 case FW_VERTEX_POINTER_TYPE:
809 ConsoleMessage (
"glVertexAttribPointer Vertexs %d at %s:%d\n",me->Vertices,file,line);
811 case FW_COLOR_POINTER_TYPE:
812 ConsoleMessage (
"glVertexAttribPointer Colours %d at %s:%d\n",me->Colours,file,line);
814 case FW_TEXCOORD_POINTER_TYPE:
815 ConsoleMessage (
"glVertexAttribPointer TexCoords %d at %s:%d\n",me->TexCoords,file,line);
818 default : {ConsoleMessage (
"sendAttribToGPU, unknown type in shader\n");}
825 case FW_NORMAL_POINTER_TYPE:
826 if (me->Normals != -1) {
827 glEnableVertexAttribArray(me->Normals);
828 glVertexAttribPointer(me->Normals, 3, dataType, normalized, stride, pointer);
831 case FW_FOG_POINTER_TYPE:
832 if (me->FogCoords != -1) {
833 glEnableVertexAttribArray(me->FogCoords);
834 glVertexAttribPointer(me->FogCoords, 1, dataType, normalized, stride, pointer);
838 case FW_VERTEX_POINTER_TYPE:
839 if (me->Vertices != -1) {
840 glEnableVertexAttribArray(me->Vertices);
841 glVertexAttribPointer(me->Vertices, dataSize, dataType, normalized, stride, pointer);
844 case FW_COLOR_POINTER_TYPE:
845 if (me->Colours != -1) {
846 glEnableVertexAttribArray(me->Colours);
847 glVertexAttribPointer(me->Colours, dataSize, dataType, normalized, stride, pointer);
850 case FW_TEXCOORD_POINTER_TYPE:
851 if (me->TexCoords[texID] != -1) {
852 glEnableVertexAttribArray(me->TexCoords[texID]);
853 glVertexAttribPointer(me->TexCoords[texID], dataSize, dataType, normalized, stride, pointer);
858 default : {printf (
"sendAttribToGPU, unknown type in shader\n");}
863 void sendBindBufferToGPU (GLenum target, GLuint buffer,
char *file,
int line) {
874 glBindBuffer(target,buffer);
883 bool setupShaderB() {
887 PRINT_GL_ERROR_IF_ANY(
"BEGIN setupShader");
892 if (!(mysp->compiledOK)) {
894 printf (
"shader compile error\n");
896 PRINT_GL_ERROR_IF_ANY(
"EXIT(false) setupShader");
901 printf (
"setupShader, we have Normals %d Vertices %d Colours %d TexCoords %d \n",
909 sendFogToShader(mysp);
910 sendClipplanesToShader(mysp);
911 sendMaterialsToShader(mysp);
912 sendMatriciesToShader(mysp);
923 void saveArraysForGPU(
int mode,
int first,
int count){
930 params.arrays.arrays_mode = mode;
931 params.arrays.arrays_count = count;
932 params.arrays.arrays_first = first;
937 void saveElementsForGPU(
int mode,
int count, ushort *indices){
946 params.elements.elements_count = count;
947 params.elements.elements_mode = mode;
948 params.elements.elements_indices = indices;
952 void reallyDrawOnce(){
960 for(i=0;i<vectorSize(p->draw_call_params_stack);i++){
962 if(params.calltype == 1)
963 glDrawArrays(params.arrays.arrays_mode,params.arrays.arrays_first,params.arrays.arrays_count);
964 else if(params.calltype == 2)
965 glDrawElements(params.elements.elements_mode,params.elements.elements_count,GL_UNSIGNED_SHORT,params.elements.elements_indices);
974 p->draw_call_params_stack->n = 0;
981 void sendArraysToGPU (
int mode,
int first,
int count) {
983 printf (
"sendArraysToGPU start\n");
998 profile_start(
"draw_arr");
1000 saveArraysForGPU(mode,first,count);
1001 profile_end(
"draw_arr");
1003 #ifdef RENDERVERBOSE
1004 printf (
"sendArraysToGPU end\n");
1010 void sendElementsToGPU (
int mode,
int count, ushort *indices) {
1011 #ifdef RENDERVERBOSE
1012 printf (
"sendElementsToGPU start\n");
1016 profile_start(
"draw_el");
1018 saveElementsForGPU(mode,count,indices);
1019 profile_end(
"draw_el");
1022 #ifdef RENDERVERBOSE
1023 printf (
"sendElementsToGPU finish\n");
1028 void initializeLightTables() {
1030 float pos[] = { 0.0f, 0.0f, 1.0f, 0.0f };
1031 float dif[] = { 1.0f, 1.0f, 1.0f, 1.0f };
1032 float shin[] = { 0.0f, 0.0f, 0.0f, 1.0f };
1033 float As[] = { 0.0f, 0.0f, 0.0f, 1.0f };
1036 PRINT_GL_ERROR_IF_ANY(
"start of initializeightTables");
1038 for(i=0; i<MAX_LIGHT_STACK; i++) {
1039 p->lightOnOff[i] = TRUE;
1040 setLightState(i,FALSE);
1042 FW_GL_LIGHTFV(i, GL_SPOT_DIRECTION, pos);
1043 FW_GL_LIGHTFV(i, GL_POSITION, pos);
1044 FW_GL_LIGHTFV(i, GL_AMBIENT, As);
1045 FW_GL_LIGHTFV(i, GL_DIFFUSE, dif);
1046 FW_GL_LIGHTFV(i, GL_SPECULAR, shin);
1047 FW_GL_LIGHTF(i, GL_CONSTANT_ATTENUATION,1.0f);
1048 FW_GL_LIGHTF(i, GL_LINEAR_ATTENUATION,0.0f);
1049 FW_GL_LIGHTF(i, GL_QUADRATIC_ATTENUATION,0.0f);
1050 FW_GL_LIGHTF(i, GL_SPOT_CUTOFF,0.0f);
1051 FW_GL_LIGHTF(i, GL_SPOT_BEAMWIDTH,0.0f);
1052 FW_GL_LIGHTF(i, GL_LIGHT_RADIUS, 100000.0);
1054 PRINT_GL_ERROR_IF_ANY(
"initizlizeLight2.10");
1056 setLightState(HEADLIGHT_LIGHT, TRUE);
1061 PRINT_GL_ERROR_IF_ANY(
"end initializeLightTables");
1068 return &p->renderstate;
1073 GLint viewport[4] = {-1,-1,2,2};
1080 struct point_XYZ r1 = {0,0,-1}, r2 = {0,0,0}, r3 = {0,1,0};
1086 return p->AnchorsAnchor;
1088 void setAnchorsAnchor(
struct X3D_Anchor* anchor)
1091 p->AnchorsAnchor = anchor;
1107 ConsoleMessage (
"rootNode, p null");
1112 void setRootNode(
struct X3D_Node *rn)
1127 void addLibrary(
char *url,
struct X3D_Proto *library,
void *res){
1130 ul->one = (
void *)STRDUP(url);
1131 ul->two = (
void *)library;
1133 vector_pushBack(
void3 *,p->libraries,ul);
1135 void3 *librarySearch(
char *absoluteUniUrlNoPound){
1140 libs = p->libraries;
1141 n = vectorSize(libs);
1143 ul = vector_get(
void3 *,libs,i);
1145 if(!strcmp(absoluteUniUrlNoPound,ul->one)){
1158 void prepare_model_view_pickmatrix0(GLDOUBLE *modelMatrix, GLDOUBLE *mvp){
1161 GLDOUBLE *pickMatrixi;
1163 pickMatrixi = getPickrayMatrix(1);
1166 matmultiplyAFFINE(mvp,modelMatrix,pickMatrixi);
1169 void prepare_model_view_pickmatrix_inverse0(GLDOUBLE *modelMatrix, GLDOUBLE *mvpi){
1174 GLDOUBLE *pickMatrix;
1176 pickMatrix = getPickrayMatrix(0);
1179 matinverseAFFINE(mvi,modelMatrix);
1180 matmultiplyAFFINE(mvpi,pickMatrix,mvi);
1203 void rayhit(
float rat,
float cx,
float cy,
float cz,
float nx,
float ny,
float nz,
1204 float tx,
float ty,
char *descr) {
1205 GLDOUBLE modelMatrix[16];
1211 #ifdef RENDERVERBOSE
1219 if(rat<0 || (rat>tg->RenderFuncs.hitPointDist && tg->RenderFuncs.hitPointDist >= 0)) {
1222 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1226 tp.x = cx; tp.y = cy; tp.z = cz;
1227 prepare_model_view_pickmatrix0(modelMatrix,mvp);
1228 transform(&tp,&tp,mvp);
1231 tg->RenderFuncs.hitPointDist = rat;
1233 #ifdef RENDERVERBOSE
1245 GLDOUBLE modelMatrix[16];
1246 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1261 prepare_model_view_pickmatrix_inverse0(modelMatrix, mvpi);
1262 transform(t_r1,&r11,mvpi);
1263 transform(t_r2,&r2,mvpi);
1264 transform(t_r3,&r3,mvpi);
1275 void setup_pickray0();
1282 upd_ray0(&p->t_r123.p1,&p->t_r123.p2,&p->t_r123.p3);
1290 void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
1291 int pickrayHitsMBB(
struct X3D_Node *node){
1296 GLDOUBLE modelMatrix[16];
1303 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
1308 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1310 prepare_model_view_pickmatrix0(modelMatrix, mvp);
1314 shapeMBBmin[i] = node->_extent[i*2 + 1];
1315 shapeMBBmax[i] = node->_extent[i*2];
1317 transformMBB(smin,smax,mvp,shapeMBBmin,shapeMBBmax);
1321 isIn = isIn && (smin[i] <= 0.0 && smax[i] >= 0.0);
1335 void update_node(
struct X3D_Node *node) {
1339 printf (
"update_node for %d %s nparents %d renderflags %x\n",node, stringNodeType(node->_nodeType),node->_nparents, node->_renderFlags);
1340 if (node->_nparents == 0) {
1341 if (node == rootNode) printf (
"...no parents, this IS the rootNode\n");
1342 else printf (
"...no parents, this IS NOT the rootNode\n");
1347 for (i = 0; i < node->_nparents; i++) {
1348 struct X3D_Node *n = X3D_NODE(node->_parents[i]);
1350 printf (
" parent %u is %s\n",n,stringNodeType(n->_nodeType));
1352 printf (
" parent %d is NULL\n",i);
1360 if (node->_parentVector == NULL) {
1364 for (i = 0; i < vectorSize(node->_parentVector); i++) {
1367 fprintf(stderr,
"Error: self-referential node structure! (node:'%s')\n", stringNodeType(node->_nodeType));
1368 vector_set(
struct X3D_Node*, node->_parentVector, i,NULL);
1369 }
else if( n != 0 ) {
1386 #define PRINT_NODE(_node, _v) do { \
1387 if (gglobal()->internalc.global_print_opengl_errors && (gglobal()->display._global_gl_err != GL_NO_ERROR)) { \
1388 printf("Render_node_v %p (%s) PREP: %p REND: %p CH: %p FIN: %p RAY: %p HYP: %p\n",_v, \
1389 stringNodeType(_node->_nodeType), \
1395 gglobal()->RenderFuncs.hypersensitive); \
1396 printf("Render_state geom %d light %d sens %d\n", \
1397 renderstate()->render_geom, \
1398 renderstate()->render_light, \
1399 renderstate()->render_sensitive); \
1400 printf("pchange %d pichange %d \n", _node->_change, _node->_ichange); \
1417 void profile_start(
char *name){
1424 if (!p->profiling_on)
return;
1425 pe = p->profile_entries;
1427 for(i=0;i<p->profile_entry_count;i++){
1428 if(!strcmp(name,pe[i].name)){
1434 pe[p->profile_entry_count].name = name;
1435 pe[p->profile_entry_count].hits = 0;
1436 ifound = p->profile_entry_count;
1437 p->profile_entry_count++;
1439 pe[ifound].start = Time1970sec();
1441 void profile_end(
char *name){
1448 if (!p->profiling_on)
return;
1449 pe = p->profile_entries;
1450 for(i=0;i<p->profile_entry_count;i++){
1451 if(!strcmp(name,pe[i].name)){
1457 pe[ifound].accum += Time1970sec() - pe[ifound].start;
1461 void profile_print_all(){
1467 if (!p->profiling_on){
1468 p->profiling_on = 1;
1469 ConsoleMessage(
"turning profiling on\n");
1472 pe = p->profile_entries;
1473 ConsoleMessage(
"frame rate: %9.3f number of items tracked: %d\n", gglobal()->Mainloop.BrowserFPS,p->profile_entry_count);
1474 ConsoleMessage(
"%15s %10s %15s %10s\n",
"profile name",
"hits",
"time(sec)",
"% of 1st");
1475 for (i = 0; i < p->profile_entry_count; i++){
1476 ConsoleMessage(
"%15s %10d %15.3f %10.2f\n", pe[i].name, pe[i].hits, pe[i].accum, pe[i].accum / pe[0].accum*100.0);
1506 void popShaderFlags(){
1520 retval = stack_top(
struct X3D_Node*,p->fog_stack);
1523 void pushFogParams(
struct X3D_Node *fogparams){
1529 stack_push(
struct X3D_Node*,p->fog_stack,fogparams);
1532 void popFogParams(){
1536 stack_pop(
struct X3D_Node*,p->fog_stack);
1555 stack_push(
struct point_XYZ3,p->ray_stack,p->t_r123);
1561 upd_ray0(&p->t_r123.p1,&p->t_r123.p2,&p->t_r123.p3);
1572 p->t_r123 = stack_top(
struct point_XYZ3,p->ray_stack);
1585 void push_render_geom(
int igeom){
1588 stack_push(
int,p->render_geom_stack,p->renderstate.render_geom);
1589 p->renderstate.render_geom = igeom;
1591 void pop_render_geom(){
1595 igeom = stack_top(
int,p->render_geom_stack);
1596 stack_pop(
int,p->render_geom_stack);
1597 p->renderstate.render_geom = igeom;
1599 void push_sensor(
struct X3D_Node *node){
1603 push_render_geom(1);
1604 stack_push(
struct currayhit,p->sensor_stack,p->rayph);
1608 p->rayph.hitNode = node;
1609 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, p->rayph.modelMatrix);
1610 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, p->rayph.projMatrix);
1619 p->rayph = stack_top(
struct currayhit,p->sensor_stack);
1620 stack_pop(
struct currayhit,p->sensor_stack);
1625 int render_foundLayerViewpoint();
1626 void render_node(
struct X3D_Node *node) {
1639 X3D_NODE_CHECK(node);
1641 #ifdef RENDERVERBOSE
1646 #ifdef RENDERVERBOSE
1647 DEBUG_RENDER(
"%d no node, quick return\n", renderLevel);
1653 virt = virtTable[node->_nodeType];
1655 #ifdef RENDERVERBOSE
1659 for(i=0;i<p->renderLevel;i++) printf(
" ");
1661 printf(
"%d node %u (%s) , v %u renderFlags %x ",p->renderLevel, node,stringNodeType(node->_nodeType),virt,node->_renderFlags);
1663 if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf (
" VF_Viewpoint");
1664 if ((node->_renderFlags & VF_Geom )== VF_Geom) printf (
" VF_Geom");
1665 if ((node->_renderFlags & VF_localLight )== VF_localLight) printf (
" VF_localLight");
1666 if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf (
" VF_Sensitive");
1667 if ((node->_renderFlags & VF_Blend) == VF_Blend) printf (
" VF_Blend");
1668 if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf (
" VF_Proximity");
1669 if ((node->_renderFlags & VF_Collision) == VF_Collision) printf (
" VF_Collision");
1670 if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf (
" VF_globalLight");
1671 if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf (
" VF_hasVisibleChildren");
1672 if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf (
" VF_shouldSortChildren");
1673 if ((node->_renderFlags & VF_Other) == VF_Other) printf (
" VF_Other");
1692 if (p->renderstate.render_vp == VF_Viewpoint) {
1694 if ((node->_renderFlags & VF_Viewpoint) != VF_Viewpoint) {
1695 #ifdef RENDERVERBOSE
1696 printf (
"doing Viewpoint, but this node is not for us - just returning\n");
1701 if(p->renderstate.render_vp == VF_Viewpoint && render_foundLayerViewpoint()){
1708 if (p->renderstate.render_light ) {
1709 if((node->_renderFlags & VF_globalLight) != VF_globalLight) {
1710 #ifdef RENDERVERBOSE
1711 printf (
"doing globalLight, but this node is not for us - just returning\n");
1717 justGeom = p->renderstate.render_geom && !p->renderstate.render_sensitive && !p->renderstate.render_blend;
1719 pushed_sensor = FALSE;
1723 DEBUG_RENDER(
"rs 2\n");
1724 profile_start(
"prep");
1726 profile_start(
"prepgeom");
1728 profile_end(
"prep");
1730 profile_end(
"prepgeom");
1735 PRINT_GL_ERROR_IF_ANY(
"prep"); PRINT_NODE(node,virt);
1737 if(p->renderstate.render_sensitive && !tg->RenderFuncs.hypersensitive) {
1741 if(p->renderstate.render_proximity && virt->proximity) {
1742 DEBUG_RENDER(
"rs 2a\n");
1743 profile_start(
"proximity");
1744 virt->proximity(node);
1745 profile_end(
"proximity");
1746 PRINT_GL_ERROR_IF_ANY(
"render_proximity"); PRINT_NODE(node,virt);
1748 if(p->renderstate.render_geom && ((node->_renderFlags & VF_USE) == VF_USE) && !p->renderstate.render_picking){
1753 if(getWindex() == 0){
1757 double modelviewMatrix[16];
1760 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
1762 usehit_add2(node,modelviewMatrix,getpickablegroupdata());
1765 if(p->renderstate.render_picking && node->_nodeType == NODE_Shape ){
1769 double modelviewMatrix[16];
1771 if(shapenode->geometry){
1774 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
1776 usehitB_add2(shapenode->geometry,modelviewMatrix,getpickablegroupdata());
1780 if(p->renderstate.render_collision && virt->collision) {
1781 DEBUG_RENDER(
"rs 2b\n");
1782 profile_start(
"collision");
1783 virt->collision(node);
1784 profile_end(
"collision");
1785 PRINT_GL_ERROR_IF_ANY(
"render_collision"); PRINT_NODE(node,virt);
1788 if(p->renderstate.render_geom && !p->renderstate.render_sensitive && !p->renderstate.render_picking && virt->rend) {
1789 DEBUG_RENDER(
"rs 3\n");
1790 PRINT_GL_ERROR_IF_ANY(
"BEFORE render_geom"); PRINT_NODE(node,virt);
1791 profile_start(
"rend");
1793 profile_end(
"rend");
1794 PRINT_GL_ERROR_IF_ANY(
"render_geom"); PRINT_NODE(node,virt);
1796 if(p->renderstate.render_other && virt->other )
1801 if(p->renderstate.render_sensitive && ((node->_renderFlags & VF_Sensitive)|| Viewer()->LookatMode ==2)) {
1802 DEBUG_RENDER(
"rs 5\n");
1803 profile_start(
"sensitive");
1805 pushed_sensor = TRUE;
1806 profile_end(
"sensitive");
1808 if(p->renderstate.render_geom && p->renderstate.render_sensitive && !tg->RenderFuncs.hypersensitive && virt->rendray) {
1809 DEBUG_RENDER(
"rs 6\n");
1810 profile_start(
"rendray");
1811 if(pickrayHitsMBB(node))
1812 virt->rendray(node);
1813 profile_end(
"rendray");
1814 PRINT_GL_ERROR_IF_ANY(
"rs 6"); PRINT_NODE(node,virt);
1827 if(virt->children) {
1828 DEBUG_RENDER(
"rs 8 - has valid child node pointer\n");
1831 virt->children(node);
1836 PRINT_GL_ERROR_IF_ANY(
"children"); PRINT_NODE(node,virt);
1840 if(p->renderstate.render_other && virt->other)
1848 DEBUG_RENDER(
"rs A\n");
1849 profile_start(
"fin");
1851 profile_start(
"fingeom");
1856 profile_end(
"fingeom");
1860 PRINT_GL_ERROR_IF_ANY(
"fin"); PRINT_NODE(node,virt);
1865 #ifdef RENDERVERBOSE
1868 for(i=0;i<p->renderLevel;i++)printf(
" ");
1870 printf(
"%d (end render_node)\n",p->renderLevel);
1886 void add_parent(
struct X3D_Node *node,
struct X3D_Node *parent,
char *file,
int line) {
1892 printf (
"add_parent; adding node %u ,to parent %u at %s:%d\n",node, parent,file,line);
1893 printf (
"add_parent; adding node %x ,to parent %x (hex) at %s:%d\n",node, parent,file,line);
1894 printf (
"add_parent; adding node %p ,to parent %p (ptr) at %s:%d\n",node, parent,file,line);
1897 printf (
"add_parent; adding node %u (%s) to parent %u (%s) at %s:%d\n",node, stringNodeType(node->_nodeType),
1898 parent, stringNodeType(parent->_nodeType),file,line);
1901 parent->_renderFlags = parent->_renderFlags | node->_renderFlags;
1904 vector_pushBack (
struct X3D_Node*,node->_parentVector, parent);
1906 itype = getTypeNode(node);
1908 setSensitive (parent, itype );
1924 for (i=0; i<vectorSize(child->_parentVector); i++) {
1925 struct X3D_Node *n = vector_get(
struct X3D_Node *, child->_parentVector,i);
1927 if (n==parent) pi = i;
1933 struct X3D_Node *n = vector_get(
struct X3D_Node *, child->_parentVector,vectorSize(child->_parentVector)-1);
1936 vector_set(
struct X3D_Node*, child->_parentVector, pi,n);
1939 vector_popBack(
struct X3D_Node*, child->_parentVector);
1951 #include "../x3d_parser/Bindable.h"
1952 int fwl_getShadingStyle();
1953 void push_globalRenderFlags(){
1958 shaderflags = getShaderFlags();
1962 if(vectorSize(getActiveBindableStacks(tg)->fog) > 0){
1964 struct X3D_Fog *fog = stack_top(
struct X3D_Fog*,getActiveBindableStacks(tg)->fog);
1965 if(fog->visibilityRange > 0.0f){
1968 shaderflags.base |= FOG_APPEARANCE_SHADER;
1970 pushFogParams((
struct X3D_Node*)fog);
1974 if(Viewer()->anaglyph || Viewer()->anaglyphB)
1975 shaderflags.base |= WANT_ANAGLYPH;
1978 switch(fwl_getShadingStyle()){
1979 case 0: shaderflags.base |= SHADINGSTYLE_FLAT;
break;
1980 case 1: shaderflags.base |= SHADINGSTYLE_GOURAUD;
break;
1981 case 2: shaderflags.base |= SHADINGSTYLE_PHONG;
break;
1982 case 3: shaderflags.base |= SHADINGSTYLE_WIRE;
break;
1984 shaderflags.base |= SHADINGSTYLE_GOURAUD;
break;
1987 pushShaderFlags(shaderflags);
1989 void pop_globalRenderFlags(){
1996 if(vectorSize(getActiveBindableStacks(tg)->fog) > 0){
1997 struct X3D_Fog *fog = stack_top(
struct X3D_Fog*,getActiveBindableStacks(tg)->fog);
1998 if(fog->visibilityRange > 0.0f){
2005 void render_hier(
struct X3D_Node *g,
int rwhat) {
2016 pushShaderFlags(shaderflags);
2018 rs->render_vp = rwhat & VF_Viewpoint;
2019 rs->render_geom = rwhat & VF_Geom;
2020 rs->render_light = rwhat & VF_globalLight;
2021 rs->render_sensitive = rwhat & VF_Sensitive;
2022 rs->render_picking = rwhat & VF_Picking;
2023 rs->render_blend = rwhat & VF_Blend;
2024 rs->render_proximity = rwhat & VF_Proximity;
2025 rs->render_collision = rwhat & VF_Collision;
2026 rs->render_other = rwhat & VF_Other;
2027 rs->render_cube = rwhat & VF_Cube;
2030 tg->RenderFuncs.hitPointDist = -1;
2033 #ifdef RENDERVERBOSE
2034 printf (
"render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
2035 rs->render_vp,rs->render_geom,rs->render_light,rs->render_sensitive,rs->render_blend,rs->render_proximity,rs->render_collision);
2044 #ifdef RENDERVERBOSE
2045 printf(
"Render_hier node=%d what=%d\n", g, rwhat);
2049 if (rs->render_sensitive) {
2052 if(rs->render_blend || rs->render_geom){
2053 push_globalRenderFlags();
2056 profile_start(
"render_hier");
2057 render_node(X3D_NODE(g));
2058 profile_end(
"render_hier");
2059 if(rs->render_blend || rs->render_geom){
2060 pop_globalRenderFlags();
2074 void compileNode (
void (*nodefn)(
void *,
void *,
void *,
void *,
void *,
void *),
void *node,
void *Icoord,
void *IfogCoord,
void *Icolor,
void *Inormal,
void *ItexCoord) {
2075 void *coord;
void *fogCoord;
void *color;
void *normal;
void *texCoord;
2078 POSSIBLE_PROTO_EXPANSION(
void *, Icoord,coord)
2079 POSSIBLE_PROTO_EXPANSION(
void *, IfogCoord,fogCoord)
2080 POSSIBLE_PROTO_EXPANSION(
void *, Icolor,color)
2081 POSSIBLE_PROTO_EXPANSION(
void *, Inormal,normal)
2082 POSSIBLE_PROTO_EXPANSION(
void *, ItexCoord,texCoord)
2084 nodefn(node, coord, fogCoord, color, normal, texCoord);
2087 void do_NurbsPositionInterpolator (
void *node);
2088 void do_NurbsOrientationInterpolator (
void *node);
2089 void do_NurbsSurfaceInterpolator (
void *node);
2092 void *returnInterpolatorPointer (
int nodeType) {
2093 void (*do_interp)(
void *);
2097 case NODE_OrientationInterpolator: do_interp = do_Oint4;
break;
2098 case NODE_CoordinateInterpolator2D: do_interp = do_OintCoord2D;
break;
2099 case NODE_PositionInterpolator2D: do_interp = do_OintPos2D;
break;
2100 case NODE_ScalarInterpolator: do_interp = do_OintScalar;
break;
2101 case NODE_ColorInterpolator: do_interp = do_ColorInterpolator;
break;
2102 case NODE_PositionInterpolator: do_interp = do_PositionInterpolator;
break;
2103 case NODE_CoordinateInterpolator: do_interp = do_OintCoord;
break;
2104 case NODE_NormalInterpolator: do_interp = do_OintNormal;
break;
2105 case NODE_EaseInEaseOut: do_interp = do_EaseInEaseOut;
break;
2106 case NODE_SplinePositionInterpolator: do_interp = do_SplinePositionInterpolator;
break;
2107 case NODE_SplinePositionInterpolator2D: do_interp = do_SplinePositionInterpolator2D;
break;
2108 case NODE_SplineScalarInterpolator: do_interp = do_SplineScalarInterpolator;
break;
2109 case NODE_SquadOrientationInterpolator: do_interp = do_SquadOrientationInterpolator;
break;
2110 case NODE_GeoPositionInterpolator: do_interp = do_GeoPositionInterpolator;
break;
2111 case NODE_NurbsPositionInterpolator: do_interp = do_NurbsPositionInterpolator;
break;
2112 case NODE_NurbsOrientationInterpolator: do_interp = do_NurbsOrientationInterpolator;
break;
2113 case NODE_NurbsSurfaceInterpolator: do_interp = do_NurbsSurfaceInterpolator;
break;
2114 case NODE_BooleanFilter: do_interp = do_BooleanFilter;
break;
2115 case NODE_BooleanSequencer: do_interp = do_BooleanSequencer;
break;
2116 case NODE_BooleanToggle: do_interp = do_BooleanToggle;
break;
2117 case NODE_BooleanTrigger: do_interp = do_BooleanTrigger;
break;
2118 case NODE_IntegerTrigger: do_interp = do_IntegerTrigger;
break;
2119 case NODE_IntegerSequencer: do_interp = do_IntegerSequencer;
break;
2120 case NODE_TimeTrigger: do_interp = do_TimeTrigger;
break;
2124 return (
void *)do_interp;
2164 if (node == NULL)
return;
2168 if (parent != NULL) ADD_PARENT(node, parent);
2170 if ((node->_nodeType<0) || (node->_nodeType>NODES_COUNT)) {
2171 ConsoleMessage (
"checkParentLink - %d not a valid nodeType",node->_nodeType);
2176 offsetptr = (
int *) NODE_OFFSETS[node->_nodeType];
2179 while (*offsetptr >= 0) {
2189 if ((offsetptr[2] == FIELDTYPE_SFNode) || (offsetptr[2] == FIELDTYPE_MFNode)) {
2190 if ((offsetptr[3] == KW_initializeOnly) || (offsetptr[3] == KW_inputOutput)) {
2193 memptr = (
char *) node;
2194 memptr += offsetptr[1];
2196 if (offsetptr[2] == FIELDTYPE_SFNode) {
2198 voidptr = (uintptr_t *) memptr;
2199 voidptr = (uintptr_t *) *voidptr;
2202 if (voidptr != NULL) {
2203 checkParentLink(X3D_NODE(voidptr),node);
2208 for (n=0; n<mfn->n; n++) {
2209 checkParentLink(mfn->p[n],node);
2219 #define X3D_COORD(node) ((struct X3D_Coordinate*)node)
2220 #define X3D_GEOCOORD(node) ((struct X3D_GeoCoordinate*)node)
2228 POSSIBLE_PROTO_EXPANSION (
struct X3D_Node *, innode,node)
2231 xc = X3D_COORD(node);
2233 if (xc->_nodeType == NODE_Coordinate) {
2234 return &(xc->point);
2235 }
else if (xc->_nodeType == NODE_GeoCoordinate) {
2236 COMPILE_IF_REQUIRED_RETURN_NULL_ON_ERROR;
2237 gxc = X3D_GEOCOORD(node);
2238 return &(gxc->__movedCoords);
2240 ConsoleMessage (
"%s - coord expected but got %s\n", stringNodeType(xc->_nodeType));