~vladh/peony

6e84a4f23548899372ab328cad5604f02d0f502c — Vlad-Stefan Harbuz 1 year, 7 months ago 98f9237
refactor gl stuff from util into glutil
7 files changed, 228 insertions(+), 210 deletions(-)

M src/_unity.cpp
A src/glutil.cpp
A src/glutil.hpp
M src/mats.cpp
M src/renderer.cpp
M src/util.cpp
M src/util.hpp
M src/_unity.cpp => src/_unity.cpp +1 -0
@@ 4,6 4,7 @@
#include "../src_external/pstr.c"
#include "logs.cpp"
#include "util.cpp"
#include "glutil.cpp"
#include "debug.cpp"
#include "memory.cpp"
#include "files.cpp"

A src/glutil.cpp => src/glutil.cpp +206 -0
@@ 0,0 1,206 @@
// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>

#pragma once

#include "logs.hpp"
#include "glutil.hpp"


char const *
glutil::stringify_glenum(GLenum thing)
{
    switch (thing) {
    case 0:
        return "(none)";
    case GL_BYTE:
        return "GLbyte";
    case GL_UNSIGNED_BYTE:
        return "GLubyte";
    case GL_SHORT:
        return "GLshort";
    case GL_UNSIGNED_SHORT:
        return "GLushort";
    case GL_INT:
        return "GLint";
    case GL_UNSIGNED_INT:
        return "GLuint";
    case GL_HALF_FLOAT:
        return "GLhalf";
    case GL_FLOAT:
        return "GLfloat";
    case GL_DOUBLE:
        return "GLdouble";
    case GL_RGB8:
        return "GL_RGB8";
    case GL_RGBA8:
        return "GL_RGBA8";
    case GL_SRGB8:
        return "GL_SRGB8";
    case GL_UNSIGNED_INT_8_8_8_8:
        return "GL_UNSIGNED_INT_8_8_8_8";
    case GL_UNSIGNED_INT_8_8_8_8_REV:
        return "GL_UNSIGNED_INT_8_8_8_8_REV";
    case GL_DEPTH_COMPONENT:
        return "GL_DEPTH_COMPONENT";
    case GL_DEPTH_STENCIL:
        return "GL_DEPTH_STENCIL";
    case GL_RED:
        return "GL_RED";
    case GL_RGB:
        return "GL_RGB";
    case GL_RGBA:
        return "GL_RGBA";
    default:
        logs::warning("Unknown GLenum %d", thing);
        return "Unknown GLenum";
    }
}


GLenum
glutil::get_texture_format_from_n_components(i32 n_components)
{
    if (n_components == 1) {
        return GL_RED;
    } else if (n_components == 3) {
        return GL_BGR;
    } else if (n_components == 4) {
        return GL_BGRA;
    } else {
        logs::fatal("Don't know what to do with n_components = %d", n_components);
        return 0;
    }
}


void
glutil::print_texture_internalformat_info(GLenum internal_format)
{
    if (!GLAD_GL_ARB_internalformat_query) {
        logs::warning("Not printing texture_internalformat as this feature is not supported on this system.");
        return;
    }

    if (!GLAD_GL_ARB_internalformat_query2) {
        logs::warning("Printing texture_internalformat, but some information may be missing, as internalformat_query2 is not supported on this system.");
    }

    GLint preferred_format;
    GLint optimal_image_format;
    GLint optimal_image_type;

    glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_INTERNALFORMAT_PREFERRED, 1, &preferred_format);
    glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_FORMAT, 1, &optimal_image_format);
    glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_TYPE, 1, &optimal_image_type);

    logs::info("internal format: %s", stringify_glenum(internal_format));
    logs::info("preferred format: %s", stringify_glenum(preferred_format));
    logs::info("optimal image format: %s", stringify_glenum(optimal_image_format));
    logs::info("optimal image type: %s", stringify_glenum(optimal_image_type));
    logs::print_newline();
}


