tavli

view src/shadow.cc @ 19:37dead56f01e

fixed shadows
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 29 Jun 2015 06:18:45 +0300
parents 986c0b76513f
children
line source
1 #include <assert.h>
2 #include "opengl.h"
3 #include "shadow.h"
4 #include "vmath/vmath.h"
6 bool shadow_pass;
8 static int tex_sz, prev_vp[4];
9 static unsigned int fbo, depth_tex, rb_color;
10 static Matrix4x4 shadow_mat;
12 bool init_shadow(int sz)
13 {
14 if(!glcaps.fbo || !glcaps.shadow) {
15 return false;
16 }
18 tex_sz = sz;
19 printf("initializing shadow buffer (%dx%d)\n", tex_sz, tex_sz);
21 glGenFramebuffers(1, &fbo);
22 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
24 glGenTextures(1, &depth_tex);
25 glBindTexture(GL_TEXTURE_2D, depth_tex);
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
27 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
28 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
30 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
31 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex_sz, tex_sz, 0,
32 GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
33 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);
35 assert(glGetError() == GL_NO_ERROR);
37 glDrawBuffer(GL_FALSE);
38 glReadBuffer(GL_FALSE);
40 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
41 fprintf(stderr, "incomplete framebuffer\n");
42 return false;
43 }
45 glBindFramebuffer(GL_FRAMEBUFFER, 0);
46 glDrawBuffer(GL_BACK);
47 glReadBuffer(GL_BACK);
48 assert(glGetError() == GL_NO_ERROR);
50 return true;
51 }
53 void destroy_shadow()
54 {
55 glDeleteTextures(1, &depth_tex);
56 glDeleteRenderbuffers(1, &rb_color);
57 glDeleteFramebuffers(1, &fbo);
58 }
60 void begin_shadow_pass(const Vector3 &lpos, const Vector3 &ltarg, float lfov)
61 {
62 shadow_pass = true;
64 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
65 glDisable(GL_LIGHTING);
66 glColorMask(0, 0, 0, 0);
67 glDepthMask(1);
69 Matrix4x4 viewmat;
70 glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
71 viewmat.transpose();
73 Matrix4x4 lt_viewmat, lt_projmat;
74 lt_projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, 8.0, 50.0);
75 lt_viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0));
76 shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse();
78 glMatrixMode(GL_PROJECTION);
79 glPushMatrix();
80 glLoadTransposeMatrixf(lt_projmat[0]);
82 glMatrixMode(GL_MODELVIEW);
83 glPushMatrix();
84 glLoadTransposeMatrixf(lt_viewmat[0]);
86 glGetIntegerv(GL_VIEWPORT, prev_vp);
87 glViewport(0, 0, tex_sz, tex_sz);
89 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
91 glPolygonOffset(2, 2);
92 glEnable(GL_POLYGON_OFFSET_FILL);
94 glClear(GL_DEPTH_BUFFER_BIT);
95 glUseProgram(0);
96 }
99 void end_shadow_pass()
100 {
101 shadow_pass = false;
103 glBindFramebuffer(GL_FRAMEBUFFER, 0);
105 glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]);
107 glMatrixMode(GL_PROJECTION);
108 glPopMatrix();
109 glMatrixMode(GL_MODELVIEW);
110 glPopMatrix();
112 glPopAttrib();
113 }
115 Matrix4x4 get_shadow_matrix()
116 {
117 return shadow_mat;
119 /*
120 glMatrixMode(GL_MODELVIEW);
121 glPushMatrix();
122 glLoadIdentity();
123 gluPerspective(lfov * 2.0, 1.0, 0.5, 50.0);
124 gluLookAt(lpos.x, lpos.y, lpos.z, ltarg.x, ltarg.y, ltarg.z, 0, 1, 0);
126 float mat[16];
127 glGetFloatv(GL_MODELVIEW_MATRIX, mat);
129 Matrix4x4 res;
130 memcpy(res[0], mat, sizeof mat);
131 res.transpose();
132 return res;
133 */
134 }
136 unsigned int get_shadow_tex()
137 {
138 return depth_tex;
139 }