FreeWRL / FreeX3D 4.3.0
Component_TextureProjector.c
1/*
2=INSERT_TEMPLATE_HERE=
3
4$Id: Component_Grouping.c,v 1.52 2013/08/01 12:55:35 crc_canada Exp $
5
6X3D Grouping Component
7
8*/
9
10
11/****************************************************************************
12This file is part of the FreeWRL/FreeX3D Distribution.
13
14Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
15
16FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
17it under the terms of the GNU Lesser Public License as published by
18the Free Software Foundation, either version 3 of the License, or
19(at your option) any later version.
20
21FreeWRL/FreeX3D is distributed in the hope that it will be useful,
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24GNU General Public License for more details.
25
26You should have received a copy of the GNU General Public License
27along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
28****************************************************************************/
29
30
31#include <config.h>
32#include <system.h>
33#include <display.h>
34#include <internal.h>
35
36#include <libFreeWRL.h>
37
38#include "../vrml_parser/Structs.h"
39#include "../vrml_parser/CRoutes.h"
40#include "../main/headers.h"
41
42#include "../opengl/OpenGL_Utils.h"
43#include "../opengl/Textures.h"
44#include "../opengl/Frustum.h"
45#include "../opengl/Material.h"
46#include "RenderFuncs.h"
47#include "Component_Shape.h"
48#include "LinearAlgebra.h"
49#include "Vector.h"
50#include "Children.h"
51#include <stdlib.h>
52
53
54//we'll share VF_globalLight render pass with global lights
55// this filter will allow global=true on the VF_globalLight render_hier pass
56// and wll allow global=false on regular pass
57#define RETURN_IF_RENDER_STATE_NOT_US \
58 if (renderstate()->render_light== VF_globalLight) { \
59 if (!node->global) return;\
60 } else { \
61 if (node->global) return; \
62 if(renderstate()->render_geom != VF_Geom) return; \
63 }
64
65
66
67// camera space (-1,-1) to (1,1)
68// texture space (0,0) to (1,1)
69// convert: scale by .5, and add .5
70const GLDOUBLE bias[16] = { 0.5, 0.0, 0.0, 0.0,
710.0, 0.5, 0.0, 0.0,
720.0, 0.0, 0.5, 0.0,
730.5, 0.5, 0.5, 1.0 };
74
75
77 struct Vector *projector_stack; //activeProjectiveTextureTable;
78 //textureTableIndexStruct_s* loadThisProjectiveTexture;
79
80 /* current index into loadparams that texture thread is working on */
81 int currentlyWorkingOn;// = -1;
82 int textureInProcess;// = -1;
83}* ppComponent_TextureProjector;
84
85void *Component_TextureProjector_constructor(){
86 void *v = malloc(sizeof(struct pComponent_TextureProjector));
87 memset(v,0,sizeof(struct pComponent_TextureProjector));
88 return v;
89}
90void Component_TextureProjector_init(struct tComponent_TextureProjector *t){
91 //public
92
93 //private
94
95 t->prv = Component_TextureProjector_constructor();
96 {
97 ppComponent_TextureProjector p = (ppComponent_TextureProjector)t->prv;
98 //p->activeProjectiveTextureTable = NULL;
99 p->projector_stack = newStack(usehit);
100
101 /* current index into loadparams that texture thread is working on */
102 p->currentlyWorkingOn = -1;
103
104 p->textureInProcess = -1;
105 }
106}
107
108void Component_TextureProjector_clear(struct tComponent_TextureProjector *t){
109 //public
110 //private
111 {
112 ppComponent_TextureProjector p = (ppComponent_TextureProjector)t->prv;
113 }
114}
115
117 int itype; //=5, 0 PointRep 1 LineRep 2 PolyRep 3 MeshRep 4 TextureRep 5 LightRep 6 ProjectorRep
118 //depth section
119 Stack* depth_buffer_stack;
120 int size;
121 double matproj[16];
122 double matview[16];
123 //projector section
124 struct X3D_Node* texture;
125 int itexture;
126};
127
128void* set_ProjectorRep(void* _projectorrep)
129{
130 struct X3D_ProjectorRep* projectorrep = _projectorrep;
131 if (!_projectorrep) {
132 _projectorrep = MALLOC(struct X3D_ProjectorRep*, sizeof(struct X3D_ProjectorRep));
133 memset(_projectorrep, 0, sizeof(struct X3D_ProjectorRep));
134 projectorrep = (struct X3D_ProjectorRep*)_projectorrep;
135 projectorrep->itype = 6;
136 projectorrep->size = 1024; //size of shadow image, or for pointlight, size of each of 6 sides of cubemap
137 }
138 return projectorrep;
139}
140
141
142
143
144//void shadowTable_clear();
145//void shadowTable_push(usehit ptuple);
146//void shadowTable_pop();
147
148void projectorTable_clear(){
149 //called once per frame, before the search for global=true projectors
150 //will clear any global=true projectors from last frame
151 ppComponent_TextureProjector p;
152 ttglobal tg = gglobal();
153 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
154 clearStack(p->projector_stack);
155}
156void projectorTable_push(usehit ptuple ){
157 //called when we find a global=true, on=true projector, and
158 //called in sib_prep for a global=false, on=false projector
159 ppComponent_TextureProjector p;
160 ttglobal tg = gglobal();
161 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
162 //we need a deep copy because the ptm node can't hold it
163 // because it can be DEF/USED with different transform each use
164 stack_push(usehit,p->projector_stack,ptuple);
165
166}
167void projectorTable_pop(){
168 //called in sib_fin for a global=false, on=true projector
169 ppComponent_TextureProjector p;
170 ttglobal tg = gglobal();
171 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
172 if(p->projector_stack->n < 1)
173 printf("ouch from projectorTable_opo()\n");
174 stack_pop(usehit,p->projector_stack);
175
176}
177int projectorTable_count() {
178 ppComponent_TextureProjector p;
179 ttglobal tg = gglobal();
180 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
181 return p->projector_stack->n;
182}
183usehit* projectorTable_item(int i) {
184 ppComponent_TextureProjector p;
185 ttglobal tg = gglobal();
186 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
187 return vector_get_ptr(usehit, p->projector_stack, i);
188}
189int projectorTable_node_use_count(struct X3D_Node* node) {
190 int count = 0;
191 for (int i = 0; i < projectorTable_count(); i++) {
192 if (projectorTable_item(i)->node == node) count++;
193 }
194 return count;
195}
196
197void clear_bound_textures(){
198 for(int i=0;i<16;i++){
199 glActiveTexture(GL_TEXTURE0 + i);
200 glBindTexture(GL_TEXTURE_2D,0);
201 }
202}
203
204void print_bound_textures(char *str){
205 GLint whichID;
206 printf("ActiveTexture boundUnit %s\n",str);
207 for(int i=0;i<16;i++){
208 glActiveTexture(GL_TEXTURE0 + i);
209 glGetIntegerv(GL_TEXTURE_BINDING_2D, &whichID);
210 printf("%12d %12d\n",i,whichID);
211 }
212}
213
214int old_waay = 0;
215
216int get_bound_image(struct X3D_Node *node);
217int getGlTextureNumberFromTextureNode(struct X3D_Node *textureNode);
218int getTextureSizeFromTextureNode(struct X3D_Node *textureNode, int *ixyz);
219int getTextureDescriptors(struct X3D_Node *textureNode, int *textures, int *modes, int *sources, int *funcs, int *width, int *height, int *samplr);
220void PRINT_GL_ERROR(GLenum _global_gl_err);
221void sendProjectorInfo()
222{
223 //called from render_shape to refresh uniform before shade draw
224 int pcount,tcount;
225 s_shader_capabilities_t *me;
226 ppComponent_TextureProjector p;
227 ttglobal tg = gglobal();
228 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
229 int MAX_PROJ = 8;
230 int projcount = min(projectorTable_count(), MAX_PROJ);
231 if (!projcount) return;
232
233 me = getAppearanceProperties()->currentShaderProperties;
234 GLuint myProg = me->myShaderProgram;
235
236 // while the number of texture samplers are a limited resource in GLSL,
237 // there could be many projectors re-using the same sampler.
238 // to accommodate multitexture per projector, and avoid [][] 2 dimenstional arrays in GLSL
239 // we have a single list of texture descriptors, and a tcounts[] that says how many texture descriptors per projector
240 // per child_shape shader run:
241 // pcount; //number of projectors, <= MAX_PROJ
242 // per sampler2D:
243 // textureUnit[MAX_TEX]
244 // per projector:
245 // projTexGenMatCam[MAX_PROJ]
246 // backCull[MAX_PROJ]
247 // ntdesc[MAX_PROJ]
248 // per texture descriptor
249 //. tunits[MAX_TDESC] //indexes into textureUnit[] array
250 // modes[MAX_TDESC]
251 // sources[MAX_TDESC]
252 // funcs[MAX_TDESC]
253 GLint saveTextureStackTop = tg->RenderFuncs.textureStackTop;
254 PRINT_GL_ERROR_IF_ANY("BEGIN resend_textureprojector_matrix");
255
256 // programmer: fetching these uniform addresses on every frame eats 35 FPS. Please find a way to store once fetched.
257 for (int i = 0; i < 8; i++) {
258 //per projector
259 char line[24];
260 sprintf(line, "ptms[%d].GenMatCam", i);
261 me->ptmGenMatCam[i] = GET_UNIFORM(myProg, line); //"projTexGenMatCam0"); //vertex shader matrix for projecting rays back to texture
262 sprintf(line, "ptms[%d].backCull", i);
263 me->ptmbackCull[i] = GET_UNIFORM(myProg, line);
264 sprintf(line, "ptms[%d].color", i);
265 me->ptmcolor[i] = GET_UNIFORM(myProg, line);
266 sprintf(line, "ptms[%d].intensity", i);
267 me->ptmintensity[i] = GET_UNIFORM(myProg, line);
268 sprintf(line, "ptms[%d].shadows", i);
269 me->ptmshadows[i] = GET_UNIFORM(myProg, line);
270 sprintf(line, "ptms[%d].shadowIntensity", i);
271 me->ptmshadowIntensity[i] = GET_UNIFORM(myProg, line);
272 sprintf(line, "ptms[%d].depthmap", i);
273 me->ptmdepthmap[i] = GET_UNIFORM(myProg, line);
274 sprintf(line, "ptms[%d].tcount", i);
275 me->ptmtcount[i] = GET_UNIFORM(myProg, line);
276 sprintf(line, "ptms[%d].tstart", i);
277 me->ptmtstart[i] = GET_UNIFORM(myProg, line);
278 sprintf(line, "ptms[%d].type", i);
279 me->ptmtype[i] = GET_UNIFORM(myProg, line);
280 sprintf(line, "ptms[%d].farDistance", i);
281 me->ptmfarDistance[i] = GET_UNIFORM(myProg, line);
282 }
283 for (int i = 0; i < 16; i++) {
284 //per texture descriptor
285 char line[24];
286 sprintf(line, "tdescs[%d].tindex", i);
287 me->tdtindex[i] = GET_UNIFORM(myProg, line);
288 sprintf(line, "tdescs[%d].mode", i);
289 me->tdmode[i] = GET_UNIFORM(myProg, line);
290 sprintf(line, "tdescs[%d].source", i);
291 me->tdsource[i] = GET_UNIFORM(myProg, line);
292 sprintf(line, "tdescs[%d].func", i);
293 me->tdfunc[i] = GET_UNIFORM(myProg, line);
294 sprintf(line, "tdescs[%d].samplr", i);
295 me->tdsamplr[i] = GET_UNIFORM(myProg, line);
296 }
297 me->ptmCount = GET_UNIFORM(myProg, "ptmCount");
298 PRINT_GL_ERROR_IF_ANY("EARLY resend_textureprojector_matrix");
299
300 int MAX_TDESC = 16;
301 int MAX_TEX = 4;
302
303 pcount = 0;
304
305 int kdesc = 0;
306 for(int j=0;j<projcount;j++)
307 {
308 float TenLinearGexMatCam0f[16];
309 usehit *ptuple;
310 GLint texture;
311 usehit* uhit = projectorTable_item(j);
312 struct X3D_Node* node = uhit->node;
313 struct X3D_TextureProjector* ptm = X3D_TEXTUREPROJECTOR(node);
314 struct X3D_TextureProjectorParallel* ppar = X3D_TEXTUREPROJECTORPARALLEL(node);
315 struct X3D_TextureProjectorPoint* ppoint = X3D_TEXTUREPROJECTORPOINT(node);
316 struct X3D_ProjectorRep* projrep = (struct X3D_ProjectorRep*)node->_intern;
317 int projType = 0;
318 //0 - projector
319 //1 - projectorparallel
320 //2 - projectorpoint
321 switch (node->_nodeType) {
322 case NODE_TextureProjector: projType = 0; break;
323 case NODE_TextureProjectorParallel: projType = 1; break;
324 case NODE_TextureProjectorPoint: projType = 2; break;
325 default: break;
326 }
327
328 {
329 if (old_waay) {
330 double matfull[16];
331 matmultiplyFULL(matfull, uhit->mvm, projrep->matproj);
332 double2float(TenLinearGexMatCam0f, matfull, 16);
333 GLUNIFORMMATRIX4FV(me->ptmGenMatCam[j], 1, GL_FALSE, TenLinearGexMatCam0f);
334 }
335 else {
336 float w2l[16];
337 {
338 //following textureProjector
339 double modelviewinv[16], eye2projector[16], matfull[16], mvm[16];
340 matcopy(mvm, uhit->mvm);
341
342 matinverse(modelviewinv, mvm);
343 matmultiplyAFFINE(eye2projector, modelviewinv, projrep->matview);
344 matmultiplyFULL(matfull, eye2projector, projrep->matproj);
345 double2float(w2l, matfull, 16);
346 }
347 //printf("w2l\n");
348 //for (int ii = 0; ii < 4; ii++){
349 // for (int jj = 0; jj < 4; jj++) printf("%f ", w2l[ii * 4 + jj]);
350 // printf("\n");
351 //}
352 GLUNIFORMMATRIX4FV(me->ptmGenMatCam[j], 1, GL_FALSE, w2l);
353
354 }
355 //backCull in theory could automatically always do it,
356 // or projector->backCull=TRUE default,
357 // and turn off when Gl_CULL_FACE is off, meaning web3d solid=FALSE
358 // X HOWEVER freewrl Feb 2020 isn't reliably discriminating solid=true/false for different geometry types
359 // - THEREFORE we will let projector->backCull be definitive and scene authors will set manually until freewrl solid is fixed
360 GLUNIFORM1I(me->ptmbackCull[j],ptm->backCull);
361 GLUNIFORM3FV(me->ptmcolor[j], 1, ptm->color.c);
362 GLUNIFORM1F(me->ptmintensity[j], ptm->intensity);
363 GLUNIFORM1I(me->ptmshadows[j], ptm->shadows);
364 GLUNIFORM1F(me->ptmshadowIntensity[j], ptm->shadowIntensity);
365 GLUNIFORM1I(me->ptmtype[j], projType);
366 GLUNIFORM1F(me->ptmfarDistance[j], ptm->farDistance);
367
368 int ntdesc = 0; //number of texture descriptors in this projector
369 struct X3D_NODE * tlist[4];
370 int modes[4];
371 int sources[4];
372 int funcs[4];
373 int textures[4];
374 int width[4], height[4], samplr[4];
375
376 render_node(projrep->texture);
377 PRINT_GL_ERROR_IF_ANY("MIDDLE resend_textureprojector_matrix");
378
379 ntdesc = getTextureDescriptors(projrep->texture,textures, modes,sources, funcs, width, height, samplr);
380 GLUNIFORM1I(me->ptmtcount[j],ntdesc);
381 PRINT_GL_ERROR_IF_ANY("M1 resend_textureprojector_matrix");
382 GLUNIFORM1I(me->ptmtstart[j], kdesc);
383 GLenum _global_gl_err = glGetError();
384 while (_global_gl_err != GL_NONE) {
385 PRINT_GL_ERROR(_global_gl_err);
386 printf(" here: %s (%s:%d)\n", "resend_textureprojector_matrix", __FILE__, __LINE__);
387 _global_gl_err = glGetError();
388 }
389
390 PRINT_GL_ERROR_IF_ANY("M2 resend_textureprojector_matrix");
391
392 for(int i=0;i<ntdesc;i++,kdesc++){
393 // re-use texture sampler if mulitple projectors and multitextures refer to same GLint texture 1:1 sampler2D
394 int kunit, iunit;
395 if (samplr[i] == 1) {
396 if (0) {
397 GLenum target;
398 printf("%s ", stringNodeType(node->_nodeType));
399 glGetTextureParameteriv(textures[i], GL_TEXTURE_TARGET, (GLint*)&target);
400 switch (target) {
401 case GL_TEXTURE_CUBE_MAP: printf("CUBE MAP \n"); break;
402 case GL_TEXTURE_2D: printf("texture2D\n"); break;
403 case GL_TEXTURE_3D: printf("texture3D\n"); break;
404 case GL_TEXTURE_2D_ARRAY: printf("GL_TEXTURE_2D_ARRAY\n");
405 default: printf("unknown %d \n", target); break;
406 }
407 }
408 PRINT_GL_ERROR_IF_ANY("TT_start_ bfor bind cube");
409
410 kunit = share_or_next_material_sampler_index_Cube(textures[i]);//returns index into shader samplerCube texterUnitCube[kunit]
411 //kunit = share_or_next_material_sampler_index_Cube(getCheckerboardTextureCube());//returns index into shader samplerCube texterUnitCube[kunit]
412 PRINT_GL_ERROR_IF_ANY("TT_start_ aftr bind cube");
413 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
414 PRINT_GL_ERROR_IF_ANY("TT_start_ aftr seamless");
415 iunit = tunitCube(kunit);//returns i as in GL_TEXTUREi, to be stored in samplerCube textureUnitCube[kunit]
416 glUniform1i(me->textureUnitCube[kunit], iunit);
417 }
418 else {
419 kunit = share_or_next_material_sampler_index_2D(textures[i]);//returns index into shader sampler2D texterUnit[kunit]
420 iunit = tunit2D(kunit);//returns i as in GL_TEXTUREi, to be stored in sampler2D textureUnit[kunit]
421 glUniform1i(me->textureUnit[kunit], iunit);
422 }
423
424 GLUNIFORM1I(me->tdtindex[kdesc],kunit); //tunits like PBR tindex - an array saying which sampler2D textureUnit[tunit[kdesc]]
425 PRINT_GL_ERROR_IF_ANY("M4 resend_textureprojector_matrix");
426
427 GLUNIFORM1I(me->tdmode[kdesc],modes[i]);
428 GLUNIFORM1I(me->tdsource[kdesc],sources[i]);
429 GLUNIFORM1I(me->tdfunc[kdesc],funcs[i]);
430 GLUNIFORM1I(me->tdsamplr[kdesc], samplr[i]);
431 PRINT_GL_ERROR_IF_ANY("M6 resend_textureprojector_matrix");
432
433 }
434 PRINT_GL_ERROR_IF_ANY("LATE resend_textureprojector_matrix");
435
436 if (ptm->shadows) {
437 struct X3D_Node* texnode = (struct X3D_Node*)vector_get(struct X3D_Node*, projrep->depth_buffer_stack, uhit->ivalue);
438 int itexunit, iunit;
439 textureTableIndexStruct_s* tti;
440 if (texnode->_nodeType == NODE_GeneratedCubeMapTexture) {
441 struct X3D_GeneratedCubeMapTexture* tex = (struct X3D_GeneratedCubeMapTexture*)texnode;
442 tti = getTableIndex(tex->__textureTableIndex);
443 PRINT_GL_ERROR_IF_ANY("sendLightInfo before bind_or_share");
444 // glEnable(GL_TEXTURE_CUBE_MAP);
445 if (0) {
446 GLuint target;
447 glGetTextureParameteriv(tti->OpenGLTexture, GL_TEXTURE_TARGET, (GLint*)&target);
448 switch (target) {
449 case GL_TEXTURE_CUBE_MAP: printf("CUBE MAP \n"); break;
450 case GL_TEXTURE_2D: printf("texture2D\n"); break;
451 case GL_TEXTURE_3D: printf("texture3D\n"); break;
452 case GL_TEXTURE_2D_ARRAY: printf("GL_TEXTURE_2D_ARRAY\n");
453 default: printf("unknown %d \n", target); break;
454 }
455
456 }
457 itexunit = share_or_next_material_sampler_index_Cube(tti->OpenGLTexture); // returns i as in GL_TEXTUREi, next available
458 iunit = tunitCube(itexunit); //returns index into shader samplerCube textureUnitCube[iunit]
459 PRINT_GL_ERROR_IF_ANY("sendProjectorInfo after bind_or_share");
460 glUniform1i(me->textureUnitCube[iunit], itexunit); // iunit);
461 }
462 else {
463 struct X3D_PixelTexture* tex = (struct X3D_PixelTexture*)texnode;
464 tti = getTableIndex(tex->__textureTableIndex);
465 PRINT_GL_ERROR_IF_ANY("sendProjectorInfo before bind_or_share");
466 itexunit = share_or_next_material_sampler_index_2D(tti->OpenGLTexture); // returns i as in GL_TEXTUREi, next available
467 iunit = tunit2D(itexunit); //returns index into shader sampler2D textureUnit[iunit]
468 PRINT_GL_ERROR_IF_ANY("sendProjectorInfo after bind_or_share");
469 glUniform1i(me->textureUnit[iunit], itexunit);
470 }
471 glUniform1i(me->ptmdepthmap[j], iunit);
472 // use the same transforms for depth as for diffuse
473
474 //float w2l[16];
475 //{
476 // //following textureProjector
477 // double modelviewinv[16], eye2projector[16], matfull[16], mvm[16];
478 // if (uhit->node->_nodeType == NODE_DirectionalLight)
479 // matmultiplyAFFINE(mvm, uhit->extra, uhit->mvm);
480 // else
481 // matcopy(mvm, uhit->mvm);
482
483 // matinverse(modelviewinv, mvm);
484 // matmultiplyAFFINE(eye2projector, modelviewinv, projrep->matview);
485 // matmultiplyFULL(matfull, eye2projector, projrep->matproj);
486 // double2float(w2l, matfull, 16);
487 //}
493 //GLUNIFORMMATRIX4FV(me->lightMat[j], 1, GL_FALSE, w2l);
494 }
495
496 pcount++;
497 tg->RenderFuncs.textureStackTop = saveTextureStackTop; //keep this frmo building up
498 }
499 }
500 GLUNIFORM1I(me->ptmCount,pcount);
501 PRINT_GL_ERROR_IF_ANY("END resend_textureprojector_matrix");
502}
503
504void generate_shadowmap_cube(usehit uhit, int index);
505void generate_shadowmap_2D(usehit uhit, int index);
506
507
508struct X3D_Node* make_depth_buffer_cube(int width, int height);
509struct X3D_Node* make_depth_buffer(int width, int height);
510
511int make_or_get_depth_buffer_projector(int index, struct X3D_Node* node) {
512 node->_intern = set_ProjectorRep(node->_intern);
513 struct X3D_ProjectorRep* projrep = (struct X3D_ProjectorRep*)node->_intern;
514 if (!projrep->depth_buffer_stack) {
515 projrep->depth_buffer_stack = newStack(struct X3D_Node*);
516 }
517 if (index > -1 && index < vectorSize(projrep->depth_buffer_stack)) return index;
518 struct X3D_Node* depth_buffer_texture = NULL;
519 if (node->_nodeType == NODE_TextureProjectorPoint)
520 depth_buffer_texture = make_depth_buffer_cube(projrep->size, projrep->size);
521 else
522 depth_buffer_texture = make_depth_buffer(projrep->size, projrep->size);
523 stack_push(struct X3D_Node*, projrep->depth_buffer_stack, X3D_NODE(depth_buffer_texture));
524 return vectorSize(projrep->depth_buffer_stack) - 1;
525}
526
527/* Projective Texture gluLookAt */
528void projLookAt(GLDOUBLE eyex, GLDOUBLE eyey, GLDOUBLE eyez,
529 GLDOUBLE centerx, GLDOUBLE centery, GLDOUBLE centerz,
530 GLDOUBLE upx, GLDOUBLE upy, GLDOUBLE upz, GLDOUBLE *matrix);
531void projPerspective(GLDOUBLE fovy, GLDOUBLE aspect, GLDOUBLE zNear, GLDOUBLE zFar, GLDOUBLE *matrix);
532void printmatrix2(GLDOUBLE* mat,char* description );
533
534void set_debug_quad_near_farplane(float nearplane, float farplane);
535
536void compile_TextureProjector(struct X3D_TextureProjector* node) {
537
538 node->_intern = set_ProjectorRep(node->_intern);
539 /* LookAt Matrix Complete */
540 float dir[3], up[3], cross1[3], cross2[3];
541 veccopy3f(node->_loc.c, node->location.c);
542 veccopy3f(dir, node->direction.c);
543 veccopy3f(up, node->upVector.c);
544 vecnormalize3f(dir, dir);
545 vecnormalize3f(up, up);
546 veccross3f(cross1, dir, up);
547 vecnormalize3f(cross1, cross1);
548 veccross3f(cross2, cross1, dir);
549 vecnormalize3f(cross2, cross2);
550 veccopy3f(node->_dir.c, dir);
551 node->_dir.c[3] = 0.0f;
552 veccopy3f(node->_upVec.c, up);
553 node->_upVec.c[3] = 0.0f;
554 // if (node->shadows) compile_shadowMap(X3D_NODE(node));
555
556 if (node->shadows)
557 set_debug_quad_near_farplane(node->nearDistance, node->farDistance);
558
559 MARK_NODE_COMPILED;
560}
561
562void render_TextureProjector0(struct X3D_Node* parent, struct X3D_TextureProjector *node) {
563 int i,j = 0;
564 int flag = 0;
565 float degree = node->fieldOfView* 180.0/3.141596;
566 GLDOUBLE cViewMat[16];
567 GLDOUBLE invcViewMat[16];
568 GLDOUBLE ViewMat[16];
569 GLDOUBLE ProjMat[16];
570 GLint tex1;
571 ppComponent_TextureProjector p;
572 ttglobal tg = gglobal();
573 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
574
575 RETURN_IF_RENDER_STATE_NOT_US
576 COMPILE_IF_REQUIRED;
577
578 if(node->on) {
579 double tempmat[16];
580 //GLDOUBLE TenLinearGexMatCam0[16];
581 GLDOUBLE modelview[16], modelviewnode[16], eye2projector[16], modelviewinv[16];
582 struct X3D_Node *tmpN = NULL;
583 struct X3D_ProjectorRep* projrep = (struct X3D_ProjectorRep*)node->_intern;
584
585 if(node->global) tg->Component_TextureProjector.globalProjector = TRUE;
586
587 //A. COMPUTE NODE-POSE MATRIX FOR: .position, .dir, .upVector
588 //glMatrixMode(GL_MODELVIEW);
589 FW_GL_MATRIX_MODE(GL_MODELVIEW);
590 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelview);
591
592 {
593 double loc[3],dir[3],up[3],eye[3];
594 float2double(loc,node->_loc.c,3);
595 float2double(dir,node->_dir.c,3);
596 float2double(up,node->_upVec.c,3);
597 vecdifd(eye,loc,dir);
598 projLookAt(eye[0],eye[1],eye[2], loc[0],loc[1],loc[2], up[0],up[1],up[2],ViewMat);
599 }
600 matcopy(projrep->matview, ViewMat);
601 //B. INVERT modelviewnode (which transforms projector to eye) to get eye-to-projector
602 matinverse(modelviewinv,modelview);
603 //C. COMBINE MODELVIEW MATRIX WITH NODE-POSE MATRIX
604 matmultiplyAFFINE(eye2projector,modelviewinv,ViewMat);
605
606 //C. COMPUTE A PROJECTION MATRIX THAT INCLUDES CAMERA SPACE TO TEXTURE SPACE BIAS
607 projPerspective((GLDOUBLE)degree,
608 (GLDOUBLE)node->aspectRatio, // aspectRatio = width/height see below, gets from image
609 (GLDOUBLE)node->nearDistance,(GLDOUBLE)node->farDistance, // near, far
610 ProjMat);
611 matcopy(projrep->matproj, ProjMat);
612
613 //matidentity4d(tempmat);
614// matmultiplyFULL(tempmat,bias,tempmat);
615 //matmultiplyFULL(tempmat,ProjMat,tempmat);
616
617 //D. COMBINE PROJECTION AND EYE-TO-PROJECTOR TRANSFORMS
618 //matmultiplyFULL(projrep->matmodelviewproj,eye2projector,tempmat);
619 //matmultiplyFULL(projrep->matmodelviewproj, eye2projector, ProjMat);
620
621
622 if(node->texture)
623 {
624 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->texture,tmpN);
625 if(tmpN){
626 int ixyz[3];
627 float aspectRatio;
628 if(getTextureSizeFromTextureNode(tmpN, ixyz)){
629 if(ixyz[0] > 0 && ixyz[1] > 0){
630 aspectRatio = (float)ixyz[0]/(float)ixyz[1];
631 if(!APPROX(node->aspectRatio,aspectRatio)){
632 node->aspectRatio = aspectRatio;
633 MARK_EVENT (X3D_NODE(node), offsetof(struct X3D_TextureProjector, aspectRatio));
634 //printf("aspectRatio= %f\n",node->aspectRatio);
635 }
636 }
637 }
638 }
639
640
641 }
642 {
643 GLuint texture;
644 usehit ptuple;
645
646 ptuple.node = X3D_NODE(node);
647 ptuple.userdata = parent;
648 if(old_waay)
649 matcopy(ptuple.mvm, eye2projector);
650 else
651 matcopy(ptuple.mvm, modelview); //concatonate in sendProjectorInfo
652 //ptuple.userdata = projrep->matproj;
653 //matcopy(ptuple.proj, projrep->matproj);
654 texture = tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop];
655 projrep->itexture = texture;
656 projrep->texture = tmpN;
657 //if (node->global && node->shadows) {
658 if (node->shadows) {
659 int nuse = projectorTable_node_use_count(X3D_NODE(node));
660 ptuple.ivalue = make_or_get_depth_buffer_projector(nuse, X3D_NODE(node));
661 generate_shadowmap_2D(ptuple, 0);
662 }
663 projectorTable_push(ptuple);
664
665
666 }
667
668 } //if(node->on)
669 }
670 void render_TextureProjector(struct X3D_TextureProjector* node) {
671 render_TextureProjector0(NULL, node);
672 }
673
674void fin_TextureProjector (struct X3D_TextureProjector *node)
675{
676 RETURN_IF_RENDER_STATE_NOT_US
677 if(node->on)
678 if(!node->global)
679 projectorTable_pop(); //just pop local projectors that we pushed above - globals are cleared once per frame
680}
681
682void prep_TextureProjector(struct X3D_TextureProjector *node) {
683
684
685 if (!renderstate()->render_light) return;
686 /* this will be a global textureprojector here... */
687 render_TextureProjector(node);
688
689}
690void child_TextureProjector (struct X3D_TextureProjector *node) {
691}
692
693
695
696
697
698void child_TextureProjectorParallel (struct X3D_TextureProjectorParallel *node) {
699}
700void fin_TextureProjectorParallel (struct X3D_TextureProjectorParallel *node) {
701
702 RETURN_IF_RENDER_STATE_NOT_US
703 if(node->on)
704 if(!node->global)
705 projectorTable_pop(); //just pop local projectors that we pushed above - globals are cleared once per frame
706
707}
708
709void compile_TextureProjectorParallel (struct X3D_TextureProjectorParallel *node) {
710 node->_intern = set_ProjectorRep(node->_intern);
711
712 /* LookAt Matrix Complete */
713 float dir[3], up[3], cross1[3],cross2[3];
714 veccopy3f(node->_loc.c,node->location.c);
715 veccopy3f(dir,node->direction.c);
716 veccopy3f(up,node->upVector.c);
717 vecnormalize3f(dir,dir);
718 vecnormalize3f(up,up);
719 veccross3f(cross1,dir,up);
720 vecnormalize3f(cross1,cross1);
721 veccross3f(cross2,cross1,dir);
722 vecnormalize3f(cross2,cross2);
723 veccopy3f(node->_dir.c,dir);
724 node->_dir.c[3] = 0.0f;
725 veccopy3f(node->_upVec.c,up);
726 node->_upVec.c[3] = 0.0f;
727
728 MARK_NODE_COMPILED;
729
730}
731
732void projOrtho (GLDOUBLE l, GLDOUBLE r, GLDOUBLE b, GLDOUBLE t,
733 GLDOUBLE n, GLDOUBLE f,GLDOUBLE *matrix);
734void mesa_Ortho(GLDOUBLE left, GLDOUBLE right, GLDOUBLE bottom, GLDOUBLE top, GLDOUBLE nearZ, GLDOUBLE farZ, GLDOUBLE *m);
735void render_TextureProjectorParallel0(struct X3D_Node* parent, struct X3D_TextureProjectorParallel *node) {
736 int i,j = 0;
737 int flag = 0;
738 //float degree = node->fieldOfView* 180/3.14;
739 GLDOUBLE cViewMat[16];
740 GLDOUBLE invcViewMat[16];
741 GLDOUBLE ViewMat[16];
742 GLDOUBLE orthoMat[16];
743 GLint tex1;
744 ppComponent_TextureProjector p;
745 ttglobal tg = gglobal();
746 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
747
748 RETURN_IF_RENDER_STATE_NOT_US
749 COMPILE_IF_REQUIRED;
750
751 if(node->on) {
752 double tempmat[16];
753 GLDOUBLE TenLinearGexMatCam0[16];
754 GLDOUBLE modelview[16], modelviewnode[16], eye2projector[16], modelviewinv[16];
755 struct X3D_Node *tmpN = NULL;
756 struct X3D_ProjectorRep* projrep = (struct X3D_ProjectorRep*)node->_intern;
757
758 if(node->global) tg->Component_TextureProjector.globalProjector = TRUE;
759
760 //A. COMPUTE NODE-POSE MATRIX FOR: .position, .dir, .upVector
761 //glMatrixMode(GL_MODELVIEW);
762 FW_GL_MATRIX_MODE(GL_MODELVIEW);
763 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelview);
764 {
765 double loc[3],dir[3],up[3],eye[3];
766 float2double(loc,node->_loc.c,3);
767 float2double(dir,node->_dir.c,3);
768 float2double(up,node->_upVec.c,3);
769 vecdifd(eye,loc,dir);
770 projLookAt(eye[0],eye[1],eye[2], loc[0],loc[1],loc[2], up[0],up[1],up[2],ViewMat);
771 }
772 matcopy(projrep->matview, ViewMat);
773 //B. INVERT modelviewnode (which transforms projector to eye) to get eye-to-projector
774 matinverse(modelviewinv,modelview);
775 //C. COMBINE MODELVIEW MATRIX WITH NODE-POSE MATRIX
776 matmultiplyAFFINE(eye2projector,modelviewinv,ViewMat);
777
778
779 //C. COMPUTE A PROJECTION MATRIX THAT INCLUDES CAMERA SPACE TO TEXTURE SPACE BIAS
780 // unsolved problem: specs show TPParallel.fieldOfView as SFVec4f, but OrthoViewpoint fov MFFloat. The 2 are incompatible in freewrl.
781 float *fov;
782 fov = node->fieldOfView.c;
783 int method = 1;
784 if (method == 0) {
785 // July 3, 2022 - this doesn't have the right zone (near/farDistance), not working right
786 mesa_Ortho((GLDOUBLE)fov[0], (GLDOUBLE)fov[2], (GLDOUBLE)fov[1], (GLDOUBLE)fov[3],
787 (GLDOUBLE)node->nearDistance, (GLDOUBLE)node->farDistance, orthoMat);
788 matcopy(projrep->matproj, orthoMat);
789 printmatrix2(orthoMat, "orthoMat");
790 }
791 else {
792 // this works a bit
793 float size[3], center[3], * ll, * ur, zz[2];
794 double mate[16], dcenter[3], dsize[3], matproj[16], matinv[16];
795 ll = &fov[0];
796 ur = &fov[2];
797 zz[0] = node->nearDistance; zz[1] = node->farDistance;
798 matidentity4d(mate);
799 vecadd2f(center, ll, ur);
800 center[2] = zz[0] + zz[1];
801 vecscale3f(center, center, .5f);
802 vecdif2f(size, ur, ll);
803 size[2] = zz[1] - zz[0];
804 mattranslate4d(mate, float2double(dcenter, center, 3));
805 matscale4d(mate, float2double(dsize, size, 3));
806 matinverse(matinv, mate);
807 mesa_Ortho(-.5, .5, -.5, .5, -.5, .5, matproj);
808 matmultiplyFULL(projrep->matproj, matproj, matinv);
809 //printmatrix2(projrep->matproj, "orthoMat");
810
811 }
812 //D. COMBINE PROJECTION AND EYE-TO-PROJECTOR TRANSFORMS
813 //matmultiplyFULL(projrep->matmodelviewproj,eye2projector,orthoMat);
814
815 {
816 float aspectRatio, denom;
817 denom = fov[3]-fov[1];
818 if(denom > 0.0){
819 aspectRatio = (fov[2]-fov[0])/denom;
820 if(!APPROX(node->aspectRatio,aspectRatio)){
821 node->aspectRatio = aspectRatio;
822 MARK_EVENT (X3D_NODE(node), offsetof(struct X3D_TextureProjectorParallel, aspectRatio));
823 //printf("aspectRatio= %f\n",node->aspectRatio);
824 }
825 }
826 }
827
828
829 if(node->texture)
830 {
831 POSSIBLE_PROTO_EXPANSION(struct X3D_Node *, node->texture,tmpN);
832 }
833 {
834 GLuint texture;
835 usehit ptuple;
836 ptuple.node = X3D_NODE(node);
837 ptuple.userdata = parent;
838 if (old_waay)
839 matcopy(ptuple.mvm, eye2projector);
840 else
841 matcopy(ptuple.mvm, modelview);
842 //matcopy(ptuple.proj, projrep->matproj);
843 //ptuple.userdata = projrep->matproj;
844 texture = tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop];
845 projrep->itexture = texture;
846 projrep->texture = tmpN;
847 //if (node->global && node->shadows) {
848 if (node->shadows) {
849 int nuse = projectorTable_node_use_count(X3D_NODE(node));
850 ptuple.ivalue = make_or_get_depth_buffer_projector(nuse, X3D_NODE(node));
851 generate_shadowmap_2D(ptuple, 0);
852 }
853 projectorTable_push(ptuple);
854 }
855
856
857 } //if(node->on)
858}
859void render_TextureProjectorParallel(struct X3D_TextureProjectorParallel* node) {
860 render_TextureProjectorParallel0(NULL, node);
861}
862
863void prep_TextureProjectorParallel(struct X3D_TextureProjectorParallel *node)
864{
865 if (!renderstate()->render_light) return;
866 /* this will be a global textureprojector here... */
867 render_TextureProjectorParallel(node);
868}
869
870
871void compile_TextureProjectorPoint(struct X3D_TextureProjectorPoint* node) {
872
873 node->_intern = set_ProjectorRep(node->_intern);
874 /* LookAt Matrix Complete */
875 float dir[3], up[3], cross1[3], cross2[3];
876 veccopy3f(node->_loc.c, node->location.c);
877 veccopy3f(dir, node->direction.c);
878 veccopy3f(up, node->upVector.c);
879 vecnormalize3f(dir, dir);
880 vecnormalize3f(up, up);
881 veccross3f(cross1, dir, up);
882 vecnormalize3f(cross1, cross1);
883 veccross3f(cross2, cross1, dir);
884 vecnormalize3f(cross2, cross2);
885 veccopy3f(node->_dir.c, dir);
886 node->_dir.c[3] = 0.0f;
887 veccopy3f(node->_upVec.c, up);
888 node->_upVec.c[3] = 0.0f;
889 // if (node->shadows) compile_shadowMap(X3D_NODE(node));
890 MARK_NODE_COMPILED;
891}
892
893double* matrix_lookAtfd(float* eye3, float* center3, float* up3, double* matrix);
894
895void render_TextureProjectorPoint0(struct X3D_Node* parent, struct X3D_TextureProjectorPoint* node) {
896 int i, j = 0;
897 int flag = 0;
898 //float degree = node->fieldOfView * 180.0 / 3.141596;
899 GLDOUBLE cViewMat[16];
900 GLDOUBLE invcViewMat[16];
901 GLDOUBLE ViewMat[16];
902 GLDOUBLE ProjMat[16];
903 GLint tex1;
904 ppComponent_TextureProjector p;
905 ttglobal tg = gglobal();
906 p = (ppComponent_TextureProjector)tg->Component_TextureProjector.prv;
907
908 RETURN_IF_RENDER_STATE_NOT_US
909 COMPILE_IF_REQUIRED;
910
911 if (node->on) {
912 double tempmat[16];
913 //GLDOUBLE TenLinearGexMatCam0[16];
914 GLDOUBLE modelview[16], modelviewnode[16], eye2projector[16], modelviewinv[16];
915 struct X3D_Node* tmpN = NULL;
916 struct X3D_ProjectorRep* projrep = (struct X3D_ProjectorRep*)node->_intern;
917
918 if (node->global) tg->Component_TextureProjector.globalProjector = TRUE;
919
920 //A. COMPUTE NODE-POSE MATRIX FOR: .position, .dir, .upVector
921 //glMatrixMode(GL_MODELVIEW);
922 FW_GL_MATRIX_MODE(GL_MODELVIEW);
923 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelview);
924
925 if(0) {
926 double loc[3], dir[3], up[3], eye[3];
927 float2double(loc, node->_loc.c, 3);
928 float2double(dir, node->_dir.c, 3);
929 float2double(up, node->_upVec.c, 3);
930 vecdifd(eye, loc, dir);
931 projLookAt(eye[0], eye[1], eye[2], loc[0], loc[1], loc[2], up[0], up[1], up[2], ViewMat);
932 matcopy(projrep->matview, ViewMat);
933 }
934 else {
935 float center[3];
936 vecadd3f(center, node->location.c, node->direction.c);
937 matrix_lookAtfd(node->location.c, center, node->upVector.c, projrep->matview);
938 }
939 //B. INVERT modelviewnode (which transforms projector to eye) to get eye-to-projector
940 matinverse(modelviewinv, modelview);
941 //C. COMBINE MODELVIEW MATRIX WITH NODE-POSE MATRIX
942 matmultiplyAFFINE(eye2projector, modelviewinv, ViewMat);
943
944 //C. COMPUTE A PROJECTION MATRIX THAT INCLUDES CAMERA SPACE TO TEXTURE SPACE BIAS
945 //projPerspective((GLDOUBLE)degree,
946 // (GLDOUBLE)node->aspectRatio, // aspectRatio = width/height see below, gets from image
947 // (GLDOUBLE)node->nearDistance, (GLDOUBLE)node->farDistance, // near, far
948 // ProjMat);
949 matidentity4d(ProjMat);
950 matcopy(projrep->matproj, ProjMat);
951
952 //matidentity4d(tempmat);
953// matmultiplyFULL(tempmat,bias,tempmat);
954 //matmultiplyFULL(tempmat,ProjMat,tempmat);
955
956 //D. COMBINE PROJECTION AND EYE-TO-PROJECTOR TRANSFORMS
957 //matmultiplyFULL(projrep->matmodelviewproj,eye2projector,tempmat);
958 //matmultiplyFULL(projrep->matmodelviewproj, eye2projector, ProjMat);
959
960
961 //if (node->texture)
962 //{
963 // POSSIBLE_PROTO_EXPANSION(struct X3D_Node*, node->texture, tmpN);
964 // if (tmpN) {
965 // int ixyz[3];
966 // float aspectRatio;
967 // if (getTextureSizeFromTextureNode(tmpN, ixyz)) {
968 // if (ixyz[0] > 0 && ixyz[1] > 0) {
969 // aspectRatio = (float)ixyz[0] / (float)ixyz[1];
970 // if (!APPROX(node->aspectRatio, aspectRatio)) {
971 // node->aspectRatio = aspectRatio;
972 // MARK_EVENT(X3D_NODE(node), offsetof(struct X3D_TextureProjector, aspectRatio));
973 // //printf("aspectRatio= %f\n",node->aspectRatio);
974 // }
975 // }
976 // }
977 // }
978
979
980 //}
981 if (node->texture)
982 {
983 POSSIBLE_PROTO_EXPANSION(struct X3D_Node*, node->texture, tmpN);
984 }
985
986 {
987 GLuint texture;
988 usehit ptuple;
989
990 ptuple.node = X3D_NODE(node);
991 ptuple.userdata = parent;
992 if (old_waay)
993 matcopy(ptuple.mvm, eye2projector);
994 else
995 matcopy(ptuple.mvm, modelview);
996 //ptuple.userdata = projrep->matproj;
997 //matcopy(ptuple.proj, projrep->matproj);
998 texture = tg->RenderFuncs.boundTextureStack[tg->RenderFuncs.textureStackTop];
999 projrep->itexture = texture;
1000 projrep->texture = tmpN;
1001 //if (node->global && node->shadows) {
1002 if (node->shadows) {
1003 int nuse = projectorTable_node_use_count(X3D_NODE(node));
1004 ptuple.ivalue = make_or_get_depth_buffer_projector(nuse, X3D_NODE(node));
1005 generate_shadowmap_cube(ptuple, 0);
1006 }
1007 projectorTable_push(ptuple);
1008 }
1009
1010 } //if(node->on)
1011}
1012void render_TextureProjectorPoint(struct X3D_TextureProjectorPoint* node) {
1013 render_TextureProjectorPoint0(NULL, node);
1014}
1015
1016void fin_TextureProjectorPoint(struct X3D_TextureProjectorPoint* node)
1017{
1018 RETURN_IF_RENDER_STATE_NOT_US
1019 if (node->on)
1020 if (!node->global)
1021 projectorTable_pop(); //just pop local projectors that we pushed above - globals are cleared once per frame
1022}
1023
1024void prep_TextureProjectorPoint(struct X3D_TextureProjectorPoint* node) {
1025
1026
1027 if (!renderstate()->render_light) return;
1028 /* this will be a global textureprojector here... */
1029 render_TextureProjectorPoint(node);
1030}
1031void child_TextureProjectorPoint(struct X3D_TextureProjectorPoint* node) {
1032}
1033
1034
1035
1036
1037
1038
1039//void render_TextureProjectors(struct X3D_Node *sibAffector){
1040// switch(sibAffector->_nodeType){
1041// case NODE_TextureProjectorParallel:
1042// render_TextureProjectorParallel((struct X3D_TextureProjectorParallel*)sibAffector);
1043// break;
1044// case NODE_TextureProjector:
1045// default:
1046// render_TextureProjector((struct X3D_TextureProjector*)sibAffector);
1047// break;
1048// }
1049//}
1050//void fin_TextureProjectors(struct X3D_Node *sibAffector){
1051// switch(sibAffector->_nodeType){
1052// case NODE_TextureProjectorParallel:
1053// fin_TextureProjectorParallel((struct X3D_TextureProjectorParallel*)sibAffector);
1054// break;
1055// case NODE_TextureProjector:
1056// default:
1057// fin_TextureProjector((struct X3D_TextureProjector*)sibAffector);
1058// break;
1059// }
1060//}
1061
1062//void sib_prep_TextureProjector(struct X3D_Node *parent, struct X3D_Node *sibAffector){
1063// if ( renderstate()->render_light != VF_globalLight){
1064// shaderflagsstruct shaderflags;
1065// shaderflags = getShaderFlags();
1066// shaderflags.base |= HAVE_PROJECTIVETEXTURE;
1067// pushShaderFlags(shaderflags);
1068//
1069// render_TextureProjectors(sibAffector);
1070// }
1071//
1072//}
1073//
1074//void sib_fin_TextureProjector(struct X3D_Node *parent, struct X3D_Node *sibAffector){
1075// if (renderstate()->render_light != VF_globalLight) {
1076// fin_TextureProjectors(sibAffector);
1077// popShaderFlags();
1078// }
1079//}
1080
1081void sib_prep_TextureProjector(struct X3D_Node* parent, struct X3D_Node* sibAffector) {
1082 struct X3D_TextureProjector* projector = X3D_TEXTUREPROJECTOR(sibAffector);
1083 if (renderstate()->render_light != VF_globalLight && !renderstate()->render_depth && renderstate()->render_geom) {
1084 if (projector->global == FALSE && projector->on == TRUE) {
1085 shaderflagsstruct shaderflags;
1086 shaderflags = getShaderFlags();
1087 shaderflags.base |= HAVE_PROJECTIVETEXTURE;
1088 pushShaderFlags(shaderflags);
1089
1090 switch (projector->_nodeType) {
1091 case NODE_TextureProjector:
1092 render_TextureProjector0(parent, (struct X3D_TextureProjector*)sibAffector);
1093 break;
1094 case NODE_TextureProjectorParallel:
1095 render_TextureProjectorParallel0(parent, (struct X3D_TextureProjectorParallel*)sibAffector);
1096 break;
1097 case NODE_TextureProjectorPoint:
1098 render_TextureProjectorPoint0(parent, (struct X3D_TextureProjectorPoint*)sibAffector);
1099 break;
1100 default:
1101 break;
1102 }
1103 }
1104 }
1105}
1106void sib_fin_TextureProjector(struct X3D_Node* parent, struct X3D_Node* sibAffector) {
1107 if (renderstate()->render_light != VF_globalLight && !renderstate()->render_depth && renderstate()->render_geom) {
1108 struct X3D_TextureProjector* projector = X3D_TEXTUREPROJECTOR(sibAffector);
1109 if (projector->global == FALSE && projector->on == TRUE) {
1110 projectorTable_pop();
1111 popShaderFlags();
1112 }
1113 }
1114}
1115