Created
October 4, 2020 18:05
-
-
Save untodesu/84744ed237f355f75fa8060070b0b665 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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