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 | } |