Created
January 6, 2023 21:24
-
-
Save deccer/0de0fd3dfc878ce8326d10dfa8d89cca 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
#include <cstddef> | |
#include <spdlog/spdlog.h> | |
#include <glad/glad.h> | |
#include <GLFW/glfw3.h> | |
#include <glm/vec3.hpp> | |
#include <fstream> | |
#include <string> | |
#include <string_view> | |
#include <vector> | |
using namespace std::literals; | |
GLuint gVertexArrayPosition = {}; | |
GLuint gVertexBuffer = {}; | |
GLuint gIndexBuffer = {}; | |
GLuint gProgram = {}; | |
struct VertexPositionColor | |
{ | |
glm::vec3 Position; | |
glm::vec3 Color; | |
}; | |
std::vector<VertexPositionColor> gVertices = | |
{ | |
VertexPositionColor{ .Position = glm::vec3(-0.5f, +0.5f, 0.0f), .Color = glm::vec3(0.8f, 0.2f, 1.0f) }, | |
VertexPositionColor{ .Position = glm::vec3(+0.5f, +0.5f, 0.0f), .Color = glm::vec3(1.0f, 0.8f, 0.0f) }, | |
VertexPositionColor{ .Position = glm::vec3(+0.0f, -0.5f, 0.0f), .Color = glm::vec3(0.2f, 1.0f, 0.8f) } | |
}; | |
std::vector<std::uint32_t> gIndices = | |
{ | |
0, 1, 2 | |
}; | |
auto CreateAndCompileShader(std::string_view vertexShaderSource, std::string_view fragmentShaderSource) -> bool | |
{ | |
int success = false; | |
char log[1024] = {}; | |
const char* vertexShaderSourcePtr = vertexShaderSource.data(); | |
const auto vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertexShaderSourcePtr, nullptr); | |
glCompileShader(vertexShader); | |
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(vertexShader, 1024, nullptr, log); | |
spdlog::error(log); | |
return false; | |
} | |
const char* fragmentShaderSourcePtr = fragmentShaderSource.data(); | |
const auto fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragmentShaderSourcePtr, nullptr); | |
glCompileShader(fragmentShader); | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(fragmentShader, 1024, nullptr, log); | |
spdlog::error(log); | |
return false; | |
} | |
gProgram = glCreateProgram(); | |
glAttachShader(gProgram, vertexShader); | |
glAttachShader(gProgram, fragmentShader); | |
glLinkProgram(gProgram); | |
glGetProgramiv(gProgram, GL_LINK_STATUS, &success); | |
if (!success) | |
{ | |
glGetProgramInfoLog(gProgram, 1024, nullptr, log); | |
spdlog::error(log); | |
return false; | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
return true; | |
} | |
auto CleanupRender() -> void | |
{ | |
glDeleteBuffers(1, &gVertexBuffer); | |
glDeleteBuffers(1, &gIndexBuffer); | |
glDeleteVertexArrays(1, &gVertexArrayPosition); | |
glDeleteProgram(gProgram); | |
} | |
auto SetupRender() -> bool | |
{ | |
glCreateBuffers(1, &gVertexBuffer); | |
glNamedBufferStorage(gVertexBuffer, sizeof(VertexPositionColor) * gVertices.size(), gVertices.data(), 0); | |
glCreateBuffers(1, &gIndexBuffer); | |
glNamedBufferStorage(gIndexBuffer, sizeof(std::uint32_t) * gIndices.size(), gIndices.data(), 0); | |
glCreateVertexArrays(1, &gVertexArrayPosition); | |
glEnableVertexArrayAttrib(gVertexArrayPosition, 0); | |
glVertexArrayAttribBinding(gVertexArrayPosition, 0, 0); | |
glVertexArrayAttribFormat(gVertexArrayPosition, 0, 3, GL_FLOAT, GL_FALSE, offsetof(VertexPositionColor, Position)); | |
glEnableVertexArrayAttrib(gVertexArrayPosition, 1); | |
glVertexArrayAttribBinding(gVertexArrayPosition, 1, 0); | |
glVertexArrayAttribFormat(gVertexArrayPosition, 1, 3, GL_FLOAT, GL_FALSE, offsetof(VertexPositionColor, Color)); | |
glVertexArrayVertexBuffer(gVertexArrayPosition, 0, gVertexBuffer, 0, sizeof(VertexPositionColor)); | |
glVertexArrayElementBuffer(gVertexArrayPosition, gIndexBuffer); | |
auto vertexShaderSource = R"glsl( | |
#version 460 core | |
layout (location = 0) in vec3 i_position; | |
layout (location = 1) in vec3 i_color; | |
layout (location = 0) out vec3 v_color; | |
void main() | |
{ | |
gl_Position = vec4(i_position, 1.0); | |
v_color = i_color; | |
})glsl"sv; | |
auto fragmentShaderSource = R"glsl( | |
#version 460 core | |
layout (location = 0) in vec3 v_color; | |
layout (location = 0) out vec4 out_color; | |
void main() | |
{ | |
out_color = vec4(v_color, 1.0); | |
})glsl"sv; | |
if (!CreateAndCompileShader(vertexShaderSource, fragmentShaderSource)) | |
{ | |
return false; | |
} | |
return true; | |
} | |
auto Render() -> void | |
{ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glUseProgram(gProgram); | |
glBindVertexArray(gVertexArrayPosition); | |
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); | |
} | |
auto main(int, char**) -> int | |
{ | |
if (glfwInit() == GLFW_FALSE) | |
{ | |
spdlog::error("GLFW: Unable to initialize"); | |
return 1; | |
} | |
glfwSetErrorCallback([](auto errorCode, auto errorMessage) | |
{ | |
spdlog::error("GLFW: Error {0}", errorMessage); | |
}); | |
auto windowWidth = 1650; | |
auto windowHeight = 1050; | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); | |
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE); | |
auto windowHandle = glfwCreateWindow(windowWidth, windowHeight, "Basic Triangle DSA", nullptr, nullptr); | |
if (windowHandle == nullptr) | |
{ | |
spdlog::error("GLFW: Unable to create window"); | |
glfwTerminate(); | |
return 1; | |
} | |
const auto primaryMonitor = glfwGetPrimaryMonitor(); | |
const auto primaryMonitorResolution = glfwGetVideoMode(primaryMonitor); | |
glfwSetWindowPos(windowHandle, primaryMonitorResolution->width / 2 - windowWidth / 2, primaryMonitorResolution->height / 2 - windowHeight / 2); | |
glfwMakeContextCurrent(windowHandle); | |
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); | |
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); | |
glDebugMessageCallback([](GLenum source, | |
GLenum type, | |
GLuint, | |
GLenum severity, | |
GLsizei, | |
const GLchar* message, | |
const void*) | |
{ | |
if (type == GL_DEBUG_TYPE_ERROR) | |
{ | |
spdlog::error("GL: DEBUG CALLBACK type = {}, severity = error, message = {}\n", type, message); | |
} | |
}, nullptr); | |
glEnable(GL_DEPTH_TEST); | |
glClearColor(0.05f, 0.05f, 0.05f, 1.0f); | |
if (!SetupRender()) | |
{ | |
glfwTerminate(); | |
return 1; | |
} | |
while (!glfwWindowShouldClose(windowHandle)) | |
{ | |
glfwPollEvents(); | |
Render(); | |
glfwSwapBuffers(windowHandle); | |
} | |
CleanupRender(); | |
glfwDestroyWindow(windowHandle); | |
glfwTerminate(); | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment