1#include "graphics/GraphicsAPI.h"
5#include "graphics/ShaderProgram.h"
6#include "render/Material.h"
7#include "render/Mesh.h"
14 glEnable(GL_DEPTH_TEST);
19 const std::string &vertexSource,
const std::string &fragmentSource
22 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
23 const char *vertexShaderCStr = vertexSource.c_str();
24 glShaderSource(vertexShader, 1, &vertexShaderCStr,
nullptr);
25 glCompileShader(vertexShader);
28 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
33 LOG_ERROR(
"Vertex shader compilation failed: %s", infoLog);
37 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
38 const char *fragmentShaderSourceCStr = fragmentSource.c_str();
39 glShaderSource(fragmentShader, 1, &fragmentShaderSourceCStr,
nullptr);
40 glCompileShader(fragmentShader);
42 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
47 LOG_ERROR(
"Fragment shader compilation failed: %s", infoLog);
51 GLuint shaderProgramID = glCreateProgram();
52 glAttachShader(shaderProgramID, vertexShader);
53 glAttachShader(shaderProgramID, fragmentShader);
54 glLinkProgram(shaderProgramID);
56 glGetProgramiv(shaderProgramID, GL_LINK_STATUS, &success);
61 LOG_ERROR(
"Shader program linking failed: %s", infoLog);
65 glDeleteShader(vertexShader);
66 glDeleteShader(fragmentShader);
68 LOG_INFO(
"Shader program created (id=%u)", shaderProgramID);
69 return std::make_shared<ShaderProgram>(shaderProgramID);
74 if (!m_defaultShaderProgram)
76 std::string vertexShaderSource = R
"(
78 layout(location = 0) in vec3 position;
79 layout(location = 1) in vec3 color;
80 layout(location = 2) in vec2 uv;
81 layout(location = 3) in vec3 normal;
89 uniform mat4 uProjection;
96 vFragPos = vec3(uModel * vec4(position, 1.0));
98 vNormal = mat3(transpose(inverse(uModel))) * normal;
99 vViewNormal = normalize(mat3(uView) * normalize(vNormal));
101 gl_Position = uProjection * uView * uModel * vec4(position, 1.0);
105 std::string fragmentShaderSource = R"(
113 uniform Light uLight;
114 uniform vec3 uCameraPos;
117 layout(location = 0) out vec4 FragColor;
118 layout(location = 1) out vec4 FragNormal;
125 uniform sampler2D baseColorTexture;
129 vec3 normal = normalize(vNormal);
131 vec3 lightDir = normalize(uLight.position - vFragPos);
132 float diff = max(dot(normal, lightDir), 0.0);
133 vec3 ambient = 0.4 * uLight.color;
134 vec3 diffuse = diff * uLight.color;
136 vec3 viewDir = normalize(uCameraPos - vFragPos);
137 vec3 reflectDir = reflect(-lightDir, normal);
138 float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
139 float specularStrength = 0.5;
140 vec3 specular = specularStrength * spec * uLight.color;
142 vec4 texColor = texture(baseColorTexture, vUV);
143 vec3 result = (diffuse + specular + ambient) * texColor.xyz * color;
145 FragColor = vec4(result, 1.0);
146 FragNormal = vec4(normalize(vViewNormal) * 0.5 + 0.5, 1.0);
152 return m_defaultShaderProgram;
158 glGenBuffers(1, &VBO);
159 glBindBuffer(GL_ARRAY_BUFFER, VBO);
160 glBufferData(GL_ARRAY_BUFFER, vertices.size() *
sizeof(
float), vertices.data(), GL_STATIC_DRAW);
161 glBindBuffer(GL_ARRAY_BUFFER, 0);
169 glGenBuffers(1, &EBO);
170 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
171 glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() *
sizeof(uint32_t), indices.data(), GL_STATIC_DRAW);
172 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
179 glClearColor(r, g, b, a);
184 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
191 shaderProgram->
Bind();
194 LOG_WARN(
"BindShaderProgram called with nullptr");
205 LOG_WARN(
"BindMaterial called with nullptr");
216 LOG_WARN(
"BindMesh called with nullptr");
227 LOG_WARN(
"BindMesh called with nullptr");
238 LOG_WARN(
"DrawMesh called with nullptr");
Engine-wide compile-time tunables and ANSI colour codes.
constexpr mnd::i32 kShaderInfoLogSize
Console logging macros for all engine and game code.
#define LOG_WARN(fmt,...)
#define LOG_INFO(fmt,...)
#define LOG_ERROR(fmt,...)
std::shared_ptr< Material > material
std::shared_ptr< Mesh > mesh
const std::shared_ptr< ShaderProgram > & GetDefaultShaderProgram()
Returns the built-in default shader (Blinn-Phong + diffuse texture).
void BindShaderProgram(ShaderProgram *shaderProgram)
Bind a compiled shader program to the current GL state.
void ClearBuffers()
Clear the colour and depth buffers ready for the next frame.
void BindMaterial(Material *material)
Upload all material parameters as uniforms to the active shader.
void UnbindMesh(Mesh *mesh)
void DrawMesh(Mesh *mesh)
Issue a draw call for the bound mesh.
void SetClearColor(float r, float g, float b, float a)
Set the colour that glClear() fills the framebuffer with.
std::shared_ptr< ShaderProgram > CreateShaderProgram(const std::string &vertexSource, const std::string &fragmentSource)
Compile vertex + fragment GLSL source and link into a program.
GLuint CreateIndexBuffer(const std::vector< uint32_t > &indices)
Upload a flat array of u32 indices to a new GPU index buffer.
bool Init()
Set up initial OpenGL state (depth test, face culling, etc.).
GLuint CreateVertexBuffer(const std::vector< float > &vertices)
Upload a flat array of floats to a new GPU vertex buffer.
void BindMesh(Mesh *mesh)
Bind the mesh's VAO so the next draw call uses its geometry.
Shader + uniform storage that defines how a surface is rendered.
Immutable GPU mesh (VAO + VBO + optional EBO).
Linked GLSL program with cached uniform locations.
void Bind()
Activate this program for subsequent draw calls (glUseProgram).