Commit e3191ce5 authored by Thery Sylvain's avatar Thery Sylvain

update FBO

parent b75bfd43
......@@ -279,10 +279,16 @@ public:
bool Alt() const { return m_glWidget->Alt(); }
/**
* height of OpenGL widget (for classic yy = H-y
* height of OpenGL widget (for classic yy = H-y)
*/
int getHeight() const { return m_glWidget->getHeight(); }
/**
* width of OpenGL widget
*/
int getWidth() const { return m_glWidget->getWidth(); }
/**
* console QTextEdit ptr
*/
......
......@@ -30,6 +30,7 @@
#include "Utils/GLSLShader.h"
#include "Utils/clippingShader.h"
#include "Utils/textures.h"
#include "Utils/gl_def.h"
namespace CGoGN
{
......@@ -68,9 +69,14 @@ public:
void setTexture(Utils::GTexture* tex);
/**
* activation of texture unit
* activation of texture unit with set texture
*/
void activeTexture();
/**
* activation of texture unit with texture id
*/
void activeTexture(CGoGNGLuint texId);
unsigned int setAttributePosition(VBO* vbo);
......
......@@ -25,7 +25,9 @@
#ifndef __CGoGN_GLSL_FBO__
#define __CGoGN_GLSL_FBO__
#include <GL/glew.h>
#include "Utils/gl_def.h"
#include "Utils/cgognStream.h"
#include <iostream>
#include <vector>
......@@ -36,64 +38,196 @@ namespace CGoGN
namespace Utils
{
// forward declaration
class GLSLShader;
/**
* Simple Fbo class to do offscreen rendering in OpenGL.
*/
class FBO
{
public:
/// default constructor
FBO();
/**
* constructor with size of frame buffer
* @param width width in pixel
* @param height heigt in pixel
*/
FBO(unsigned int width, unsigned int height);
/// destructor
~FBO();
/**
*
*/
void attachRender(GLenum internalformat);
/**
*
*/
void attachTexture(GLenum internalformat, GLint filter = GL_LINEAR);
void bindTexInput();
void bindTexInput(int num);
void bindTexOutput();
void bindTexOutput(int num);
void unbind();
void setSize(unsigned int width, unsigned int height)
{
m_width = width;
m_height = height;
}
public:
void checkFBO();
/**
* Constructor.
* \param width Width of the Fbo in pixels
* \param heigth Height of the Fbo in pixels
*/
FBO(unsigned int width, unsigned int height);
/**
* Destructor.
*/
~FBO();
/**
* Attach a render buffer to the Fbo.\n
* If another render buffer is already attached, it will be deleted and replaced with the new one.\n
* When calling this function, no Fbo should be bound.\n
* \param internalFormat Internal format of the render buffer : GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, or GL_DEPTH_STENCIL
*/
// void attachRenderbuffer(GLenum internalFormat);
/**
* Attach a color texture to the Fbo.\n
* This function fails if the maximum number of attached color textures is already reached.\n
* When calling this function, no Fbo should be bound.\n
* @param internalFormat Internal format of the texture : GL_RGBA, GL_RGB, GL_RGBA32F, or GL_RGB32F
* @param filter Filter used to minify or magnify the texture (default value is GL_LINEAR)
* @return id of attachement
*/
int createAttachColorTexture(GLenum internalFormat, GLint filter = GL_LINEAR);
/**
* Attach a color texture to the Fbo.\n
* This function fails if the maximum number of attached color textures is already reached.\n
* When calling this function, no Fbo should be bound.\n
* @param textureId id of texture to attach (default is 0: texture us creatated with internal format)
* @return id of attachement
*/
int attachColorTexture(CGoGNGLuint textureId);
/**
* Create and attach a depth texture to the Fbo.\n
* This function fails if a depth texture was already attached to the Fbo.\n
* When calling this function, no Fbo should be bound.\n
* @param filter Filter used to minify or magnify the texture (default value is GL_LINEAR)
* @return true if creation & attachment success
*/
bool createAttachDepthTexture(GLint filter = GL_LINEAR);
/**
* Attach a depth texture to the Fbo.\n
* This function fails if a depth texture was already attached to the Fbo.\n
* When calling this function, no Fbo should be bound.\n
* @param textureId depth texture from another FBO, with getDepthTexId
* @return true if attachment success
*/
bool attachDepthTexture(CGoGNGLuint textureId);
/**
* Enable every color attachments of the Fbo.\n
* Useless for Fbos containing only one color attachment.\n
* When calling this function, this Fbo must be bound.\n
*/
void enableAllColorAttachments();
/**
* Enable a specific color attachment of the Fbo.\n
* Useless for Fbos containing only one color attachment.\n
* When calling this function, this Fbo must be bound.\n
* \param num Number of the color attachment that should be enabled
*/
void enableColorAttachment(int num);
/**
* Get an attached color texture id.
* \param att Number of the color texture (the number is equivalent to the color attachment)
* \returns Color texture id
*/
CGoGNGLuint getColorTexId(int att);
/**
* Get the attached depth texture id.
* \returns Depth texture id
*/
CGoGNGLuint getDepthTexId();
/**
* draw full screen attached texture
* @param attach id of attachment
*/
void draw(int attach=0);
/**
* draw full screen attached texture
* @param attach id of attachment
*/
void drawWithDepth(int attach=0);
/**
* draw full screen attached texture
* @param attach id of attachment
*/
void drawWithDepth(int attach, CGoGNGLuint depthTexId);
/**
*
*/
static void draw(Utils::GLSLShader* shader);
/**
* Bind this Fbo.\n
* When calling this function, no Fbo should be bound.\n
*/
void bind();
/**
* Unbind this Fbo.\n
*/
void unbind();
/**
* Call glFlush(), unbind this Fbo, call glDrawBuffer(GL_BACK).\n
*/
void safeUnbind();
/**
* Check the completeness of this Fbo.\n
* When calling this function, no Fbo should be bound.\n
*/
void checkFBO();
/**
* \returns Width of the Fbo in pixels.
*/
unsigned int getWidth() const;
/**
* \returns Height of the Fbo in pixels.
*/
unsigned int getHeight() const;
protected:
unsigned int m_width;
unsigned int m_height;
int m_maxColorAttachments;
CGoGNGLuint m_fboID;
CGoGNGLuint m_renderID;
std::vector<CGoGNGLuint> m_texID;
CGoGNGLenumTable m_attachmentPoints;
/// Width (in pixels) of the Fbo.
unsigned int m_width;
/// Height (in pixels) of the Fbo.
unsigned int m_height;
/// Maximum number of color attachments.
int m_maxColorAttachments;
/// Fbo id.
CGoGNGLuint m_fboId;
/// Render buffer id.
CGoGNGLuint m_renderBufferId;
/// Color textures ids (up to m_maxColorAttachments color textures).
std::vector<CGoGNGLuint> m_colorTexId;
/// Depth textures ids (only one depth texture actually).
std::vector<CGoGNGLuint> m_depthTexId;
/// Color attachments of the Fbo.
CGoGNGLenumTable m_colorAttachmentPoints;
/// Original viewport (x, y, width, height), saved when binding the Fbo, restored when unbinding it.
GLint m_oldViewport[4];
/// Indicates wether the Fbo is bound or not.
bool m_bound;
/// Indicates wether any Fbo is bound or not.
static bool sm_anyFboBound;
};
}
}
} // namespace Utils
} // namespace CGoGN
#endif /* FRAMEBUFFER_HPP */
......@@ -32,6 +32,8 @@
#include <GL/glew.h>
#include "Utils/cgognStream.h"
namespace CGoGN
{
......@@ -65,6 +67,21 @@ typedef FalsePtr<GLenum*> CGoGNGLenumTable;
#endif
inline void glCheckErrors()
{
GLenum glError = glGetError();
if (glError != GL_NO_ERROR)
CGoGNerr<<"GL error: " << gluErrorString(glError) << CGoGNendl;
}
inline void glCheckErrors(const std::string& message)
{
GLenum glError = glGetError();
if (glError != GL_NO_ERROR)
CGoGNerr<< message <<" : " << gluErrorString(glError) << CGoGNendl;
}
}
......
......@@ -24,6 +24,7 @@
#ifdef WITH_QT
#include <GL/glew.h>
#include "Utils/Shaders/shaderSimpleTexture.h"
......@@ -69,7 +70,7 @@ ShaderSimpleTexture::ShaderSimpleTexture()
loadShadersFromMemory(glxvert.c_str(), glxfrag.c_str());
*m_unif_unit = glGetUniformLocation(this->program_handler(), "textureUnit");
m_unif_unit = glGetUniformLocation(this->program_handler(), "textureUnit");
}
void ShaderSimpleTexture::setTextureUnit(GLenum texture_unit)
......@@ -87,11 +88,15 @@ void ShaderSimpleTexture::setTexture(Utils::GTexture* tex)
void ShaderSimpleTexture::activeTexture()
{
glActiveTexture(GL_TEXTURE0+m_unit);
glActiveTexture(GL_TEXTURE0 + m_unit);
m_tex_ptr->bind();
}
void ShaderSimpleTexture::activeTexture(CGoGNGLuint texId)
{
glActiveTexture(GL_TEXTURE0 + m_unit);
glBindTexture(GL_TEXTURE_2D, *texId);
}
unsigned int ShaderSimpleTexture::setAttributePosition(VBO* vbo)
{
......@@ -107,9 +112,14 @@ unsigned int ShaderSimpleTexture::setAttributeTexCoord(VBO* vbo)
void ShaderSimpleTexture::restoreUniformsAttribs()
{
m_unif_unit = glGetUniformLocation(this->program_handler(), "textureUnit");
bindVA_VBO("VertexPosition", m_vboPos);
bindVA_VBO("VertexTexCoord", m_vboTexCoord);
this->bind();
glUniform1iARB(*m_unif_unit,m_unit);
this->unbind();
}
} // namespace Utils
......
......@@ -22,6 +22,7 @@
* *
*******************************************************************************/
#include "Utils/fbo.h"
#include "Utils/textureSticker.h"
namespace CGoGN
{
......@@ -29,168 +30,462 @@ namespace CGoGN
namespace Utils
{
FBO::FBO()
{
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_maxColorAttachments);
*m_attachmentPoints = new GLenum[m_maxColorAttachments];
glGenFramebuffers(1, &(*m_fboID));
}
// Initialize static variables and constants
bool FBO::sm_anyFboBound = false;
FBO::FBO(unsigned int width, unsigned int height)
: m_width (width)
, m_height (height)
, m_maxColorAttachments (0)
, m_fboId (CGoGNGLuint(0))
, m_renderBufferId (CGoGNGLuint(0))
, m_colorAttachmentPoints (CGoGNGLenumTable(NULL))
, m_bound (false)
{
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_maxColorAttachments);
*m_attachmentPoints = new GLenum[m_maxColorAttachments];
glGenFramebuffers(1, &(*m_fboID));
m_width = width;
m_height = height;
// Generate Fbo
glGenFramebuffers(1, &(*m_fboId));
// Get the maximum number of available color attachments
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_maxColorAttachments);
*m_colorAttachmentPoints = new GLenum[m_maxColorAttachments];
}
FBO::~FBO()
{
GLuint tex_id;
GLuint textureId;
for (unsigned int i = 0; i < m_colorTexId.size(); i++)
{
textureId = *(m_colorTexId.at(i));
if (glIsTexture(textureId))
glDeleteTextures(1, &textureId);
}
for (unsigned int i = 0; i < m_depthTexId.size(); i++)
{
textureId = *(m_depthTexId.at(i));
if (glIsTexture(textureId))
glDeleteTextures(1, &textureId);
}
if (glIsRenderbuffer(*m_renderBufferId))
glDeleteRenderbuffers(1, &(*m_renderBufferId));
if (glIsFramebuffer(*m_fboId))
glDeleteFramebuffers(1, &(*m_fboId));
delete[] *m_colorAttachmentPoints;
}
for( unsigned int i = 0; i < m_texID.size(); ++i ) {
tex_id = *(m_texID.at(i));
glDeleteTextures(1, &tex_id);
}
/*
void FBO::attachRenderbuffer(GLenum internalFormat)
{
if (sm_anyFboBound)
{
CGoGNerr << "FBO::AttachRenderbuffer : No Fbo should be bound when attaching a render buffer." << CGoGNendl;
return;
}
GLenum attachment;
GLuint renderBufferId;
switch (internalFormat)
{
case GL_DEPTH_COMPONENT :
attachment = GL_DEPTH_ATTACHMENT;
break;
case GL_STENCIL_INDEX :
attachment = GL_STENCIL_ATTACHMENT;
break;
case GL_DEPTH_STENCIL :
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
break;
default :
CGoGNerr << "FBO::AttachRenderbuffer : Bad internal format." << CGoGNendl;
return;
break;
}
// Delete old render buffer if it exists
if (glIsRenderbuffer(*m_renderBufferId))
glDeleteRenderbuffers(1, &(*m_renderBufferId));
// Generate render buffer
glGenRenderbuffers(1, &renderBufferId);
glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId);
glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, m_width, m_height);
// Attach render buffer to Fbo
glBindFramebuffer(GL_FRAMEBUFFER, *m_fboId);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, renderBufferId);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
*m_renderBufferId = renderBufferId;
}
*/
glDeleteFramebuffers(1, &(*m_fboID));
delete[] *m_attachmentPoints;
int FBO::createAttachColorTexture(GLenum internalFormat, GLint filter)
{
if (sm_anyFboBound)
{
CGoGNerr << "FBO::AttachColorTexture : No Fbo should be bound when attaching a texture." << CGoGNendl;
return -1;
}
if ((int) m_colorTexId.size() == m_maxColorAttachments)
{
CGoGNerr << "FBO::AttachColorTexture : The maximum number of color textures has been exceeded." << CGoGNendl;
return -1;
}
GLenum attachment;
GLenum format;
GLenum type;
GLuint textureId;
attachment = GL_COLOR_ATTACHMENT0 + m_colorTexId.size();
switch (internalFormat)
{
// four components
case GL_RGBA :
format = GL_RGBA;
type = GL_FLOAT;
break;
case GL_RGBA32F :
format = GL_RGBA;
type = GL_FLOAT;
break;
// three components
case GL_RGB :
format = GL_RGB;
type = GL_FLOAT;
break;
case GL_RGB32F :
format = GL_RGB;
type = GL_FLOAT;
break;
// two components
case GL_RG32F:
format = GL_RG;
type = GL_FLOAT;
break;
case GL_RG:
format = GL_RG;
type = GL_FLOAT;
break;
// one component
case GL_R32F:
format = GL_RED;
type = GL_FLOAT;
break;
case GL_RED:
format = GL_RED;
type = GL_FLOAT;
break;
default :
CGoGNerr << "FBO::AttachColorTexture : Specified internal format not handled." << CGoGNendl;
return false;
break;
}
// Generate texture
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, m_width, m_height, 0, format, type, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Attach texture to Fbo
glBindFramebuffer(GL_FRAMEBUFFER, *m_fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, textureId, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
m_colorTexId.push_back(CGoGNGLuint(textureId));
unsigned int num = m_colorTexId.size() - 1;
(*m_colorAttachmentPoints)[num] = attachment;
return int(num);
}
void FBO::attachRender(GLenum internalformat)
int FBO::attachColorTexture(CGoGNGLuint textureId)
{
GLenum attachment;
GLuint renderID;
if (sm_anyFboBound)
{
CGoGNerr << "FBO::AttachColorTexture : No Fbo should be bound when attaching a texture." << CGoGNendl;
return -1;
}
if( internalformat == GL_DEPTH_COMPONENT ) {
attachment = GL_DEPTH_ATTACHMENT;
}
if ((int) m_colorTexId.size() == m_maxColorAttachments)
{
CGoGNerr << "FBO::AttachColorTexture : The maximum number of color textures has been exceeded." << CGoGNendl;
return -1;
}
else if( internalformat == GL_STENCIL_INDEX ) {
attachment = GL_STENCIL_ATTACHMENT;
}
GLenum attachment;
else if( internalformat == GL_DEPTH_STENCIL ) {
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
}
attachment = GL_COLOR_ATTACHMENT0 + m_colorTexId.size();
else {
std::cout << "FBO::attachRender : Bad Internal Format" << std::endl;
return;
}
// Attach texture to Fbo
glBindFramebuffer(GL_FRAMEBUFFER, *m_fboId);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, *textureId, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glGenRenderbuffers(1, &renderID);
glBindFramebuffer(GL_FRAMEBUFFER, *m_fboID);
glBindRenderbuffer(GL_RENDERBUFFER, renderID);
glRenderbufferStorage(GL_RENDERBUFFER, internalformat, m_width, m_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
GL_RENDERBUFFER, renderID);
m_colorTexId.push_back(textureId);
unsigned int num = m_colorTexId.size() - 1;
(*m_colorAttachmentPoints)[num] = attachment;
*m_renderID = renderID;
return int(num);
}
void FBO::attachTexture(GLenum internalformat, GLint filter)
bool FBO::createAttachDepthTexture(GLint filter)
{
GLenum attachment;
GLenum format;
GLenum type;
GLuint texID;
if (sm_anyFboBound)