Major refactor
This commit is contained in:
parent
8978d581d7
commit
890117d3d0
8
shaders/shader.frag
Normal file
8
shaders/shader.frag
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
in vec4 vertex_color;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
color = vertex_color;
|
||||||
|
}
|
||||||
13
shaders/shader.vert
Normal file
13
shaders/shader.vert
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 330
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 pos;
|
||||||
|
|
||||||
|
out vec4 vertex_color;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 model;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * model * vec4(pos, 1.0);
|
||||||
|
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
|
||||||
|
}
|
||||||
21
src/file.cpp
Normal file
21
src/file.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
std::string read_entire_file(const char *path) {
|
||||||
|
std::string content;
|
||||||
|
std::ifstream file_stream(path, std::ios::in);
|
||||||
|
|
||||||
|
if (!file_stream.is_open()) {
|
||||||
|
printf("Failed to read %s! File doesn't exist.", path);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line = "";
|
||||||
|
while (!file_stream.eof())
|
||||||
|
{
|
||||||
|
std::getline(file_stream, line);
|
||||||
|
content.append(line + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
file_stream.close();
|
||||||
|
return content;
|
||||||
|
}
|
||||||
7
src/file.h
Normal file
7
src/file.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
std::string read_entire_file(const char *path);
|
||||||
@ -1,23 +0,0 @@
|
|||||||
#include "geometry.h"
|
|
||||||
|
|
||||||
void create_triangle(GLuint *VAO, GLuint *VBO) {
|
|
||||||
GLfloat vertices[] = {
|
|
||||||
-1.0f, -1.0f, 0.0f,
|
|
||||||
1.0f, -1.0f, 0.0f,
|
|
||||||
0.0f, 1.0f, 0.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
glGenVertexArrays(1, VAO);
|
|
||||||
glBindVertexArray(*VAO);
|
|
||||||
|
|
||||||
glGenBuffers(1, VBO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, *VBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
// Unbinding
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <GL/glew.h>
|
|
||||||
|
|
||||||
void create_triangle(GLuint *VAO, GLuint *VBO);
|
|
||||||
164
src/main.cpp
164
src/main.cpp
@ -1,122 +1,88 @@
|
|||||||
#include <GL/glew.h>
|
#include "mesh.h"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <cmath>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
|
||||||
|
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "geometry.h"
|
|
||||||
#include "math.h"
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
// Window dimensions
|
|
||||||
|
static const char *vertex_shader_code = "shaders/shader.vert";
|
||||||
|
static const char *fragment_shader_code = "shaders/shader.frag";
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
GLuint VAO, VBO, shader_program, uniform_model;
|
Mesh *meshes[10] = {nullptr};
|
||||||
bool direction = true;
|
Shader shaders[10];
|
||||||
float tri_offset = 0.0f;
|
|
||||||
float tri_max_offset = 0.7f;
|
|
||||||
float tri_increment = 0.005f;
|
|
||||||
float current_angle = 0.0f;
|
|
||||||
bool size_direction = true;
|
|
||||||
float current_size = 0.4f;
|
|
||||||
float max_size = 0.9f;
|
|
||||||
float min_size = 0.1f;
|
|
||||||
|
|
||||||
Window window;
|
Window window;
|
||||||
bool success = setup_window(&window);
|
bool success = setup_window(&window);
|
||||||
|
|
||||||
Shader vertex_shader;
|
{
|
||||||
vertex_shader.type = VERTEX;
|
// Create a mesh
|
||||||
vertex_shader.raw_code = " \n\
|
f32 vertices[] = {
|
||||||
#version 330 \n\
|
-1.0f, -1.0f, 0.0f,
|
||||||
\n\
|
0.0f, -1.0f, 1.0f,
|
||||||
layout (location = 0) in vec3 pos; \n\
|
1.0f, -1.0f, 0.0f,
|
||||||
\n\
|
0.0f, 1.0f, 0.0f
|
||||||
uniform mat4 model; \n\
|
};
|
||||||
\n\
|
|
||||||
void main() { \n\
|
|
||||||
gl_Position = model * vec4(pos, 1.0); \n\
|
|
||||||
}";
|
|
||||||
|
|
||||||
Shader fragment_shader;
|
u32 indices[] = {
|
||||||
fragment_shader.type = FRAGMENT;
|
0, 3, 1,
|
||||||
fragment_shader.raw_code = " \n\
|
1, 3, 2,
|
||||||
#version 330 \n\
|
2, 3, 0,
|
||||||
\n\
|
0, 1, 2
|
||||||
out vec4 color; \n\
|
};
|
||||||
\n\
|
|
||||||
void main() { \n\
|
|
||||||
color = vec4(1.0, 0.0, 0.0, 1.0); \n\
|
|
||||||
}";
|
|
||||||
|
|
||||||
// Create our triangle
|
Mesh *triangle = new Mesh();
|
||||||
create_triangle(&VAO, &VBO);
|
create_mesh(triangle, vertices, indices, 12, 12);
|
||||||
compile_shaders(&shader_program, &uniform_model, &vertex_shader, &fragment_shader);
|
meshes[0] = triangle;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop until window is closed
|
{
|
||||||
while (!glfwWindowShouldClose(window.gl_window)) {
|
// Create a shader
|
||||||
// Get and handle user input events
|
Shader *shader = new Shader();
|
||||||
glfwPollEvents();
|
create_shader(shader, vertex_shader_code, fragment_shader_code);
|
||||||
|
shaders[0] = *shader;
|
||||||
|
}
|
||||||
|
|
||||||
if (direction) {
|
Matrix4 projection = glm::perspective(
|
||||||
tri_offset += tri_increment;
|
45.0f, (GLfloat)window.buffer_width / (GLfloat)window.buffer_height, 0.1f,
|
||||||
} else {
|
100.0f);
|
||||||
tri_offset -= tri_increment;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (std::abs(tri_offset) >= tri_max_offset) {
|
u32 uniform_projection = 0, uniform_model = 0;
|
||||||
direction = !direction;
|
f32 current_angle = 0.1f;
|
||||||
}
|
|
||||||
|
|
||||||
current_angle += 0.1f;
|
// Loop until window is closed
|
||||||
|
while (!glfwWindowShouldClose(window.gl_window)) {
|
||||||
|
// Get and handle user input events
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
// This isn't necessary except for safety reasons
|
// Clear window
|
||||||
// the program will still run correctly, but if left open too
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
// long the number will overflow.
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
if (current_angle >= 360) {
|
|
||||||
current_angle -= 360;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size_direction) {
|
glUseProgram(shaders[0].id);
|
||||||
current_size += 0.01f;
|
uniform_model = shaders[0].uniform_model;
|
||||||
} else {
|
uniform_projection = shaders[0].uniform_projection;
|
||||||
current_size -= 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_size >= max_size || current_size <= min_size) {
|
Matrix4 model(1.0f);
|
||||||
size_direction = !size_direction;
|
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
|
||||||
}
|
model = glm::rotate(model, current_angle * RADIAN_FACTOR, Vector3(0.0f, 1.0f, 0.0f));
|
||||||
|
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
|
||||||
|
|
||||||
// Clear window
|
current_angle += 0.5f;
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
glUseProgram(shader_program);
|
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
||||||
|
glUniformMatrix4fv(uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
|
||||||
|
|
||||||
Matrix4 model = Matrix4(1.0f);
|
render_mesh(meshes[0]);
|
||||||
// The order of these matter
|
|
||||||
model = glm::translate(model, Vector3(tri_offset, 0.0f, 0.0f));
|
|
||||||
model = glm::scale(model, Vector3(current_size, 0.4f, 1.0f));
|
|
||||||
model = glm::rotate(model, current_angle * RADIAN_FACTOR, Vector3(0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(model));
|
glUseProgram(0);
|
||||||
|
|
||||||
glBindVertexArray(VAO);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
// We usually have two buffers, the first is hidden and that's
|
||||||
glUseProgram(0);
|
// the one we draw to. The second is the one we display, so
|
||||||
|
// when we're done drawing we call this glfwSwapBuffers() to
|
||||||
|
// swap the buffers to show the one we've been drawing to so
|
||||||
|
// that it now shows. We then can start drawing on the other
|
||||||
|
// buffer.
|
||||||
|
glfwSwapBuffers(window.gl_window);
|
||||||
|
}
|
||||||
|
|
||||||
// We usually have two buffers, the first is hidden and that's
|
return 0;
|
||||||
// the one we draw to. The second is the one we display, so
|
|
||||||
// when we're done drawing we call this glfwSwapBuffers() to
|
|
||||||
// swap the buffers to show the one we've been drawing to so
|
|
||||||
// that it now shows. We then can start drawing on the other
|
|
||||||
// buffer.
|
|
||||||
glfwSwapBuffers(window.gl_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/math.h
31
src/math.h
@ -1,11 +1,38 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
// using u8 = uint8_t;
|
||||||
|
// using u16 = uint16_t;
|
||||||
|
// using u32 = uint32_t;
|
||||||
|
// using u64 = uint64_t;
|
||||||
|
|
||||||
|
// using i8 = int8_t;
|
||||||
|
// using i16 = int16_t;
|
||||||
|
// using i32 = int32_t;
|
||||||
|
// using i64 = int64_t;
|
||||||
|
|
||||||
|
typedef char unsigned u8;
|
||||||
|
typedef short unsigned u16;
|
||||||
|
typedef int unsigned u32;
|
||||||
|
typedef long long unsigned u64;
|
||||||
|
|
||||||
|
typedef char s8;
|
||||||
|
typedef short s16;
|
||||||
|
typedef int s32;
|
||||||
|
typedef long long s64;
|
||||||
|
|
||||||
|
typedef s32 b32;
|
||||||
|
|
||||||
|
typedef float f32;
|
||||||
|
typedef double f64;
|
||||||
|
|
||||||
|
#define array_count(Array) (sizeof(Array) / sizeof((Array)[0]))
|
||||||
|
|
||||||
using Matrix4 = glm::mat4;
|
using Matrix4 = glm::mat4;
|
||||||
using Vector3 = glm::vec3;
|
using Vector3 = glm::vec3;
|
||||||
|
|
||||||
const float RADIAN_FACTOR = 3.14159265f / 180.0f;
|
const f32 RADIAN_FACTOR = 3.14159265f / 180.0f;
|
||||||
|
|
||||||
|
|||||||
70
src/mesh.cpp
Normal file
70
src/mesh.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "mesh.h"
|
||||||
|
|
||||||
|
Mesh::Mesh() {
|
||||||
|
VAO = 0;
|
||||||
|
VBO = 0;
|
||||||
|
IBO = 0;
|
||||||
|
index_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::~Mesh() {
|
||||||
|
clear_mesh(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_mesh(
|
||||||
|
Mesh *mesh,
|
||||||
|
f32 *vertices,
|
||||||
|
u32 *indices,
|
||||||
|
u32 vertices_count,
|
||||||
|
u32 indices_count
|
||||||
|
) {
|
||||||
|
mesh->index_count = indices_count;
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &mesh->VAO);
|
||||||
|
glBindVertexArray(mesh->VAO);
|
||||||
|
|
||||||
|
glGenBuffers(1, &mesh->IBO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->IBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices_count, indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glGenBuffers(1, &mesh->VBO);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, mesh->VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices_count, vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
// Unbinding
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_mesh(Mesh *mesh) {
|
||||||
|
glBindVertexArray(mesh->VAO);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->IBO);
|
||||||
|
glDrawElements(GL_TRIANGLES, mesh->index_count, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
// Unbinding
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_mesh(Mesh *mesh) {
|
||||||
|
if (mesh->IBO != 0) {
|
||||||
|
glDeleteBuffers(1, &mesh->IBO);
|
||||||
|
mesh->IBO = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->VBO != 0) {
|
||||||
|
glDeleteBuffers(1, &mesh->VBO);
|
||||||
|
mesh->VBO = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->VAO != 0) {
|
||||||
|
glDeleteVertexArrays(1, &mesh->VAO);
|
||||||
|
mesh->VAO = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->index_count = 0;
|
||||||
|
}
|
||||||
17
src/mesh.h
Normal file
17
src/mesh.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "math.h"
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
struct Mesh {
|
||||||
|
u32 VAO, VBO, IBO;
|
||||||
|
u32 index_count;
|
||||||
|
|
||||||
|
Mesh();
|
||||||
|
~Mesh();
|
||||||
|
};
|
||||||
|
|
||||||
|
void create_mesh(Mesh *mesh, f32 *vertices, u32 *indices, u32 vertices_count, u32 indices_count);
|
||||||
|
void render_mesh(Mesh *mesh);
|
||||||
|
void clear_mesh(Mesh *mesh);
|
||||||
|
|
||||||
@ -28,3 +28,9 @@ Creating a Shader program
|
|||||||
6. Link program (creates executables from shaders and links them together).
|
6. Link program (creates executables from shaders and links them together).
|
||||||
7. Validate program (because things run on the GPU it's harder to debug).
|
7. Validate program (because things run on the GPU it's harder to debug).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Projections: Coordinate systems
|
||||||
|
- Local space: raw position of each vertex draw relative to origin.
|
||||||
|
- World space: position in the word itself if camery is assumed to be positioned at the origin.
|
||||||
|
|
||||||
|
|||||||
160
src/shader.cpp
160
src/shader.cpp
@ -1,66 +1,106 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
|
||||||
bool add_shader(GLuint *program, Shader *shader) {
|
Shader::Shader() {
|
||||||
shader->gl = glCreateShader(shader->type);
|
id = 0;
|
||||||
const GLchar *code[1];
|
uniform_projection = 0;
|
||||||
code[0] = shader->raw_code;
|
uniform_model = 0;
|
||||||
|
|
||||||
GLint code_length[1];
|
|
||||||
code_length[0] = strlen(shader->raw_code);
|
|
||||||
|
|
||||||
glShaderSource(shader->gl, 1, code, code_length);
|
|
||||||
glCompileShader(shader->gl);
|
|
||||||
|
|
||||||
GLint result = 0;
|
|
||||||
GLchar errors[1024] = { 0 };
|
|
||||||
|
|
||||||
glGetShaderiv(shader->gl, GL_COMPILE_STATUS, &result);
|
|
||||||
if (!result) {
|
|
||||||
glGetShaderInfoLog(shader->gl, sizeof(errors), NULL, errors);
|
|
||||||
printf("Error compiling the %d shader->gl: '%s'\n", shader->type, errors);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
glAttachShader(*program, shader->gl);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compile_shaders(GLuint *program, GLuint *uniform_model, Shader *vertex_shader, Shader *fragment_shader) {
|
Shader::~Shader() {
|
||||||
*program = glCreateProgram();
|
clear_shader(this);
|
||||||
|
}
|
||||||
if (!program) {
|
|
||||||
printf("Error creating shader program!\n");
|
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path) {
|
||||||
return false;
|
std::string vertex_shader_code = read_entire_file(vertex_shader_path);
|
||||||
}
|
std::string fragment_shader_code = read_entire_file(fragment_shader_path);
|
||||||
|
|
||||||
add_shader(program, vertex_shader);
|
|
||||||
add_shader(program, fragment_shader);
|
shader->id = glCreateProgram();
|
||||||
|
|
||||||
GLint result = 0;
|
if (!shader) {
|
||||||
GLchar errors[1024] = { 0 };
|
printf("Error creating shader shader!\n");
|
||||||
|
return false;
|
||||||
glLinkProgram(*program);
|
}
|
||||||
glGetProgramiv(*program, GL_LINK_STATUS, &result);
|
|
||||||
|
{
|
||||||
if (!result) {
|
bool success = add_shader(shader, vertex_shader_code.c_str(), VERTEX);
|
||||||
glGetProgramInfoLog(*program, sizeof(errors), NULL, errors);
|
|
||||||
printf("Error linking program: '%s'\n", errors);
|
if (!success) {
|
||||||
return false;
|
printf("Error adding vertex shader");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
glValidateProgram(*program);
|
}
|
||||||
glGetProgramiv(*program, GL_VALIDATE_STATUS, &result);
|
|
||||||
|
{
|
||||||
if (!result) {
|
bool success = add_shader(shader, fragment_shader_code.c_str(), FRAGMENT);
|
||||||
glGetProgramInfoLog(*program, sizeof(errors), NULL, errors);
|
|
||||||
printf("Error validating program: '%s'\n", errors);
|
if (!success) {
|
||||||
return false;
|
printf("Error adding fragment shader");
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
*uniform_model = glGetUniformLocation(*program, "model");
|
}
|
||||||
|
|
||||||
return true;
|
s32 result = 0;
|
||||||
|
s8 errors[1024] = {0};
|
||||||
|
|
||||||
|
glLinkProgram(shader->id);
|
||||||
|
glGetProgramiv(shader->id, GL_LINK_STATUS, &result);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors);
|
||||||
|
printf("Error linking shader: '%s'\n", errors);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glValidateProgram(shader->id);
|
||||||
|
glGetProgramiv(shader->id, GL_VALIDATE_STATUS, &result);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
glGetProgramInfoLog(shader->id, sizeof(errors), NULL, errors);
|
||||||
|
printf("Error validating shader: '%s'\n", errors);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->uniform_projection = glGetUniformLocation(shader->id, "projection");
|
||||||
|
shader->uniform_model = glGetUniformLocation(shader->id, "model");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_shader(Shader *shader, const char *shader_code, Shader_Type shader_type) {
|
||||||
|
u32 _shader = glCreateShader(shader_type);
|
||||||
|
|
||||||
|
const char *code[1];
|
||||||
|
code[0] = shader_code;
|
||||||
|
|
||||||
|
int code_length[1];
|
||||||
|
code_length[0] = strlen(shader_code);
|
||||||
|
|
||||||
|
glShaderSource(_shader, 1, code, code_length);
|
||||||
|
glCompileShader(_shader);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
char errors[1024] = {0};
|
||||||
|
|
||||||
|
glGetShaderiv(_shader, GL_COMPILE_STATUS, &result);
|
||||||
|
if (!result) {
|
||||||
|
glGetShaderInfoLog(_shader, sizeof(errors), NULL, errors);
|
||||||
|
printf("Error compiling the %d shader->id: '%s'\n", shader_type, errors);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glAttachShader(shader->id, _shader);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_shader(Shader *shader) {
|
||||||
|
if (shader->id != 0) {
|
||||||
|
glDeleteProgram(shader->id);
|
||||||
|
shader->id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->uniform_model = 0;
|
||||||
|
shader->uniform_projection = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
src/shader.h
19
src/shader.h
@ -2,18 +2,23 @@
|
|||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
#include "math.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
enum Shader_Type : unsigned int {
|
enum Shader_Type : u32 {
|
||||||
VERTEX = GL_VERTEX_SHADER,
|
VERTEX = GL_VERTEX_SHADER,
|
||||||
FRAGMENT = GL_FRAGMENT_SHADER
|
FRAGMENT = GL_FRAGMENT_SHADER
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
Shader_Type type;
|
u32 id;
|
||||||
const char *raw_code;
|
u32 uniform_projection;
|
||||||
GLuint gl;
|
u32 uniform_model;
|
||||||
|
|
||||||
|
Shader();
|
||||||
|
~Shader();
|
||||||
};
|
};
|
||||||
|
|
||||||
bool add_shader(GLuint *program, Shader *shader, const char *raw_code);
|
bool create_shader(Shader *shader, const char *vertex_shader_path, const char *fragment_shader_path);
|
||||||
|
bool add_shader(Shader *shader, const char *shader_code, Shader_Type type);
|
||||||
bool compile_shaders(GLuint *shader_program, GLuint *uniform_model, Shader *vertex_shader, Shader *fragment_shader);
|
void clear_shader(Shader *shader);
|
||||||
|
|||||||
@ -1,67 +1,60 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <cmath>
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
bool setup_window(Window *window) {
|
bool setup_window(Window *window) {
|
||||||
// Initialize GLFW
|
// Initialize GLFW
|
||||||
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
|
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
|
||||||
|
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
printf("GLFW initialization failed!");
|
printf("GLFW initialization failed!");
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup GLFW window properties
|
// Setup GLFW window properties
|
||||||
// OpenGL version
|
// OpenGL version
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||||
// Core profile means it will not be backwards compatible
|
// Core profile means it will not be backwards compatible
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||||
|
|
||||||
window->gl_window = glfwCreateWindow(window->width, window->height, "Test Window", NULL, NULL);
|
window->gl_window = glfwCreateWindow(window->width, window->height, "Test Window", NULL, NULL);
|
||||||
|
|
||||||
if (!window) {
|
if (!window) {
|
||||||
const char *desc;
|
const char *desc;
|
||||||
int code = glfwGetError(&desc);
|
int code = glfwGetError(&desc);
|
||||||
printf("GLFW window creation failed!");
|
printf("GLFW window creation failed!");
|
||||||
printf("GLFW error code: %d, description: %s\n", code, desc ? desc : "No description given");
|
printf("GLFW error code: %d, description: %s\n", code,
|
||||||
glfwTerminate();
|
desc ? desc : "No description given");
|
||||||
return false;
|
glfwTerminate();
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Get Buffer size information
|
// Get Buffer size information
|
||||||
int buffer_width, buffer_height;
|
glfwGetFramebufferSize(window->gl_window, &window->buffer_width, &window->buffer_height);
|
||||||
glfwGetFramebufferSize(window->gl_window, &buffer_width, &buffer_height);
|
|
||||||
|
|
||||||
// Set context for GLEW to use
|
// Set context for GLEW to use
|
||||||
glfwMakeContextCurrent(window->gl_window);
|
glfwMakeContextCurrent(window->gl_window);
|
||||||
|
|
||||||
glGetError();
|
glGetError();
|
||||||
|
|
||||||
// Allow modern extension features
|
// Allow modern extension features
|
||||||
glewExperimental = GL_TRUE;
|
glewExperimental = GL_TRUE;
|
||||||
|
|
||||||
GLenum err = glewInit();
|
GLenum err = glewInit();
|
||||||
if (err != GLEW_OK && err != GLEW_ERROR_NO_GLX_DISPLAY) {
|
if (err != GLEW_OK && err != GLEW_ERROR_NO_GLX_DISPLAY) {
|
||||||
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
|
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||||
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
|
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
|
||||||
printf("glewInit() returned: %d\n", err);
|
printf("glewInit() returned: %d\n", err);
|
||||||
glfwDestroyWindow(window->gl_window);
|
glfwDestroyWindow(window->gl_window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup viewport size
|
glEnable(GL_DEPTH_TEST);
|
||||||
glViewport(0, 0, buffer_width, buffer_height);
|
|
||||||
|
|
||||||
return true;
|
// Setup viewport size
|
||||||
|
glViewport(0, 0, window->buffer_width, window->buffer_height);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
struct Window {
|
struct Window {
|
||||||
GLint width = 800, height = 600;
|
u32 width = 800, height = 600;
|
||||||
|
s32 buffer_width, buffer_height;
|
||||||
GLFWwindow *gl_window = nullptr;
|
GLFWwindow *gl_window = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user