Cube Map FBO Omni-Directional Shadow Mapping Issues

Hello,

I am trying to get omni-directional shadow mapping to work. However, I can’t seem to be able to actually render anything to the cube map FBO. It always remains blank, unless I call glClear (I can change the colors).
I checked this both be rendering a cube map face to the screen and by using gDEBugger.
I am quite certain that the matrices are set up properly.

Here is the relevant code:


void CubeMapFBO::Create(unsigned int resolution, GLuint internalFormat, GLuint textureFormat, GLuint dataType)
{
#ifdef DEBUG
	int result;
	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &result);
	size_t uResult = static_cast<unsigned>(result);
	assert(resolution > 0 && resolution <= uResult);
#endif


	m_resolution = resolution;


	glGenTextures(1, &m_cubeMapID);


	glBindTexture(GL_TEXTURE_CUBE_MAP, m_cubeMapID);
	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_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);


	glGenFramebuffers(1, &m_fboID);
	glBindFramebuffer(GL_FRAMEBUFFER, m_fboID);


	// Create all faces
	for(unsigned int i = 0; i < 6; i++)
	{
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, m_resolution, m_resolution, 0, textureFormat, dataType, NULL);
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_cubeMapID, 0);
	}


	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);


	// Render buffer creation for depth buffer
	glGenRenderbuffers(1, &m_depthID);
	glBindRenderbuffer(GL_RENDERBUFFER, m_depthID);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_resolution, m_resolution);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthID);


	// Unbind
	glBindRenderbuffer(GL_RENDERBUFFER, 0);
	glBindFramebuffer(GL_FRAMEBUFFER, 0);


	// Check that the buffer was properly created
#ifdef DEBUG
	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		std::cerr << "Could not create cube map FBO!" << std::endl;
#endif


	// Set up view matrices
	m_baseViews[0] = Matrix4x4f::CameraDirectionMatrix(Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 1.0f, 0.0f));
	m_baseViews[1] = Matrix4x4f::CameraDirectionMatrix(Vec3f(-1.0f, 0.0f, 0.0f), Vec3f(0.0f, 1.0f, 0.0f));
	m_baseViews[2] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, 1.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f));
	m_baseViews[3] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, -1.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f));
	m_baseViews[4] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f));
	m_baseViews[5] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, 0.0f, -1.0f), Vec3f(0.0f, 1.0f, 0.0f));


	m_created = true;


	GL_ERROR_CHECK();
}


void CubeMapFBO::Render(class Scene* pScene, const Vec3f &position, float zNear, float zFar, float distance)
{
	assert(m_created);


	glBindFramebuffer(GL_FRAMEBUFFER, m_fboID);


	//glDisable(GL_CULL_FACE);


	glMatrixMode(GL_PROJECTION);
	Matrix4x4f::PerspectiveMatrix(pif_over_2, 1.0f, zNear, zFar).GL_Load();
	glMatrixMode(GL_MODELVIEW);


	// Clear all color buffers simultaneously
	GLenum allBuffers[6] = {
		GL_COLOR_ATTACHMENT0,
		GL_COLOR_ATTACHMENT1,
		GL_COLOR_ATTACHMENT2,
		GL_COLOR_ATTACHMENT3,
		GL_COLOR_ATTACHMENT4,
		GL_COLOR_ATTACHMENT5,
	};


	glDrawBuffers(6, allBuffers);
	glClear(GL_COLOR_BUFFER_BIT);


	SetViewport();


	for(unsigned int i = 0; i < 6; i++)
	{	
		glDrawBuffer(GL_COLOR_ATTACHMENT0 + i);


		glClear(GL_DEPTH_BUFFER_BIT);


		Matrix4x4f viewMatrix(m_baseViews[i] * Matrix4x4f::TranslateMatrix(-position));
		pScene->SetCustomViewMatrix(viewMatrix);
		
		pScene->ExtractFrustum(Matrix4x4f::GL_Get_Projection() * viewMatrix);


		pScene->SetWorldMatrix(Matrix4x4f::IdentityMatrix());


		pScene->Render_Distance(distance);
	}


	//glEnable(GL_CULL_FACE);


	// Reset projection
	pScene->m_pWin->SetViewport();
	pScene->m_pWin->SetPerspective();


	// Reset view matrix
	pScene->SetWorldMatrix(Matrix4x4f::IdentityMatrix());


	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

textureFormat is GL_RGB16F and dataType is GL_FLOAT. I tried some other formats as well, but it didn’t seem to make a difference.

Thank you for any help you can offer!

Check out this working source code by deadc0de:

Thanks for the reply!
I switched from using color buffers to depth buffers only. I did have the depth test enabled, and made sure that the depth mask was true. However, the cube map is still completely blank. As a result, I just get a plain unshadowed point light when running the program.

EDIT: I compiled the glut program, but it just gives me a memory access violation :dejection:

Here is the new code:


void CubeMapDepthFBO::Create(unsigned int resolution, Precision precision)
{
    m_resolution = resolution;


    glGenTextures(1, &m_depthCubeMapID);


    glBindTexture(GL_TEXTURE_CUBE_MAP, m_depthCubeMapID);
    
    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);


    // For PCF
    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);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);                 


    GLenum precisionEnum;


    switch(precision)
    {
    case e_16:
        precisionEnum = GL_DEPTH_COMPONENT16;
        break;
    case e_32:
        precisionEnum = GL_DEPTH_COMPONENT32;
        break;
    }


    // Create all faces
    for(unsigned int i = 0; i < 6; i++)
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, precisionEnum, m_resolution, m_resolution, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);


    // Unbind
    glBindTexture(GL_TEXTURE_CUBE_MAP, 0);


    glGenFramebuffers(1, &m_fboID);
    glBindFramebuffer(GL_FRAMEBUFFER, m_fboID);


    glDrawBuffer(GL_NONE); // No color buffer
    glReadBuffer(GL_NONE);


    // For completeness
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_depthCubeMapID, 0);


    // Check that the buffer was properly created
#ifdef DEBUG
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        std::cerr << "Could not create depth cube map FBO!" << std::endl;
#endif


    glBindFramebuffer(GL_FRAMEBUFFER, 0);


    // Set up view matrices
    m_baseViews[0] = Matrix4x4f::CameraDirectionMatrix(Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 1.0f, 0.0f));
    m_baseViews[1] = Matrix4x4f::CameraDirectionMatrix(Vec3f(-1.0f, 0.0f, 0.0f), Vec3f(0.0f, 1.0f, 0.0f));
    m_baseViews[2] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, 1.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f));
    m_baseViews[3] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, -1.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f));
    m_baseViews[4] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, 0.0f, 1.0f), Vec3f(0.0f, 1.0f, 0.0f));
    m_baseViews[5] = Matrix4x4f::CameraDirectionMatrix(Vec3f(0.0f, 0.0f, -1.0f), Vec3f(0.0f, 1.0f, 0.0f));


    m_created = true;
}


void CubeMapDepthFBO::Render(class Scene* pScene, const Vec3f &position, float zNear, float zFar, float distance)
{
    assert(m_created);


    glBindFramebuffer(GL_FRAMEBUFFER, m_fboID);


    //glDisable(GL_CULL_FACE);


    // Same projection every time
    glMatrixMode(GL_PROJECTION);
    Matrix4x4f::PerspectiveMatrix(pif_over_2, 1.0f, zNear, zFar).GL_Load();
    glMatrixMode(GL_MODELVIEW);


    SetViewport();


    // Temporarily move the camera
    Vec3f oldPosition(pScene->m_camera.m_position);


    pScene->m_camera.m_position = position;


    for(unsigned int i = 0; i < 6; i++)
    {    
        Matrix4x4f viewMatrix(m_baseViews[i] * Matrix4x4f::TranslateMatrix(-position));
        pScene->SetCustomViewMatrix(viewMatrix);
        
        pScene->ExtractFrustum(Matrix4x4f::GL_Get_Projection() * viewMatrix);


        pScene->SetWorldMatrix(Matrix4x4f::IdentityMatrix());


        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_depthCubeMapID, 0);


        glClear(GL_DEPTH_BUFFER_BIT);


        pScene->Render();
    }


    pScene->m_camera.m_position = oldPosition;


    //glEnable(GL_CULL_FACE);


    // Reset projection
    pScene->m_pWin->SetViewport();
    pScene->m_pWin->SetPerspective();


    // Reset view matrix
    pScene->SetWorldMatrix(Matrix4x4f::IdentityMatrix());


    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