void APIENTRY
glutil::debug_message_callback(
    GLenum source,
    GLenum type,
    unsigned int id,
    GLenum severity,
    GLsizei length,
    char const *message,
    const void *userParam
) {
    // Ignore insignificant error/warning codes
    if (
        // Framebuffer detailed info: The driver allocated storage for
        // renderbuffer 1.
        id == 131169 ||
        // Program/shader state performance warning: Vertex shader in program 19
        // is being recompiled based on GL state.
        id == 131218 ||
        // Buffer detailed info: Buffer object 1522 (bound to
        // GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), and GL_ARRAY_BUFFER_ARB,
        // usage hint is GL_DYNAMIC_DRAW) will use VIDEO memory as the source for
        // buffer object operations.
        id == 131185 ||
        // Texture state usage warning: The texture object (0) bound to texture
        // image unit 4 does not have a defined base level and cannot be used for
        // texture mapping.
        id == 131204 ||
        // Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering.
        id == 131154
    ) {
        return;
    }

    logs::warning("Debug message (%d): %s", id, message);

    switch (source) {
    case GL_DEBUG_SOURCE_API:
        logs::warning("Source: API");
        break;
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
        logs::warning("Source: Window System");
        break;
    case GL_DEBUG_SOURCE_SHADER_COMPILER:
        logs::warning("Source: Shader Compiler");
        break;
    case GL_DEBUG_SOURCE_THIRD_PARTY:
        logs::warning("Source: Third Party");
        break;
    case GL_DEBUG_SOURCE_APPLICATION:
        logs::warning("Source: Application");
        break;
    case GL_DEBUG_SOURCE_OTHER:
        logs::warning("Source: Other");
        break;
    }

    switch (type) {
    case GL_DEBUG_TYPE_ERROR:
        logs::warning("Type: Error");
        break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
        logs::warning("Type: Deprecated Behaviour");
        break;
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
        logs::warning("Type: Undefined Behaviour");
        break;
    case GL_DEBUG_TYPE_PORTABILITY:
        logs::warning("Type: Portability");
        break;
    case GL_DEBUG_TYPE_PERFORMANCE:
        logs::warning("Type: Performance");
        break;
    case GL_DEBUG_TYPE_MARKER:
        logs::warning("Type: Marker");
        break;
    case GL_DEBUG_TYPE_PUSH_GROUP:
        logs::warning("Type: Push Group");
        break;
    case GL_DEBUG_TYPE_POP_GROUP:
        logs::warning("Type: Pop Group");
        break;
    case GL_DEBUG_TYPE_OTHER:
        logs::warning("Type: Other");
        break;
    }

    switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH:
        logs::warning("Severity: high");
        break;
    case GL_DEBUG_SEVERITY_MEDIUM:
        logs::warning("Severity: medium");
        break;
    case GL_DEBUG_SEVERITY_LOW:
        logs::warning("Severity: low");
        break;
    case GL_DEBUG_SEVERITY_NOTIFICATION:
        logs::warning("Severity: notification");
        break;
    }

    logs::print_newline();
}

A src/glutil.hpp => src/glutil.hpp +17 -0
@@ 0,0 1,17 @@
// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>

#pragma once

#include "../src_external/glad/glad.h"
#include "types.hpp"

class glutil {
public:
    static char const * stringify_glenum(GLenum thing);
    static GLenum get_texture_format_from_n_components(i32 n_components);
    static void print_texture_internalformat_info(GLenum internal_format);
    static void APIENTRY debug_message_callback(
        GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length,
        char const *message, const void *userParam
    );
};

M src/mats.cpp => src/mats.cpp +2 -1
@@ 4,6 4,7 @@
#include "shaders.hpp"
#include "array.hpp"
#include "util.hpp"
#include "glutil.hpp"
#include "logs.hpp"
#include "files.hpp"
#include "mats.hpp"


@@ 562,7 563,7 @@ mats::generate_textures_from_pbo(Material *material)
        texture->texture_name = get_new_texture_name(texture->width);
        glBindTexture(GL_TEXTURE_2D, texture->texture_name);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texture->width, texture->height,
            util::get_texture_format_from_n_components(texture->n_components),
            glutil::get_texture_format_from_n_components(texture->n_components),
            GL_UNSIGNED_BYTE,
            get_offset_for_persistent_pbo_idx(texture->pbo_idx_for_copy));
        glGenerateMipmap(GL_TEXTURE_2D);

