From 354d7df4d2779ed7391701d1ef4344e959b64582 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Wed, 27 Dec 2017 19:21:12 +0000 Subject: [Broken] Texture is black. --- yage/render/batch.h | 3 - yage/render/glslprogram.cpp | 215 -------------------------------------------- yage/render/glslprogram.h | 58 ------------ yage/render/rectangle.cpp | 37 ++++++++ yage/render/rectangle.h | 12 ++- yage/render/shader.cpp | 132 +++++++++++++++++++++++++++ yage/render/shader.h | 49 ++++++++++ yage/render/shape.h | 1 + yage/render/sprite.cpp | 6 +- yage/render/sprite.h | 2 +- yage/render/spritebatch.cpp | 32 +++---- yage/render/spritebatch.h | 5 +- 12 files changed, 249 insertions(+), 303 deletions(-) delete mode 100644 yage/render/glslprogram.cpp delete mode 100644 yage/render/glslprogram.h create mode 100644 yage/render/rectangle.cpp create mode 100644 yage/render/shader.cpp create mode 100644 yage/render/shader.h (limited to 'yage/render') diff --git a/yage/render/batch.h b/yage/render/batch.h index e301531c..57f997c1 100644 --- a/yage/render/batch.h +++ b/yage/render/batch.h @@ -28,10 +28,7 @@ public: virtual bool init(); virtual void begin(); virtual void end(); - virtual void draw(); virtual void render(); - -protected: }; } // namespace yage diff --git a/yage/render/glslprogram.cpp b/yage/render/glslprogram.cpp deleted file mode 100644 index 13abbba3..00000000 --- a/yage/render/glslprogram.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: glslprogram.cpp - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -#include "glslprogram.h" - -#include -#include -#include - -namespace yage -{ - -GlslProgram::~GlslProgram() -{ - /// cleans up all the shaders and the program - if (fragment_shader_id_ != 0) { - glDeleteShader(fragment_shader_id_); - } - - if (vertex_shader_id_ != 0) { - glDeleteShader(vertex_shader_id_); - } - - if (program_id_ != 0) { - glDeleteProgram(program_id_); - } -} - -void GlslProgram::compileShader(GLuint shader, const std::string &shaderContent) -{ - // cast source to a c string to get the address of it and input it for - // compilation - const auto *vertex_source = (const GLchar *)shaderContent.c_str(); - glShaderSource(shader, 1, &vertex_source, nullptr); - glCompileShader(shader); - - // check if compilation was successful - GLint is_compiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, (int *)&is_compiled); - - // if it isn't compiled throw exception to clean up - if (is_compiled == GL_FALSE) { - GLint max_length = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &max_length); - - std::vector error_log(max_length); - glGetShaderInfoLog(shader, max_length, &max_length, &error_log[0]); - std::string error_log_str((const char *)&error_log[0]); - - std::string shaderName; - if (shader == vertex_shader_id_) - shaderName = "vertex shader"; - else - shaderName = "fragment shader"; - - throw std::runtime_error("Couldn't compile the " + shaderName + " : " + - error_log_str); - } -} - -void GlslProgram::compileShaderFromFile(GLuint shader, - const std::string &file_path) -{ - // get a string with the input from the shader file - std::ifstream file(file_path); - if (!file.is_open()) { - throw std::runtime_error("Failed to open '" + file_path + "'"); - } - - std::string content = ""; - std::string line; - - while (std::getline(file, line)) { - content += line + "\n"; - } - file.close(); - - compileShader(shader, content); -} - -void GlslProgram::initShaderId() -{ - // create the program that will be run on GPU - program_id_ = glCreateProgram(); - - // create vertex shader - vertex_shader_id_ = glCreateShader(GL_VERTEX_SHADER); - if (vertex_shader_id_ == 0) { - throw std::runtime_error("Vertex shader failed to be created"); - } - - // create fragment shader - fragment_shader_id_ = glCreateShader(GL_FRAGMENT_SHADER); - if (fragment_shader_id_ == 0) { - throw std::runtime_error("Fragment shader failed to be created"); - } -} - -void GlslProgram::compileShaders(const std::string &vertexShader, - const std::string fragmentShader) -{ - initShaderId(); - - compileShader(vertex_shader_id_, vertexShader); - compileShader(fragment_shader_id_, fragmentShader); -} - -void GlslProgram::compileShadersFromFile( - const std::string &vertex_shader_path, - const std::string &fragment_shader_path) -{ - initShaderId(); - - // compile the two shaders - compileShaderFromFile(vertex_shader_id_, vertex_shader_path); - compileShaderFromFile(fragment_shader_id_, fragment_shader_path); -} - -void GlslProgram::linkShaders() -{ - // attach the shaders that we want - glAttachShader(program_id_, vertex_shader_id_); - glAttachShader(program_id_, fragment_shader_id_); - - // link our program - glLinkProgram(program_id_); - - GLint is_linked = 0; - glGetProgramiv(program_id_, GL_LINK_STATUS, (int *)&is_linked); - if (is_linked == GL_FALSE) { - GLint max_length = 0; - glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &max_length); - - std::vector error_log(max_length); - glGetProgramInfoLog(program_id_, max_length, &max_length, - &error_log[0]); - - std::string error_log_str((const char *)&error_log[0]); - - throw std::runtime_error("Could not link program: " + error_log_str); - } - - // detach shaders after successful link - glDetachShader(program_id_, fragment_shader_id_); - glDetachShader(program_id_, vertex_shader_id_); - - // we can then delete the shaders once we have the program - glDeleteShader(fragment_shader_id_); - glDeleteShader(vertex_shader_id_); -} - -void GlslProgram::addAttribute(const std::string &attribute_name) -{ - glBindAttribLocation(program_id_, attribute_index_++, - attribute_name.c_str()); -} - -GLint GlslProgram::getUniformLocation(const std::string &uniform_name) -{ - GLint location = glGetUniformLocation(program_id_, uniform_name.c_str()); - if ((GLuint)location == GL_INVALID_INDEX) { - throw std::runtime_error("'" + uniform_name + "' not found"); - } - return location; -} - -void GlslProgram::use() -{ - glUseProgram(program_id_); - for (int i = 0; i < attribute_index_; ++i) { - glEnableVertexAttribArray(i); - } -} - -void GlslProgram::unuse() -{ - for (int i = 0; i < attribute_index_; ++i) { - glDisableVertexAttribArray(i); - } - glUseProgram(0); -} - -void GlslProgram::defaultSetup() -{ - std::string vertexShader = - "#version 130\n\nin vec2 vertex_position;\nin vec4 vertex_colour;\nin " - "vec2 vertex_uv;\n\nout vec2 fragment_position;\nout vec4 " - "fragment_colour;\nout vec2 fragment_uv;\n\nuniform mat4 P;\n\nvoid " - "main()\n{\n gl_Position.xy = (P*vec4(vertex_position, 0.0, " - "1.0)).xy;\n gl_Position.z = 0.0;\n gl_Position.w = 1.0;\n\n " - "fragment_position = vertex_position;\n fragment_colour = " - "vertex_colour;\n fragment_uv = vec2(vertex_uv.x, " - "1-vertex_uv.y);\n\n}"; - - std::string fragmentShader = - "#version 130\n\nin vec2 fragment_position;\nin vec4 " - "fragment_colour;\nin vec2 fragment_uv;\n\nout vec4 colour;\n\nuniform " - "sampler2D texture_sampler;\n\nvoid main()\n{\n vec4 texture_color " - "= texture(texture_sampler, fragment_uv);\n\n colour = " - "texture_color;\n}"; - - compileShaders(vertexShader, fragmentShader); - addAttribute("vertex_position"); - addAttribute("vertex_colour"); - addAttribute("vertex_uv"); - - linkShaders(); -} - -} // namespace yage diff --git a/yage/render/glslprogram.h b/yage/render/glslprogram.h deleted file mode 100644 index 0617bc1e..00000000 --- a/yage/render/glslprogram.h +++ /dev/null @@ -1,58 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: glslprogram.h - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -#ifndef GLSL_PROGRAM_H -#define GLSL_PROGRAM_H - -#include - -#include - -namespace yage -{ - -class GlslProgram -{ -public: - GlslProgram() = default; - GlslProgram(const GlslProgram &) = delete; - GlslProgram(GlslProgram &&) = delete; - ~GlslProgram(); - - GlslProgram &operator=(const GlslProgram &) = delete; - GlslProgram &operator=(GlslProgram &&) = delete; - - /// compiles vertex and fragment shader - void compileShaders(const std::string &vertexShader, - const std::string fragmentShader); - void compileShadersFromFile(const std::string &vertex_shader_path, - const std::string &fragment_shader_path); - void linkShaders(); - void addAttribute(const std::string &attribute_name); - GLint getUniformLocation(const std::string &uniform_name); - void use(); - void unuse(); - - void defaultSetup(); - -private: - /// compiled shader program id - GLuint program_id_ = 0; - GLuint vertex_shader_id_ = 0; - GLuint fragment_shader_id_ = 0; - int attribute_index_ = 0; - - /// compiles one shader - void compileShader(GLuint shader, const std::string &shaderContent); - void compileShaderFromFile(GLuint shader, const std::string &file_path); - void initShaderId(); -}; - -} // namespace yage - -#endif diff --git a/yage/render/rectangle.cpp b/yage/render/rectangle.cpp new file mode 100644 index 00000000..365d058d --- /dev/null +++ b/yage/render/rectangle.cpp @@ -0,0 +1,37 @@ +#include "rectangle.h" + +#include "../data/vertex.h" + +#include + +#include + +namespace yage +{ + +Rectangle::Rectangle(glm::vec4 position) : position_(position) {} + +void Rectangle::render() const +{ + // create vertex array + GLuint rect_vao, rect_vbo; + + // bind vertex array object + glGenVertexArrays(1, &rect_vao); + glBindVertexArray(rect_vao); + + // bind vertex buffer object + glGenBuffers(1, &rect_vbo); + glBindBuffer(GL_ARRAY_BUFFER, rect_vbo); + + // enable vertex attribute arrays + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + + // set the vertex attribute pointers + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, position)); + + glBindVertexArray(0); +} + +} // namepsace yage diff --git a/yage/render/rectangle.h b/yage/render/rectangle.h index 11df8a18..ad38caa5 100644 --- a/yage/render/rectangle.h +++ b/yage/render/rectangle.h @@ -3,11 +3,19 @@ #include "shape.h" -namespace yage { +#include -class Rectangle +namespace yage { + +class Rectangle : public Shape +{ +public: + Rectangle(glm::vec4 position); virtual void render() const; + +private: + glm::vec4 position_; }; } // namespace yage diff --git a/yage/render/shader.cpp b/yage/render/shader.cpp new file mode 100644 index 00000000..be2e77e2 --- /dev/null +++ b/yage/render/shader.cpp @@ -0,0 +1,132 @@ +/** --------------------------------------------------------------------------- + * @file: shader.cpp + * + * Copyright (c) 2017 Yann Herklotz Grave + * MIT License, see LICENSE file for more details. + * ---------------------------------------------------------------------------- + */ + +#include "shader.h" + +#include +#include +#include +#include +#include + +using std::runtime_error; + +namespace yage +{ + +Shader::Shader(const std::string &vertex_path, const std::string &fragment_path) +{ + std::string vertex_source, fragment_source; + std::ifstream vertex_file, fragment_file; + + vertex_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + fragment_file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + try { + vertex_file.open(vertex_path); + fragment_file.open(fragment_path); + + std::ostringstream vertex_stream, fragment_stream; + vertex_stream << vertex_file.rdbuf(); + fragment_stream << fragment_file.rdbuf(); + + vertex_file.close(); + fragment_file.close(); + + vertex_source = vertex_stream.str(); + fragment_source = fragment_stream.str(); + } catch (std::ifstream::failure e) { + throw runtime_error("File could not be opened: " + + std::string(e.what())); + } + + const char *vertex_source_c = vertex_source.c_str(); + const char *fragment_source_c = fragment_source.c_str(); + + GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_source_c, NULL); + glCompileShader(vertex_shader); + errorCheck(vertex_shader, "vertex"); + + GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_source_c, NULL); + glCompileShader(fragment_shader); + errorCheck(fragment_shader, "fragment"); + + program_id_ = glCreateProgram(); + glAttachShader(program_id_, vertex_shader); + glAttachShader(program_id_, fragment_shader); + glLinkProgram(program_id_); + errorCheck(program_id_, "program"); + + glDetachShader(program_id_, vertex_shader); + glDetachShader(program_id_, fragment_shader); + + glDeleteShader(vertex_shader); + glDeleteShader(fragment_shader); +} + +Shader::~Shader() +{ + /// cleans up all the shaders and the program + if (program_id_ != 0) { + glDeleteProgram(program_id_); + } +} + +void Shader::use() const +{ + glUseProgram(program_id_); +} + +void Shader::setUniform(const std::string &name, int value) const +{ + glUniform1i(getUniformLocation(name), static_cast(value)); +} + +void Shader::setUniform(const std::string &name, float value) const +{ + glUniform1f(getUniformLocation(name), static_cast(value)); +} + +void Shader::setUniform(const std::string &name, const glm::mat4 &matrix) const +{ + glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &(matrix[0][0])); +} + +GLint Shader::getUniformLocation(const std::string &uniform_name) const +{ + GLint location = glGetUniformLocation(program_id_, uniform_name.c_str()); + if (location == GL_INVALID_INDEX) { + throw std::runtime_error("'" + uniform_name + "' not found"); + } + return location; +} + +void Shader::errorCheck(GLuint shader, const std::string &shader_type) const +{ + int success; + char info_log[1024]; + if (shader_type != std::string("program")) { + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) { + glGetShaderInfoLog(shader, 1024, NULL, info_log); + throw runtime_error(shader_type + + " failed to compile: " + std::string(info_log)); + } + } else { + glGetProgramiv(shader, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shader, 1024, NULL, info_log); + throw runtime_error(shader_type + + " failed to link: " + std::string(info_log)); + } + } +} + +} // namespace yage diff --git a/yage/render/shader.h b/yage/render/shader.h new file mode 100644 index 00000000..7f4d2f9d --- /dev/null +++ b/yage/render/shader.h @@ -0,0 +1,49 @@ +/** --------------------------------------------------------------------------- + * @file: shader.h + * + * Copyright (c) 2017 Yann Herklotz Grave + * MIT License, see LICENSE file for more details. + * ---------------------------------------------------------------------------- + */ + +#ifndef YAGE_RENDER_SHADER_H +#define YAGE_RENDER_SHADER_H + +#include +#include + +#include + +namespace yage +{ + +class Shader +{ +public: + Shader(const std::string &vertex_path, const std::string &fragment_path); + Shader(const Shader &) = delete; + Shader(Shader &&) = delete; + ~Shader(); + + Shader &operator=(const Shader &) = delete; + Shader &operator=(Shader &&) = delete; + + /// compiles vertex and fragment shader + void use() const; + + /// set uniforms of different type + void setUniform(const std::string &name, int value) const; + void setUniform(const std::string &name, float value) const; + void setUniform(const std::string &name, const glm::mat4 &matrix) const; + +private: + /// compiled shader program id + GLuint program_id_ = 0; + + GLint getUniformLocation(const std::string &uniform_name) const; + void errorCheck(GLuint shader, const std::string &shader_type) const; +}; + +} // namespace yage + +#endif diff --git a/yage/render/shape.h b/yage/render/shape.h index bdf318ed..1fdf1c4f 100644 --- a/yage/render/shape.h +++ b/yage/render/shape.h @@ -8,6 +8,7 @@ namespace yage class Shape : public Drawable { +public: virtual void render() const; }; diff --git a/yage/render/sprite.cpp b/yage/render/sprite.cpp index 6862f910..98853c94 100644 --- a/yage/render/sprite.cpp +++ b/yage/render/sprite.cpp @@ -6,9 +6,9 @@ * ---------------------------------------------------------------------------- */ -#include -#include -#include +#include "sprite.h" +#include "../core/resourcemanager.h" +#include "../data/vertex.h" #include diff --git a/yage/render/sprite.h b/yage/render/sprite.h index 852f4f28..51821be5 100644 --- a/yage/render/sprite.h +++ b/yage/render/sprite.h @@ -9,7 +9,7 @@ #ifndef SPRITE_H #define SPRITE_H -#include "texture.h" +#include "../data/texture.h" #include diff --git a/yage/render/spritebatch.cpp b/yage/render/spritebatch.cpp index d65340d7..fb6c3d78 100644 --- a/yage/render/spritebatch.cpp +++ b/yage/render/spritebatch.cpp @@ -25,11 +25,6 @@ Glyph::Glyph(GLuint texture, float depth, const Vertex &top_left, { } -RenderBatch::RenderBatch(GLint offset, GLsizei num_vertices, GLuint texture) - : num_vertices_(num_vertices), offset_(offset), texture_(texture) -{ -} - SpriteBatch::SpriteBatch() { createVertexArray(); @@ -42,7 +37,7 @@ SpriteBatch::~SpriteBatch() } if (vbo_ != 0) { - glDeleteVertexArrays(1, &vbo_); + glDeleteBuffers(1, &vbo_); } } @@ -59,8 +54,8 @@ void SpriteBatch::end() createRenderBatches(); } -void SpriteBatch::draw(const yage::Vector4f &destination_rect, - const yage::Vector4f &uv_rect, GLuint texture, +void SpriteBatch::draw(const glm::vec4 &destination_rect, + const glm::vec4 &uv_rect, GLuint texture, const Colour &colour, float depth) { Vertex top_left, top_right, bottom_right, bottom_left; @@ -93,15 +88,15 @@ void SpriteBatch::draw(const yage::Vector4f &destination_rect, void SpriteBatch::render() { // sort and create render batches + glBindVertexArray(vao_); sortGlyphs(); createRenderBatches(); - glBindVertexArray(vao_); for (auto &&batch : render_batches_) { - glBindTexture(GL_TEXTURE_2D, batch.texture()); - glDrawArrays(GL_TRIANGLES, batch.offset(), batch.num_vertices()); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, batch.texture); + glDrawArrays(GL_TRIANGLES, batch.offset, batch.num_vertices); } - glBindVertexArray(0); // clear and reset the vectors glyphs_.clear(); @@ -129,11 +124,6 @@ void SpriteBatch::createVertexArray() // bind vertex buffer object glBindBuffer(GL_ARRAY_BUFFER, vbo_); - // enable vertex attribute arrays - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - // set the vertex attribute pointers glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, position)); @@ -141,7 +131,11 @@ void SpriteBatch::createVertexArray() (void *)offsetof(Vertex, colour)); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, uv)); - glDrawArrays(GL_TRIANGLES, 0, 6); + + // enable vertex attribute arrays + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); // unbind vertex array object glBindVertexArray(0); @@ -162,7 +156,7 @@ void SpriteBatch::createRenderBatches() render_batches_.emplace_back(i * NUM_VERTICES, NUM_VERTICES, glyph_ptrs_[i]->texture()); } else { - render_batches_.back().num_vertices_ += NUM_VERTICES; + render_batches_.back().num_vertices += NUM_VERTICES; } vertices.push_back(glyph_ptrs_[i]->bottom_left()); diff --git a/yage/render/spritebatch.h b/yage/render/spritebatch.h index c018bdc6..e82268b8 100644 --- a/yage/render/spritebatch.h +++ b/yage/render/spritebatch.h @@ -10,7 +10,8 @@ #define YAGE_SPRITE_BATCH_H #include "batch.h" -#include "vertex.h" +#include "../data/vertex.h" +#include "../data/renderbatch.h" #include #include @@ -48,7 +49,7 @@ public: }; -class SpriteBatch : public Batch +class SpriteBatch { public: static const int NUM_VERTICES = 6; -- cgit