Commit of work up to day 11 of learnopengl.com.

This commit is contained in:
Zed A. Shaw 2026-08-21 13:15:55 -04:00
commit 5ce5b4dda4
447 changed files with 126678 additions and 0 deletions

View file

@ -0,0 +1,48 @@
#include "dbc.hpp"
#include <iostream>
#include <format>
void dbc::log(const string &message, const std::source_location location) {
std::cout << '[' << location.file_name() << ':'
<< location.line() << "|"
<< location.function_name() << "] "
<< message << std::endl;
}
void dbc::sentinel(const string &message, const std::source_location location) {
string err = std::format("[SENTINEL!] {}", message);
dbc::log(err, location);
throw dbc::SentinelError{err};
}
void dbc::pre(const string &message, bool test, const std::source_location location) {
if(!test) {
string err = std::format("[PRE!] {}", message);
dbc::log(err, location);
throw dbc::PreCondError{err};
}
}
void dbc::pre(const string &message, std::function<bool()> tester, const std::source_location location) {
dbc::pre(message, tester(), location);
}
void dbc::post(const string &message, bool test, const std::source_location location) {
if(!test) {
string err = std::format("[POST!] {}", message);
dbc::log(err, location);
throw dbc::PostCondError{err};
}
}
void dbc::post(const string &message, std::function<bool()> tester, const std::source_location location) {
dbc::post(message, tester(), location);
}
void dbc::check(bool test, const string &message, const std::source_location location) {
if(!test) {
string err = std::format("[CHECK!] {}\n", message);
dbc::log(err, location);
throw dbc::CheckError{err};
}
}

View file

@ -0,0 +1,49 @@
#pragma once
#include <string>
#include <functional>
#include <source_location>
using std::string;
namespace dbc {
class Error {
public:
const string message;
Error(string m) : message{m} {}
Error(const char *m) : message{m} {}
};
class CheckError : public Error {};
class SentinelError : public Error {};
class PreCondError : public Error {};
class PostCondError : public Error {};
void log(const string &message,
const std::source_location location =
std::source_location::current());
[[noreturn]] void sentinel(const string &message,
const std::source_location location =
std::source_location::current());
void pre(const string &message, bool test,
const std::source_location location =
std::source_location::current());
void pre(const string &message, std::function<bool()> tester,
const std::source_location location =
std::source_location::current());
void post(const string &message, bool test,
const std::source_location location =
std::source_location::current());
void post(const string &message, std::function<bool()> tester,
const std::source_location location =
std::source_location::current());
void check(bool test, const string &message,
const std::source_location location =
std::source_location::current());
}

View file

@ -0,0 +1,188 @@
#define _USE_MATH_DEFINES
#include <math.h>
#include "dbc.hpp"
#include <print>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <vector>
#include <functional>
void framebuffer_size_callback(GLFWwindow *window, int widht, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
struct Config {
unsigned int shaderProgram = 0;
unsigned int VAO = 0;
unsigned int EBO = 0;
};
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
void init_glfw() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
void framebuffer_size_callback(GLFWwindow *, int width, int height) {
glViewport(0, 0, width, height);
}
GLFWwindow* create_window() {
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
dbc::check(window != NULL, "failed to open window");
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
auto good = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
dbc::check(good, "failed to load GLAD");
return window;
}
void processInput(GLFWwindow *window) {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
void check_status(const char* what, unsigned int shader, GLenum check_type) {
int success = 0;
char infoLog[512] = {0};
if(check_type == GL_LINK_STATUS) {
glGetProgramiv(shader, check_type, &success);
} else {
glGetShaderiv(shader, check_type, &success);
}
if(!success) {
glGetShaderInfoLog(shader, 512, NULL, infoLog);
std::println("ERROR: Shader {} compile failed: {}", what, infoLog);
}
}
Config setup() {
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
check_status("vertex shader", vertexShader, GL_COMPILE_STATUS);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
check_status("fragment shader", fragmentShader, GL_COMPILE_STATUS);
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
check_status("shader program", shaderProgram, GL_LINK_STATUS);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float vertices[] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f // top left
};
unsigned int indices[] = { // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
};
unsigned int VBO = 0;
unsigned int VAO = 0;
unsigned int EBO = 0;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 0 in arg one matches the vertexShader, line 1, location=0
// this attaches the vertices to that location in the shader
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// unbinds the magic currently active buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
return {
.shaderProgram = shaderProgram,
.VAO = VAO,
.EBO = EBO};
}
void render(GLFWwindow* window, const Config& config) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(config.shaderProgram);
glBindVertexArray(config.VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
void cleanup(Config& config) {
glDeleteVertexArrays(1, &config.VAO);
glDeleteBuffers(1, &config.VAO);
glDeleteBuffers(1, &config.EBO);
glDeleteProgram(config.shaderProgram);
}
int main() {
init_glfw();
auto window = create_window();
auto config = setup();
while(!glfwWindowShouldClose(window)) {
processInput(window);
render(window, config);
}
cleanup(config);
glfwTerminate();
return 0;
}