Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: GLSL - cube shadows - projecting

  1. #11
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    13

    Re: GLSL - cube shadows - projecting

    Right, i knew it's gonna be a nightmare to implement that,
    anyone has any example in regards to what Dark Photon said?

    I understand i can't do anything with what i already have as i need to have 6 separate matrices for each face of the cube calculated and passed to the shader right?

    Any idea how to calculate them per face attached to FBO ?

  2. #12
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    13

    Re: GLSL - cube shadows - projecting

    Ok managed to calculate light matrices per face,
    this is how they look per face:

    [268447156] FACE:0
    -1.000000 0.000000 0.000000 0.000000
    0.000000 1.000000 0.000000 0.000000
    0.000000 0.000000 -1.000000 0.000000
    0.000000 -88.000000 0.000000 1.000000
    [268447156] FACE:1
    1.000000 0.000000 0.000000 0.000000
    0.000000 1.000000 0.000000 0.000000
    0.000000 0.000000 1.000000 0.000000
    0.000000 -88.000000 0.000000 1.000000
    [268447156] FACE:2
    0.000000 1.000000 0.000000 0.000000
    0.000000 0.000000 1.000000 0.000000
    1.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 -88.000000 1.000000
    [268447156] FACE:3
    0.000000 -1.000000 0.000000 0.000000
    0.000000 0.000000 -1.000000 0.000000
    1.000000 0.000000 0.000000 0.000000
    0.000000 0.000000 88.000000 1.000000
    [268447156] FACE:4
    0.000000 0.000000 -1.000000 0.000000
    0.000000 1.000000 0.000000 0.000000
    1.000000 0.000000 0.000000 0.000000
    0.000000 -88.000000 0.000000 1.000000
    [268447156] FACE:5
    0.000000 0.000000 1.000000 0.000000
    0.000000 1.000000 0.000000 0.000000
    -1.000000 0.000000 0.000000 0.000000
    0.000000 -88.000000 0.000000 1.000000

    Photon,

    having 6 separate camera-eye-space-to-light-clip-space transform matrices (see below for a diagram),
    you choose the right one based the fragment-to-eye-vector transformed back into the light's frame of reference, and
    This is messy, can you please explain what do i do with those 6 matrices and which should i choose and how do i know exactly which is the correct one?

  3. #13
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,124

    Re: GLSL - cube shadows - projecting

    Quote Originally Posted by donmof
    having 6 separate camera-eye-space-to-light-clip-space transform matrices (see below for a diagram),
    you choose the right one based the fragment-to-eye-vector transformed back into the light's frame of reference, and
    This is messy, can you please explain what do i do with those 6 matrices and which should i choose and how do i know exactly which is the correct one?
    Well, I'm not suggesting you take this approach over the others. I'm suggesting that you get intimately familiar with the pros and cons of each and take the approach that works best for your requirements (I'm certainly not that intimate with the pros/cons of various approaches myself -- I haven't implemented point light shadows with cubemaps nor read the literature with that level of detail in mind ...yet).

    However, if you were to take this approach:

    1) Compute unit vector from light to fragment in eye space,
    2) Project onto light's (cube-map's) basis vectors,
    3) The maximum component of this vector in the light's FoR is the cube face to select,
    4) Use this face index to select the eye-to-clip transform for that face,
    5) Transform fragment's eye-space position by this transform
    6) Do shadow map lookup for that face.

    Probably could be optimized some. But as the references state, there are pros and cons for doing this. Note that with this you don't strictly need a cube map at all. You can use 6 2D depth maps, one per face, which apparently opens up some filtering options (and allegedly GPU depth comparisons, though I don't quite appreciate why yet; I need to read up on this).

    The cons are of course that you're managing the projections for each of the faces separately. If instead you store radial distance in the cube map, you don't need to do that. Just compute a direction vector, do a depth lookup, and compare to fragment distance. ...or at least that's the jist I got from spot-skimming. I'll read about this in more detail soon.

  4. #14
    Junior Member Newbie
    Join Date
    Apr 2011
    Posts
    2

    Re: GLSL - cube shadows - projecting

    I think you can calculate the face and depth value (R) to test against the depth cube without having to store an array of values for each cube face.

    I will assume that the matrices you used to render each face are as follows:

    Code :
      face0: mat_light_projection * mat_face[0] * mat_light;
      ...
      face5: mat_light_projection * mat_face[5] * mat_light;
    Where:
    mat_light is matrix to transform world space coordinates into light space.
    mat_light_projection is a perspective projection matrix with a fov of 90 degrees.
    mat_face[n] are the matrices to transform light space coordinates to each face which I will refer to as face space.


    Given a camera space position, cs_position, we can convert it to light space as follows:

    Code :
    ls_position = mat_light * mat_camera_inv * cs_position
    In light space, the light's position is at (0, 0, 0). So ls_position is also the unnormalized direction vector we can use to index the cube map.

    Cube map face selection is done by taking the component with the largest magnitude. If we were to do that with ls_position and transform it by the selected mat_face[n] you will see that the Z value of the new position is the same as the component that was used to select this face, but always negative. This is very useful because the value in the depth buffer is only dependent on Z and not X or Y.

    This allows us to construct a vector in 'face space' that should yield the same depth value as ls_position would have once we project it. Since the same projection matrix is used for all faces it really doesn't matter which face the position belongs to.

    Below is some pseudo-GLSL that should get you started. The calculation of depth from Z can be simplified a lot but left as it is for clarity.

    Code :
     
    ## inputs
     
    // camera space position
    vec4 cs_position;
     
    // camera space to world space transform
    mat4x4 mat_camera_inv;
     
    // world space to light space transform
    mat4x4 mat_light;
     
    // projection matrix you used to render the cube map faces
    mat4x4 mat_light_projection;
     
    // depth cube map
    uniform samplerCubeShadow shadow;
     
    ## code
     
    // transform the vertex from camera to light space
    vec4 ls_position = mat_light * mat_camera_inv * cs_position;
     
    // calculate our 'face space' Z
    vec4 abs_position = abs(ls_position);
    float fs_z = -max(abs_position.x, max(abs_position.y, abs_position.z));
     
    // calculate depth from Z
    vec4 clip = mat_light_projection * vec4(0.0, 0.0, fs_z, 1.0);
    float depth = (clip.z / clip.w) * 0.5 + 0.5;
     
    vec4 result = shadowCube(shadow, vec4(ls_position.xyz, depth));

  5. #15
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    13

    Re: GLSL - cube shadows - projecting

    deadc0de - thanks for sharing,

    just for 'clarity' - did you manage to have cube shadow mapping done at all? or i am trying to get something running that would never work...

    i am getting down to study your pseudocode now..

  6. #16
    Junior Member Newbie
    Join Date
    Apr 2011
    Posts
    2

    Re: GLSL - cube shadows - projecting

    Yes. It works. Below is a standalone GLUT program that will do depth cube map shadows as I explained above.

    <div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
    Code :
    // Example Depth Cube Map Shadowing
     
    #include <glut/glut.h>
    #include <math.h>
    #include <stdlib.h>
     
     
    #define WINDOW_SIZE     (512)
    #define WINDOW_NEAR     (1.0)
    #define WINDOW_FAR      (100.0)
     
    #define SHADOW_SIZE     (256)
    #define SHADOW_NEAR     (1.0)
    #define SHADOW_FAR      (10.0)
     
     
    static float camera_position[3] = { -8.0f, 8.0f, -8.0f };
    static float camera_view_matrix[16];
    static float camera_view_matrix_inv[16];
    static float camera_projection_matrix[16];
     
    static float light_distance = 5.0f;
    static float light_inclination = 45.0f * (M_PI / 180.0f);
    static float light_azimuth = 0.0f;
     
    static float light_position_ws[3];
    static float light_position_cs[3];
    static float light_view_matrix[16];
    static float light_face_matrix[6][16];
    static float light_projection_matrix[16];
     
    static GLuint tex_depth_cube;
     
    static GLuint program_shadow;
    static GLuint shader_shadow_vs;
     
    static GLuint program_render;
    static GLuint shader_render_vs;
    static GLuint shader_render_fs;
     
    static GLuint framebuffer_shadow;
     
    static const char *shader_shadow_vs_source =
    	"#version 120\n"
    	"#extension GL_EXT_gpu_shader4 : require\n"
    	"void main()\n"
    	"{\n"
    	"	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
    	"}\n"
    ;
    static const char *shader_render_vs_source =
    	"#version 120\n"
    	"#extension GL_EXT_gpu_shader4 : require\n"
    	"varying vec4 position_cs;\n"
    	"varying vec3 normal_cs;\n"
    	"varying vec3 color;\n"
    	"void main()\n"
    	"{\n"
    	"	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
    	"	position_cs = gl_ModelViewMatrix * gl_Vertex;\n"
    	"	normal_cs = gl_NormalMatrix * gl_Normal;\n"
    	"	color = gl_Color.rgb;\n"
    	"}\n"
    ;
    static const char *shader_render_fs_source =
    	"#version 120\n"
    	"#extension GL_EXT_gpu_shader4 : require\n"
    	"varying vec4 position_cs;\n"
    	"varying vec3 normal_cs;\n"
    	"varying vec3 color;\n"
    	"uniform mat4x4 camera_view_matrix_inv;\n"
    	"uniform mat4x4 light_view_matrix;\n"
    	"uniform mat4x4 light_projection_matrix;\n"
    	"uniform samplerCubeShadow shadow;\n"
    	"uniform vec3 light_position;\n"
    	"void main()\n"
    	"{\n"
    	"	vec4 position_ls = light_view_matrix * camera_view_matrix_inv * position_cs;\n"
     
    	// shadow map test
    	"	vec4 abs_position = abs(position_ls);\n"
    	"	float fs_z = -max(abs_position.x, max(abs_position.y, abs_position.z));\n"
    	"	vec4 clip = light_projection_matrix * vec4(0.0, 0.0, fs_z, 1.0);\n"
    	"	float depth = (clip.z / clip.w) * 0.5 + 0.5;\n"
    	"	vec4 result = shadowCube(shadow, vec4(position_ls.xyz, depth));\n"
     
    	"	vec3 lvector = light_position - position_cs.xyz;\n"
    	"	float ldistance = length(lvector);\n"
    	"	float lintensity = max(dot(normal_cs, normalize(lvector)), 0.0) * 10.0;\n"
    	"	lintensity /= ldistance * ldistance;\n"
    	"	lintensity /= lintensity + 0.5;\n"
    	"	vec3 diffuse = lintensity * result.xyz * color;\n"
    	"	gl_FragColor = vec4(diffuse,1);\n"
    	"}\n"
    ;
     
    static void
    app_init()
    {
    	glEnable(GL_CULL_FACE);
    	glEnable(GL_DEPTH_TEST);
     
    	// create camera matrix
    	glLoadIdentity();
    	gluLookAt(camera_position[0], camera_position[1], camera_position[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    	glGetFloatv(GL_MODELVIEW_MATRIX, camera_view_matrix);
     
    	// create camera inverse matrix
    	camera_view_matrix_inv[ 0] = camera_view_matrix[ 0];
    	camera_view_matrix_inv[ 1] = camera_view_matrix[ 4];
    	camera_view_matrix_inv[ 2] = camera_view_matrix[ 8];
    	camera_view_matrix_inv[ 4] = camera_view_matrix[ 1];
    	camera_view_matrix_inv[ 5] = camera_view_matrix[ 5];
    	camera_view_matrix_inv[ 6] = camera_view_matrix[ 9];
    	camera_view_matrix_inv[ 8] = camera_view_matrix[ 2];
    	camera_view_matrix_inv[ 9] = camera_view_matrix[ 6];
    	camera_view_matrix_inv[10] = camera_view_matrix[10];
    	camera_view_matrix_inv[12] = camera_position[0];
    	camera_view_matrix_inv[13] = camera_position[1];
    	camera_view_matrix_inv[14] = camera_position[2];
    	camera_view_matrix_inv[ 3] = 0.0f;
    	camera_view_matrix_inv[ 7] = 0.0f;
    	camera_view_matrix_inv[11] = 0.0f;
    	camera_view_matrix_inv[15] = 1.0f;
     
    	// create light face matrices
    	glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0,  1.0, 0.0, 0.0,  0.0,-1.0, 0.0); // +X
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_face_matrix[0]);
    	glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0, -1.0, 0.0, 0.0,  0.0,-1.0, 0.0); // -X
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_face_matrix[1]);
    	glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0,  0.0, 1.0, 0.0,  0.0, 0.0, 1.0); // +Y
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_face_matrix[2]);
    	glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,-1.0); // -Y
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_face_matrix[3]);
    	glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0,  0.0, 0.0, 1.0,  0.0,-1.0, 0.0); // +Z
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_face_matrix[4]);
    	glLoadIdentity(); gluLookAt(0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,-1.0, 0.0); // -Z
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_face_matrix[5]);
     
    	// create light projection matrix
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluPerspective(90.0, 1.0, SHADOW_NEAR, SHADOW_FAR);
    	glGetFloatv(GL_PROJECTION_MATRIX, light_projection_matrix);
    	glMatrixMode(GL_MODELVIEW);
     
    	// create depth cube map
    	glGenTextures(1, &amp;tex_depth_cube);
    	glBindTexture(GL_TEXTURE_CUBE_MAP, tex_depth_cube);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
    	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    	for (size_t i = 0; i < 6; ++i) {
    		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_SIZE, SHADOW_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
    	}
    	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
     
    	// create shadow shader
    	shader_shadow_vs = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(shader_shadow_vs, 1, &amp;shader_shadow_vs_source, NULL);
    	glCompileShader(shader_shadow_vs);
     
    	// create shadow program
    	program_shadow = glCreateProgram();
    	glAttachShader(program_shadow, shader_shadow_vs);
    	glLinkProgram(program_shadow);
     
    	// create render shader
    	shader_render_vs = glCreateShader(GL_VERTEX_SHADER);
    	glShaderSource(shader_render_vs, 1, &amp;shader_render_vs_source, NULL);
    	glCompileShader(shader_render_vs);
    	shader_render_fs = glCreateShader(GL_FRAGMENT_SHADER);
    	glShaderSource(shader_render_fs, 1, &amp;shader_render_fs_source, NULL);
    	glCompileShader(shader_render_fs);
     
    	// create render program
    	program_render = glCreateProgram();
    	glAttachShader(program_render, shader_render_vs);
    	glAttachShader(program_render, shader_render_fs);
    	glLinkProgram(program_render);
     
    	// create shadow framebuffer
    	glGenFramebuffersEXT(1, &amp;framebuffer_shadow);
    }
     
    static void
    draw_shadow_casters()
    {
    	glColor3ub(255,0,0);
    	glPushMatrix();
    		glTranslated(-1.0, 0.0,-1.0);
    		glutSolidSphere(1.0, 20, 10);
    	glPopMatrix();
     
    	glColor3ub(0,255,0);
    	glPushMatrix();
    		glTranslated( 1.0, 0.0, 1.0);
    		glutSolidCube(2.0);
    	glPopMatrix();
     
    	glColor3ub(0,0,255);
    	glPushMatrix();
    		glTranslated( 1.0, 0.0,-1.0);
    		glutSolidIcosahedron();
    	glPopMatrix();
     
    	glColor3ub(255,0,255);
    	glPushMatrix();
    		glTranslated(-1.0, 0.0, 1.0);
    		glutSolidOctahedron();
    	glPopMatrix();
    }
     
    static void
    draw_scene()
    {
    	draw_shadow_casters();
     
    	glColor3ub(255, 255, 255);
    	glNormal3f(0.0f, 1.0f, 0.0f);
    	glBegin(GL_QUADS);
    		glVertex3i( 10, -1,-10);
    		glVertex3i(-10, -1,-10);
    		glVertex3i(-10, -1, 10);
    		glVertex3i( 10, -1, 10);
    	glEnd();
    }
     
    static void
    app_update()
    {
    	// rotate the light about the Y-axis
    	light_azimuth = fmodf(light_azimuth + (0.1f * M_PI / 180.0f), 2.0f * M_PI);
     
    	// update the world space light position
    	light_position_ws[0] = light_distance * sinf(light_inclination) * cosf(light_azimuth);
    	light_position_ws[1] = light_distance * cosf(light_inclination);
    	light_position_ws[2] = light_distance * sinf(light_inclination) * sinf(light_azimuth);
     
    	// create the light view matrix (construct this as you would a camera matrix)
    	glLoadIdentity();
    	glTranslatef(-light_position_ws[0], -light_position_ws[1], -light_position_ws[2]);
    	glGetFloatv(GL_MODELVIEW_MATRIX, light_view_matrix);
     
    	// transform world space light position to camera space
    	light_position_cs[0] =
    		camera_view_matrix[ 0] * light_position_ws[0] +
    		camera_view_matrix[ 4] * light_position_ws[1] +
    		camera_view_matrix[ 8] * light_position_ws[2] +
    		camera_view_matrix[12];
    	light_position_cs[1] =
    		camera_view_matrix[ 1] * light_position_ws[0] +
    		camera_view_matrix[ 5] * light_position_ws[1] +
    		camera_view_matrix[ 9] * light_position_ws[2] +
    		camera_view_matrix[13];
    	light_position_cs[2] =
    		camera_view_matrix[ 2] * light_position_ws[0] +
    		camera_view_matrix[ 6] * light_position_ws[1] +
    		camera_view_matrix[10] * light_position_ws[2] +
    		camera_view_matrix[14];
    }
     
    static void
    app_display()
    {
    	app_update();
     
    	////////////////////////////////////////////////////////////////////////////
    	// RENDER DEPTH CUBE MAP
     
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_shadow);
    	glDrawBuffer(GL_NONE);
    	glReadBuffer(GL_NONE);
    	glViewport(0, 0, SHADOW_SIZE, SHADOW_SIZE);
     
    	glCullFace(GL_FRONT);
     
    	glMatrixMode(GL_PROJECTION);
    	glLoadMatrixf(light_projection_matrix);
    	glMatrixMode(GL_MODELVIEW);
     
    	for (size_t i = 0; i < 6; ++i) {
    		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, tex_depth_cube, 0);
     
    		glClear(GL_DEPTH_BUFFER_BIT);
     
    		glLoadMatrixf(light_face_matrix[i]);
    		glMultMatrixf(light_view_matrix);
     
    		glUseProgram(program_shadow);
     
    		draw_shadow_casters();
    	}
     
    	////////////////////////////////////////////////////////////////////////////
    	// RENDER SCENE
     
    	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    	glDrawBuffer(GL_BACK);
    	glReadBuffer(GL_BACK);
    	glViewport(0, 0, WINDOW_SIZE, WINDOW_SIZE);
     
    	glCullFace(GL_BACK);
     
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluPerspective(45.0, 1.0, WINDOW_NEAR, WINDOW_FAR);
    	glMatrixMode(GL_MODELVIEW);
     
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     
    	glLoadMatrixf(camera_view_matrix);
     
    	glUseProgram(program_render);
    	glUniform1i(glGetUniformLocation(program_render, "shadow"), 0);
    	glUniform3fv(glGetUniformLocation(program_render, "light_position"), 1, light_position_cs);
    	glUniformMatrix4fv(glGetUniformLocation(program_render, "camera_view_matrix_inv"), 1, GL_FALSE, camera_view_matrix_inv);
    	glUniformMatrix4fv(glGetUniformLocation(program_render, "light_view_matrix"), 1, GL_FALSE, light_view_matrix);
    	glUniformMatrix4fv(glGetUniformLocation(program_render, "light_projection_matrix"), 1, GL_FALSE, light_projection_matrix);
     
    	glEnable(GL_TEXTURE_CUBE_MAP);
    	glBindTexture(GL_TEXTURE_CUBE_MAP, tex_depth_cube);
     
    	draw_scene();
     
    	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
    	glDisable(GL_TEXTURE_CUBE_MAP);
     
    	glUseProgram(0);
    	glPushMatrix();
    		glTranslatef(light_position_ws[0], light_position_ws[1], light_position_ws[2]);
    		glColor3ub(255,255,0);
    		glutSolidSphere(0.1, 10, 5);
    	glPopMatrix();
     
    	glutSwapBuffers();
    }
     
    static void
    app_idle()
    {
    	glutPostRedisplay();
    }
     
    int
    main(int argc, char *argv[])
    {
    	glutInit(&amp;argc, argv);
    	glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_STENCIL | GLUT_DOUBLE);
    	glutInitWindowSize(WINDOW_SIZE, WINDOW_SIZE);
    	glutInitWindowPosition(-1, -1);
    	glutCreateWindow("example");
     
    	glutDisplayFunc(app_display);
    	glutIdleFunc(app_idle);
     
    	app_init();
     
    	glutMainLoop();
     
    	return (0);
    }
    [/QUOTE]</div>

  7. #17
    Junior Member Newbie
    Join Date
    Mar 2011
    Posts
    13

    Re: GLSL - cube shadows - projecting

    perfect!
    thank you very much !!

    i appreciate your help, there is nothing else than a source code that can clearly help out people to understand the thing.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •