Skip to content

Instantly share code, notes, and snippets.

@untodesu
Created October 4, 2020 18:05
Show Gist options
  • Save untodesu/84744ed237f355f75fa8060070b0b665 to your computer and use it in GitHub Desktop.
Save untodesu/84744ed237f355f75fa8060070b0b665 to your computer and use it in GitHub Desktop.
//
// backend_ogl.cpp -- opengl graphics backend.
// Copyright (C) 2020, Voxelius team.
//
#include <voxelius/debug.h>
#include "graphics/backend_ogl.h"
void VxOpenGlGraphicsBackend::Init(SDL_Window *pWindow)
{
m_pWindow = pWindow;
m_glContext = SDL_GL_CreateContext(m_pWindow);
Vx_AssertMsg(m_glContext != nullptr, "Failed to create OpenGL context.");
SDL_GL_MakeCurrent(m_pWindow, m_glContext);
GLenum result = glewInit();
Vx_AssertMsg(result = GLEW_OK, "GLEW initialization failure.");
}
void VxOpenGlGraphicsBackend::Shutdown(void)
{
for(const auto &it : m_meshes) {
glDeleteBuffers(1, &it.second.m_ebo);
glDeleteBuffers(1, &it.second.m_vbo);
glDeleteVertexArrays(1, &it.second.m_vao);
}
m_meshes.clear();
for(const auto &it : m_textures)
glDeleteTextures(1, &it.second);
m_textures.clear();
SDL_GL_DeleteContext(m_glContext);
m_pWindow = nullptr;
}
void VxOpenGlGraphicsBackend::LoadTexture(const VxImage &data, unsigned int &id)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
unsigned int tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.GetWidth(), data.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data.GetPixels());
glBindTexture(GL_TEXTURE_2D, 0);
id = m_textureIndex++;
m_textures[id] = tex;
}
void VxOpenGlGraphicsBackend::UpdateTexture(unsigned int id, const VxImage &data)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
const auto &it = m_textures.find(id);
Vx_AssertMsg(it != m_textures.cend(), "Invalid texture handle.");
glBindTexture(GL_TEXTURE_2D, it->second);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.GetWidth(), data.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data.GetPixels());
glBindTexture(GL_TEXTURE_2D, 0);
}
void VxOpenGlGraphicsBackend::BindTexture(unsigned int id)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
const auto &it = m_textures.find(id);
Vx_AssertMsg(it != m_textures.cend(), "Invalid texture handle.");
glBindTexture(GL_TEXTURE_2D, it->second);
}
void VxOpenGlGraphicsBackend::UnbindTexture(void)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
glBindTexture(GL_TEXTURE_2D, 0);
}
void VxOpenGlGraphicsBackend::UnloadTexture(unsigned int id)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
const auto &it = m_textures.find(id);
Vx_AssertMsg(it != m_textures.cend(), "Invalid texture handle.");
glDeleteTextures(1, &it->second);
m_textures.erase(it);
}
void VxOpenGlGraphicsBackend::LoadMesh(const VxMesh &mesh, unsigned int &id)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
VxOpenGlMesh_t glMesh;
glGenVertexArrays(1, &glMesh.m_vao);
glGenBuffers(1, &glMesh.m_vbo);
glGenBuffers(1, &glMesh.m_ebo);
glBindVertexArray(glMesh.m_vao);
glBindBuffer(GL_ARRAY_BUFFER, glMesh.m_vbo);
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(mesh.GetVerticesCount() * sizeof(VxVertex)), mesh.GetVertices(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glMesh.m_ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(mesh.GetIndicesCount() * sizeof(unsigned int)), mesh.GetIndices(), GL_STATIC_DRAW);
// These will automatically be at:
// layout(location = 0) in dvec3 g_position;
// layout(location = 1) in dvec3 g_normal;
// layout(location = 2) in dvec2 g_tcoord;
// layout(location = 3) in dvec4 g_color;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, sizeof(VxVertex), (void *)offsetof(VxVertex, m_position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_DOUBLE, GL_FALSE, sizeof(VxVertex), (void *)offsetof(VxVertex, m_normal));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_DOUBLE, GL_FALSE, sizeof(VxVertex), (void *)offsetof(VxVertex, m_tcoord));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_DOUBLE, GL_FALSE, sizeof(VxVertex), (void *)offsetof(VxVertex, m_color));
glBindVertexArray(0);
id = m_meshIndex++;;
m_meshes[id] = glMesh;
}
void VxOpenGlGraphicsBackend::UpdateMesh(unsigned int id, const VxMesh &mesh)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
const auto &it = m_meshes.find(id);
Vx_AssertMsg(it != m_meshes.cend(), "Invalid mesh handle.");
VxOpenGlMesh_t &glMesh = it->second;
glBindVertexArray(glMesh.m_vao);
glBindBuffer(GL_ARRAY_BUFFER, glMesh.m_vbo);
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(mesh.GetVerticesCount() * sizeof(VxVertex)), mesh.GetVertices(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glMesh.m_ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(mesh.GetIndicesCount() * sizeof(unsigned int)), mesh.GetIndices(), GL_STATIC_DRAW);
glBindVertexArray(0);
}
void VxOpenGlGraphicsBackend::UnloadMesh(unsigned int id)
{
Vx_AssertMsg(m_pWindow && m_glContext, "Backend is not initialized.");
const auto &it = m_meshes.find(id);
Vx_AssertMsg(it != m_meshes.cend(), "Invalid mesh handle.");
glDeleteBuffers(1, &it->second.m_ebo);
glDeleteBuffers(1, &it->second.m_vbo);
glDeleteVertexArrays(1, &it->second.m_vao);
m_meshes.erase(it);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment