34#include <libFreeWRL.h>
36#include "../vrml_parser/Structs.h"
37#include "../main/headers.h"
38#include "../opengl/OpenGL_Utils.h"
39#include "../opengl/Frustum.h"
40#include "RenderFuncs.h"
42#include "LinearAlgebra.h"
44#include "Component_Shape.h"
47 Stack* genshadow_stack;
49}*ppComponent_Lighting;
51static void* Component_Lighting_constructor() {
58void Component_Lighting_init(
struct tComponent_Lighting* t) {
61 t->prv = Component_Lighting_constructor();
63 ppComponent_Lighting p = (ppComponent_Lighting)t->prv;
64 p->genshadow_stack = newStack(
usehit);
65 p->light_stack = newStack(
usehit);
70void Component_Lighting_clear(
struct tComponent_Lighting* t) {
74 ppComponent_Lighting p = (ppComponent_Lighting)t->prv;
75 deleteVector(
usehit, p->genshadow_stack);
76 deleteVector(
usehit, p->light_stack);
81void get_view_matrix(
double* savePosOri,
double* saveView);
82void set_debug_quad_near_farplane(
float nearplane,
float farplane);
83void lightTable_clear();
84void lightTable_push(
usehit tuple);
86int lightTable_count();
87usehit* lightTable_item(
int i);
88void generate_shadowmap_2D(
usehit uhit,
int index);
89int make_or_get_depth_buffer(
int index,
struct X3D_Node* node);
93void lightTable_clear() {
96 ppComponent_Lighting p = (ppComponent_Lighting)gglobal()->Component_Lighting.prv;
97 clearStack(p->light_stack);
99void lightTable_push(
usehit tuple) {
102 ppComponent_Lighting p = (ppComponent_Lighting)gglobal()->Component_Lighting.prv;
103 stack_push(
usehit, p->light_stack, tuple);
106void lightTable_pop() {
108 ppComponent_Lighting p = (ppComponent_Lighting)gglobal()->Component_Lighting.prv;
109 if (p->light_stack->n < 1)
110 printf(
"ouch from lightTable_pop()\n");
111 stack_pop(
usehit, p->light_stack);
113int lightTable_count() {
114 ppComponent_Lighting p = (ppComponent_Lighting)gglobal()->Component_Lighting.prv;
115 return p->light_stack->n;
117usehit *lightTable_item(
int i) {
118 ppComponent_Lighting p = (ppComponent_Lighting)gglobal()->Component_Lighting.prv;
119 return vector_get_ptr(
usehit,p->light_stack,i);
121int lightTable_node_use_count(
struct X3D_Node *node) {
123 for (
int i = 0; i < lightTable_count(); i++) {
124 if (lightTable_item(i)->node == node) count++;
134 Stack* depth_buffer_stack;
144void* set_LightRep(
void* _lightrep)
152 lightrep->ilightbuf = -1;
153 lightrep->size = 1024;
158void delete_LightRep(
void* _lightrep) {
162 if (lightrep->depth_buffer_stack) {
165 deleteStack(
struct X3D_Node*, lightrep->depth_buffer_stack);
167 FREE_IF_NZ(_lightrep);
179static int gcm_method_used = 0;
181 return gcm_method_used;
184#define RETURN_IF_LIGHT_STATE_NOT_US \
185 if (renderstate()->render_light== VF_globalLight) { \
186 if (!node->global) return;\
188 } else if (node->global || renderstate()->render_depth || !renderstate()->render_geom ) return; \
192void projPerspective(
double fovy,
double aspect,
double zNear,
double zFar,
double* matrix);
193void projOrtho(
double left,
double right,
double bottom,
double top,
194 double nearZ,
double farZ,
double* matrix);
195void projLookAt(
double eyex,
double eyey,
double eyez,
196 double centerx,
double centery,
double centerz,
197 double upx,
double upy,
double upz,
double* matrix);
198double* matrix_lookAtd(
double* eye3,
double* center3,
double* up3,
double* matrix) {
203 projLookAt(eye3[0], eye3[1], eye3[2], center3[0], center3[1], center3[2], up3[0], up3[1], up3[2], matrix);
206double* matrix_lookAtfd(
float* eye3,
float* center3,
float* up3,
double* matrix) {
207 double eyed[3], centerd[3], upd[3];
208 float2double(eyed, eye3, 3);
209 float2double(centerd, center3, 3);
210 float2double(upd, up3, 3);
211 matrix_lookAtd(eyed, centerd, upd, matrix);
220void mesa_Ortho(GLDOUBLE left, GLDOUBLE right, GLDOUBLE bottom, GLDOUBLE top, GLDOUBLE nearZ, GLDOUBLE farZ, GLDOUBLE* m);
224 RETURN_IF_LIGHT_STATE_NOT_US
231 uhit.node = X3D_NODE(node);
232 uhit.userdata = parent;
233 fw_glGetDoublev(GL_MODELVIEW_MATRIX, uhit.mvm);
237 node->_intern = set_LightRep(node->_intern);
243 float up[3], center[3], location[3];
244 vecset3f(up, 0.0f, 1.0f, 0.0f);
245 vecset3f(location, 0.0f, 0.0f, 0.0f);
246 vecadd3f(center, location, node->direction.c);
247 matrix_lookAtfd(location, center, up, lightrep->matview);
251 float eout6[6], ein6[6];
254 extent6f_copy(ein6, rootNode()->_extent);
257 extent6f_copy(ein6, parent->_extent);
259 if (!extent6f_isSet(ein6) ) {
260 float e6[6], scale3[3];
261 extent6f_constructor(e6, -1.0f, 1.0f, -1.0f, 1.0f, .1f, 15.0f);
262 extent6f_scale3f(eout6, e6, vecset3f(scale3, 8.0f, 4.0f, 1.0f));
265 float e6[6], scale3[3];
266 extent6f_mattransform4d(e6, ein6, lightrep->matview);
267 extent6f_scale3f(eout6, e6, vecset3f(scale3, 1.01f, 1.01f, 1.01f));
273 float2double(ed, eout6, 6);
275 mesa_Ortho(ed[1], ed[0], ed[3], ed[2], .1, ed[4], lightrep->matproj);
277 set_debug_quad_near_farplane(eout6[4], eout6[5]);
279 else if (method == 1) {
283 double mate[16], matel[16], dcenter[3], dsize[3], matviewInv[16], mvm2[16], matev[16], matevinv[16];
284 extent6f2bbox(eout6, center, size);
289 mattranslate4d(mate, float2double(dcenter, center, 3));
290 matscale4d(mate, float2double(dsize, size, 3));
294 matcopy(uhit.extra, mate);
298 mesa_Ortho(-.5,.5,-.5,.5, .001,.5, lightrep->matproj);
300 set_debug_quad_near_farplane(.0, .5);
303 int nuse = lightTable_node_use_count(X3D_NODE(node));
304 uhit.ivalue = make_or_get_depth_buffer(nuse, X3D_NODE(node));
305 generate_shadowmap_2D(uhit, 0);
308 lightTable_push(uhit);
312 render_DirectionalLight0(NULL, node);
316 if (!renderstate()->render_light)
return;
317 render_DirectionalLight(node);
321void push_headlight() {
323 headlight = createNewX3DNode(NODE_DirectionalLight);
324 compile_DirectionalLight(headlight);
325 vecset3f(headlight->direction.c, 0.0f, 0.0f, -1.0f);
326 headlight->global = TRUE;
327 headlight->on = TRUE;
334 RETURN_IF_LIGHT_STATE_NOT_US
336 uhit.node = X3D_NODE(headlight);
337 matidentity4d(uhit.mvm);
338 lightTable_push(uhit);
341void render_headlight() {
344 if (fwl_get_headlight())
353 node->_intern = set_LightRep(node->_intern);
355 set_debug_quad_near_farplane(.5f, node->radius);
361 float up[3], direction[3], center[3];
362 vecset3f(up, 0.0f, 1.0f, 0.0f);
363 vecset3f(direction, 0.0f, 0.0f, 1.0f);
364 vecadd3f(center, node->location.c, direction);
365 matrix_lookAtfd(node->location.c, center, up, lightrep->matview);
366 matidentity4d(lightrep->matproj);
371void generate_shadowmap_cube(
usehit uhit,
int index);
376 RETURN_IF_LIGHT_STATE_NOT_US
383 uhit.node = X3D_NODE(node);
384 uhit.userdata = parent;
385 fw_glGetDoublev(GL_MODELVIEW_MATRIX, uhit.mvm);
387 int nuse = lightTable_node_use_count(X3D_NODE(node));
388 uhit.ivalue = make_or_get_depth_buffer(nuse, X3D_NODE(node));
389 generate_shadowmap_cube(uhit, uhit.ivalue);
391 getAppearanceProperties()->cubeFace = 0;
395 lightTable_push(uhit);
399 render_PointLight0(NULL, node);
404 if (!renderstate()->render_light)
return;
406 render_PointLight(node);
467 node->_intern = set_LightRep(node->_intern);
469 projPerspective(node->cutOffAngle * (180.0 / PI) * 2.0, 1.0, .5, (
double)node->radius, lightrep->matproj);
470 set_debug_quad_near_farplane(.5f, node->radius);
475 float up[3], center[3];
476 vecset3f(up, 0.0f, 1.0f, 0.0f);
477 vecadd3f(center, node->location.c, node->direction.c);
478 matrix_lookAtfd(node->location.c, center, up, lightrep->matview);
529 RETURN_IF_LIGHT_STATE_NOT_US
536 uhit.node = X3D_NODE(node);
537 uhit.userdata = parent;
538 fw_glGetDoublev(GL_MODELVIEW_MATRIX, uhit.mvm);
540 int nuse = lightTable_node_use_count(X3D_NODE(node));
543 uhit.ivalue = make_or_get_depth_buffer(nuse,X3D_NODE(node));
544 generate_shadowmap_2D(uhit, 0);
547 lightTable_push(uhit);
575 render_SpotLight0(NULL, node);
579 if (!renderstate()->render_light)
return;
580 render_SpotLight(node);
595 if (renderstate()->render_light != VF_globalLight && !renderstate()->render_depth && renderstate()->render_geom) {
596 if (light->global == FALSE && light->on == TRUE) {
598 switch (light->_nodeType) {
600 render_SpotLight0(parent,(
struct X3D_SpotLight*)sibAffector);
602 case NODE_PointLight:
605 case NODE_DirectionalLight:
615 if (renderstate()->render_light != VF_globalLight && !renderstate()->render_depth && renderstate()->render_geom) {
617 if(light->global == FALSE && light->on == TRUE)
628#include "Component_Shape.h"
629#include "../opengl/Textures.h"
630void pushnset_framebuffer(
int ibuffer);
631void popnset_framebuffer();
633#ifdef GL_DEPTH_COMPONENT32
634#define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT32
636#define FW_GL_DEPTH_COMPONENT GL_DEPTH_COMPONENT16
638int haveFrameBufferObject();
645struct X3D_Node * make_depth_buffer(
int width,
int height) {
647 PRINT_GL_ERROR_IF_ANY(
"make_depth_buffer START");
654 tti = getTableIndex(tex->__textureTableIndex);
655 tti->status = TEX_LOADED;
656 tti->idepthbuffer = 1;
661 if (tti->ifbobuffer == 0 && haveFrameBufferObject()) {
668 glGenFramebuffers(1, &tti->ifbobuffer);
669 pushnset_framebuffer(tti->ifbobuffer);
671 glGenTextures(1, &tti->OpenGLTexture);
672 glBindTexture(GL_TEXTURE_2D, tti->OpenGLTexture);
673 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
674 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
677 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
679 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tti->OpenGLTexture, 0);
680 glDrawBuffer(GL_NONE);
681 glReadBuffer(GL_NONE);
682 popnset_framebuffer();
686 PRINT_GL_ERROR_IF_ANY(
"make_depth_buffer END");
689 return X3D_NODE(tex);
694struct X3D_Node* make_depth_buffer_cube(
int width,
int height) {
701 PRINT_GL_ERROR_IF_ANY(
"make_depth_buffer_cube START");
707 tti = getTableIndex(cubetex->__textureTableIndex);
708 tti->status = TEX_LOADED;
712 tti->idepthbuffer = 1;
714 if (tti->ifbobuffer == 0 && haveFrameBufferObject()) {
721 glGenTextures(1, &tti->OpenGLTexture);
722 glBindTexture(GL_TEXTURE_CUBE_MAP, tti->OpenGLTexture);
723 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
724 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
725 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
726 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
727 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
729 for (
size_t i = 0; i < 6; ++i) {
730 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
732 glGenFramebuffers(1, &tti->ifbobuffer);
733 pushnset_framebuffer(tti->ifbobuffer);
734 PRINT_GL_ERROR_IF_ANY(
"make_depth_buffer_cube 1");
735 glDrawBuffer(GL_NONE);
736 glViewport(0, 0, width, height);
739 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 0, tti->OpenGLTexture, 0);
740 status = glCheckNamedFramebufferStatus(tti->ifbobuffer, GL_FRAMEBUFFER);
742 popnset_framebuffer();
743 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
750 status = glCheckNamedFramebufferStatus(tti->ifbobuffer, GL_FRAMEBUFFER);
751 if (status != GL_FRAMEBUFFER_COMPLETE) {
752 printf(
"make_depth_buffer_cube: framebuffer not complete\n");
754 case GL_FRAMEBUFFER_UNDEFINED:
755 printf(
"GL_FRAMEBUFFER_UNDEFINED\n");
break;
756 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
757 printf(
"GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n");
break;
758 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
759 printf(
"GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n");
break;
760 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
761 printf(
"GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n");
break;
762 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
763 printf(
"GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n");
break;
764 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
765 printf(
"GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n");
break;
766 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
767 printf(
"GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n");
break;
768 case GL_FRAMEBUFFER_UNSUPPORTED:
769 printf(
"GL_FRAMEBUFFER_UNSUPPORTED\n");
break;
771 printf(
"unknown GL error %u\n", (
unsigned int)status);
break;
776 PRINT_GL_ERROR_IF_ANY(
"make_depth_buffer_cube END");
781 return X3D_NODE(cubetex);
784int make_or_get_depth_buffer(
int index,
struct X3D_Node* node) {
785 node->_intern = set_LightRep(node->_intern);
787 if (!lightrep->depth_buffer_stack) {
788 lightrep->depth_buffer_stack = newStack(
struct X3D_Node*);
790 if (index > -1 && index < vectorSize(lightrep->depth_buffer_stack))
return index;
791 struct X3D_Node* depth_buffer_texture = NULL;
792 if(node->_nodeType == NODE_PointLight)
793 depth_buffer_texture = make_depth_buffer_cube(lightrep->size, lightrep->size);
795 depth_buffer_texture = make_depth_buffer(lightrep->size, lightrep->size);
796 stack_push(
struct X3D_Node*, lightrep->depth_buffer_stack, X3D_NODE(depth_buffer_texture));
797 return vectorSize(lightrep->depth_buffer_stack) - 1;
807static unsigned int quadVAO = 0;
808static unsigned int quadVBO;
813 float quadVertices[] = {
815 -.8f, .8f, 0.0f, 0.0f, 1.0f,
816 -.8f, -.8f, 0.0f, 0.0f, 0.0f,
817 .8f, .8f, 0.0f, 1.0f, 1.0f,
818 .8f, -.8f, 0.0f, 1.0f, 0.0f,
821 glGenVertexArrays(1, &quadVAO);
822 glGenBuffers(1, &quadVBO);
823 glBindVertexArray(quadVAO);
824 glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
825 glBufferData(GL_ARRAY_BUFFER,
sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
826 glEnableVertexAttribArray(0);
827 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 *
sizeof(
float), (
void*)0);
828 glEnableVertexAttribArray(1);
829 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 *
sizeof(
float), (
void*)(3 *
sizeof(
float)));
831 glBindVertexArray(quadVAO);
832 PRINT_GL_ERROR_IF_ANY(
"render_quad before glDrawArrays");
833 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
834 PRINT_GL_ERROR_IF_ANY(
"render_quad after glDrawArrays");
835 glBindVertexArray(0);
837static struct debug_quad {
839 int which_debug_shader;
840 float near_plane, far_plane;
841} debug_quad = { -1,0,1.0f,15.0f };
842void set_debug_quad(
int which_debug_shader,
int textureID) {
852 debug_quad.textureID = textureID;
853 debug_quad.which_debug_shader = which_debug_shader;
855void set_debug_quad_near_farplane(
float nearplane,
float farplane) {
856 debug_quad.near_plane = nearplane;
857 debug_quad.far_plane = farplane;
859void render_debug_quad() {
863 if (debug_quad.textureID < 0)
return;
864 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad START");
865 s_shader_capabilities_t* scap;
868 shader_requirements.debug = debug_quad.which_debug_shader;
869 scap = getMyShaders(shader_requirements);
870 enableGlobalShader(scap);
871 if (debug_quad.which_debug_shader > 2 && debug_quad.which_debug_shader < 5 || debug_quad.which_debug_shader == 6) {
872 ia = glGetUniformLocation(scap->myShaderProgram,
"near_plane");
873 glUniform1f(ia, debug_quad.near_plane);
874 ia = glGetUniformLocation(scap->myShaderProgram,
"far_plane");
875 glUniform1f(ia, debug_quad.far_plane);
877 ia = glGetUniformLocation(scap->myShaderProgram,
"textureUnit");
879 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad before ActiveTexture");
881 glActiveTexture(GL_TEXTURE0);
882 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad before enable CUBE_MAP");
884 if (debug_quad.which_debug_shader > 3 && debug_quad.which_debug_shader < 7) {
885 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad before bind CUBE_MAP");
886 glBindTexture(GL_TEXTURE_CUBE_MAP, debug_quad.textureID);
889 glBindTexture(GL_TEXTURE_2D, debug_quad.textureID);
890 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad before renderQuad");
893 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad after renderQuad");
895 if (debug_quad.which_debug_shader > 3 && debug_quad.which_debug_shader < 7) {
896 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
898 PRINT_GL_ERROR_IF_ANY(
"render_debug_quad END");
921#define RADIANS_PER_DEGREE (double)0.0174532925199432957692
922#define DEGREES_PER_RADIAN (double)57.2957795130823208768
925void fw_gluPerspective_2(
double xcenter,
double fovy,
double aspect,
double zNear,
double zFar);
926void pushnset_viewport(
float* vpFraction);
927void popnset_viewport();
928void render_bound_background();
931#include "../x3d_parser/Bindable.h"
932void generate_shadowmap_cube(
usehit uhit,
int index) {
943 double savebackmat[16];
946 double modelviewmatrix[16];
947 textureTableIndexStruct_s* tti;
948 float vp[4] = { 0.0f,1.0f,0.0f,1.0f };
952 ttglobal tg = gglobal();
953 bstack = getActiveBindableStacks(tg);
958 memcpy(savebackmat, bstack->backgroundmatrix, 16 *
sizeof(
double));
961 float radius = 10.0f;
962 if (node->_nodeType == NODE_PointLight)
964 else if (node->_nodeType == NODE_TextureProjectorPoint)
968 memcpy(modelviewmatrix, uhit.mvm, 16 *
sizeof(
double));
971 tti = getTableIndex(cubetex->__textureTableIndex);
972 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps before cube 6 loop");
974 pushnset_framebuffer(tti->ifbobuffer);
975 glDrawBuffer(GL_NONE);
976 glReadBuffer(GL_NONE);
978 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps after drawBuffers");
980 pushnset_viewport(vp);
981 glViewport(0, 0, tti->x, tti->y);
982 FW_GL_MATRIX_MODE(GL_PROJECTION);
984 FW_GL_LOAD_IDENTITY();
985 FW_GL_MATRIX_MODE(GL_MODELVIEW);
987 FW_GL_LOAD_IDENTITY();
989 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps before loop 2");
990 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
991 printf(
"generate_shadowmap_cube: framebuffer not complete\n");
996 glEnable(GL_TEXTURE_GEN_S);
997 glEnable(GL_TEXTURE_GEN_T);
998 glEnable(GL_TEXTURE_GEN_R);
1000 glBindTexture(GL_TEXTURE_CUBE_MAP, tti->OpenGLTexture);
1002 for (
int j = 0; j < 6; j++) {
1003 textureTableIndexStruct_s* ttip;
1007 PRINT_GL_ERROR_IF_ANY(
"generate_cube shadow before glFramebufferTexture2D");
1008 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, tti->OpenGLTexture, 0);
1010 PRINT_GL_ERROR_IF_ANY(
"generate_cube shadow after glFramebufferTexture2D");
1011 FW_GL_CLEAR(GL_DEPTH_BUFFER_BIT);
1012 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps GL calls 1");
1016 double world2light[16], world2lightview[16], mvm[16];
1017 double savePosOri[16], saveView[16], viewmatrix[16], mvmInverse[16], matrotside[16], world2lightviewside[16];
1019 get_view_matrix(savePosOri, saveView);
1020 matmultiplyAFFINE(viewmatrix, saveView, savePosOri);
1023 matcopy(mvm, uhit.mvm);
1024 matinverseAFFINE(mvmInverse, mvm);
1027 matmultiplyAFFINE(world2light, viewmatrix, mvmInverse);
1030 matmultiplyAFFINE(world2lightview, world2light, lightrep->matview);
1032 matrotate(matrotside,RADIANS_PER_DEGREE * sideangle[j].angle, sideangle[j].x, sideangle[j].y, sideangle[j].z);
1033 matmultiplyAFFINE(world2lightviewside, world2lightview, matrotside);
1037 projPerspective(90.0, 1.0, .1, radius, matproj);
1038 fw_glSetDoublev(GL_PROJECTION_MATRIX, matproj);
1041 fw_glSetDoublev(GL_MODELVIEW_MATRIX, world2lightviewside);
1044 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps before render_hier");
1046 profile_start(
"hier_geom");
1047 render_hier2(rootNode(), VF_Geom | VF_Depth);
1048 profile_end(
"hier_geom");
1049 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps after render_hier");
1051 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps after GL calls");
1055 static char* texdata = NULL;
1057 texdata = malloc(tti->x * tti->y *
sizeof(
float));
1058 memset(texdata, 0, tti->x * tti->y *
sizeof(
float));
1060 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps cube in quad prep 0");
1061 glReadPixels(0, 0, tti->x, tti->y, GL_DEPTH_COMPONENT, GL_FLOAT, texdata);
1062 float* ftex = (
float*)texdata;
1063 for (
int ik = 0; ik < tti->y; ik += 128) {
1064 for (
int jk = 0; jk < tti->x; jk += 128)
1065 printf(
"%4f ", ftex[ik * tti->x + jk]);
1070 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps cube in quad prep 2");
1071 set_debug_quad_near_farplane(.1f, radius);
1073 set_debug_quad(6, tti->OpenGLTexture);
1074 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps cube in quad prep 3");
1079 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
1081 FW_GL_MATRIX_MODE(GL_PROJECTION);
1083 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1087 popnset_framebuffer();
1089 memcpy(bstack->backgroundmatrix, savebackmat, 16 *
sizeof(
double));
1092void PRINT_GL_ERROR(GLenum _global_gl_err) {
1093 if (_global_gl_err == GL_INVALID_ENUM) {printf (
"GL_INVALID_ENUM"); }
1094 else if (_global_gl_err == GL_INVALID_VALUE) {printf (
"GL_INVALID_VALUE"); }
1095 else if (_global_gl_err == GL_INVALID_OPERATION) {printf (
"GL_INVALID_OPERATION"); }
1096 else if (_global_gl_err == GL_STACK_OVERFLOW) {printf (
"GL_STACK_UNDERFLOW"); }
1097 else if (_global_gl_err == GL_STACK_UNDERFLOW) {printf (
"GL_STACK_UNDERFLOW"); }
1098 else if (_global_gl_err == GL_OUT_OF_MEMORY) {printf (
"GL_OUT_OF_MEMORY"); }
1099 else if (_global_gl_err == GL_INVALID_FRAMEBUFFER_OPERATION) {printf (
"GL_INVALID_FRAMEBUFFER_OPERATION"); }
1100 else if (_global_gl_err == GL_CONTEXT_LOST) {printf (
"GL_CONTEXT_LOST"); }
1101 else if (_global_gl_err == GL_TABLE_TOO_LARGE) {printf (
"GL_TABLE_TOO_LARGE"); }
1102 else printf (
"unknown error %d ",_global_gl_err);
1104void generate_shadowmap_2D(
usehit uhit,
int index) {
1114 double savebackmat[16];
1117 double modelviewmatrix[16];
1118 textureTableIndexStruct_s* tti;
1119 float vp[4] = { 0.0f,1.0f,0.0f,1.0f };
1123 ttglobal tg = gglobal();
1124 bstack = getActiveBindableStacks(tg);
1128 memcpy(savebackmat, bstack->backgroundmatrix, 16 *
sizeof(
double));
1130 node = (
struct X3D_Node*)uhit.node;
1133 memcpy(modelviewmatrix, uhit.mvm, 16 *
sizeof(
double));
1136 tti = getTableIndex(tex->__textureTableIndex);
1137 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps_2D before");
1140 pushnset_framebuffer(tti->ifbobuffer);
1141 pushnset_viewport(vp);
1142 glViewport(0, 0, tti->x, tti->y);
1143 FW_GL_MATRIX_MODE(GL_PROJECTION);
1144 FW_GL_PUSH_MATRIX();
1145 FW_GL_LOAD_IDENTITY();
1146 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1147 FW_GL_PUSH_MATRIX();
1148 FW_GL_LOAD_IDENTITY();
1151 textureTableIndexStruct_s* ttip;
1159 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps before GL calls");
1161 FW_GL_CLEAR(GL_DEPTH_BUFFER_BIT);
1168 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps GL calls 1");
1172 double world2light[16], world2lightview[16], mvm[16];
1173 double savePosOri[16], saveView[16], viewmatrix[16], mvmInverse[16];
1174 get_view_matrix(savePosOri, saveView);
1175 matmultiplyAFFINE(viewmatrix, saveView, savePosOri);
1178 if (uhit.node->_nodeType == NODE_DirectionalLight)
1179 matmultiplyAFFINE(mvm, uhit.extra, uhit.mvm);
1181 matcopy(mvm, uhit.mvm);
1182 matinverseAFFINE(mvmInverse, mvm);
1185 matmultiplyAFFINE(world2light, viewmatrix, mvmInverse);
1188 matmultiplyAFFINE(world2lightview, world2light, lightrep->matview);
1193 fw_glSetDoublev(GL_PROJECTION_MATRIX, lightrep->matproj);
1196 fw_glSetDoublev(GL_MODELVIEW_MATRIX, world2lightview);
1199 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps before render_hier");
1201 profile_start(
"hier_geom");
1202 struct X3D_Node* root = uhit.userdata ? uhit.userdata : rootNode();
1203 render_hier2(root, VF_Geom | VF_Depth);
1204 profile_end(
"hier_geom");
1205 PRINT_GL_ERROR_IF_ANY(
"generate_shadowMaps after render_hier");
1209 if (index == -1) set_debug_quad(2, tti->OpenGLTexture);
1210 FW_GL_MATRIX_MODE(GL_PROJECTION);
1212 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1216 popnset_framebuffer();
1217 memcpy(bstack->backgroundmatrix, savebackmat, 16 *
sizeof(
double));
1224void transformPositionToEye0(
double *modelMatrix,
float* pos)
1228 transformf(aux, pos, modelMatrix);
1229 veccopy3f(pos, aux);
1232void transformDirectionToEye0(
double *modelMatrix,
float* dir)
1240 aux[0] = (float)(b[0] * a[0] + b[4] * a[1] + b[8] * a[2]);
1241 aux[1] = (float)(b[1] * a[0] + b[5] * a[1] + b[9] * a[2]);
1242 aux[2] = (float)(b[2] * a[0] + b[6] * a[1] + b[10] * a[2]);
1243 veccopy3f(dir, aux);
1248GLint tunit(
int index);
1249void sendLightInfo2(s_shader_capabilities_t* me) {
1251 if (me == NULL)
return;
1258 PRINT_GL_ERROR_IF_ANY(
"BEGIN sendLightInfo2");
1259 int lightcount = lightTable_count();
1261 for (
int j = 0; j < lightcount; j++) {
1262 usehit* uhit = lightTable_item(j);
1263 struct X3D_Node* node = uhit->node;
1272 switch (plight->_nodeType) {
1273 case NODE_PointLight: lightType = 0;
break;
1274 case NODE_SpotLight: lightType = 1;
break;
1275 case NODE_DirectionalLight: lightType = 2;
break;
1279 if (lightType < 2) {
1280 GLUNIFORM3FV(me->lightAtten[j], 1, plight->attenuation.c);
1281 GLUNIFORM1F(me->lightRadius[j], plight->radius);
1283 veccopy3f(location, plight->location.c);
1284 transformPositionToEye0(uhit->mvm, location);
1285 GLUNIFORM3FV(me->lightLocation[j], 1, location);
1287 if (lightType == 1) {
1288 GLUNIFORM1F(me->lightSpotCutoffAngle[j], slight->cutOffAngle);
1289 GLUNIFORM1F(me->lightSpotBeamWidth[j], slight->beamWidth);
1291 veccopy3f(direction, slight->direction.c);
1292 transformDirectionToEye0(uhit->mvm, direction);
1293 GLUNIFORM3FV(me->lightDirection[j], 1, direction);
1295 if (lightType == 2) {
1297 veccopy3f(direction, dlight->direction.c);
1298 transformDirectionToEye0(uhit->mvm, direction);
1299 GLUNIFORM3FV(me->lightDirection[j], 1, direction);
1301 GLUNIFORM1F(me->lightAmbientIntensity[j], plight->ambientIntensity);
1302 GLUNIFORM3FV(me->lightColor[j], 1, plight->color.c);
1303 GLUNIFORM1F(me->lightIntensity[j], plight->intensity);
1304 GLUNIFORM1I(me->lightType[j], lightType);
1305 GLUNIFORM1I(me->lightshadows[j], plight->shadows);
1306 GLUNIFORM1F(me->lightshadowIntensity[j], plight->shadowIntensity);
1307 if (plight->shadows) {
1310 struct X3D_Node* texnode = (
struct X3D_Node*)vector_get(
struct X3D_Node*, lightrep->depth_buffer_stack, uhit->ivalue);
1311 int itexunit, iunit;
1312 textureTableIndexStruct_s* tti;
1313 if (texnode->_nodeType == NODE_GeneratedCubeMapTexture && !gcm_method()) {
1315 tti = getTableIndex(tex->__textureTableIndex);
1316 PRINT_GL_ERROR_IF_ANY(
"sendLightInfo before bind_or_share");
1320 glGetTextureParameteriv(tti->OpenGLTexture, GL_TEXTURE_TARGET, (GLint*)&target);
1322 case GL_TEXTURE_CUBE_MAP: printf(
"CUBE MAP \n");
break;
1323 case GL_TEXTURE_2D: printf(
"texture2D\n");
break;
1324 case GL_TEXTURE_3D: printf(
"texture3D\n");
break;
1325 case GL_TEXTURE_2D_ARRAY: printf(
"GL_TEXTURE_2D_ARRAY\n");
1326 default: printf(
"unknown %d \n", target);
break;
1330 itexunit = share_or_next_material_sampler_index_Cube(tti->OpenGLTexture);
1331 iunit = tunitCube(itexunit);
1332 PRINT_GL_ERROR_IF_ANY(
"sendLightInfo after bind_or_share");
1333 glUniform1i(me->textureUnitCube[iunit], itexunit);
1337 tti = getTableIndex(tex->__textureTableIndex);
1338 PRINT_GL_ERROR_IF_ANY(
"sendLightInfo before bind_or_share");
1339 itexunit = share_or_next_material_sampler_index_2D(tti->OpenGLTexture);
1340 iunit = tunit2D(itexunit);
1341 PRINT_GL_ERROR_IF_ANY(
"sendLightInfo after bind_or_share");
1342 glUniform1i(me->textureUnit[iunit], itexunit);
1344 GLUNIFORM1I(me->lightdepthmap[j], iunit);
1348 double modelviewinv[16], eye2projector[16], matfull[16], mvm[16];
1349 if (uhit->node->_nodeType == NODE_DirectionalLight)
1350 matmultiplyAFFINE(mvm, uhit->extra, uhit->mvm);
1352 matcopy(mvm, uhit->mvm);
1354 matinverse(modelviewinv, mvm);
1355 matmultiplyAFFINE(eye2projector, modelviewinv, lightrep->matview);
1356 matmultiplyFULL(matfull, eye2projector, lightrep->matproj);
1357 double2float(w2l, matfull, 16);
1364 GLUNIFORMMATRIX4FV(me->lightMat[j], 1, GL_FALSE, w2l);
1367 GLUNIFORM1I(me->lightcount, lightcount);
1369 PRINT_GL_ERROR_IF_ANY(
"END sendLightInfo");