aboutsummaryrefslogtreecommitdiff
path: root/src/RenderBackend/OpenGL/Shader.cpp
blob: 32e2fe6540de63ee813e656f2059287274156490 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include "../../../include/RenderBackend/OpenGL/Shader.hpp"
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"

namespace amalgine {
    static GLuint to_opengl_shader_type(Shader::Type type) {
        switch(type) {
            case Shader::Type::VERTEX:
                return GL_VERTEX_SHADER;
            case Shader::Type::PIXEL:
                return GL_FRAGMENT_SHADER;
        }
        assert(false);
        return 0;
    }

    static std::string get_shader_compile_log(GLuint shaderId)
    {
        std::string result;
        GLint shaderLogLength;
        glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &shaderLogLength);
        if(shaderLogLength > 0) {
            result.resize(shaderLogLength);
            glGetShaderInfoLog(shaderId, shaderLogLength, NULL, &result[0]);
        }
        return result;
    }

    Shader::Shader(u32 shader_id) : id(shader_id) {
        
    }

    Shader::~Shader() {
        glDeleteShader(id);
    }
    
    // static
    Result<std::unique_ptr<Shader>> Shader::compile(Type type, const char *str, int size) {
        GLuint shader_id = glCreateShader(to_opengl_shader_type(type));
        GLint shader_lengths[1] = { size };
        glShaderSource(shader_id, 1, &str, shader_lengths);
        glCompileShader(shader_id);
        
        GLint status;
        glGetShaderiv(shader_id, GL_COMPILE_STATUS, &status);
        std::string compileLog = get_shader_compile_log(shader_id);
        if(status == GL_TRUE) {
            if(!compileLog.empty())
                fprintf(stderr, "Shader compile log:\n%s", compileLog.c_str());
            std::unique_ptr<Shader> shader;
            shader.reset(new Shader(shader_id));
            return Result<std::unique_ptr<Shader>>::Ok(std::move(shader));
        }
        else
            return Result<std::unique_ptr<Shader>>::Err(compileLog);
    }
}