kick
|
00001 // 00002 // Created by morten on 05/06/14. 00003 // 00004 00005 #include "texture_render_target.h" 00006 00007 #include <iostream> 00008 #include <string> 00009 00010 using namespace std; 00011 00012 namespace kick { 00013 TextureRenderTarget::TextureRenderTarget() 00014 { 00015 glGenFramebuffers(1, &mFramebuffer); 00016 } 00017 00018 TextureRenderTarget::~TextureRenderTarget() { 00019 glDeleteFramebuffers(1, &mFramebuffer); 00020 mFramebuffer = 0; 00021 } 00022 00023 void TextureRenderTarget::bind() { 00024 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 00025 if (mColorTextures.size() == 0){ 00026 glDrawBuffer(GL_NONE); 00027 glReadBuffer(GL_NONE); 00028 } 00029 } 00030 00031 void TextureRenderTarget::unbind() { 00032 glBindFramebuffer(GL_FRAMEBUFFER, 0); 00033 if (mColorTextures.size() == 0){ 00034 glDrawBuffer(GL_BACK); 00035 glReadBuffer(GL_BACK); 00036 } 00037 } 00038 00039 void TextureRenderTarget::apply() { 00040 if (mRenderBuffers.size()) { 00041 glDeleteRenderbuffers(mRenderBuffers.size(), mRenderBuffers.data()); 00042 mRenderBuffers.clear(); 00043 } 00044 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 00045 00046 // bind color attachment 00047 if (mColorTextures.size() > 0){ 00048 for (int i=0;i< mColorTextures.size();i++) { 00049 Texture2D* colorTexture = mColorTextures[i].get(); 00050 glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum) (GL_COLOR_ATTACHMENT0+i), GL_TEXTURE_2D, colorTexture->mTextureid, 0); 00051 } 00052 } else { 00053 /*GLuint renderBuffer; 00054 glGenRenderbuffers(1, &renderBuffer); 00055 mRenderBuffers.push_back(renderBuffer); 00056 glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); 00057 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, mSize.x, mSize.y); 00058 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer); */ 00059 glDrawBuffer(GL_NONE); 00060 glReadBuffer(GL_NONE); 00061 } 00062 00063 // bind depth attachments 00064 if (mDepthTexture){ 00065 glFramebufferTexture2D(GL_FRAMEBUFFER, (GLenum) GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture->mTextureid, 0); 00066 } else { 00067 GLuint renderBuffer; 00068 glGenRenderbuffers(1, &renderBuffer); 00069 mRenderBuffers.push_back(renderBuffer); 00070 glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); 00071 glRenderbufferStorage(GL_RENDERBUFFER, 00072 #ifdef KICK_CONTEXT_ES2 00073 GL_DEPTH_COMPONENT16, 00074 #else 00075 GL_DEPTH_COMPONENT32, 00076 #endif 00077 00078 mSize.x, mSize.y); 00079 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer); 00080 } 00081 checkStatus(); 00082 00083 cout << "Make rendertarget"<<endl; 00084 00085 glBindFramebuffer(GL_FRAMEBUFFER, 0); 00086 } 00087 00088 void TextureRenderTarget::checkStatus() { 00089 GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); 00090 if (frameBufferStatus != GL_FRAMEBUFFER_COMPLETE) { 00091 switch (frameBufferStatus) { 00092 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 00093 cerr << ("GL_FRAMEBUFFER_UNDEFINED"); 00094 break; 00095 #ifdef GL_ES_VERSION_2_0 00096 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 00097 cerr << ("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); 00098 break; 00099 #endif 00100 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 00101 cerr << ("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); 00102 break; 00103 case GL_FRAMEBUFFER_UNSUPPORTED: 00104 cerr << ("FRAMEBUFFER_UNSUPPORTED"); 00105 break; 00106 #ifndef GL_ES_VERSION_2_0 00107 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: 00108 cerr << ("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"); 00109 break; 00110 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: 00111 cerr << ("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"); 00112 break; 00113 case GL_FRAMEBUFFER_UNDEFINED: 00114 cerr << ("FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); 00115 break; 00116 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: 00117 cerr << ("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"); 00118 break; 00119 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: 00120 cerr << ("GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS"); 00121 break; 00122 #endif 00123 default: 00124 cerr << string("Invalid framebuffer ")+ std::to_string(frameBufferStatus); 00125 break; 00126 } 00127 } 00128 } 00129 00130 void TextureRenderTarget::setSize(glm::ivec2 size) { 00131 TextureRenderTarget::mSize = size; 00132 } 00133 00134 glm::ivec2 TextureRenderTarget::size() const { 00135 return mSize; 00136 } 00137 00138 void TextureRenderTarget::setColorTexture(size_t channel, std::shared_ptr<Texture2D> texture) { 00139 if (mColorTextures.size() <= channel){ 00140 mColorTextures.resize(channel+1, nullptr); 00141 } 00142 mColorTextures[channel] = texture; 00143 } 00144 00145 std::shared_ptr<Texture2D> TextureRenderTarget::colorTexture(size_t channel) { 00146 if (mColorTextures.size() <= channel){ 00147 return nullptr; 00148 } 00149 return mColorTextures[channel]; 00150 } 00151 00152 bool TextureRenderTarget::deleteColorTexture(size_t channel) { 00153 if (mColorTextures.size() <= channel){ 00154 return false; 00155 } 00156 mColorTextures[channel].reset(); 00157 mColorTextures.erase(mColorTextures.begin() + channel); 00158 return true; 00159 } 00160 00161 bool TextureRenderTarget::deleteDepthTexture() { 00162 bool wasNotEmpty = mDepthTexture.get(); 00163 mDepthTexture.reset(); 00164 return wasNotEmpty; 00165 } 00166 00167 void TextureRenderTarget::setDepthTexture(std::shared_ptr<Texture2D> texture) { 00168 mDepthTexture = texture; 00169 } 00170 }