Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
GraphicsAPI.cpp
Go to the documentation of this file.
1#include "graphics/GraphicsAPI.h"
2
3#include "Constants.h"
4#include "Log.h"
5#include "graphics/ShaderProgram.h"
6#include "render/Material.h"
7#include "render/Mesh.h"
8
9namespace mnd
10{
11
13{
14 glEnable(GL_DEPTH_TEST);
15 return true;
16}
17
18std::shared_ptr<ShaderProgram> GraphicsAPI::CreateShaderProgram(
19 const std::string &vertexSource, const std::string &fragmentSource
20)
21{
22 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
23 const char *vertexShaderCStr = vertexSource.c_str();
24 glShaderSource(vertexShader, 1, &vertexShaderCStr, nullptr);
25 glCompileShader(vertexShader);
26
27 GLint success;
28 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
29 if (!success)
30 {
31 char infoLog[kShaderInfoLogSize];
32 glGetShaderInfoLog(vertexShader, kShaderInfoLogSize, nullptr, infoLog);
33 LOG_ERROR("Vertex shader compilation failed: %s", infoLog);
34 return nullptr;
35 }
36
37 GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
38 const char *fragmentShaderSourceCStr = fragmentSource.c_str();
39 glShaderSource(fragmentShader, 1, &fragmentShaderSourceCStr, nullptr);
40 glCompileShader(fragmentShader);
41
42 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
43 if (!success)
44 {
45 char infoLog[kShaderInfoLogSize];
46 glGetShaderInfoLog(fragmentShader, kShaderInfoLogSize, nullptr, infoLog);
47 LOG_ERROR("Fragment shader compilation failed: %s", infoLog);
48 return nullptr;
49 }
50
51 GLuint shaderProgramID = glCreateProgram();
52 glAttachShader(shaderProgramID, vertexShader);
53 glAttachShader(shaderProgramID, fragmentShader);
54 glLinkProgram(shaderProgramID);
55
56 glGetProgramiv(shaderProgramID, GL_LINK_STATUS, &success);
57 if (!success)
58 {
59 char infoLog[kShaderInfoLogSize];
60 glGetProgramInfoLog(shaderProgramID, kShaderInfoLogSize, nullptr, infoLog);
61 LOG_ERROR("Shader program linking failed: %s", infoLog);
62 return nullptr;
63 }
64
65 glDeleteShader(vertexShader);
66 glDeleteShader(fragmentShader);
67
68 LOG_INFO("Shader program created (id=%u)", shaderProgramID);
69 return std::make_shared<ShaderProgram>(shaderProgramID);
70}
71
72const std::shared_ptr<ShaderProgram> &GraphicsAPI::GetDefaultShaderProgram()
73{
74 if (!m_defaultShaderProgram)
75 {
76 std::string vertexShaderSource = R"(
77 #version 330 core
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;
82
83 out vec2 vUV;
84 out vec3 vNormal;
85 out vec3 vViewNormal;
86 out vec3 vFragPos;
87
88 uniform mat4 uModel;
89 uniform mat4 uProjection;
90 uniform mat4 uView;
91
92 void main()
93 {
94 vUV = uv;
95
96 vFragPos = vec3(uModel * vec4(position, 1.0));
97
98 vNormal = mat3(transpose(inverse(uModel))) * normal;
99 vViewNormal = normalize(mat3(uView) * normalize(vNormal));
100
101 gl_Position = uProjection * uView * uModel * vec4(position, 1.0);
102 }
103 )";
104
105 std::string fragmentShaderSource = R"(
106 #version 330 core
107
108 struct Light {
109 vec3 color;
110 vec3 position;
111 };
112
113 uniform Light uLight;
114 uniform vec3 uCameraPos;
115 uniform vec3 color;
116
117 layout(location = 0) out vec4 FragColor;
118 layout(location = 1) out vec4 FragNormal;
119
120 in vec2 vUV;
121 in vec3 vNormal;
122 in vec3 vViewNormal;
123 in vec3 vFragPos;
124
125 uniform sampler2D baseColorTexture;
126
127 void main()
128 {
129 vec3 normal = normalize(vNormal);
130
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;
135
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;
141
142 vec4 texColor = texture(baseColorTexture, vUV);
143 vec3 result = (diffuse + specular + ambient) * texColor.xyz * color;
144
145 FragColor = vec4(result, 1.0);
146 FragNormal = vec4(normalize(vViewNormal) * 0.5 + 0.5, 1.0);
147 }
148 )";
149
150 m_defaultShaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);
151 }
152 return m_defaultShaderProgram;
154
155GLuint GraphicsAPI::CreateVertexBuffer(const std::vector<float> &vertices)
156{
157 GLuint VBO = 0;
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);
162
163 return VBO;
165
166GLuint GraphicsAPI::CreateIndexBuffer(const std::vector<uint32_t> &indices)
167{
168 GLuint EBO = 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);
173
174 return EBO;
176
177void GraphicsAPI::SetClearColor(float r, float g, float b, float a)
178{
179 glClearColor(r, g, b, a);
181
183{
184 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
186
188{
189 if (shaderProgram)
190 {
191 shaderProgram->Bind();
192 } else
193 {
194 LOG_WARN("BindShaderProgram called with nullptr");
195 }
197
199{
200 if (material)
201 {
202 material->Bind();
203 } else
204 {
205 LOG_WARN("BindMaterial called with nullptr");
206 }
208
210{
211 if (mesh)
212 {
213 mesh->Bind();
214 } else
215 {
216 LOG_WARN("BindMesh called with nullptr");
217 }
219
221{
222 if (mesh)
223 {
224 mesh->Unbind();
225 } else
226 {
227 LOG_WARN("BindMesh called with nullptr");
228 }
230
232{
233 if (mesh)
234 {
235 mesh->Draw();
236 } else
237 {
238 LOG_WARN("DrawMesh called with nullptr");
239 }
240}
241
242} // namespace mnd
Engine-wide compile-time tunables and ANSI colour codes.
constexpr mnd::i32 kShaderInfoLogSize
Definition Constants.h:57
int GLint
Definition GLForward.h:13
unsigned int GLuint
Definition GLForward.h:11
Console logging macros for all engine and game code.
#define LOG_WARN(fmt,...)
Definition Log.h:80
#define LOG_INFO(fmt,...)
Definition Log.h:79
#define LOG_ERROR(fmt,...)
Definition Log.h:81
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.
Definition Material.h:54
Immutable GPU mesh (VAO + VBO + optional EBO).
Definition Mesh.h:43
Linked GLSL program with cached uniform locations.
void Bind()
Activate this program for subsequent draw calls (glUseProgram).