RenderTexture::RenderTexture(int width, int height, int sample_count, GLenum target) : Texture(new GLTexture(target)), target_(target), width_(width), height_(height), sample_count_(sample_count), back_color_{0, 0, 0}, use_stencil_(0), renderTexture_gl_render_buffer_(new GLRenderBuffer()), renderTexture_gl_frame_buffer_(new GLFrameBuffer()) { initialize(width, height); if (target_ == GL_TEXTURE_2D_ARRAY) { PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) eglGetProcAddress( "glFramebufferTextureMultisampleMultiviewOVR"); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindTexture(target_, gl_texture_->id()); glTexImage3D(target, 0, GL_RGBA8, width, height, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(target_, 0); createArrayTexture(frameBufferDepthTextureId, width_, height_, GL_DEPTH_COMPONENT16); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTexture_gl_frame_buffer_->id()); glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gl_texture_->id(), 0, sample_count_, 0, 2); glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBufferDepthTextureId, 0, sample_count_, 0, 2); } else { glBindTexture(target_, gl_texture_->id()); glTexImage2D(target_, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindTexture(target_, 0); glBindRenderbuffer(GL_RENDERBUFFER, renderTexture_gl_render_buffer_->id()); MSAA::glRenderbufferStorageMultisampleIMG(GL_RENDERBUFFER, sample_count, GL_DEPTH_COMPONENT16, width, height); glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, renderTexture_gl_frame_buffer_->id()); MSAA::glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target_, gl_texture_->id(), 0, sample_count); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderTexture_gl_render_buffer_->id()); } }
void RenderTexture::createArrayRenderTexture(int jcolor_format, int jdepth_format, bool resolve_depth) { glBindFramebuffer(GL_FRAMEBUFFER, 0); GLenum depth_format; glBindTexture(target_, gl_texture_->id()); texImage3D(jcolor_format, width_, height_, target_); switch (jdepth_format) { case DepthFormat::DEPTH_24: depth_format = GL_DEPTH_COMPONENT24; break; case DepthFormat::DEPTH_24_STENCIL_8: depth_format = GL_DEPTH24_STENCIL8_OES; break; default: depth_format = GL_DEPTH_COMPONENT16; break; } PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) eglGetProcAddress( "glFramebufferTextureMultiviewOVR"); PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) eglGetProcAddress( "glFramebufferTextureMultisampleMultiviewOVR"); if (jdepth_format != DepthFormat::DEPTH_0) createArrayTexture(frameBufferDepthTextureId, width_, height_, depth_format); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTexture_gl_frame_buffer_->id()); if (sample_count_ <= 1 && !resolve_depth) { glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gl_texture_->id(), 0, 0, 2); } if (sample_count_ > 1 && !resolve_depth) { if (jdepth_format != DepthFormat::DEPTH_0) { glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBufferDepthTextureId, 0, sample_count_, 0, 2); } glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gl_texture_->id(), 0, sample_count_, 0, 2); } if (resolve_depth && sample_count_ > 1) { if (jdepth_format != DepthFormat::DEPTH_0) glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, frameBufferDepthTextureId, 0, 0, 2); glGenTextures(1, &render_texture_gl_texture_); glBindTexture(GL_TEXTURE_2D_ARRAY, render_texture_gl_texture_); texImage3D(jcolor_format, width_, height_, GL_TEXTURE_2D_ARRAY); glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, render_texture_gl_texture_, 0, sample_count_, 0, 2); } /* Check BO is OK. */ GLenum result = (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); if (result != GL_FRAMEBUFFER_COMPLETE) { LOGE("RenderTextureArray::bindFrameBuffer Could not bind framebuffer: %d", result); switch (result) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT : LOGE("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: LOGE("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); break; case GL_FRAMEBUFFER_UNSUPPORTED: LOGE("GL_FRAMEBUFFER_UNSUPPORTED"); break; } LOGE("Framebuffer incomplete at %s:%i\n", __FILE__, __LINE__); /* Unbind framebuffer. */ (glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); } checkGLError("glFramebufferTextureMultiviewOVR 2"); glScissor(0, 0, width_, height_); glViewport(0, 0, width_, height_); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); if (resolve_depth && sample_count_ > 1) { delete renderTexture_gl_resolve_buffer_; renderTexture_gl_resolve_buffer_ = new GLFrameBuffer(); glBindFramebuffer(GL_FRAMEBUFFER, renderTexture_gl_resolve_buffer_->id()); glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, gl_texture_->id(), 0, 0, 2); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { LOGE( "resolve FBO %i is not complete: 0x%x", renderTexture_gl_resolve_buffer_->id(), status); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); }
GLMultiviewRenderTexture::GLMultiviewRenderTexture(int width, int height, int sample_count, int jcolor_format, int jdepth_format, bool resolve_depth, const TextureParameters* texture_parameters, int layers, int const viewport[]):GLRenderTexture(width, height, sample_count, jcolor_format, jdepth_format, resolve_depth, texture_parameters, viewport), mLayers_(layers) { GLRenderImage* colorbuffer = new GLRenderImage(width, height, layers, jcolor_format, texture_parameters); GLenum depth_format; setImage(colorbuffer); initialize(); colorbuffer->isReady(); switch (jdepth_format) { case DepthFormat::DEPTH_24: depth_format = GL_DEPTH_COMPONENT24_OES; break; case DepthFormat::DEPTH_24_STENCIL_8: depth_format = GL_DEPTH24_STENCIL8_OES; break; default: depth_format = GL_DEPTH_COMPONENT16; break; } const GLenum depthStencilAttachment = GL_DEPTH24_STENCIL8_OES == depth_format ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) eglGetProcAddress( "glFramebufferTextureMultiviewOVR"); PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) eglGetProcAddress( "glFramebufferTextureMultisampleMultiviewOVR"); if (jdepth_format != DepthFormat::DEPTH_0) createArrayTexture(frameBufferDepthTextureId, width, height, depth_format); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderTexture_gl_frame_buffer_->id()); if (sample_count <= 1 && !resolve_depth) { glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getId(), 0, 0, 2); } if (sample_count > 1 && !resolve_depth) { if (jdepth_format != DepthFormat::DEPTH_0) { glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, depthStencilAttachment, frameBufferDepthTextureId, 0, sample_count, 0, 2); } glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, getId(), 0, sample_count, 0, 2); } if (resolve_depth && sample_count > 1) { if (jdepth_format != DepthFormat::DEPTH_0) glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, depthStencilAttachment, frameBufferDepthTextureId, 0, 0, 2); glGenTextures(1, &render_texture_gl_texture_); glBindTexture(GL_TEXTURE_2D_ARRAY, render_texture_gl_texture_); texImage3D(jcolor_format, width, height,2, GL_TEXTURE_2D_ARRAY); glFramebufferTextureMultisampleMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, render_texture_gl_texture_, 0, sample_count, 0, 2); } /* Check BO is OK. */ GLenum result = (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); if (result != GL_FRAMEBUFFER_COMPLETE) { LOGE("RenderTextureArray::bindFrameBuffer Could not bind framebuffer: %d", result); switch (result) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT : LOGE("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: LOGE("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); break; case GL_FRAMEBUFFER_UNSUPPORTED: LOGE("GL_FRAMEBUFFER_UNSUPPORTED"); break; } LOGE("Framebuffer incomplete at %s:%i\n", __FILE__, __LINE__); /* Unbind framebuffer. */ (glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); } checkGLError("glFramebufferTextureMultiviewOVR 2"); glScissor(0, 0, width, height); glViewport(0, 0, width, height); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); if (resolve_depth && sample_count > 1) { delete renderTexture_gl_resolve_buffer_; renderTexture_gl_resolve_buffer_ = new GLFrameBuffer(); glBindFramebuffer(GL_FRAMEBUFFER, renderTexture_gl_resolve_buffer_->id()); glFramebufferTextureMultiviewOVR(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorbuffer->getId(), 0, 0, 2); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { LOGE( "resolve FBO %i is not complete: 0x%x", renderTexture_gl_resolve_buffer_->id(), status); } } glBindFramebuffer(GL_FRAMEBUFFER, 0); /////////////////////////////////////////////////////////////////// }