ld33_umonster

annotate src/shadow.cc @ 2:35349df5392d

wtf?
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 22 Aug 2015 23:55:21 +0300
parents
children 93ff21458a16
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 &ltarg, 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@0 93 glPolygonOffset(2, 1);
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 }