M src/renderer.cpp => src/renderer.cpp +2 -1
@@ 6,6 6,7 @@
#include "mats.hpp"
#include "debug.hpp"
#include "util.hpp"
#include "glutil.hpp"
#include "logs.hpp"
#include "debug_ui.hpp"
#include "debugdraw.hpp"


@@ 122,7 123,7 @@ renderer::init_window(WindowSize *window_size)
            if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {
                glEnable(GL_DEBUG_OUTPUT);
                glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
                glDebugMessageCallback(util::debug_message_callback, nullptr);
                glDebugMessageCallback(glutil::debug_message_callback, nullptr);
                glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
            } else {
                logs::fatal("Tried to initialise OpenGL debug output but couldn't");

M src/util.cpp => src/util.cpp +0 -200
@@ 4,73 4,6 @@
#include "util.hpp"


char const *
util::stringify_glenum(GLenum thing)
{
    switch (thing) {
    case 0:
        return "(none)";
    case GL_BYTE:
        return "GLbyte";
    case GL_UNSIGNED_BYTE:
        return "GLubyte";
    case GL_SHORT:
        return "GLshort";
    case GL_UNSIGNED_SHORT:
        return "GLushort";
    case GL_INT:
        return "GLint";
    case GL_UNSIGNED_INT:
        return "GLuint";
    case GL_HALF_FLOAT:
        return "GLhalf";
    case GL_FLOAT:
        return "GLfloat";
    case GL_DOUBLE:
        return "GLdouble";
    case GL_RGB8:
        return "GL_RGB8";
    case GL_RGBA8:
        return "GL_RGBA8";
    case GL_SRGB8:
        return "GL_SRGB8";
    case GL_UNSIGNED_INT_8_8_8_8:
        return "GL_UNSIGNED_INT_8_8_8_8";
    case GL_UNSIGNED_INT_8_8_8_8_REV:
        return "GL_UNSIGNED_INT_8_8_8_8_REV";
    case GL_DEPTH_COMPONENT:
        return "GL_DEPTH_COMPONENT";
    case GL_DEPTH_STENCIL:
        return "GL_DEPTH_STENCIL";
    case GL_RED:
        return "GL_RED";
    case GL_RGB:
        return "GL_RGB";
    case GL_RGBA:
        return "GL_RGBA";
    default:
        logs::warning("Unknown GLenum %d", thing);
        return "Unknown GLenum";
    }
}


GLenum
util::get_texture_format_from_n_components(i32 n_components)
{
    if (n_components == 1) {
        return GL_RED;
    } else if (n_components == 3) {
        return GL_BGR;
    } else if (n_components == 4) {
        return GL_BGRA;
    } else {
        logs::fatal("Don't know what to do with n_components = %d", n_components);
        return 0;
    }
}


f64
util::random(f64 min, f64 max)
{


@@ 123,139 56,6 @@ util::aimatrix4x4_to_glm(aiMatrix4x4 *from)
}


void
util::print_texture_internalformat_info(GLenum internal_format)
{
    if (!GLAD_GL_ARB_internalformat_query) {
        logs::warning("Not printing texture_internalformat as this feature is not supported on this system.");
        return;
    }

    if (!GLAD_GL_ARB_internalformat_query2) {
        logs::warning("Printing texture_internalformat, but some information may be missing, as internalformat_query2 is not supported on this system.");
    }

    GLint preferred_format;
    GLint optimal_image_format;
    GLint optimal_image_type;

    glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_INTERNALFORMAT_PREFERRED, 1, &preferred_format);
    glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_FORMAT, 1, &optimal_image_format);
    glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_TYPE, 1, &optimal_image_type);

    logs::info("internal format: %s", stringify_glenum(internal_format));
    logs::info("preferred format: %s", stringify_glenum(preferred_format));
    logs::info("optimal image format: %s", stringify_glenum(optimal_image_format));
    logs::info("optimal image type: %s", stringify_glenum(optimal_image_type));
    logs::print_newline();
}


