rev |
line source |
nuclear@0
|
1 #include "opengl.h"
|
nuclear@0
|
2 #include "rtarg.h"
|
nuclear@0
|
3
|
nuclear@0
|
4 static int next_pow2(int x);
|
nuclear@0
|
5
|
nuclear@0
|
6 RenderTarget::RenderTarget()
|
nuclear@0
|
7 {
|
nuclear@0
|
8 xsz = ysz = 0;
|
nuclear@0
|
9 fbo = color = depth = 0;
|
nuclear@0
|
10
|
nuclear@0
|
11 tex_fmt = 0;
|
nuclear@0
|
12 tex_xsz = tex_ysz = 0;
|
nuclear@0
|
13 }
|
nuclear@0
|
14
|
nuclear@0
|
15 RenderTarget::~RenderTarget()
|
nuclear@0
|
16 {
|
nuclear@0
|
17 destroy();
|
nuclear@0
|
18 }
|
nuclear@0
|
19
|
nuclear@0
|
20 bool RenderTarget::create(int xsz, int ysz)
|
nuclear@0
|
21 {
|
nuclear@0
|
22 destroy();
|
nuclear@0
|
23
|
nuclear@0
|
24 this->xsz = xsz;
|
nuclear@0
|
25 this->ysz = ysz;
|
nuclear@0
|
26
|
nuclear@0
|
27 tex_xsz = next_pow2(xsz);
|
nuclear@0
|
28 tex_ysz = next_pow2(ysz);
|
nuclear@0
|
29 tex_fmt = check_extension("GL_ARB_texture_float") ? GL_RGB16F : GL_RGB;
|
nuclear@0
|
30
|
nuclear@0
|
31 glGenFramebuffers(1, &fbo);
|
nuclear@0
|
32 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@0
|
33
|
nuclear@0
|
34 glGenTextures(1, &color);
|
nuclear@0
|
35 glBindTexture(GL_TEXTURE_2D, color);
|
nuclear@0
|
36 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@0
|
37 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@0
|
38 glTexImage2D(GL_TEXTURE_2D, 0, tex_fmt, tex_xsz, tex_ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
nuclear@0
|
39 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
|
nuclear@0
|
40
|
nuclear@0
|
41 glGenRenderbuffers(1, &depth);
|
nuclear@0
|
42 glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
nuclear@0
|
43 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
|
nuclear@0
|
44 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
|
nuclear@0
|
45
|
nuclear@0
|
46 return true;
|
nuclear@0
|
47 }
|
nuclear@0
|
48
|
nuclear@0
|
49 bool RenderTarget::resize(int xsz, int ysz)
|
nuclear@0
|
50 {
|
nuclear@0
|
51 if(!fbo) {
|
nuclear@0
|
52 return create(xsz, ysz);
|
nuclear@0
|
53 }
|
nuclear@0
|
54
|
nuclear@0
|
55 this->xsz = xsz;
|
nuclear@0
|
56 this->ysz = ysz;
|
nuclear@0
|
57 int new_tex_xsz = next_pow2(xsz);
|
nuclear@0
|
58 int new_tex_ysz = next_pow2(ysz);
|
nuclear@0
|
59
|
nuclear@0
|
60 if(tex_xsz != new_tex_xsz || tex_ysz != new_tex_ysz) {
|
nuclear@0
|
61 glBindTexture(GL_TEXTURE_2D, color);
|
nuclear@0
|
62 glTexImage2D(GL_TEXTURE_2D, 0, tex_fmt, tex_xsz, tex_ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
nuclear@0
|
63
|
nuclear@0
|
64 glBindRenderbuffer(GL_RENDERBUFFER, depth);
|
nuclear@0
|
65 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
|
nuclear@0
|
66
|
nuclear@0
|
67 tex_xsz = new_tex_xsz;
|
nuclear@0
|
68 tex_ysz = new_tex_ysz;
|
nuclear@0
|
69 }
|
nuclear@0
|
70 return true;
|
nuclear@0
|
71 }
|
nuclear@0
|
72
|
nuclear@0
|
73 void RenderTarget::destroy()
|
nuclear@0
|
74 {
|
nuclear@0
|
75 if(fbo) {
|
nuclear@0
|
76 glDeleteFramebuffers(1, &fbo);
|
nuclear@0
|
77 }
|
nuclear@0
|
78 if(color) {
|
nuclear@0
|
79 glDeleteTextures(1, &color);
|
nuclear@0
|
80 }
|
nuclear@0
|
81 if(depth) {
|
nuclear@0
|
82 glDeleteRenderbuffers(1, &depth);
|
nuclear@0
|
83 }
|
nuclear@0
|
84 fbo = color = depth = 0;
|
nuclear@0
|
85 }
|
nuclear@0
|
86
|
nuclear@0
|
87 bool RenderTarget::is_valid() const
|
nuclear@0
|
88 {
|
nuclear@0
|
89 return fbo != 0;
|
nuclear@0
|
90 }
|
nuclear@0
|
91
|
nuclear@0
|
92 unsigned int RenderTarget::get_texture() const
|
nuclear@0
|
93 {
|
nuclear@0
|
94 return color;
|
nuclear@0
|
95 }
|
nuclear@0
|
96
|
nuclear@0
|
97 int RenderTarget::get_width() const
|
nuclear@0
|
98 {
|
nuclear@0
|
99 return xsz;
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102 int RenderTarget::get_height() const
|
nuclear@0
|
103 {
|
nuclear@0
|
104 return ysz;
|
nuclear@0
|
105 }
|
nuclear@0
|
106
|
nuclear@0
|
107 int RenderTarget::get_tex_width() const
|
nuclear@0
|
108 {
|
nuclear@0
|
109 return tex_xsz;
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@0
|
112 int RenderTarget::get_tex_height() const
|
nuclear@0
|
113 {
|
nuclear@0
|
114 return tex_ysz;
|
nuclear@0
|
115 }
|
nuclear@0
|
116
|
nuclear@0
|
117 void set_render_target(const RenderTarget *rtarg)
|
nuclear@0
|
118 {
|
nuclear@0
|
119 if(rtarg) {
|
nuclear@0
|
120 glBindFramebuffer(GL_FRAMEBUFFER, rtarg->color);
|
nuclear@0
|
121 } else {
|
nuclear@0
|
122 glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
nuclear@0
|
123 }
|
nuclear@0
|
124 }
|
nuclear@0
|
125
|
nuclear@0
|
126 static int next_pow2(int x)
|
nuclear@0
|
127 {
|
nuclear@0
|
128 x--;
|
nuclear@0
|
129 x = (x >> 1) | x;
|
nuclear@0
|
130 x = (x >> 2) | x;
|
nuclear@0
|
131 x = (x >> 4) | x;
|
nuclear@0
|
132 x = (x >> 8) | x;
|
nuclear@0
|
133 x = (x >> 16) | x;
|
nuclear@0
|
134 return x + 1;
|
nuclear@0
|
135 }
|