Thanks for the help so far!

memory access violation

At which call?

That’s odd. I just compiled it here. You’ll need to tweak the includes and replace the "&"s with “&” (probably happened when we switched forum software. Here’s a copy of that test prog that literally compiles as-is:


// Example Depth Cube Map Shadowing
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glext.h> 
#include <GL/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
"
 "#extension GL_EXT_gpu_shader4 : require
"
 "void main()
"
 "{
"
 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
"
 "}
"
;
static const char *shader_render_vs_source =
 "#version 120
"
 "#extension GL_EXT_gpu_shader4 : require
"
 "varying vec4 position_cs;
"
 "varying vec3 normal_cs;
"
 "varying vec3 color;
"
 "void main()
"
 "{
"
 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
"
 " position_cs = gl_ModelViewMatrix * gl_Vertex;
"
 " normal_cs = gl_NormalMatrix * gl_Normal;
"
 " color = gl_Color.rgb;
"
 "}
"
;
static const char *shader_render_fs_source =
 "#version 120
"
 "#extension GL_EXT_gpu_shader4 : require
"
 "varying vec4 position_cs;
"
 "varying vec3 normal_cs;
"
 "varying vec3 color;
"
 "uniform mat4x4 camera_view_matrix_inv;
"
 "uniform mat4x4 light_view_matrix;
"
 "uniform mat4x4 light_projection_matrix;
"
 "uniform samplerCubeShadow shadow;
"
 "uniform vec3 light_position;
"
 "void main()
"
 "{
"
 " vec4 position_ls = light_view_matrix * camera_view_matrix_inv * position_cs;
"
 
 // shadow map test
 " vec4 abs_position = abs(position_ls);
"
 " float fs_z = -max(abs_position.x, max(abs_position.y, abs_position.z));
"
 " vec4 clip = light_projection_matrix * vec4(0.0, 0.0, fs_z, 1.0);
"
 " float depth = (clip.z / clip.w) * 0.5 + 0.5;
"
 " vec4 result = shadowCube(shadow, vec4(position_ls.xyz, depth));
"
 
 " vec3 lvector = light_position - position_cs.xyz;
"
 " float ldistance = length(lvector);
"
 " float lintensity = max(dot(normal_cs, normalize(lvector)), 0.0) * 10.0;
"
 " lintensity /= ldistance * ldistance;
"
 " lintensity /= lintensity + 0.5;
"
 " vec3 diffuse = lintensity * result.xyz * color;
"
 " gl_FragColor = vec4(diffuse,1);
"
 "}
"
;
 
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, &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, &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, &shader_render_vs_source, NULL);
 glCompileShader(shader_render_vs);
 shader_render_fs = glCreateShader(GL_FRAGMENT_SHADER);
 glShaderSource(shader_render_fs, 1, &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, &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(&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);
}


If this doesn’t work I’d start to suspect you might have GL driver or GPU problems. Which driver and GPU are you using?

I still get the memory access violation. It occurs at this line:

 shader_shadow_vs = glCreateShader(GL_VERTEX_SHADER);

I used GLEW instead of glext, and I added windows.h. Those were the only modifications I made to the code you posted.

I am using a Radeon 6970M, with Catalyst 12.1 (I can’t update this, since it needs special Dell drivers for switchable graphics :doh:). I never had a problem running any games.

I will try running it on a different machine to see if it makes any difference!

On my cell right now so reading code is a bit tedious.

Do you call glewInit? Can you make GL calls before the call to CreateShader?

There’s not a driver bug in 12.1 regarding that particular function, but I had trouble with layered rendering as well. Also, does AMD not provide a combined driver for all Radeon incarnations? I can’t check the hybrid stuff, only the desktop side.

Ah, yes, I forgot about that! The GLUT program runs now, so now I need to figure out what is different between my code and the GLUT demo program.

I tried removing all the “EXT” calls in the GLUT program and replacing it with normal ones, and it suddenly stopped working. I thought that the EXT stuff was only used in older OpenGL versions before these functions were part of the standard.

Edit: NVM, find and replace didn’t replace all of them… :whistle:

I got it to work! I had the wrong FOVY set (PI??). Anyways, thank you so much for your help!