36#include <libFreeWRL.h>
38#include "../vrml_parser/Structs.h"
39#include "../vrml_parser/CRoutes.h"
40#include "../main/headers.h"
42#include "../opengl/OpenGL_Utils.h"
43#include "../opengl/Frustum.h"
44#include "../opengl/Material.h"
45#include "Component_Shape.h"
46#include "LinearAlgebra.h"
55#define RETURN_IF_RENDER_STATE_NOT_US \
56 if (renderstate()->render_light== VF_globalLight) { \
57 if (!node->global) return;\
59 if (node->global) return; \
60 if(renderstate()->render_geom != VF_Geom) return; \
68const GLDOUBLE bias[16] = { 0.5, 0.0, 0.0, 0.0,
76 GLDOUBLE TenLinearGexMat[16];
81 GLDOUBLE TenLinearGexMat[16];
90 struct Vector *projector_stack;
94 int currentlyWorkingOn;
99void *Component_PTM_constructor(){
104void Component_PTM_init(
struct tComponent_PTM *t){
109 t->prv = Component_PTM_constructor();
117 p->currentlyWorkingOn = -1;
119 p->textureInProcess = -1;
123void Component_PTM_clear(
struct tComponent_PTM *t){
132void projectorTable_clear(){
138 clearStack(p->projector_stack);
151void projectorTable_pop(){
156 if(p->projector_stack->n < 1)
157 printf(
"ouch from projectorTable_opo()\n");
161void clear_bound_textures(){
162 for(
int i=0;i<16;i++){
163 glActiveTexture(GL_TEXTURE0 + i);
164 glBindTexture(GL_TEXTURE_2D,0);
168void print_bound_textures(
char *str){
170 printf(
"ActiveTexture boundUnit %s\n",str);
171 for(
int i=0;i<16;i++){
172 glActiveTexture(GL_TEXTURE0 + i);
173 glGetIntegerv(GL_TEXTURE_BINDING_2D, &whichID);
174 printf(
"%12d %12d\n",i,whichID);
178int get_bound_image(
struct X3D_Node *node);
179int getGlTextureNumberFromTextureNode(
struct X3D_Node *textureNode);
180int getTextureSizeFromTextureNode(
struct X3D_Node *textureNode,
int *ixyz);
181int getTextureDescriptors(
struct X3D_Node *textureNode,
int *textures,
int *modes,
int *sources,
int *funcs,
int *width,
int *height);
182void resend_textureprojector_matrix()
193 me = getAppearanceProperties()->currentShaderProperties;
215 tcount = min(p->projector_stack->n,MAX_PROJ);
220 for(
int i=0;i<tcount;i++)
222 float TenLinearGexMatCam0f[16];
225 if(me->projTexGenMatCam[i] > -1){
226 ptuple = vector_get_ptr(
struct projector_tuple, p->projector_stack, i);
227 double2float(TenLinearGexMatCam0f, ptuple->TenLinearGexMat,16);
228 GLUNIFORMMATRIX4FV (me->projTexGenMatCam[i],1,GL_FALSE, TenLinearGexMatCam0f);
235 GLUNIFORM1I(me->pbackCull[i],ptuple->backCull);
239 struct X3D_NODE * tlist[4];
244 int width[4], height[4];
247 glActiveTexture(GL_TEXTURE0+toffset+pcount);
248 render_node(ptuple->textureNode);
250 ntdesc = getTextureDescriptors(ptuple->textureNode,textures, modes,sources, funcs, width, height);
251 GLUNIFORM1I(me->ntdesc[i],ntdesc);
252 for(
int j=0;j<ntdesc;j++,kdesc++){
256 texture = textures[j];
258 for(
int k=0;k<nunit;k++){
259 if(unitTextures[k] == texture){
266 nunit = min(nunit++,MAX_TEX);
269 glActiveTexture(GL_TEXTURE0+toffset+kunit);
270 glBindTexture(GL_TEXTURE_2D,texture);
271 glUniform1i(me->textureUnit[kunit],kunit+toffset);
272 glActiveTexture(GL_TEXTURE0);
275 unitTextures[kunit] = texture;
276 GLUNIFORM1I(me->tunits[kdesc],kunit);
277 GLUNIFORM1I(me->modes[kdesc],modes[j]);
278 GLUNIFORM1I(me->sources[kdesc],sources[j]);
279 GLUNIFORM1I(me->funcs[kdesc],funcs[j]);
282 tg->RenderFuncs.textureStackTop = 1;
285 GLUNIFORM1I(me->pCount,pcount);
293 float dir[3], up[3], cross1[3],cross2[3];
294 veccopy3f(node->_loc.c,node->location.c);
295 veccopy3f(dir,node->direction.c);
296 veccopy3f(up,node->upVector.c);
297 vecnormalize3f(dir,dir);
298 vecnormalize3f(up,up);
299 veccross3f(cross1,dir,up);
300 vecnormalize3f(cross1,cross1);
301 veccross3f(cross2,cross1,dir);
302 vecnormalize3f(cross2,cross2);
303 veccopy3f(node->_dir.c,dir);
304 node->_dir.c[3] = 0.0f;
305 veccopy3f(node->_upVec.c,up);
306 node->_upVec.c[3] = 0.0f;
312void projLookAt(GLDOUBLE eyex, GLDOUBLE eyey, GLDOUBLE eyez,
313 GLDOUBLE centerx, GLDOUBLE centery, GLDOUBLE centerz,
314 GLDOUBLE upx, GLDOUBLE upy, GLDOUBLE upz, GLDOUBLE *matrix);
315void projPerspective(GLDOUBLE fovy, GLDOUBLE aspect, GLDOUBLE zNear, GLDOUBLE zFar, GLDOUBLE *matrix);
316void printmatrix2(GLDOUBLE* mat,
char* description );
320 static int datacount = 0;
321 float degree = node->fieldOfView* 180.0/3.141596;
322 GLDOUBLE cViewMat[16];
323 GLDOUBLE invcViewMat[16];
324 GLDOUBLE ViewMat[16];
325 GLDOUBLE ProjMat[16];
334 RETURN_IF_RENDER_STATE_NOT_US
339 GLDOUBLE TenLinearGexMatCam0[16];
340 GLDOUBLE modelview[16], modelviewnode[16], eye2projector[16], modelviewinv[16];
343 if(node->global) tg->Component_PTM.globalProjector = TRUE;
347 FW_GL_MATRIX_MODE(GL_MODELVIEW);
348 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelview);
351 double loc[3],dir[3],up[3],eye[3];
352 float2double(loc,node->_loc.c,3);
353 float2double(dir,node->_dir.c,3);
354 float2double(up,node->_upVec.c,3);
355 vecdifd(eye,loc,dir);
356 projLookAt(eye[0],eye[1],eye[2], loc[0],loc[1],loc[2], up[0],up[1],up[2],ViewMat);
360 matinverse(modelviewinv,modelview);
362 matmultiplyAFFINE(eye2projector,modelviewinv,ViewMat);
365 projPerspective((GLDOUBLE)degree,
366 (GLDOUBLE)node->aspectRatio,
367 (GLDOUBLE)node->nearDistance,(GLDOUBLE)node->farDistance,
370 matidentity4d(tempmat);
372 matmultiplyFULL(tempmat,ProjMat,tempmat);
375 matmultiplyFULL(TenLinearGexMatCam0,eye2projector,tempmat);
380 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->texture,tmpN);
384 if(getTextureSizeFromTextureNode(tmpN, ixyz)){
385 if(ixyz[0] > 0 && ixyz[1] > 0){
386 aspectRatio = (float)ixyz[0]/(
float)ixyz[1];
387 if(!APPROX(node->aspectRatio,aspectRatio)){
388 node->aspectRatio = aspectRatio;
401 ptuple.des = node->description;
402 memcpy(ptuple.TenLinearGexMat, TenLinearGexMatCam0,16*sizeof (GLDOUBLE));
403 ptuple.backCull = node->backCull == TRUE? 1 : 0;
405 ptuple.global = node->global;
407 texture = tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop];
408 ptuple.texture = texture;
409 ptuple.textureNode = tmpN;
410 projectorTable_push(&ptuple);
419 RETURN_IF_RENDER_STATE_NOT_US
422 projectorTable_pop();
428 if (!renderstate()->render_light)
return;
430 render_TextureProjectorPerspective(node);
445 RETURN_IF_RENDER_STATE_NOT_US
448 projectorTable_pop();
455 float dir[3], up[3], cross1[3],cross2[3];
456 veccopy3f(node->_loc.c,node->location.c);
457 veccopy3f(dir,node->direction.c);
458 veccopy3f(up,node->upVector.c);
459 vecnormalize3f(dir,dir);
460 vecnormalize3f(up,up);
461 veccross3f(cross1,dir,up);
462 vecnormalize3f(cross1,cross1);
463 veccross3f(cross2,cross1,dir);
464 vecnormalize3f(cross2,cross2);
465 veccopy3f(node->_dir.c,dir);
466 node->_dir.c[3] = 0.0f;
467 veccopy3f(node->_upVec.c,up);
468 node->_upVec.c[3] = 0.0f;
474void projOrtho (GLDOUBLE l, GLDOUBLE r, GLDOUBLE b, GLDOUBLE t,
475 GLDOUBLE n, GLDOUBLE f,GLDOUBLE *matrix);
476void mesa_Ortho(GLDOUBLE left, GLDOUBLE right, GLDOUBLE bottom, GLDOUBLE top, GLDOUBLE nearZ, GLDOUBLE farZ, GLDOUBLE *m);
480 static int datacount = 0;
482 GLDOUBLE cViewMat[16];
483 GLDOUBLE invcViewMat[16];
484 GLDOUBLE ViewMat[16];
485 GLDOUBLE orthoMat[16];
494 RETURN_IF_RENDER_STATE_NOT_US
499 GLDOUBLE TenLinearGexMatCam0[16];
500 GLDOUBLE modelview[16], modelviewnode[16], eye2projector[16], modelviewinv[16];
503 if(node->global) tg->Component_PTM.globalProjector = TRUE;
507 FW_GL_MATRIX_MODE(GL_MODELVIEW);
508 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelview);
510 double loc[3],dir[3],up[3],eye[3];
511 float2double(loc,node->_loc.c,3);
512 float2double(dir,node->_dir.c,3);
513 float2double(up,node->_upVec.c,3);
514 vecdifd(eye,loc,dir);
515 projLookAt(eye[0],eye[1],eye[2], loc[0],loc[1],loc[2], up[0],up[1],up[2],ViewMat);
519 matinverse(modelviewinv,modelview);
521 matmultiplyAFFINE(eye2projector,modelviewinv,ViewMat);
525 mesa_Ortho((GLDOUBLE)node->fieldOfView.p[0],(GLDOUBLE)node->fieldOfView.p[2],(GLDOUBLE)node->fieldOfView.p[1],(GLDOUBLE)node->fieldOfView.p[3],
526 (GLDOUBLE)node->nearDistance, (GLDOUBLE)node->farDistance,orthoMat);
528 matidentity4d(tempmat);
530 matmultiplyFULL(tempmat,orthoMat,tempmat);
533 matmultiplyFULL(TenLinearGexMatCam0,eye2projector,tempmat);
536 float aspectRatio, denom, *fov;
537 fov = node->fieldOfView.p;
538 denom = fov[3]-fov[1];
540 aspectRatio = (fov[2]-fov[0])/denom;
541 if(!APPROX(node->aspectRatio,aspectRatio)){
542 node->aspectRatio = aspectRatio;
552 POSSIBLE_PROTO_EXPANSION(
struct X3D_Node *, node->texture,tmpN);
557 ptuple.des = node->description;
558 memcpy(ptuple.TenLinearGexMat, TenLinearGexMatCam0,16*sizeof (GLDOUBLE));
559 ptuple.backCull = node->backCull == TRUE? 1 : 0;
560 ptuple.global = node->global;
562 texture = tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop];
563 ptuple.texture = texture;
564 ptuple.textureNode = tmpN;
565 projectorTable_push(&ptuple);
575 if (!renderstate()->render_light)
return;
577 render_TextureProjectorParallel(node);
582void render_TextureProjector(
struct X3D_Node *sibAffector){
583 switch(sibAffector->_nodeType){
584 case NODE_TextureProjectorParallel:
587 case NODE_TextureProjectorPerspective:
593void fin_TextureProjector(
struct X3D_Node *sibAffector){
594 switch(sibAffector->_nodeType){
595 case NODE_TextureProjectorParallel:
598 case NODE_TextureProjectorPerspective:
605void sib_prep_TextureProjector(
struct X3D_Node *parent,
struct X3D_Node *sibAffector){
606 if ( renderstate()->render_light != VF_globalLight){
608 shaderflags = getShaderFlags();
609 shaderflags.base |= HAVE_PROJECTIVETEXTURE;
610 pushShaderFlags(shaderflags);
612 render_TextureProjector(sibAffector);
617void sib_fin_TextureProjector(
struct X3D_Node *parent,
struct X3D_Node *sibAffector){
618 if (renderstate()->render_light != VF_globalLight) {
619 fin_TextureProjector(sibAffector);