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