Fix the 2d triangle, create square, create VAO, and VBO objects.

This commit is contained in:
SeanOMik 2021-11-25 16:15:24 -05:00
parent 741b0c5b07
commit 862833fc71
10 changed files with 286 additions and 39 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ cmake-build-cmake-build-w10-msvc-debug/*
cmake-build-debug-wsl/*
build/*
.cache/*
c/*
# Compiled source #
###################

View File

@ -25,6 +25,8 @@ target_link_libraries(simpleengine PUBLIC glfw)
target_link_libraries(simpleengine PUBLIC glm::glm)
target_link_libraries(simpleengine PUBLIC soil2)
include_directories(${GLM_INCLUDE_DIRS})
# Add examples as a target if the user has them enabled
if (SIMPLE_ENGINE_BUILD_EXAMPLES)
add_subdirectory(examples)

View File

@ -3,19 +3,21 @@
// Github: https://github.com/SeanOMik
//
#include "simpleengine/shapes/2d/square.h"
#include <simpleengine/shader.h>
#include <simpleengine/renderable.h>
#include <simpleengine/event/event.h>
#include <simpleengine/shader_program.h>
#include <simpleengine/game.h>
#include <simpleengine/shapes/2d/triangle.h>
#include <simpleengine/vertex.h>
#include <chrono>
#include <iostream>
#include <sstream>
#include <stdint.h>
#include <cmrc/cmrc.hpp>
#include <stdint.h>
CMRC_DECLARE(resource_shaders);
std::string read_resource_shader(const std::string& path) {
@ -26,7 +28,7 @@ std::string read_resource_shader(const std::string& path) {
}
int main(int argc, char *argv[]) {
simpleengine::Game game(1280, 720, "SimpleEngine 3D OpenGL - Developer Testing", false);
simpleengine::Game game(640, 480, "SimpleEngine 3D OpenGL - Developer Testing", GLFW_OPENGL_CORE_PROFILE, 4, 4, false);
// Load shaders
std::string vertex_core = read_resource_shader("shaders/vertex_core.glsl");
@ -34,14 +36,47 @@ int main(int argc, char *argv[]) {
// Create shader program
simpleengine::ShaderProgram shader_prog;
shader_prog.add_shader_from_source(simpleengine::ShaderType::Vertex, vertex_core);
shader_prog.add_shader_from_source(simpleengine::ShaderType::Fragment, fragment_core);
shader_prog.add_shader_from_source(simpleengine::ShaderType::ST_Vertex, vertex_core);
shader_prog.add_shader_from_source(simpleengine::ShaderType::ST_Fragment, fragment_core);
shader_prog.link();
std::shared_ptr<GLuint> base_shader_program = shader_prog.program;
// Create just a simple 2d triangle
std::shared_ptr<simpleengine::Event> tri(new simpleengine::shapes_2d::Triangle(base_shader_program));
game.add_event(tri);
/* std::vector<glm::vec3> vertices = {
glm::vec3(-0.5f, -0.5f, 0.f),
glm::vec3(0.5f, -0.5f, 0.f),
glm::vec3(0.f, 0.5f, 0.f),
}; */
/* std::vector<glm::vec3> vertices = {
glm::vec3(0.5f, 0.5f, 0.0f),
glm::vec3(0.5f, -0.5f, 0.0f),
glm::vec3(-0.5f, 0.5f, 0.0f),
};
std::shared_ptr<simpleengine::Event> tri(new simpleengine::shapes_2d::Triangle(base_shader_program, vertices));
game.add_event(tri); */
/* 0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, 0.5f, 0.0f, // top left
// second triangle
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f */
std::vector<glm::vec3> vertices = {
glm::vec3(0.5f, 0.5f, 0.f), // top right
glm::vec3(0.5f, -0.5f, 0.f), // bottom right
glm::vec3(-0.5f, -0.5f, 0.f), // bottom left
glm::vec3(-0.5f, 0.5f, 0.f), // top left
};
std::vector<GLuint> indicies = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
std::shared_ptr<simpleengine::Event> square(new simpleengine::shapes_2d::Square(base_shader_program, vertices, indicies));
game.add_event(square);
return game.run();
}

