SHOW:
|
|
- or go back to the newest paste.
1 | #include "RenderTarget.h" | |
2 | #include "Context.h" | |
3 | #include <math.h> | |
4 | #include <stdio.h> | |
5 | ||
6 | #include "Helper.h" // remove this | |
7 | ||
8 | RenderTarget::Viewport RenderTarget::viewport; | |
9 | ||
10 | RenderTarget::RenderTarget(GLint width, GLint height, GLint texCount) | |
11 | { | |
12 | rot = 0; | |
13 | ||
14 | size.x = width; | |
15 | size.y = height; | |
16 | this->texCount = texCount; | |
17 | windowSize.x = Context::getWindowWidth(); | |
18 | windowSize.y = Context::getWindowHeight(); | |
19 | ||
20 | // Create and initialize framebuffer | |
21 | texRT = new GLuint[texCount]; | |
22 | ||
23 | GLint prev_bound_texture; | |
24 | - | glBindFramebuffer(GL_FRAMEBUFFER, frameBufferRT); |
24 | + | glGetInteger(GL_TEXTURE_BINDING_2D, &prev_bound_texture); |
25 | glGenTextures(texCount, texRT); | |
26 | for(int i = 0; i < texCount; i ++) | |
27 | { | |
28 | glBindTexture(GL_TEXTURE_2D, texRT[i]); | |
29 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); | |
30 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
31 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
32 | } | |
33 | - | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texRT[i], 0); |
33 | + | glBindTexture(GL_TEXTURE_2D, 0); |
34 | ||
35 | glGenFramebuffers(1, &frameBufferRT); | |
36 | ||
37 | printf("+ RenderTarget added\n"); | |
38 | } | |
39 | ||
40 | RenderTarget::~RenderTarget() | |
41 | { | |
42 | printf("- RenderTarget deleted\n"); | |
43 | delete[] texRT; | |
44 | } | |
45 | ||
46 | void RenderTarget::Begin() | |
47 | { | |
48 | // Setup framebuffer | |
49 | glGetIntegerv(GL_VIEWPORT, viewport.vp); | |
50 | glViewport(0, size.y - windowSize.y, windowSize.x, windowSize.y); | |
51 | - | glBindFramebuffer(GL_FRAMEBUFFER, frameBufferRT); |
51 | + | |
52 | GLint max_texture_image_units, active_unit; | |
53 | glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_image_units); | |
54 | glGetInteger(GL_ACTIVE_TEXTURE, &active_unit); // yes I know the naming is odd | |
55 | - | GLenum* buffers = new GLenum[texCount]; |
55 | + | |
56 | { | |
57 | for (GLuint i = 0; i < texCount; i++) | |
58 | { | |
59 | // make sure RT textures are unbound before attaching | |
60 | for(GLuint u = 0; u < max_texture_image_units; u++) { | |
61 | GLuint bound_texture; | |
62 | glActiveTexture(GL_TEXTURE0 + u); | |
63 | glGetInteger(GL_TEXTURE_BINDING_2D, &bound_texture); | |
64 | if(bound_texture = texRT[i]) { | |
65 | // better yet, store (unit,texture) pairs, so that we can restore in RenderTarget::End. | |
66 | glBindTexture(GL_TEXTURE_2D, 0); | |
67 | } | |
68 | } | |
69 | } | |
70 | ||
71 | glActiveTexture(active_unit); //okay, this is a kludge. Ideally the code rendering to the FBO takes care of this. But if now, we fail safely. | |
72 | ||
73 | GLenum* buffers = new GLenum[texCount]; | |
74 | glBindFramebuffer(GL_FRAMEBUFFER, frameBufferRT); | |
75 | for (GLuint i = 0; i < texCount; i++) | |
76 | { | |
77 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texRT[i], 0); | |
78 | buffers[i] = GL_COLOR_ATTACHMENT0 + i; | |
79 | } | |
80 | glDrawBuffers(texCount, buffers); | |
81 | delete[] buffers; | |
82 | } | |
83 | ||
84 | // vvvv Those should not be here, but in the part actually rendering to the FBO | |
85 | ||
86 | // Set blend-mode | |
87 | glDisable(GL_BLEND); | |
88 | ||
89 | // Clear the buffer | |
90 | glClearColor(0.0, 0.0, 0.0, 0.0); | |
91 | glClear(GL_COLOR_BUFFER_BIT); | |
92 | } | |
93 | ||
94 | void RenderTarget::End() | |
95 | { | |
96 | // Reset blend-mode | |
97 | glEnable(GL_BLEND); | |
98 | ||
99 | // Reset framebuffer | |
100 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
101 | ||
102 | // Reset viewport | |
103 | glViewport(viewport.x, viewport.y, viewport.width, viewport.height); | |
104 | } | |
105 | ||
106 | void RenderTarget::Draw(GLint x, GLint y) | |
107 | { | |
108 | Draw(x, y, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0, 0, size.x, size.y); | |
109 | } | |
110 | ||
111 | void RenderTarget::Draw(GLint x, GLint y, GLfloat alpha) | |
112 | { | |
113 | Draw(x, y, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, alpha, 0, 0, size.x, size.y); | |
114 | } | |
115 | ||
116 | void RenderTarget::Draw(GLint x, GLint y, GLfloat rotation, GLfloat scaleX, GLfloat scaleY, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha, GLint xx, GLint yy, GLint w, GLint h) | |
117 | { | |
118 | // Draw the framebuffer-texture | |
119 | // Bind texture | |
120 | glBindTexture(GL_TEXTURE_2D, texRT[0]); | |
121 | ||
122 | // Push the matrix | |
123 | glPushMatrix(); | |
124 | ||
125 | // Rotate and translate the quad | |
126 | glTranslatef(x, y, 0.0f); | |
127 | glRotatef(rotation, 0.0f, 0.0f, 1.0f); | |
128 | ||
129 | // Calculate coordinates | |
130 | GLdouble coX1, coX2, coY1, coY2; | |
131 | coX1 = (GLdouble)xx / size.x; | |
132 | coY1 = (GLdouble)yy / size.y; | |
133 | coX2 = (GLdouble)(xx + w) / size.x; | |
134 | coY2 = (GLdouble)(yy + h) / size.y; | |
135 | ||
136 | // Testing blend functions | |
137 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
138 | ||
139 | // Draw the textured quad | |
140 | glBegin(GL_QUADS); | |
141 | glColor4f(red, green, blue, alpha); | |
142 | ||
143 | glTexCoord2d(coX1, coY2); glVertex2d(0, 0); | |
144 | glTexCoord2d(coX2, coY2); glVertex2d(w * scaleX, 0); | |
145 | glTexCoord2d(coX2, coY1); glVertex2d(w * scaleX, h * scaleY); | |
146 | glTexCoord2d(coX1, coY1); glVertex2d(0, h * scaleY); | |
147 | //glTexCoord2d(coX1, coY2); glVertex2d(lenDirX(5, rot * 2), lenDirY(5, rot * 3)); | |
148 | //glTexCoord2d(coX2, coY2); glVertex2d(w * scaleX + lenDirX(5, rot), lenDirX(5, rot * 4)); | |
149 | //glTexCoord2d(coX2, coY1); glVertex2d(w * scaleX + lenDirY(5, rot * 4), h * scaleY + lenDirX(5, rot)); | |
150 | //glTexCoord2d(coX1, coY1); glVertex2d(lenDirX(-5, rot * 3), h * scaleY + lenDirX(-5, rot * 2)); | |
151 | glEnd(); | |
152 | ||
153 | // Return to default blend-function | |
154 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
155 | ||
156 | // Pop the matrix | |
157 | glPopMatrix(); | |
158 | ||
159 | rot += 0.5f; | |
160 | } | |
161 | ||
162 | // Get size of rendertarget | |
163 | Point RenderTarget::GetSize() | |
164 | { | |
165 | return size; | |
166 | } |