rev |
line source |
nuclear@0
|
1 #include <GL/glew.h>
|
nuclear@0
|
2 #include "rtarg.h"
|
nuclear@0
|
3
|
nuclear@0
|
4 RenderTarget::RenderTarget()
|
nuclear@0
|
5 {
|
nuclear@0
|
6 fbo = tex = zbuf = 0;
|
nuclear@0
|
7 }
|
nuclear@0
|
8
|
nuclear@0
|
9 RenderTarget::~RenderTarget()
|
nuclear@0
|
10 {
|
nuclear@0
|
11 destroy();
|
nuclear@0
|
12 }
|
nuclear@0
|
13
|
nuclear@0
|
14 bool RenderTarget::create(int xsz, int ysz)
|
nuclear@0
|
15 {
|
nuclear@0
|
16 destroy();
|
nuclear@0
|
17
|
nuclear@0
|
18 glGenFramebuffers(1, &fbo);
|
nuclear@0
|
19 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@0
|
20
|
nuclear@0
|
21 this->xsz = xsz;
|
nuclear@0
|
22 this->ysz = ysz;
|
nuclear@0
|
23 tex_xsz = next_pow2(xsz);
|
nuclear@0
|
24 tex_ysz = next_pow2(ysz);
|
nuclear@0
|
25
|
nuclear@0
|
26 glGenTextures(1, &tex);
|
nuclear@0
|
27 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@0
|
28 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@0
|
29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
30 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
nuclear@0
|
31 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
nuclear@0
|
32 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
nuclear@0
|
33
|
nuclear@0
|
34 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
nuclear@0
|
35
|
nuclear@0
|
36 glGenRenderbuffers(1, &zbuf);
|
nuclear@0
|
37 glBindRenderbuffer(GL_RENDERBUFFER, zbuf);
|
nuclear@0
|
38 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
|
nuclear@0
|
39
|
nuclear@0
|
40 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf);
|
nuclear@0
|
41
|
nuclear@0
|
42 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@0
|
43 return true;
|
nuclear@0
|
44 }
|
nuclear@0
|
45
|
nuclear@0
|
46 void RenderTarget::destroy()
|
nuclear@0
|
47 {
|
nuclear@0
|
48 if(fbo) {
|
nuclear@0
|
49 glDeleteFramebuffers(1, &fbo);
|
nuclear@0
|
50 }
|
nuclear@0
|
51 if(tex) {
|
nuclear@0
|
52 glDeleteTextures(1, &tex);
|
nuclear@0
|
53 }
|
nuclear@0
|
54 if(zbuf) {
|
nuclear@0
|
55 glDeleteRenderbuffers(1, &zbuf);
|
nuclear@0
|
56 }
|
nuclear@0
|
57 }
|
nuclear@0
|
58
|
nuclear@0
|
59 void RenderTarget::reshape(int new_xsz, int new_ysz)
|
nuclear@0
|
60 {
|
nuclear@0
|
61 if(!fbo) {
|
nuclear@0
|
62 create(new_xsz, new_ysz);
|
nuclear@0
|
63 return;
|
nuclear@0
|
64 }
|
nuclear@0
|
65
|
nuclear@0
|
66 xsz = new_xsz;
|
nuclear@0
|
67 ysz = new_ysz;
|
nuclear@0
|
68
|
nuclear@0
|
69 int new_txsz = next_pow2(new_xsz);
|
nuclear@0
|
70 int new_tysz = next_pow2(new_ysz);
|
nuclear@0
|
71
|
nuclear@0
|
72 if(tex_xsz >= new_txsz && tex_ysz >= new_tysz) {
|
nuclear@0
|
73 return;
|
nuclear@0
|
74 }
|
nuclear@0
|
75
|
nuclear@0
|
76 tex_xsz = new_txsz;
|
nuclear@0
|
77 tex_ysz = new_tysz;
|
nuclear@0
|
78
|
nuclear@0
|
79 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@0
|
80 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
nuclear@0
|
81
|
nuclear@0
|
82 glBindRenderbuffer(GL_RENDERBUFFER, zbuf);
|
nuclear@0
|
83 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
|
nuclear@0
|
84 }
|
nuclear@0
|
85
|
nuclear@0
|
86 void RenderTarget::display() const
|
nuclear@0
|
87 {
|
nuclear@0
|
88 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
89 glPushMatrix();
|
nuclear@0
|
90 glLoadIdentity();
|
nuclear@0
|
91 glMatrixMode(GL_PROJECTION);
|
nuclear@0
|
92 glPushMatrix();
|
nuclear@0
|
93 glLoadIdentity();
|
nuclear@0
|
94
|
nuclear@0
|
95 glPushAttrib(GL_ENABLE_BIT);
|
nuclear@0
|
96 glDisable(GL_DEPTH_TEST);
|
nuclear@0
|
97 glDisable(GL_LIGHTING);
|
nuclear@0
|
98 glEnable(GL_TEXTURE_2D);
|
nuclear@0
|
99 glBindTexture(GL_TEXTURE_2D, tex);
|
nuclear@0
|
100
|
nuclear@0
|
101 float max_u = (float)xsz / (float)tex_xsz;
|
nuclear@0
|
102 float max_v = (float)ysz / (float)tex_ysz;
|
nuclear@0
|
103
|
nuclear@0
|
104 glBegin(GL_QUADS);
|
nuclear@0
|
105 glColor3f(1, 1, 1);
|
nuclear@0
|
106 glTexCoord2f(0, 0);
|
nuclear@0
|
107 glVertex2f(-1, -1);
|
nuclear@0
|
108 glTexCoord2f(max_u, 0);
|
nuclear@0
|
109 glVertex2f(1, -1);
|
nuclear@0
|
110 glTexCoord2f(max_u, max_v);
|
nuclear@0
|
111 glVertex2f(1, 1);
|
nuclear@0
|
112 glTexCoord2f(0, max_v);
|
nuclear@0
|
113 glVertex2f(-1, 1);
|
nuclear@0
|
114 glEnd();
|
nuclear@0
|
115
|
nuclear@0
|
116 glPopAttrib();
|
nuclear@0
|
117 glPopMatrix();
|
nuclear@0
|
118 glMatrixMode(GL_MODELVIEW);
|
nuclear@0
|
119 glPopMatrix();
|
nuclear@0
|
120 }
|
nuclear@0
|
121
|
nuclear@0
|
122 void bind_render_target(const RenderTarget *rtarg)
|
nuclear@0
|
123 {
|
nuclear@0
|
124 glBindFramebuffer(GL_FRAMEBUFFER, rtarg ? rtarg->fbo : 0);
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 int next_pow2(int x)
|
nuclear@0
|
128 {
|
nuclear@0
|
129 x--;
|
nuclear@0
|
130 x = (x >> 1) | x;
|
nuclear@0
|
131 x = (x >> 2) | x;
|
nuclear@0
|
132 x = (x >> 4) | x;
|
nuclear@0
|
133 x = (x >> 8) | x;
|
nuclear@0
|
134 x = (x >> 16) | x;
|
nuclear@0
|
135 return x + 1;
|
nuclear@0
|
136 }
|