rev |
line source |
nuclear@18
|
1 #include <assert.h>
|
nuclear@18
|
2 #include "opengl.h"
|
nuclear@18
|
3 #include "shadow.h"
|
nuclear@18
|
4 #include "vmath/vmath.h"
|
nuclear@18
|
5
|
nuclear@18
|
6 static int tex_sz, prev_vp[4];
|
nuclear@18
|
7 static unsigned int fbo, depth_tex, rb_color;
|
nuclear@18
|
8 static Matrix4x4 shadow_mat;
|
nuclear@18
|
9
|
nuclear@18
|
10 bool init_shadow(int sz)
|
nuclear@18
|
11 {
|
nuclear@18
|
12 if(!glcaps.fbo) {
|
nuclear@18
|
13 return true;
|
nuclear@18
|
14 }
|
nuclear@18
|
15
|
nuclear@18
|
16 tex_sz = sz;
|
nuclear@18
|
17
|
nuclear@18
|
18 glGenFramebuffers(1, &fbo);
|
nuclear@18
|
19 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@18
|
20
|
nuclear@18
|
21 glGenTextures(1, &depth_tex);
|
nuclear@18
|
22 glBindTexture(GL_TEXTURE_2D, depth_tex);
|
nuclear@18
|
23 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
nuclear@18
|
24 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
nuclear@18
|
25 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@18
|
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@18
|
27 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
|
nuclear@18
|
28 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex_sz, tex_sz, 0,
|
nuclear@18
|
29 GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
nuclear@18
|
30 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);
|
nuclear@18
|
31
|
nuclear@18
|
32 assert(glGetError() == GL_NO_ERROR);
|
nuclear@18
|
33
|
nuclear@18
|
34 glDrawBuffer(GL_FALSE);
|
nuclear@18
|
35 glReadBuffer(GL_FALSE);
|
nuclear@18
|
36
|
nuclear@18
|
37 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
nuclear@18
|
38 fprintf(stderr, "incomplete framebuffer\n");
|
nuclear@18
|
39 return false;
|
nuclear@18
|
40 }
|
nuclear@18
|
41
|
nuclear@18
|
42 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@18
|
43 glDrawBuffer(GL_BACK);
|
nuclear@18
|
44 glReadBuffer(GL_BACK);
|
nuclear@18
|
45 assert(glGetError() == GL_NO_ERROR);
|
nuclear@18
|
46
|
nuclear@18
|
47 return true;
|
nuclear@18
|
48 }
|
nuclear@18
|
49
|
nuclear@18
|
50 void destroy_shadow()
|
nuclear@18
|
51 {
|
nuclear@18
|
52 glDeleteTextures(1, &depth_tex);
|
nuclear@18
|
53 glDeleteRenderbuffers(1, &rb_color);
|
nuclear@18
|
54 glDeleteFramebuffers(1, &fbo);
|
nuclear@18
|
55 }
|
nuclear@18
|
56
|
nuclear@18
|
57 void begin_shadow_pass(const Vector3 &lpos, const Vector3 <arg, float lfov)
|
nuclear@18
|
58 {
|
nuclear@18
|
59 Matrix4x4 viewmat, projmat;
|
nuclear@18
|
60
|
nuclear@18
|
61 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
|
nuclear@18
|
62 glDisable(GL_LIGHTING);
|
nuclear@18
|
63 glColorMask(0, 0, 0, 0);
|
nuclear@18
|
64 glDepthMask(1);
|
nuclear@18
|
65
|
nuclear@18
|
66 projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, 0.5, 500.0);
|
nuclear@18
|
67 viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0));
|
nuclear@18
|
68 shadow_mat = viewmat * projmat;
|
nuclear@18
|
69
|
nuclear@18
|
70 glMatrixMode(GL_PROJECTION);
|
nuclear@18
|
71 glPushMatrix();
|
nuclear@18
|
72 glLoadTransposeMatrixf(projmat[0]);
|
nuclear@18
|
73 glMatrixMode(GL_MODELVIEW);
|
nuclear@18
|
74 glPushMatrix();
|
nuclear@18
|
75 glLoadTransposeMatrixf(viewmat[0]);
|
nuclear@18
|
76
|
nuclear@18
|
77 glGetIntegerv(GL_VIEWPORT, prev_vp);
|
nuclear@18
|
78 glViewport(0, 0, tex_sz, tex_sz);
|
nuclear@18
|
79
|
nuclear@18
|
80 glCullFace(GL_FRONT);
|
nuclear@18
|
81 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@18
|
82 }
|
nuclear@18
|
83
|
nuclear@18
|
84
|
nuclear@18
|
85 void end_shadow_pass()
|
nuclear@18
|
86 {
|
nuclear@18
|
87 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@18
|
88 glCullFace(GL_BACK);
|
nuclear@18
|
89
|
nuclear@18
|
90 glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]);
|
nuclear@18
|
91
|
nuclear@18
|
92 glMatrixMode(GL_PROJECTION);
|
nuclear@18
|
93 glPopMatrix();
|
nuclear@18
|
94 glMatrixMode(GL_MODELVIEW);
|
nuclear@18
|
95 glPopMatrix();
|
nuclear@18
|
96
|
nuclear@18
|
97 glPopAttrib();
|
nuclear@18
|
98 }
|
nuclear@18
|
99
|
nuclear@18
|
100 Matrix4x4 get_shadow_matrix()
|
nuclear@18
|
101 {
|
nuclear@18
|
102 return shadow_mat;
|
nuclear@18
|
103 }
|
nuclear@18
|
104
|
nuclear@18
|
105 unsigned int get_shadow_tex()
|
nuclear@18
|
106 {
|
nuclear@18
|
107 return depth_tex;
|
nuclear@18
|
108 }
|