From c5b2dd897b46919cae9896c0203e14806f27af23 Mon Sep 17 00:00:00 2001 From: Hugo Willaume Date: Mon, 15 Apr 2019 13:52:39 +0900 Subject: [PATCH] 1st part of FBO use is ok, verified through printing FBO to bitmap file --- BaseGLProject/BaseGLProject.vcxproj | 12 +- BaseGLProject/BaseGLProject.vcxproj.filters | 33 +++++ BaseGLProject/Multipass.cpp | 118 +++++++++++++++++ BaseGLProject/Multipass.h | 37 ++++++ BaseGLProject/MyGLWindow.cpp | 67 +++++++--- BaseGLProject/MyGLWindow.h | 6 +- BaseGLProject/SceneContext.h | 4 + BaseGLProject/TextureViewer.cpp | 135 ++++++++++++++++++++ BaseGLProject/TextureViewer.h | 57 +++++++++ BaseGLProject/fboManager.cpp | 118 +++++++++++++++++ BaseGLProject/fboManager.h | 49 +++++++ BaseGLProject/textureManager.cpp | 101 +++++++++++++++ BaseGLProject/textureManager.h | 41 ++++++ BaseGLProject/textureViewer.frag | 34 +++++ BaseGLProject/textureViewer.vert | 12 ++ 15 files changed, 807 insertions(+), 17 deletions(-) create mode 100644 BaseGLProject/Multipass.cpp create mode 100644 BaseGLProject/Multipass.h create mode 100644 BaseGLProject/TextureViewer.cpp create mode 100644 BaseGLProject/TextureViewer.h create mode 100644 BaseGLProject/fboManager.cpp create mode 100644 BaseGLProject/fboManager.h create mode 100644 BaseGLProject/textureManager.cpp create mode 100644 BaseGLProject/textureManager.h create mode 100644 BaseGLProject/textureViewer.frag create mode 100644 BaseGLProject/textureViewer.vert diff --git a/BaseGLProject/BaseGLProject.vcxproj b/BaseGLProject/BaseGLProject.vcxproj index 0b45579..e4f9ed4 100644 --- a/BaseGLProject/BaseGLProject.vcxproj +++ b/BaseGLProject/BaseGLProject.vcxproj @@ -95,7 +95,7 @@ true Console C:\Graphics\Tools\SOIL\lib;C:\Graphics\Tools\Assimp\lib\x86;C:\Graphics\Tools\glfw\lib\x86;C:\Graphics\Tools\glew\lib;%(AdditionalLibraryDirectories) - assimp.lib;SOIL.lib;glfw3.lib;glew32.lib;opengl32.lib;%(AdditionalDependencies) + assimp.lib;SOIL.lib;glfw3.lib;glew32.lib;opengl32.lib;FreeImage.lib;%(AdditionalDependencies) @@ -147,6 +147,7 @@ + @@ -155,15 +156,19 @@ + + + + @@ -177,11 +182,14 @@ + + + @@ -195,6 +203,8 @@ + + Geometry diff --git a/BaseGLProject/BaseGLProject.vcxproj.filters b/BaseGLProject/BaseGLProject.vcxproj.filters index a3dfe79..e3cd1e0 100644 --- a/BaseGLProject/BaseGLProject.vcxproj.filters +++ b/BaseGLProject/BaseGLProject.vcxproj.filters @@ -22,6 +22,9 @@ {af32f844-b061-4424-a685-e3f537232cf8} + + {b0c228ca-8e29-48df-a9f6-59fb58accad5} + @@ -69,6 +72,18 @@ Source Files + + MankyuCode + + + MankyuCode + + + MankyuCode + + + Source Files + @@ -131,6 +146,18 @@ Header Files + + MankyuCode + + + MankyuCode + + + MankyuCode + + + Header Files + @@ -190,6 +217,12 @@ Shaders + + MankyuCode + + + MankyuCode + diff --git a/BaseGLProject/Multipass.cpp b/BaseGLProject/Multipass.cpp new file mode 100644 index 0000000..efd2f76 --- /dev/null +++ b/BaseGLProject/Multipass.cpp @@ -0,0 +1,118 @@ +#include "Multipass.h" + +Multipass::Multipass() : _quad_shader("textureViewer.vert", "textureViewer.frag") +{ + _draw_buffers_size = 0; + glGenFramebuffers(1, &_fboId); + glBindFramebuffer(GL_FRAMEBUFFER, _fboId); + _createQuad(); +} + +void Multipass::setDrawBuffers() +{ + glDrawBuffers(_draw_buffers_size, _draw_buffers); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + throw std::runtime_error("Error during framebuffer initialisation"); +} + +void Multipass::bindToFrameBuffer(GLenum type, GLenum texture, std::string texName) +{ + glFramebufferTexture2D(GL_FRAMEBUFFER, type, texture, _pass_textures[texName], 0); + if (type != GL_DEPTH_ATTACHMENT) { + _draw_buffers[_draw_buffers_size] = type; + _draw_buffers_size++; + } +} + +Multipass::~Multipass() +{ + glDeleteFramebuffers(1, &_fboId); +} + +void Multipass::addTexture(const std::string & tex_name, GLuint filter, GLuint type, GLuint type_2, + bool depth, SceneContext &scnctx) +{ + glGenTextures(1, &_pass_textures[tex_name]);; + glBindTexture(GL_TEXTURE_2D, _pass_textures[tex_name]); + glTexImage2D(GL_TEXTURE_2D, 0, type, scnctx.width, scnctx.height, 0, type_2, GL_FLOAT, 0); + 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); + if (depth) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + } + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void Multipass::enableFrameBufferTexture(const std::string tex_name) +{ + _current_tex = tex_name; + glBindFramebuffer(GL_FRAMEBUFFER, _fboId); +} + +void Multipass::drawResultToScreen(SceneContext & scnctx) +{ + //EXAMPLE CODE + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glViewport(0, 0, scnctx.width, scnctx.height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + _quad_shader.enable(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _pass_textures[_current_tex]); + _quad_shader.addUniform("tex", (int)_pass_textures[_current_tex]); + glBindVertexArray(_quad_vao); + glBindBuffer(GL_ARRAY_BUFFER, _quad_vbo); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBindTexture(GL_TEXTURE_2D, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + _quad_shader.disable(); +} + +void Multipass::_createQuad() +{ + float pos[] = { + -1.0, 1.0, + 1.0, 1.0, + -1.0, -1.0, + 1.0, -1.0 + }; + + float uv[] = { + 0.0, 1.0, + 1.0, 1.0, + 0.0, 0.0, + 1.0, 0.0 + }; + + //Generate VAO + glGenVertexArrays(1, &_quad_vao); + //Bind VAO + glBindVertexArray(_quad_vao); + + //Generate VBO + glGenBuffers(1, &_quad_vbo); + //Bind VBO + glBindBuffer(GL_ARRAY_BUFFER, _quad_vbo); + //Alocate buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(pos) + sizeof(uv), NULL, GL_STATIC_DRAW); + //Fill VBO + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(pos), pos); + glBufferSubData(GL_ARRAY_BUFFER, 8 * sizeof(float), sizeof(uv), uv); + + //Fill attributes and uniforms + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, (sizeof(float) * 2), (void*)0); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, (sizeof(float) * 2), (GLvoid*)(sizeof(float) * 8)); + + //unbind buffer + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindVertexArray(0); +} diff --git a/BaseGLProject/Multipass.h b/BaseGLProject/Multipass.h new file mode 100644 index 0000000..e94cfda --- /dev/null +++ b/BaseGLProject/Multipass.h @@ -0,0 +1,37 @@ +#pragma once +#include +#include +#include +#include "Shader.h" +#include "SceneContext.h" + +class Multipass +{ +public: + Multipass(); + + ~Multipass(); + + void setDrawBuffers(); + void bindToFrameBuffer(GLenum type, GLenum texture, std::string texName); + + void addTexture(const std::string &tex_name, GLuint filter, GLuint type, GLuint type_2, + bool depth, SceneContext &scnctx); + + void enableFrameBufferTexture(const std::string tex_name); + void drawResultToScreen(SceneContext &scnctx); +private: + + void _createQuad(); + + GLuint _fboId; + + GLuint _quad_vao; + GLuint _quad_vbo; + Shader _quad_shader; + std::string _current_tex; + std::map _pass_textures; + + GLenum _draw_buffers[5]; + GLuint _draw_buffers_size; +}; \ No newline at end of file diff --git a/BaseGLProject/MyGLWindow.cpp b/BaseGLProject/MyGLWindow.cpp index a890747..cf0e2a8 100644 --- a/BaseGLProject/MyGLWindow.cpp +++ b/BaseGLProject/MyGLWindow.cpp @@ -1,5 +1,5 @@ -#include #include "MyGlWindow.h" +#include "..\..\..\..\Downloads\FreeImage3180Win32Win64\FreeImage\Dist\x32\FreeImage.h" //Getting the projection matrix glm::mat4x4 perspective(float fovy, float aspect, float near, float far) { @@ -41,6 +41,9 @@ MyGlWindow::MyGlWindow(int w, int h) : m_width = w; m_height = h; + _scnctx.height = m_height; + _scnctx.width = m_width; + setup(); } @@ -51,9 +54,7 @@ MyGlWindow::~MyGlWindow() void MyGlWindow::setBgColor(float bgColor[3]) { - _bgColor[0] = bgColor[0]; - _bgColor[1] = bgColor[1]; - _bgColor[2] = bgColor[2]; + _scnctx.bg = glm::vec4(bgColor[0], bgColor[1], bgColor[2], 1); } void MyGlWindow::textureSetup() @@ -110,7 +111,7 @@ void MyGlWindow::shaderSetup() shaders["Toon"]->uniformFlags &= ~ShaderFlags::SHINE_FLAG; shaders["Skybox"] = new Shader("skybox.vert", "skybox.frag"); - shaders["Skybox"]->uniformFlags = MVP_FLAG | MODEL_MATRIX_FLAG | SKYBOX_TEX_FLAG; + shaders["Skybox"]->uniformFlags = MVP_FLAG | MODEL_MATRIX_FLAG | SKYBOX_TEX_FLAG; shaders["Skybox"]->addUniform("RefractionIndex", glm::vec3(0.65, 0.67, 0.69)); } @@ -129,6 +130,18 @@ void MyGlWindow::lightSetup() //_scnctx.lights.emplace("Light5", Light(glm::vec3(0.5f, 0.5f, 0.5f), glm::vec4(3.09, 10, -9.51, 1))); } +void MyGlWindow::multipassSetup() +{ + _multipassManager.addTexture("render_tex", GL_NEAREST, GL_RGB, GL_RGB, false, _scnctx); + _multipassManager.bindToFrameBuffer(GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, "render_tex"); + + //_multipassManager.addTexture("depth_tex", GL_LINEAR, GL_DEPTH_COMPONENT24, + // GL_DEPTH_COMPONENT, true, _scnctx); + //_multipassManager.bindToFrameBuffer(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, "depth_tex"); + + _multipassManager.setDrawBuffers(); +} + void MyGlWindow::setup() { glEnable(GL_DEPTH_TEST); @@ -167,7 +180,7 @@ void MyGlWindow::setup() //meshes["Cube"]->assignTexture(_scnctx.textures["MossTex"]); //meshes["Cube"]->addTranslation(glm::vec4(4, 3, -4, 0)); - //meshes.emplace("Mountain", new Mesh("mountain/mount.blend1.obj", shaders["TexBaseLight"])); + meshes.emplace("Mountain", new Mesh("mountain/mount.blend1.obj", shaders["TexBaseLight"])); //meshes.emplace("Sponza", new Mesh("sponza/sponza.obj", shaders["TexBaseLight"])); //meshes["Sponza"]->addTranslation(glm::vec4(0, -200, 0, 1)); @@ -195,31 +208,55 @@ void MyGlWindow::setup() //meshes["Teapot"]->addTranslation(glm::vec4(5, 0, 3, 1)); //meshes["Teapot"]->cullMode = BACK; - meshes.emplace("Teapot", new Mesh("teapot.obj", shaders["Skybox"])); - + //meshes.emplace("Teapot", new Mesh("teapot.obj", shaders["Skybox"])); + + multipassSetup(); } void MyGlWindow::draw() { - glClearColor(_bgColor[0], _bgColor[1], _bgColor[2], 1); - glViewport(0, 0, m_width, m_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + _scnctx.height = m_height; + _scnctx.width = m_width; glm::vec3 eye(viewer.getViewPoint().x, viewer.getViewPoint().y, viewer.getViewPoint().z); glm::vec3 look(viewer.getViewCenter().x, viewer.getViewCenter().y, viewer.getViewCenter().z); glm::vec3 up(viewer.getUpVector().x, viewer.getUpVector().y, viewer.getUpVector().z); glm::mat4 view = lookAt(eye, look, up); //Calculate view matrix from parameters of m_viewer - glm::mat4 projection = perspective(45.0f, (float)m_width / (float)m_height, 0.1f, 2000.0f); - + glm::mat4 projection = perspective(45.0f, (float)_scnctx.width / (float)_scnctx.height, 0.1f, 2000.0f); + _scnctx.viewMatrix = view; _scnctx.projectionMatrix = projection; - shaders["Skybox"]->addUniform("WorldCamPos", eye); + _multipassManager.enableFrameBufferTexture("render_tex"); + glClearColor(_scnctx.bg.r, _scnctx.bg.g, _scnctx.bg.b, _scnctx.bg.a); + glViewport(0, 0, _scnctx.width, _scnctx.height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //shaders["Skybox"]->addUniform("WorldCamPos", eye); + for (auto it = meshes.begin(); it != meshes.end(); it++) (*it).second->draw(_scnctx); - skybox.draw(shaders["Skybox"], _scnctx); + + //_multipassManager.drawResultToScreen(_scnctx); + //skybox.draw(shaders["Skybox"], _scnctx); + + + BYTE* pixels = new BYTE[3 * _scnctx.width * _scnctx.height]; + + glReadPixels(0, 0, _scnctx.width, _scnctx.height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + // Convert to FreeImage format & save to file + FIBITMAP* image = FreeImage_ConvertFromRawBits(pixels, _scnctx.width, _scnctx.height, 3 * _scnctx.width, 24, 0x0000FF, 0xFF0000, 0x00FF00, false); + FreeImage_Save(FIF_BMP, image, "D:/Users/Hurlu/Desktop/bitmap.bmp", 0); + + // Free resources + FreeImage_Unload(image); + delete[] pixels; + exit(0); } + + void MyGlWindow::resize(int w, int h) { m_width = w; diff --git a/BaseGLProject/MyGLWindow.h b/BaseGLProject/MyGLWindow.h index 30865ff..25bdf3e 100644 --- a/BaseGLProject/MyGLWindow.h +++ b/BaseGLProject/MyGLWindow.h @@ -12,6 +12,7 @@ #include "SceneContext.h" #include "Models/Mesh.h" #include "imgui/stb_image.h" +#include "Multipass.h" struct vertexAttr { GLfloat posX, posY, posZ; @@ -39,12 +40,15 @@ private: float _bgColor[3]; + Multipass _multipassManager; + Skybox skybox; GLuint _vaoHandle; - GLuint _iboHandle; + GLuint _iboHandle; void textureSetup(); void shaderSetup(); void lightSetup(); + void multipassSetup(); void setup(); }; \ No newline at end of file diff --git a/BaseGLProject/SceneContext.h b/BaseGLProject/SceneContext.h index 1bbc23a..5a44b92 100644 --- a/BaseGLProject/SceneContext.h +++ b/BaseGLProject/SceneContext.h @@ -23,6 +23,10 @@ struct SceneContext std::map textures; + GLuint height; + GLuint width; + glm::vec4 bg; + void adjustSpots() { for (auto it : lights) diff --git a/BaseGLProject/TextureViewer.cpp b/BaseGLProject/TextureViewer.cpp new file mode 100644 index 0000000..eef0e5b --- /dev/null +++ b/BaseGLProject/TextureViewer.cpp @@ -0,0 +1,135 @@ +#include "TextureViewer.h" + + +TextureViewer::TextureViewer() +{ + this->s = new ShaderProgram(); + this->fs = "default.frag"; + this->vs = "default.vs"; + this->depth = false; + setUpShaders(); +} + + +TextureViewer::TextureViewer(GLuint tex, std::string vs, std::string fs) { + this->s = new ShaderProgram(); + this->texture = tex; + this->fs = fs; + this->vs = vs; + this->depth = false; + + + setUpShaders(); +} + + +TextureViewer::~TextureViewer() +{ + delete s; + glDeleteBuffers(1, &VBO); + glDeleteBuffers(1, &VAO); +} + +void TextureViewer::draw() { + //Bind VAO + glBindVertexArray(VAO); + //Bind VBO + glBindBuffer(GL_ARRAY_BUFFER, VBO); + + s->use(); + + glUniform1i(s->uniform("depth"), this->depth); + + //Bind texture + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, this->texture); + + //Draw + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + //Unbind texture for sure + glBindTexture(GL_TEXTURE_2D, 0); + + s->disable(); + + //Unbind VBO - just for sure + glBindBuffer(GL_ARRAY_BUFFER, 0); + //Unbind VAO + glBindVertexArray(0); + +} + +void TextureViewer::setDepthOnly(bool depth) { + this->depth = depth; +} + +//Called only once in constructor +void TextureViewer::setUpShaders() +{ + //We need only vertex and fragment shaders + s->initFromFiles(this->vs,this->fs); + + + + s->use(); + + //Create uniforms and attributes (filled later) + + s->addUniform("tex"); + s->addUniform("depth"); + + + //Quad verticles - omitted z coord, because it will always be 1 + float pos[] = { + -1.0, 1.0, + 1.0, 1.0, + -1.0, -1.0, + 1.0, -1.0 + }; + + float uv[] = { + 0.0, 1.0, + 1.0, 1.0, + 0.0, 0.0, + 1.0, 0.0 + }; + + //Generate VAO + glGenVertexArrays(1, &VAO); + //Bind VAO + glBindVertexArray(VAO); + + //Generate VBO + glGenBuffers(1, &VBO); + //Bind VBO + glBindBuffer(GL_ARRAY_BUFFER, VBO); + //Alocate buffer + glBufferData(GL_ARRAY_BUFFER, sizeof(pos)+sizeof(uv), NULL, GL_STATIC_DRAW); + //Fill VBO + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(pos), pos); + glBufferSubData(GL_ARRAY_BUFFER, 8 * sizeof(float), sizeof(uv), uv); + + //Fill attributes and uniforms + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, (sizeof(float)* 2), (void*)0); + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, (sizeof(float)* 2), (GLvoid*)(sizeof(float)* 8)); + + glUniform1i(s->uniform("tex"), 0); + + s->disable(); + //unbind buffer + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindVertexArray(0); +} + +//Setters +void TextureViewer::setTexture(GLuint tex) { + this->texture = tex; +} +//Getters +GLuint TextureViewer::getTexture() { + return this->texture; +} \ No newline at end of file diff --git a/BaseGLProject/TextureViewer.h b/BaseGLProject/TextureViewer.h new file mode 100644 index 0000000..5f7a3a1 --- /dev/null +++ b/BaseGLProject/TextureViewer.h @@ -0,0 +1,57 @@ + + +#define GLM_ENABLE_EXPERIMENTAL + +#ifndef CTEXTUREVIEWER_H +#define CTEXTUREVIEWER_H +#include +#include +#include + + +#include + +#include +#include +#include +#include + + +#include "Loader.h" + + +/* +* Simple class, which will render texture on screen +*/ +class TextureViewer +{ +private: + + GLuint texture; + //VBO - don't need EBO, i'll use glDrawArrays() + GLuint VBO; + //VAO - needed for glDrawArrays() + GLuint VAO; + ShaderProgram * s; + //Default shaders + std::string vs; + std::string fs; + bool depth; + void setUpShaders(); + + +public: + + TextureViewer(); + TextureViewer(GLuint tex, std::string vs, std::string fs); + void draw(); + //Setters + void setTexture(GLuint tex); + void setDepthOnly(bool depth); + //Getters + GLuint getTexture(); + ~TextureViewer(); +}; + +#endif + diff --git a/BaseGLProject/fboManager.cpp b/BaseGLProject/fboManager.cpp new file mode 100644 index 0000000..77e7851 --- /dev/null +++ b/BaseGLProject/fboManager.cpp @@ -0,0 +1,118 @@ +#include "fboManager.h" + + + +#include + + + +FboManager::FboManager() { + useRenderDepthBuffer = false; + attachmentCount = 0; + /*for(int i=0;i<5;i++) { + mrt[i] = GL_COLOR_ATTACHMENT0+i; + }*/ +} + +FboManager::~FboManager() { + glDeleteFramebuffers(1, &_fboId); + if(useRenderDepthBuffer) { + glDeleteRenderbuffers(1, &_renderDepthBufferId); + } +} + + +//create FBO +void FboManager::initFbo() { + glGenFramebuffers(1, &_fboId); +} + +//generate and bind depth buffer +void FboManager::genRenderDepthBuffer(unsigned w, unsigned h) { + glGenRenderbuffers(1,&_renderDepthBufferId); + glBindRenderbuffer(GL_RENDERBUFFER, _renderDepthBufferId); + glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,w,h); + glBindRenderbuffer(GL_RENDERBUFFER, 0); +} + +//bind depth buffer +void FboManager::bindRenderDepthBuffer() { + glBindFramebuffer(GL_FRAMEBUFFER,_fboId); + glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,_renderDepthBufferId); + //glBindFramebuffer(GL_FRAMEBUFFER,0); +} + +void FboManager::setDrawBuffers() { + glDrawBuffers(attachmentCount, mrt); +} + +void FboManager::bindToFbo(GLenum type, GLenum texture, GLuint textureId) { + glBindFramebuffer(GL_FRAMEBUFFER,_fboId); + glFramebufferTexture2D(GL_FRAMEBUFFER,type,texture,textureId,0); + if(type != GL_DEPTH_ATTACHMENT) { + mrt[attachmentCount] = type; + attachmentCount += 1; + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } + //glBindFramebuffer(GL_FRAMEBUFFER,0); +} + +void FboManager::bind3DTextureToFbo(GLenum type, GLuint textureId) { + glBindFramebuffer(GL_FRAMEBUFFER, _fboId); + glFramebufferTexture(GL_FRAMEBUFFER, type, textureId, 0); + //glFramebufferTexture3D(GL_FRAMEBUFFER, type, GL_TEXTURE_3D, textureId, 0, 0); + if (type != GL_DEPTH_ATTACHMENT) { + mrt[attachmentCount] = type; + attachmentCount += 1; + glDrawBuffer(GL_NONE); + glReadBuffer(GL_NONE); + } +} + +GLuint FboManager::getFboId() { + return _fboId; +} + +bool FboManager::checkFboStatus() { + // check FBO status + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE_EXT: + std::cout << "Framebuffer complete." << std::endl; + return true; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + std::cout << "[ERROR] Framebuffer incomplete: Attachment is NOT complete." << std::endl; + return false; + + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + std::cout << "[ERROR] Framebuffer incomplete: No image is attached to FBO." << std::endl; + return false; + + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + std::cout << "[ERROR] Framebuffer incomplete: Attached images have different dimensions." << std::endl; + return false; + + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + std::cout << "[ERROR] Framebuffer incomplete: Color attached images have different internal formats." << std::endl; + return false; + + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + std::cout << "[ERROR] Framebuffer incomplete: Draw buffer." << std::endl; + return false; + + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + std::cout << "[ERROR] Framebuffer incomplete: Read buffer." << std::endl; + return false; + + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + std::cout << "[ERROR] Unsupported by FBO implementation." << std::endl; + return false; + + default: + std::cout << "[ERROR] Unknow error." << std::endl; + return false; + } +} \ No newline at end of file diff --git a/BaseGLProject/fboManager.h b/BaseGLProject/fboManager.h new file mode 100644 index 0000000..df664ed --- /dev/null +++ b/BaseGLProject/fboManager.h @@ -0,0 +1,49 @@ +/* +* File: fboManager.h +* Desc: Jednoduchy "manager" pro FBO objekty +* +*/ + + +#define GLM_ENABLE_EXPERIMENTAL + + +#ifndef FBOMANAGER_H +#define FBOMANAGER_H + + +#include + +#include +#include +#include +#include + +class FboManager { +public: + FboManager(); + ~FboManager(); + //check fbo status + bool checkFboStatus(); + + //create a renderbuffer object + void genRenderDepthBuffer(unsigned w, unsigned h); + + //bind a renderbuffer object + void bindRenderDepthBuffer(); + + void bindToFbo(GLenum type, GLenum texture, GLuint textureId); + + void bind3DTextureToFbo(GLenum type, GLuint textureId); + void initFbo(); + void setDrawBuffers(); + GLuint getFboId(); +private: + GLuint _fboId; + GLuint _renderDepthBufferId; + bool useRenderDepthBuffer; + unsigned attachmentCount; + GLenum mrt[6]; +}; + +#endif \ No newline at end of file diff --git a/BaseGLProject/textureManager.cpp b/BaseGLProject/textureManager.cpp new file mode 100644 index 0000000..8b0af1d --- /dev/null +++ b/BaseGLProject/textureManager.cpp @@ -0,0 +1,101 @@ + + +#include "textureManager.h" + + +#define MAX_GRID_SIZE 32 + + +TextureManager::TextureManager() : clearTextureExtension(true) { +} + +TextureManager::~TextureManager() { + textures.clear(); +} + +void TextureManager::add(const string& texture) { + GLuint tmpId; + glGenTextures(1, &tmpId); + textures[texture] = tmpId; +} + +void TextureManager::createTexture(const string& texture, const string filePath,unsigned w, unsigned h, GLuint filter, GLuint type, GLuint type_2, bool depth = false) +{ +// SDL_Surface *surface; + GLuint textureid; + int mode; + add(texture); + glBindTexture(GL_TEXTURE_2D, textures[texture]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + //No image data - for frameBuffer + if(filePath.empty()) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexImage2D(GL_TEXTURE_2D, 0 ,type, w, h, 0, type_2, GL_FLOAT, 0); + glTexImage2D(GL_TEXTURE_2D, 0 ,type, w, h, 0, type_2, GL_FLOAT, 0); + if (depth) { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + //glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + } + } +} + +void TextureManager::createRGBA16F3DTexture(const string& texture, glm::vec3 dim, GLuint filter, GLuint wrap) { + GLuint tex; + add(texture); + glBindTexture(GL_TEXTURE_3D, textures[texture]); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, wrap); + //glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, w, h, d, 0, GL_RGBA, GL_FLOAT, NULL); + //glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, w, h, d, 0, GL_RGBA, GL_FLOAT, &emptyData[0]); + std::vector emptyData(dim.x * dim.y * dim.z * sizeof(float), 0.0); + glBindTexture(GL_TEXTURE_3D, textures[texture]); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, dim.x, dim.y, dim.z, 0, GL_RGBA, GL_FLOAT, &emptyData[0]); + glBindTexture(GL_TEXTURE_3D, 0); + //clear3Dtexture(textures[texture], dim); + //glBindTexture(GL_TEXTURE_3D, 0); +} + +void TextureManager::clear3Dtexture(GLuint texture) { + if (clearTextureExtension) { + GLfloat data[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + glClearTexImage(texture, 0, GL_RGBA, GL_FLOAT, &data[0]); + } + else { + //MUCH SLOWER version, but should work on version lower than 4.4 + std::vector emptyData(MAX_GRID_SIZE * MAX_GRID_SIZE * MAX_GRID_SIZE * sizeof(float), 0.0); + glBindTexture(GL_TEXTURE_3D, texture); + //glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, MAX_GRID_SIZE, MAX_GRID_SIZE, MAX_GRID_SIZE, 0, GL_RGBA, GL_FLOAT, &emptyData[0]); + //or + glTexSubImage3D(GL_TEXTURE_3D, 0, 0,0,0, MAX_GRID_SIZE, MAX_GRID_SIZE, MAX_GRID_SIZE, GL_RGBA, GL_FLOAT, &emptyData[0]); + glBindTexture(GL_TEXTURE_3D, 0); + } +} + +void TextureManager::createRGBA3DTexture(const string& texture, glm::vec3 dim, GLuint filter, GLuint wrap) { + GLuint tex; + add(texture); + glBindTexture(GL_TEXTURE_3D, textures[texture]); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, wrap); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, dim.x, dim.y, dim.z, 0, GL_RGBA, GL_FLOAT, NULL); + //glBindTexture(GL_TEXTURE_3D, 0); +} + +GLuint TextureManager::operator[] (const string& texture) { + return textures[texture]; +} \ No newline at end of file diff --git a/BaseGLProject/textureManager.h b/BaseGLProject/textureManager.h new file mode 100644 index 0000000..a22f81b --- /dev/null +++ b/BaseGLProject/textureManager.h @@ -0,0 +1,41 @@ +#define GLM_ENABLE_EXPERIMENTAL + + +#ifndef TEXTUREMANAGER_H +#define TEXTUREMANAGER_H + + +#include +#include +#include + + +#include +#include +#include +#include +#include + + +using namespace std; + +class TextureManager { +public: + TextureManager(); + ~TextureManager(); + GLuint operator[](const string& texture); + void add(const string& texture); + void createTexture(const string& texture, const string filePath, unsigned w, unsigned h, + GLuint filter, GLuint type, GLuint type_2, bool depth); + void createRGBA16F3DTexture(const string& texture, glm::vec3 dim, GLuint filter, GLuint wrap); + void createRGBA3DTexture(const string& texture, glm::vec3 dim, GLuint filter, GLuint wrap); + void clear3Dtexture(GLuint texture); + void setClearTextureExtension(bool v) { + clearTextureExtension = v; + } +private: + map textures; + bool clearTextureExtension; +}; + +#endif \ No newline at end of file diff --git a/BaseGLProject/textureViewer.frag b/BaseGLProject/textureViewer.frag new file mode 100644 index 0000000..dcbfa88 --- /dev/null +++ b/BaseGLProject/textureViewer.frag @@ -0,0 +1,34 @@ +#version 430 + +in vec2 uv; + +out vec4 final_color; + +uniform sampler2D tex; +uniform bool depth; + + +float LinearizeDepth(in vec2 uv) +{ + float zNear = .1; // zNear of your perspective projection + float zFar = 2000.0; // zFar of your perspective projection + float depth = texture(tex, uv).x; + return (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear)); +} + + + + +void main() +{ + //rrra because depth textures are not usual textures, they have only one channel + final_color = (depth) ? texture(tex, uv).rrra : texture(tex, uv).rgba; + + if (depth) { + float d; + d = LinearizeDepth(uv); + final_color = vec4(d,d,d,1.0); + } + final_color = texture(tex, uv).rgba; + //final_color = vec4(1.0,0.0,0.0,1.0); +} \ No newline at end of file diff --git a/BaseGLProject/textureViewer.vert b/BaseGLProject/textureViewer.vert new file mode 100644 index 0000000..ae3216e --- /dev/null +++ b/BaseGLProject/textureViewer.vert @@ -0,0 +1,12 @@ +#version 430 + +layout(location = 0) in vec2 vPosition; +layout(location = 1) in vec2 vUV; + +out vec2 uv; + +void main() +{ + gl_Position = vec4(vPosition,0.0,1.0); + uv = vUV; +} \ No newline at end of file