View File

@ -0,0 +1,82 @@
//
// Created by SeanOMik on 7/2/2020.
// Github: https://github.com/SeanOMik
//
#ifndef SIMPLEENGINE_VAO_H
#define SIMPLEENGINE_VAO_H
#include <gl/glew.h>
#include <gl/GL.h>
#include "vbo.h"
namespace simpleengine::gfx {
class VAO {
public:
GLuint handle;
VAO() {
glGenVertexArrays(1, &handle);
}
~VAO() {
destroy();
}
void destroy() {
glDeleteVertexArrays(1, &handle);
}
void bind() {
glBindVertexArray(handle);
}
void attr(VBO vbo) {
bind();
vbo.bind();
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void enable_attrib(VBO vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset) {
bind();
vbo.bind();
// NOTE: glVertexAttribPointer will AUTO-CONVERT integer values to floating point.
// Integer vertex attributes must be specified with glVertexAttribIPointer.
// THIS IS EVIL. OpenGL is bad. Who designed this to fail silently?
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_INT:
case GL_UNSIGNED_INT:
case GL_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_2_10_10_10_REV:
glVertexAttribIPointer(index, size, type, stride, (void *) offset);
break;
default:
glVertexAttribPointer(index, size, type, GL_FALSE, stride, (void *) 0);
break;
}
glEnableVertexAttribArray(index);
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's
// bound vertex buffer object so afterwards we can safely unbind.
glBindBuffer(GL_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this
// rarely happens. Modifying other VAOs requires a call to glBindVertexArray anyways so we generally
// don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0);
}
};
}
#endif

View File

@ -0,0 +1,42 @@
//
// Created by SeanOMik on 7/2/2020.
// Github: https://github.com/SeanOMik
//
#ifndef SIMPLEENGINE_VBO_H
#define SIMPLEENGINE_VBO_H
#include <gl/glew.h>
#include <gl/GL.h>
namespace simpleengine::gfx {
class VBO {
public:
GLuint handle;
GLint type;
bool dynamic;
VBO(GLint type, bool dynamic) : type(type), dynamic(dynamic) {
glGenBuffers(1, &handle);
}
~VBO() {
destroy();
}
void destroy() {
glDeleteBuffers(1, &handle);
}
void bind() {
glBindBuffer(type, handle);
}
void buffer(void *data, size_t offset, size_t count) {
bind();
glBufferData(type, count - offset, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
}
};
}
#endif

View File

@ -17,21 +17,22 @@
#include <fstream>
#include <gl/gl.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <iostream>
#include <sstream>
namespace simpleengine {
class ShaderException : public std::exception {
class ShaderException : public std::runtime_error {
public:
explicit ShaderException(char const* const msg) : std::exception(msg) {
explicit ShaderException(char const* const msg) : std::runtime_error(msg) {
}
};
enum ShaderType {
Vertex = GL_VERTEX_SHADER,
Fragment = GL_FRAGMENT_SHADER,
ST_Vertex = GL_VERTEX_SHADER,
ST_Fragment = GL_FRAGMENT_SHADER,
};
class Shader : public simpleengine::Event {

View File

@ -44,7 +44,7 @@ namespace simpleengine {
*/
ShaderProgram& add_shader(Shader& shader) {
if (shader.program != this->program) {
throw std::exception("The added shader does not have the same program as this shade program!");
throw std::runtime_error("The added shader does not have the same program as this shade program!");
}
shaders.push_back(shader);
@ -88,7 +88,7 @@ namespace simpleengine {
*/
void link() {
if (shaders.empty()) {
throw std::exception("Shaders cannot be empty when running simpleengine::ShaderProgram::link()!");
throw std::runtime_error("Shaders cannot be empty when running simpleengine::ShaderProgram::link()!");
}
glLinkProgram(*program);

View File

@ -0,0 +1,67 @@
//
// Created by SeanOMik on 7/2/2020.
// Github: https://github.com/SeanOMik
//
#ifndef SIMPLEENGINE_SQUARE_H
#define SIMPLEENGINE_SQUARE_H
#include <gl/glew.h>
#include <gl/gl.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include "../../renderable.h"
#include "../../vertex.h"
#include "../../gfx/vbo.h"
#include "../../gfx/vao.h"
#include "simpleengine/gfx/vao.h"
#include <stdint.h>
#include <vector>
namespace simpleengine::shapes_2d {
class Square : public simpleengine::Renderable {
private:
using super = simpleengine::Renderable;
private:
std::shared_ptr<GLuint> shader_program;
public:
std::vector<glm::vec3> vertices;
std::vector<GLuint> indicies;
gfx::VBO ebo;
gfx::VBO vbo;
gfx::VAO vao;
Square(std::shared_ptr<GLuint> shader_program, std::vector<glm::vec3> vertices, std::vector<GLuint> indicies) :
super(nullptr), shader_program(shader_program), vertices(vertices), indicies(indicies),
ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)),
vao(gfx::VAO()) {
vao.bind();
vbo.buffer(vertices.data(), 0, vertices.size() * sizeof(float) * 3);
ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint));
// idfk why its 3
vao.enable_attrib(ebo, 0, 3, GL_FLOAT, 3 * sizeof(float), 0);
}
virtual ~Square() = default;
virtual void update(const float& delta_time) override {
}
virtual void render(std::shared_ptr<GLFWwindow> target) override {
glUseProgram(*shader_program);
vao.bind();
glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0);
}
};
}
#endif //SIMPLEENGINE_TRIANGLE_H

View File

@ -11,7 +11,16 @@
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include "../../renderable.h"
#include "../../vertex.h"
#include "../../gfx/vbo.h"
#include "../../gfx/vao.h"
#include "simpleengine/gfx/vao.h"
#include <vector>
namespace simpleengine::shapes_2d {
class Triangle : public simpleengine::Renderable {
@ -20,33 +29,17 @@ namespace simpleengine::shapes_2d {
private:
std::shared_ptr<GLuint> shader_program;
public:
float vertices[9];
uint32_t vbo;
uint32_t vao;
std::vector<glm::vec3> vertices;
gfx::VBO vbo;
gfx::VAO vao;
Triangle(std::shared_ptr<GLuint> shader_program) : super(nullptr), shader_program(shader_program), vertices{
-0.5f, -0.5f, 0.0f, // left
0.5f, -0.5f, 0.0f, // right
0.0f, 0.5f, 0.0f // top
} {
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(vao);
Triangle(std::shared_ptr<GLuint> shader_program, std::vector<glm::vec3> vertices) : super(nullptr),
shader_program(shader_program), vertices(vertices), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)),
vao(gfx::VAO()) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0);
vao.bind();
vbo.buffer(vertices.data(), 0, vertices.size() * sizeof(float) * 3); // 3 floats are in each "row" of the vector.
vao.enable_attrib(vbo, 0, vertices.size(), GL_FLOAT, 3 * sizeof(float), 0);
}
virtual ~Triangle() = default;
@ -57,7 +50,8 @@ namespace simpleengine::shapes_2d {
virtual void render(std::shared_ptr<GLFWwindow> target) override {
glUseProgram(*shader_program);
glBindVertexArray(vao);
vao.bind();
glDrawArrays(GL_TRIANGLES, 0, 3);
}
};

View File

@ -0,0 +1,23 @@
//
// Created by SeanOMik on 7/2/2020.
// Github: https://github.com/SeanOMik
//
#ifndef SIMPLEENGINE_VERTEX_H
#define SIMPLEENGINE_VERTEX_H
#include <gl/glew.h>
#include <gl/gl.h>
#include <glm/glm.hpp>
namespace simpleengine {
class Vertex {
public:
glm::vec3 position;
glm::vec3 color;
glm::vec2 tex_coord;
};
}
#endif //SIMPLEENGINE_VERTEX_H