34#include <libFreeWRL.h>
36#include "../vrml_parser/Structs.h"
37#include "../main/headers.h"
38#include "../scenegraph/Component_ProgrammableShaders.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"
53#include "../ui/common.h"
55typedef 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;
144void *RenderFuncs_constructor(){
149void 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;
208void 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);
217void 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;
267void 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);
276void 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){
320 p->usehitsB_stack->n = 0;
322Stack *getUseHitBStack(){
324 return p->usehitsB_stack;
330void push_pickablegroupdata(
void *userdata){
332 stack_push(
void*,p->pickablegroupdata_stack,userdata);
334void pop_pickablegroupdata(){
336 stack_pop(
void*,p->pickablegroupdata_stack);
338void *getpickablegroupdata(){
342 if(vectorSize(p->pickablegroupdata_stack)>0)
343 ret = stack_top(
void*,p->pickablegroupdata_stack);
348void unload_libraryscenes();
349int gc_broto_instance(
struct X3D_Proto* node);
350void 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);
364void 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);
396void clearLightTable(){
399 p->nextFreeLight = 0;
409 int rv = p->nextFreeLight;
410 if(rv == HEADLIGHT_LIGHT) {
413 p->lightChanged[rv] = 0;
419void setLightType(GLint light,
int type) {
421 p->lightType[light] = type;
423void setLightChangedFlag(GLint light) {
425 p->lightChanged[light] = 1;
429void 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");
442void saveLightState2(
int *last) {
444 *last = p->nextFreeLight;
447void restoreLightState2(
int last) {
449 p->nextFreeLight = last;
451void refreshLightUniforms(){
453 p->refreshLightUniforms = TRUE;
457 int rv = p->nextFreeLight;
466 if(p->localLight_stack->n)
467 retval = stack_top(
int,p->localLight_stack);
470void pushLocalLight(
int lastlight){
476 stack_push(
int,p->localLight_stack,lastlight);
482 stack_pop(
int,p->localLight_stack);
486void 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]);
532void 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);}
584void 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");
740void finishedWithGlobalShader(
void) {
745 getAppearanceProperties()->currentShaderProperties = NULL;
746FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
748FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
757void resetGlobalShader() {
763 p->currentShader = 0;
766void 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;
792void sendAttribToGPU(
int myType,
int dataSize,
int dataType,
int normalized,
int stride,
float *pointer,
int texID,
char *file,
int line){
802ConsoleMessage (
"sendAttribToGPU, getAppearanceProperties()->currentShaderProperties %p\n",getAppearanceProperties()->currentShaderProperties);
803ConsoleMessage (
"myType %d, dataSize %d, dataType %d, stride %d\n",myType,dataSize,dataType,stride);
806 case FW_NORMAL_POINTER_TYPE:
807 ConsoleMessage (
"glVertexAttribPointer Normals %d at %s:%d\n",me->Normals,file,line);
809 case FW_VERTEX_POINTER_TYPE:
810 ConsoleMessage (
"glVertexAttribPointer Vertexs %d at %s:%d\n",me->Vertices,file,line);
812 case FW_COLOR_POINTER_TYPE:
813 ConsoleMessage (
"glVertexAttribPointer Colours %d at %s:%d\n",me->Colours,file,line);
815 case FW_TEXCOORD_POINTER_TYPE:
816 ConsoleMessage (
"glVertexAttribPointer TexCoords %d at %s:%d\n",me->TexCoords,file,line);
819 default : {ConsoleMessage (
"sendAttribToGPU, unknown type in shader\n");}
826 case FW_NORMAL_POINTER_TYPE:
827 if (me->Normals != -1) {
828 glEnableVertexAttribArray(me->Normals);
829 glVertexAttribPointer(me->Normals, 3, dataType, normalized, stride, pointer);
832 case FW_FOG_POINTER_TYPE:
833 if (me->FogCoords != -1) {
834 glEnableVertexAttribArray(me->FogCoords);
835 glVertexAttribPointer(me->FogCoords, 1, dataType, normalized, stride, pointer);
839 case FW_VERTEX_POINTER_TYPE:
840 if (me->Vertices != -1) {
841 glEnableVertexAttribArray(me->Vertices);
842 glVertexAttribPointer(me->Vertices, dataSize, dataType, normalized, stride, pointer);
845 case FW_COLOR_POINTER_TYPE:
846 if (me->Colours != -1) {
847 glEnableVertexAttribArray(me->Colours);
848 glVertexAttribPointer(me->Colours, dataSize, dataType, normalized, stride, pointer);
851 case FW_TEXCOORD_POINTER_TYPE:
852 if (me->TexCoords[texID] != -1) {
853 glEnableVertexAttribArray(me->TexCoords[texID]);
854 glVertexAttribPointer(me->TexCoords[texID], dataSize, dataType, normalized, stride, pointer);
859 default : {printf (
"sendAttribToGPU, unknown type in shader\n");}
864void sendBindBufferToGPU (GLenum target, GLuint buffer,
char *file,
int line) {
875 glBindBuffer(target,buffer);
888PRINT_GL_ERROR_IF_ANY(
"BEGIN setupShader");
893 if (!(mysp->compiledOK)) {
895 printf (
"shader compile error\n");
897 PRINT_GL_ERROR_IF_ANY(
"EXIT(false) setupShader");
902 printf (
"setupShader, we have Normals %d Vertices %d Colours %d TexCoords %d \n",
910 sendFogToShader(mysp);
911 sendClipplanesToShader(mysp);
912 sendMaterialsToShader(mysp);
913 sendMatriciesToShader(mysp);
924void saveArraysForGPU(
int mode,
int first,
int count){
931 params.arrays.arrays_mode = mode;
932 params.arrays.arrays_count = count;
933 params.arrays.arrays_first = first;
938void saveElementsForGPU(
int mode,
int count, ushort *indices){
947 params.elements.elements_count = count;
948 params.elements.elements_mode = mode;
949 params.elements.elements_indices = indices;
953void reallyDrawOnce(){
962 for(i=0;i<vectorSize(p->draw_call_params_stack);i++){
964 if(params->calltype == 1){
969 #define CATCH_GLDRAWARRAYS_THROWS 1
970 #if defined(CATCH_GLDRAWARRAYS_THROWS) && defined(_MSC_VER) && defined(W_DEBUG)
972 glDrawArrays(params->arrays.arrays_mode,params->arrays.arrays_first,params->arrays.arrays_count);
974 __except(EXCEPTION_EXECUTE_HANDLER) {
975 printf(
"\n ouch from reallyDrawOnce glDrawArrays \n");
976 printf(
"i= %d n= %d",i,vectorSize(p->draw_call_params_stack));
979 glDrawArrays(params->arrays.arrays_mode,params->arrays.arrays_first,params->arrays.arrays_count);
981 }
else if(params->calltype == 2){
982 glDrawElements(params->elements.elements_mode,params->elements.elements_count,GL_UNSIGNED_SHORT,params->elements.elements_indices);
992 p->draw_call_params_stack->n = 0;
999void sendArraysToGPU (
int mode,
int first,
int count) {
1000 #ifdef RENDERVERBOSE
1001 printf (
"sendArraysToGPU start\n");
1017 profile_start(
"draw_arr");
1019 saveArraysForGPU(mode,first,count);
1020 profile_end(
"draw_arr");
1022 #ifdef RENDERVERBOSE
1023 printf (
"sendArraysToGPU end\n");
1029void sendElementsToGPU (
int mode,
int count, ushort *indices) {
1030 #ifdef RENDERVERBOSE
1031 printf (
"sendElementsToGPU start\n");
1035 profile_start(
"draw_el");
1037 saveElementsForGPU(mode,count,indices);
1038 profile_end(
"draw_el");
1041 #ifdef RENDERVERBOSE
1042 printf (
"sendElementsToGPU finish\n");
1047void initializeLightTables() {
1049 float pos[] = { 0.0f, 0.0f, 1.0f, 0.0f };
1050 float dif[] = { 1.0f, 1.0f, 1.0f, 1.0f };
1051 float shin[] = { 0.0f, 0.0f, 0.0f, 1.0f };
1052 float As[] = { 0.0f, 0.0f, 0.0f, 1.0f };
1055 PRINT_GL_ERROR_IF_ANY(
"start of initializeightTables");
1057 for(i=0; i<MAX_LIGHT_STACK; i++) {
1058 p->lightOnOff[i] = TRUE;
1059 setLightState(i,FALSE);
1061 FW_GL_LIGHTFV(i, GL_SPOT_DIRECTION, pos);
1062 FW_GL_LIGHTFV(i, GL_POSITION, pos);
1063 FW_GL_LIGHTFV(i, GL_AMBIENT, As);
1064 FW_GL_LIGHTFV(i, GL_DIFFUSE, dif);
1065 FW_GL_LIGHTFV(i, GL_SPECULAR, shin);
1066 FW_GL_LIGHTF(i, GL_CONSTANT_ATTENUATION,1.0f);
1067 FW_GL_LIGHTF(i, GL_LINEAR_ATTENUATION,0.0f);
1068 FW_GL_LIGHTF(i, GL_QUADRATIC_ATTENUATION,0.0f);
1069 FW_GL_LIGHTF(i, GL_SPOT_CUTOFF,0.0f);
1070 FW_GL_LIGHTF(i, GL_SPOT_BEAMWIDTH,0.0f);
1071 FW_GL_LIGHTF(i, GL_LIGHT_RADIUS, 100000.0);
1073 PRINT_GL_ERROR_IF_ANY(
"initizlizeLight2.10");
1075 setLightState(HEADLIGHT_LIGHT, TRUE);
1080 PRINT_GL_ERROR_IF_ANY(
"end initializeLightTables");
1087 return &p->renderstate;
1092GLint viewport[4] = {-1,-1,2,2};
1099struct point_XYZ r1 = {0,0,-1}, r2 = {0,0,0}, r3 = {0,1,0};
1105 return p->AnchorsAnchor;
1107void setAnchorsAnchor(
struct X3D_Anchor* anchor)
1110 p->AnchorsAnchor = anchor;
1126 ConsoleMessage (
"rootNode, p null");
1131void setRootNode(
struct X3D_Node *rn)
1146void addLibrary(
char *url,
struct X3D_Proto *library,
void *res){
1149 ul->one = (
void *)STRDUP(url);
1150 ul->two = (
void *)library;
1152 vector_pushBack(
void3 *,p->libraries,ul);
1154void3 *librarySearch(
char *absoluteUniUrlNoPound){
1159 libs = p->libraries;
1160 n = vectorSize(libs);
1162 ul = vector_get(
void3 *,libs,i);
1164 if(!strcmp(absoluteUniUrlNoPound,ul->one)){
1177void prepare_model_view_pickmatrix0(GLDOUBLE *modelMatrix, GLDOUBLE *mvp){
1180 GLDOUBLE *pickMatrixi;
1182 pickMatrixi = getPickrayMatrix(1);
1185 matmultiplyAFFINE(mvp,modelMatrix,pickMatrixi);
1188void prepare_model_view_pickmatrix_inverse0(GLDOUBLE *modelMatrix, GLDOUBLE *mvpi){
1193 GLDOUBLE *pickMatrix;
1195 pickMatrix = getPickrayMatrix(0);
1198 matinverseAFFINE(mvi,modelMatrix);
1199 matmultiplyAFFINE(mvpi,pickMatrix,mvi);
1222void rayhit(
float rat,
float cx,
float cy,
float cz,
float nx,
float ny,
float nz,
1223 float tx,
float ty,
char *descr) {
1224 GLDOUBLE modelMatrix[16];
1238 if(rat<0 || (rat>tg->RenderFuncs.hitPointDist && tg->RenderFuncs.hitPointDist >= 0)) {
1241 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1245 tp.x = cx; tp.y = cy; tp.z = cz;
1246 prepare_model_view_pickmatrix0(modelMatrix,mvp);
1247 transform(&tp,&tp,mvp);
1250 tg->RenderFuncs.hitPointDist = rat;
1253 printf (
"Rayhit, hp.x y z: - %f %f %f hitPointDist %f %s\n",p->hp.x,p->hp.y,p->hp.z, rat, descr);
1264 GLDOUBLE modelMatrix[16];
1265 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1284 struct point_XYZ view_cam_axis, local_cam_axis;
1286 view_cam_axis.x = 0.0;
1287 view_cam_axis.y = 0.0;
1288 view_cam_axis.z = -1.0;
1289 matinverseAFFINE(mvi,modelMatrix);
1290 transformAFFINE(&local_cam_axis,&view_cam_axis,mvi);
1291 tg->RenderFuncs.camera_axis[0] = local_cam_axis.x;
1292 tg->RenderFuncs.camera_axis[1] = local_cam_axis.y;
1293 tg->RenderFuncs.camera_axis[2] = local_cam_axis.z;
1296 prepare_model_view_pickmatrix_inverse0(modelMatrix, mvpi);
1297 transform(t_r1,&r11,mvpi);
1298 transform(t_r2,&r2,mvpi);
1299 transform(t_r3,&r3,mvpi);
1310void setup_pickray0();
1317 upd_ray0(&p->t_r123.p1,&p->t_r123.p2,&p->t_r123.p3);
1325void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
1326int pickrayHitsMBB(
struct X3D_Node *node){
1331 GLDOUBLE modelMatrix[16];
1338 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
1343 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
1345 prepare_model_view_pickmatrix0(modelMatrix, mvp);
1349 shapeMBBmin[i] = node->_extent[i*2 + 1];
1350 shapeMBBmax[i] = node->_extent[i*2];
1352 transformMBB(smin,smax,mvp,shapeMBBmin,shapeMBBmax);
1356 isIn = isIn && (smin[i] <= 0.0 && smax[i] >= 0.0);
1370void update_node(
struct X3D_Node *node) {
1374 printf (
"update_node for %d %s nparents %d renderflags %x\n",node, stringNodeType(node->_nodeType),node->_nparents, node->_renderFlags);
1375 if (node->_nparents == 0) {
1376 if (node == rootNode) printf (
"...no parents, this IS the rootNode\n");
1377 else printf (
"...no parents, this IS NOT the rootNode\n");
1382 for (i = 0; i < node->_nparents; i++) {
1383 struct X3D_Node *n = X3D_NODE(node->_parents[i]);
1385 printf (
" parent %u is %s\n",n,stringNodeType(n->_nodeType));
1387 printf (
" parent %d is NULL\n",i);
1395 if (node->_parentVector == NULL) {
1399 for (i = 0; i < vectorSize(node->_parentVector); i++) {
1402 fprintf(stderr,
"Error: self-referential node structure! (node:'%s')\n", stringNodeType(node->_nodeType));
1403 vector_set(
struct X3D_Node*, node->_parentVector, i,NULL);
1404 }
else if( n != 0 ) {
1421#define PRINT_NODE(_node, _v) do { \
1422 if (gglobal()->internalc.global_print_opengl_errors && (gglobal()->display._global_gl_err != GL_NO_ERROR)) { \
1423 printf("Render_node_v %p (%s) PREP: %p REND: %p CH: %p FIN: %p RAY: %p HYP: %p\n",_v, \
1424 stringNodeType(_node->_nodeType), \
1430 gglobal()->RenderFuncs.hypersensitive); \
1431 printf("Render_state geom %d light %d sens %d\n", \
1432 renderstate()->render_geom, \
1433 renderstate()->render_light, \
1434 renderstate()->render_sensitive); \
1435 printf("pchange %d pichange %d \n", _node->_change, _node->_ichange); \
1452void profile_start(
char *name){
1459 if (!p->profiling_on)
return;
1460 pe = p->profile_entries;
1462 for(i=0;i<p->profile_entry_count;i++){
1463 if(!strcmp(name,pe[i].name)){
1469 pe[p->profile_entry_count].name = name;
1470 pe[p->profile_entry_count].hits = 0;
1471 ifound = p->profile_entry_count;
1472 p->profile_entry_count++;
1474 pe[ifound].start = Time1970sec();
1476void profile_end(
char *name){
1483 if (!p->profiling_on)
return;
1484 pe = p->profile_entries;
1485 for(i=0;i<p->profile_entry_count;i++){
1486 if(!strcmp(name,pe[i].name)){
1492 pe[ifound].accum += Time1970sec() - pe[ifound].start;
1496void profile_print_all(){
1502 if (!p->profiling_on){
1503 p->profiling_on = 1;
1504 ConsoleMessage(
"turning profiling on\n");
1507 pe = p->profile_entries;
1508 ConsoleMessage(
"frame rate: %9.3f number of items tracked: %d\n", gglobal()->Mainloop.BrowserFPS,p->profile_entry_count);
1509 ConsoleMessage(
"%15s %10s %15s %10s\n",
"profile name",
"hits",
"time(sec)",
"% of 1st");
1510 for (i = 0; i < p->profile_entry_count; i++){
1511 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);
1541void popShaderFlags(){
1555 retval = stack_top(
struct X3D_Node*,p->fog_stack);
1558void pushFogParams(
struct X3D_Node *fogparams){
1564 stack_push(
struct X3D_Node*,p->fog_stack,fogparams);
1571 stack_pop(
struct X3D_Node*,p->fog_stack);
1590 stack_push(
struct point_XYZ3,p->ray_stack,p->t_r123);
1596 upd_ray0(&p->t_r123.p1,&p->t_r123.p2,&p->t_r123.p3);
1607 p->t_r123 = stack_top(
struct point_XYZ3,p->ray_stack);
1620void push_render_geom(
int igeom){
1623 stack_push(
int,p->render_geom_stack,p->renderstate.render_geom);
1624 p->renderstate.render_geom = igeom;
1626void pop_render_geom(){
1630 igeom = stack_top(
int,p->render_geom_stack);
1631 stack_pop(
int,p->render_geom_stack);
1632 p->renderstate.render_geom = igeom;
1634void push_sensor(
struct X3D_Node *node){
1638 push_render_geom(1);
1639 stack_push(
struct currayhit,p->sensor_stack,p->rayph);
1643 p->rayph.hitNode = node;
1644 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, p->rayph.modelMatrix);
1645 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, p->rayph.projMatrix);
1654 p->rayph = stack_top(
struct currayhit,p->sensor_stack);
1655 stack_pop(
struct currayhit,p->sensor_stack);
1660int render_foundLayerViewpoint();
1661void extent6f_draw(
float *extent);
1662static int draw_extents = TRUE;
1663void render_node(
struct X3D_Node *node) {
1676 X3D_NODE_CHECK(node);
1684 DEBUG_RENDER(
"%d no node, quick return\n", renderLevel);
1689 virt = virtTable[node->_nodeType];
1695 for(i=0;i<p->renderLevel;i++) printf(
" ");
1697 printf(
"%d node %u (%s) , v %u renderFlags %x ",p->renderLevel, node,stringNodeType(node->_nodeType),virt,node->_renderFlags);
1699 if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf (
" VF_Viewpoint");
1700 if ((node->_renderFlags & VF_Geom )== VF_Geom) printf (
" VF_Geom");
1701 if ((node->_renderFlags & VF_localLight )== VF_localLight) printf (
" VF_localLight");
1702 if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf (
" VF_Sensitive");
1703 if ((node->_renderFlags & VF_Blend) == VF_Blend) printf (
" VF_Blend");
1704 if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf (
" VF_Proximity");
1705 if ((node->_renderFlags & VF_Collision) == VF_Collision) printf (
" VF_Collision");
1706 if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf (
" VF_globalLight");
1707 if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf (
" VF_hasVisibleChildren");
1708 if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf (
" VF_shouldSortChildren");
1709 if ((node->_renderFlags & VF_Other) == VF_Other) printf (
" VF_Other");
1728 if (p->renderstate.render_vp == VF_Viewpoint) {
1730 if ((node->_renderFlags & VF_Viewpoint) != VF_Viewpoint) {
1731 #ifdef RENDERVERBOSE
1732 printf (
"doing Viewpoint, but this node is not for us - just returning\n");
1737 if(p->renderstate.render_vp == VF_Viewpoint && render_foundLayerViewpoint()){
1744 if (p->renderstate.render_light ) {
1745 if((node->_renderFlags & VF_globalLight) != VF_globalLight) {
1746 #ifdef RENDERVERBOSE
1747 printf (
"doing globalLight, but this node is not for us - just returning\n");
1753 justGeom = p->renderstate.render_geom && !p->renderstate.render_sensitive && !p->renderstate.render_blend;
1755 pushed_sensor = FALSE;
1759 DEBUG_RENDER(
"rs 2\n");
1760 profile_start(
"prep");
1762 profile_start(
"prepgeom");
1764 profile_end(
"prep");
1766 profile_end(
"prepgeom");
1771 PRINT_GL_ERROR_IF_ANY(
"prep"); PRINT_NODE(node,virt);
1772 if(p->renderstate.render_boxes) extent6f_draw(node->_extent);
1775 if(p->renderstate.render_sensitive && !tg->RenderFuncs.hypersensitive) {
1779 if(p->renderstate.render_proximity && virt->proximity) {
1780 DEBUG_RENDER(
"rs 2a\n");
1781 profile_start(
"proximity");
1782 virt->proximity(node);
1783 profile_end(
"proximity");
1784 PRINT_GL_ERROR_IF_ANY(
"render_proximity"); PRINT_NODE(node,virt);
1786 if(p->renderstate.render_geom && ((node->_renderFlags & VF_USE) == VF_USE) && !p->renderstate.render_picking){
1791 if(getWindex() == 0){
1795 double modelviewMatrix[16];
1798 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
1800 usehit_add2(node,modelviewMatrix,getpickablegroupdata());
1803 if(p->renderstate.render_picking && node->_nodeType == NODE_Shape ){
1807 double modelviewMatrix[16];
1809 if(shapenode->geometry){
1812 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelviewMatrix);
1814 usehitB_add2(shapenode->geometry,modelviewMatrix,getpickablegroupdata());
1818 if(p->renderstate.render_collision && virt->collision) {
1819 DEBUG_RENDER(
"rs 2b\n");
1820 profile_start(
"collision");
1821 virt->collision(node);
1822 profile_end(
"collision");
1823 PRINT_GL_ERROR_IF_ANY(
"render_collision"); PRINT_NODE(node,virt);
1826 if(p->renderstate.render_geom && !p->renderstate.render_sensitive && !p->renderstate.render_picking && virt->rend) {
1827 DEBUG_RENDER(
"rs 3\n");
1828 PRINT_GL_ERROR_IF_ANY(
"BEFORE render_geom"); PRINT_NODE(node,virt);
1829 profile_start(
"rend");
1831 profile_end(
"rend");
1832 PRINT_GL_ERROR_IF_ANY(
"render_geom"); PRINT_NODE(node,virt);
1834 if(p->renderstate.render_other && virt->other )
1839 if(p->renderstate.render_sensitive && ((node->_renderFlags & VF_Sensitive)|| Viewer()->LookatMode ==2)) {
1840 DEBUG_RENDER(
"rs 5\n");
1841 profile_start(
"sensitive");
1843 pushed_sensor = TRUE;
1844 profile_end(
"sensitive");
1846 if(p->renderstate.render_geom && p->renderstate.render_sensitive && !tg->RenderFuncs.hypersensitive && virt->rendray) {
1847 DEBUG_RENDER(
"rs 6\n");
1848 profile_start(
"rendray");
1849 if(pickrayHitsMBB(node))
1850 virt->rendray(node);
1851 profile_end(
"rendray");
1852 PRINT_GL_ERROR_IF_ANY(
"rs 6"); PRINT_NODE(node,virt);
1865 if(virt->children) {
1866 DEBUG_RENDER(
"rs 8 - has valid child node pointer\n");
1869 virt->children(node);
1874 PRINT_GL_ERROR_IF_ANY(
"children"); PRINT_NODE(node,virt);
1878 if(p->renderstate.render_other && virt->other)
1886 DEBUG_RENDER(
"rs A\n");
1887 profile_start(
"fin");
1889 profile_start(
"fingeom");
1894 profile_end(
"fingeom");
1898 PRINT_GL_ERROR_IF_ANY(
"fin"); PRINT_NODE(node,virt);
1906 for(i=0;i<p->renderLevel;i++)printf(
" ");
1908 printf(
"%d (end render_node)\n",p->renderLevel);
1924void add_parent(
struct X3D_Node *node,
struct X3D_Node *parent,
char *file,
int line) {
1930 printf (
"add_parent; adding node %u ,to parent %u at %s:%d\n",node, parent,file,line);
1931 printf (
"add_parent; adding node %x ,to parent %x (hex) at %s:%d\n",node, parent,file,line);
1932 printf (
"add_parent; adding node %p ,to parent %p (ptr) at %s:%d\n",node, parent,file,line);
1935 printf (
"add_parent; adding node %u (%s) to parent %u (%s) at %s:%d\n",node, stringNodeType(node->_nodeType),
1936 parent, stringNodeType(parent->_nodeType),file,line);
1939 parent->_renderFlags = parent->_renderFlags | node->_renderFlags;
1942 vector_pushBack (
struct X3D_Node*,node->_parentVector, parent);
1944 itype = getTypeNode(node);
1946 setSensitive (parent, itype );
1962 for (i=0; i<vectorSize(child->_parentVector); i++) {
1963 struct X3D_Node *n = vector_get(
struct X3D_Node *, child->_parentVector,i);
1965 if (n==parent) pi = i;
1971 struct X3D_Node *n = vector_get(
struct X3D_Node *, child->_parentVector,vectorSize(child->_parentVector)-1);
1974 vector_set(
struct X3D_Node*, child->_parentVector, pi,n);
1977 vector_popBack(
struct X3D_Node*, child->_parentVector);
1989#include "../x3d_parser/Bindable.h"
1990int fwl_getShadingStyle();
1991void push_globalRenderFlags(){
1996 shaderflags = getShaderFlags();
2000 if(vectorSize(getActiveBindableStacks(tg)->fog) > 0){
2002 struct X3D_Fog *fog = stack_top(
struct X3D_Fog*,getActiveBindableStacks(tg)->fog);
2003 if(fog->visibilityRange > 0.0f){
2006 shaderflags.base |= FOG_APPEARANCE_SHADER;
2008 pushFogParams((
struct X3D_Node*)fog);
2012 if(Viewer()->anaglyph || Viewer()->anaglyphB)
2013 shaderflags.base |= WANT_ANAGLYPH;
2016 switch(fwl_getShadingStyle()){
2017 case 0: shaderflags.base |= SHADINGSTYLE_FLAT;
break;
2018 case 1: shaderflags.base |= SHADINGSTYLE_GOURAUD;
break;
2019 case 2: shaderflags.base |= SHADINGSTYLE_PHONG;
break;
2020 case 3: shaderflags.base |= SHADINGSTYLE_WIRE;
break;
2022 shaderflags.base |= SHADINGSTYLE_GOURAUD;
break;
2024 if(tg->Component_PTM.globalProjector){
2025 shaderflags.base |= HAVE_PROJECTIVETEXTURE;
2027 pushShaderFlags(shaderflags);
2029void pop_globalRenderFlags(){
2036 if(vectorSize(getActiveBindableStacks(tg)->fog) > 0){
2037 struct X3D_Fog *fog = stack_top(
struct X3D_Fog*,getActiveBindableStacks(tg)->fog);
2038 if(fog->visibilityRange > 0.0f){
2044 tg->Component_PTM.globalProjector = 0;
2047void render_hier(
struct X3D_Node *g,
int rwhat) {
2058 pushShaderFlags(shaderflags);
2060 rs->render_vp = rwhat & VF_Viewpoint;
2061 rs->render_geom = rwhat & VF_Geom;
2062 rs->render_light = rwhat & VF_globalLight;
2063 rs->render_sensitive = rwhat & VF_Sensitive;
2064 rs->render_picking = rwhat & VF_Picking;
2065 rs->render_blend = rwhat & VF_Blend;
2066 rs->render_proximity = rwhat & VF_Proximity;
2067 rs->render_collision = rwhat & VF_Collision;
2068 rs->render_other = rwhat & VF_Other;
2069 rs->render_cube = rwhat & VF_Cube;
2070 rs->render_background = rwhat & VF_Background;
2071 rs->render_boxes = (rwhat & VF_Geom) && fwl_getDrawBoundingBoxes();
2074 tg->RenderFuncs.hitPointDist = -1;
2078 printf (
"render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
2079 rs->render_vp,rs->render_geom,rs->render_light,rs->render_sensitive,rs->render_blend,rs->render_proximity,rs->render_collision);
2089 printf(
"Render_hier node=%d what=%d\n", g, rwhat);
2093 if (rs->render_sensitive) {
2096 if(rs->render_blend || rs->render_geom){
2097 push_globalRenderFlags();
2100 profile_start(
"render_hier");
2101 render_node(X3D_NODE(g));
2102 profile_end(
"render_hier");
2103 if(rs->render_blend || rs->render_geom){
2104 pop_globalRenderFlags();
2118void compileNode (
void (*nodefn)(
void *,
void *,
void *,
void *,
void *,
void *),
void *node,
void *Icoord,
void *IfogCoord,
void *Icolor,
void *Inormal,
void *ItexCoord) {
2119 void *coord;
void *fogCoord;
void *color;
void *normal;
void *texCoord;
2122 POSSIBLE_PROTO_EXPANSION(
void *, Icoord,coord)
2123 POSSIBLE_PROTO_EXPANSION(
void *, IfogCoord,fogCoord)
2124 POSSIBLE_PROTO_EXPANSION(
void *, Icolor,color)
2125 POSSIBLE_PROTO_EXPANSION(
void *, Inormal,normal)
2126 POSSIBLE_PROTO_EXPANSION(
void *, ItexCoord,texCoord)
2128 nodefn(node, coord, fogCoord, color, normal, texCoord);
2131void do_NurbsPositionInterpolator (
void *node);
2132void do_NurbsOrientationInterpolator (
void *node);
2133void do_NurbsSurfaceInterpolator (
void *node);
2136void *returnInterpolatorPointer (
int nodeType) {
2137 void (*do_interp)(
void *);
2141 case NODE_OrientationInterpolator: do_interp = do_Oint4;
break;
2142 case NODE_CoordinateInterpolator2D: do_interp = do_OintCoord2D;
break;
2143 case NODE_PositionInterpolator2D: do_interp = do_OintPos2D;
break;
2144 case NODE_ScalarInterpolator: do_interp = do_OintScalar;
break;
2145 case NODE_ColorInterpolator: do_interp = do_ColorInterpolator;
break;
2146 case NODE_PositionInterpolator: do_interp = do_PositionInterpolator;
break;
2147 case NODE_CoordinateInterpolator: do_interp = do_OintCoord;
break;
2148 case NODE_NormalInterpolator: do_interp = do_OintNormal;
break;
2149 case NODE_EaseInEaseOut: do_interp = do_EaseInEaseOut;
break;
2150 case NODE_SplinePositionInterpolator: do_interp = do_SplinePositionInterpolator;
break;
2151 case NODE_SplinePositionInterpolator2D: do_interp = do_SplinePositionInterpolator2D;
break;
2152 case NODE_SplineScalarInterpolator: do_interp = do_SplineScalarInterpolator;
break;
2153 case NODE_SquadOrientationInterpolator: do_interp = do_SquadOrientationInterpolator;
break;
2154 case NODE_GeoPositionInterpolator: do_interp = do_GeoPositionInterpolator;
break;
2155 case NODE_NurbsPositionInterpolator: do_interp = do_NurbsPositionInterpolator;
break;
2156 case NODE_NurbsOrientationInterpolator: do_interp = do_NurbsOrientationInterpolator;
break;
2157 case NODE_NurbsSurfaceInterpolator: do_interp = do_NurbsSurfaceInterpolator;
break;
2158 case NODE_BooleanFilter: do_interp = do_BooleanFilter;
break;
2159 case NODE_BooleanSequencer: do_interp = do_BooleanSequencer;
break;
2160 case NODE_BooleanToggle: do_interp = do_BooleanToggle;
break;
2161 case NODE_BooleanTrigger: do_interp = do_BooleanTrigger;
break;
2162 case NODE_IntegerTrigger: do_interp = do_IntegerTrigger;
break;
2163 case NODE_IntegerSequencer: do_interp = do_IntegerSequencer;
break;
2164 case NODE_TimeTrigger: do_interp = do_TimeTrigger;
break;
2165 case NODE_GeoConvert: do_interp = do_GeoConvert;
break;
2169 return (
void *)do_interp;
2210 if (node == NULL)
return;
2214 if (parent != NULL) ADD_PARENT(node, parent);
2216 if ((node->_nodeType<0) || (node->_nodeType>NODES_COUNT)) {
2217 ConsoleMessage (
"checkParentLink - %d not a valid nodeType",node->_nodeType);
2222 offsetptr = (
int *) NODE_OFFSETS[node->_nodeType];
2225 while (*offsetptr >= 0) {
2235 if ((offsetptr[2] == FIELDTYPE_SFNode) || (offsetptr[2] == FIELDTYPE_MFNode)) {
2236 if ((offsetptr[3] == KW_initializeOnly) || (offsetptr[3] == KW_inputOutput)) {
2239 memptr = (
char *) node;
2240 memptr += offsetptr[1];
2242 if (offsetptr[2] == FIELDTYPE_SFNode) {
2244 voidptr = (uintptr_t *) memptr;
2245 voidptr = (uintptr_t *) *voidptr;
2248 if (voidptr != NULL) {
2249 checkParentLink(X3D_NODE(voidptr),node);
2254 for (n=0; n<mfn->n; n++) {
2255 checkParentLink(mfn->p[n],node);
2261 offsetptr += FIELDOFFSET_LENGTH;
2265#define X3D_COORD(node) ((struct X3D_Coordinate*)node)
2266#define X3D_GEOCOORD(node) ((struct X3D_GeoCoordinate*)node)
2274 POSSIBLE_PROTO_EXPANSION (
struct X3D_Node *, innode,node)
2277 xc = X3D_COORD(node);
2279 if (xc->_nodeType == NODE_Coordinate) {
2280 return &(xc->point);
2281 }
else if (xc->_nodeType == NODE_GeoCoordinate) {
2282 COMPILE_IF_REQUIRED_RETURN_NULL_ON_ERROR;
2283 gxc = X3D_GEOCOORD(node);
2284 return &(gxc->__movedCoords);
2286 ConsoleMessage (
"%s - coord expected but got %s\n", stringNodeType(xc->_nodeType));