void
APIENTRY util::debug_message_callback(
    GLenum source,
    GLenum type,
    unsigned int id,
    GLenum severity,
    GLsizei length,
    char const *message,
    const void *userParam
) {
    // Ignore insignificant error/warning codes
    if (
        // Framebuffer detailed info: The driver allocated storage for
        // renderbuffer 1.
        id == 131169 ||
        // Program/shader state performance warning: Vertex shader in program 19
        // is being recompiled based on GL state.
        id == 131218 ||
        // Buffer detailed info: Buffer object 1522 (bound to
        // GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), and GL_ARRAY_BUFFER_ARB,
        // usage hint is GL_DYNAMIC_DRAW) will use VIDEO memory as the source for
        // buffer object operations.
        id == 131185 ||
        // Texture state usage warning: The texture object (0) bound to texture
        // image unit 4 does not have a defined base level and cannot be used for
        // texture mapping.
        id == 131204 ||
        // Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering.
        id == 131154
    ) {
        return;
    }

    logs::warning("Debug message (%d): %s", id, message);

    switch (source) {
    case GL_DEBUG_SOURCE_API:
        logs::warning("Source: API");
        break;
    case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
        logs::warning("Source: Window System");
        break;
    case GL_DEBUG_SOURCE_SHADER_COMPILER:
        logs::warning("Source: Shader Compiler");
        break;
    case GL_DEBUG_SOURCE_THIRD_PARTY:
        logs::warning("Source: Third Party");
        break;
    case GL_DEBUG_SOURCE_APPLICATION:
        logs::warning("Source: Application");
        break;
    case GL_DEBUG_SOURCE_OTHER:
        logs::warning("Source: Other");
        break;
    }

    switch (type) {
    case GL_DEBUG_TYPE_ERROR:
        logs::warning("Type: Error");
        break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
        logs::warning("Type: Deprecated Behaviour");
        break;
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
        logs::warning("Type: Undefined Behaviour");
        break;
    case GL_DEBUG_TYPE_PORTABILITY:
        logs::warning("Type: Portability");
        break;
    case GL_DEBUG_TYPE_PERFORMANCE:
        logs::warning("Type: Performance");
        break;
    case GL_DEBUG_TYPE_MARKER:
        logs::warning("Type: Marker");
        break;
    case GL_DEBUG_TYPE_PUSH_GROUP:
        logs::warning("Type: Push Group");
        break;
    case GL_DEBUG_TYPE_POP_GROUP:
        logs::warning("Type: Pop Group");
        break;
    case GL_DEBUG_TYPE_OTHER:
        logs::warning("Type: Other");
        break;
    }

    switch (severity) {
    case GL_DEBUG_SEVERITY_HIGH:
        logs::warning("Severity: high");
        break;
    case GL_DEBUG_SEVERITY_MEDIUM:
        logs::warning("Severity: medium");
        break;
    case GL_DEBUG_SEVERITY_LOW:
        logs::warning("Severity: low");
        break;
    case GL_DEBUG_SEVERITY_NOTIFICATION:
        logs::warning("Severity: notification");
        break;
    }

    logs::print_newline();
}


f32
util::round_to_nearest_multiple(f32 n, f32 multiple_of)
{

M src/util.hpp => src/util.hpp +0 -8
@@ 5,22 5,14 @@
#include <chrono>
namespace chrono = std::chrono;
#include <assimp/cimport.h>
#include "../src_external/glad/glad.h"
#include "types.hpp"

class util {
public:
    static char const * stringify_glenum(GLenum thing);
    static GLenum get_texture_format_from_n_components(i32 n_components);
    static f64 random(f64 min, f64 max);
    static v3 aiVector3D_to_glm(aiVector3D *vec);
    static quat aiQuaternion_to_glm(aiQuaternion *rotation);
    static m4 aimatrix4x4_to_glm(aiMatrix4x4 *from);
    static void print_texture_internalformat_info(GLenum internal_format);
    static void APIENTRY debug_message_callback(
        GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length,
        char const *message, const void *userParam
    );
    static f32 round_to_nearest_multiple(f32 n, f32 multiple_of);
    static f64 get_us_from_duration(chrono::duration<f64> duration);
    static v3 get_orthogonal_vector(v3 *v);