Initial commit. Did not add some dependencies as they will be dropped.

This commit is contained in:
Relintai 2023-12-18 17:06:11 +01:00
commit 492acd0c26
37 changed files with 1956 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
bin/
obj/
*.layout
*.depend
# These are tmeporary:
libs/
*.bmp

19
LICENSE.txt Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2023-present Péter Magyar.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# SFW - Simple Framework

121
application.cpp Normal file
View File

@ -0,0 +1,121 @@
#include "application.h"
#include <chrono>
void Application::event(const SDL_Event &ev) {
if (ev.type == SDL_QUIT) {
running = false;
}
scene->event(ev);
}
void Application::update(float delta) {
scene->update(delta);
}
void Application::render() {
scene->render();
SDL_GL_SwapWindow(window);
}
void Application::main_loop() {
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
//handle input
SDL_Event current_event;
while (SDL_PollEvent(&current_event)) {
event(current_event);
}
//update_world
update(frame_delta);
//render
render();
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
double t = elapsed_seconds.count();
double tfps = 1.0 / static_cast<float>(target_fps);
double remaining = tfps - t;
if (remaining > 0) {
Uint32 fms = static_cast<Uint32>(remaining * 1000.0);
frame_delta = tfps;
SDL_Delay(fms);
} else {
frame_delta = t;
}
}
Application::Application() {
_instance = this;
running = true;
target_fps = 60;
scene = NULL;
frame_delta = 0;
SDL_SetMainReady();
int error = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
if (error) {
SDL_Log("SDL_Init fail: %s\n", SDL_GetError());
running = false;
return;
}
#if defined(_WIN64) || defined(_WIN32)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
#else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
#endif
window = SDL_CreateWindow("SDL + OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
if (!window) {
SDL_Log("SDL_CreateWindow Failed! %s\n", SDL_GetError());
running = false;
return;
}
context = SDL_GL_CreateContext(window);
#if defined(_WIN64) || defined(_WIN32)
gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress);
#endif // defined
printf("%s\n", glGetString(GL_VERSION));
}
Application::~Application() {
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
}
Application *Application::get_singleton() {
return _instance;
}
Application * Application::_instance = NULL;

38
application.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef APPLICATION_H
#define APPLICATION_H
#include <stdio.h>
#include <SDL.h>
#include "opengl.h"
#include "scene.h"
class Application {
public:
bool running;
int target_fps;
virtual void event(const SDL_Event &ev);
virtual void update(float delta);
virtual void render();
void main_loop();
Application();
virtual ~Application();
Scene *scene;
SDL_Window *window;
SDL_GLContext context;
static Application *get_singleton();
double frame_delta;
protected:
static Application * _instance;
};
#endif // APPLICATION_H

73
camera.cpp Normal file
View File

@ -0,0 +1,73 @@
#include "camera.h"
#include "./libs/glm/gtc/matrix_transform.hpp"
void Camera::bind() {
make_current();
model_view_matrix = glm::mat4(1);
}
void Camera::make_current() {
current_camera = this;
}
Camera::Camera() {
width = 2;
height = 2;
fov = glm::radians(45.0);
position = glm::vec3(0, 0, 0);
rotation = glm::vec3(0, 0, 0);
scale = glm::vec3(1, 1, 1);
}
Camera::~Camera() {
}
Camera* Camera::current_camera = NULL;
void OrthographicCamera::bind() {
Camera::bind();
projection_matrix = glm::ortho<float>(-(width / 2.0),
width / 2.0,
-(height / 2.0),
height / 2.0);
projection_matrix = glm::translate(projection_matrix, -position);
projection_matrix = glm::rotate(projection_matrix, rotation.x, glm::vec3(1, 0, 0));
projection_matrix = glm::rotate(projection_matrix, rotation.y, glm::vec3(0, 1, 0));
projection_matrix = glm::rotate(projection_matrix, rotation.z, glm::vec3(0, 0, 1));
projection_matrix = glm::scale(projection_matrix, scale);
}
OrthographicCamera::OrthographicCamera() : Camera() {
}
OrthographicCamera::~OrthographicCamera() {
}
void PerspectiveCamera::bind() {
Camera::bind();
projection_matrix = glm::perspectiveFov<float>(fov, width, height, near, far);
projection_matrix = glm::translate(projection_matrix, -position);
projection_matrix = glm::rotate(projection_matrix, rotation.x, glm::vec3(1, 0, 0));
projection_matrix = glm::rotate(projection_matrix, rotation.y, glm::vec3(0, 1, 0));
projection_matrix = glm::rotate(projection_matrix, rotation.z, glm::vec3(0, 0, 1));
projection_matrix = glm::scale(projection_matrix, scale);
}
PerspectiveCamera::PerspectiveCamera() : Camera() {
near = 0.1;
far = 10;
}
PerspectiveCamera::~PerspectiveCamera() {
}

51
camera.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef CAMERA_H
#define CAMERA_H
#include "opengl.h"
#include "./libs/glm/vec3.hpp"
#include "./libs/glm/matrix.hpp"
class Camera {
public:
virtual void bind();
void make_current();
Camera();
virtual ~Camera();
float width;
float height;
float fov;
glm::vec3 position;
glm::vec3 rotation;
glm::vec3 scale;
static Camera* current_camera;
glm::mat4x4 projection_matrix;
glm::mat4x4 model_view_matrix;
};
class OrthographicCamera : public Camera {
public:
void bind();
OrthographicCamera();
~OrthographicCamera();
};
class PerspectiveCamera : public Camera {
public:
float near;
float far;
void bind();
PerspectiveCamera();
~PerspectiveCamera();
};
#endif // CAMERA_H

73
colored_material.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef COLORED_MATERIAL_H
#define COLORED_MATERIAL_H
#include "material.h"
#include "./libs/glm/vec4.hpp"
#include "./libs/glm/gtc/type_ptr.hpp"
#include "camera.h"
class ColoredMaterial : public Material {
public:
int get_material_id() {
return 1;
}
void bind_uniforms() {
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
glUniform4f(tri_color_uniform_location, color.r, color.g, color.b, color.a);
}
void setup_uniforms() {
projection_matrix_location = get_uniform("u_proj_matrix");
model_view_matrix_location = get_uniform("u_model_view_matrix");
tri_color_uniform_location = get_uniform("fragment_color");
}
const GLchar **get_vertex_shader_source() {
static const GLchar *vertex_shader_source[] = {
"uniform mat4 u_proj_matrix;\n"
"uniform mat4 u_model_view_matrix;\n"
"\n"
"attribute vec4 a_position;\n"
"\n"
"void main() {\n"
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
"}"
};
return vertex_shader_source;
}
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform vec4 fragment_color;\n"
"\n"
"void main() {\n"
" gl_FragColor = fragment_color;\n"
"}"
};
return fragment_shader_source;
}
ColoredMaterial() : Material() {
color = glm::vec4(1, 1, 1, 1);
}
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint tri_color_uniform_location;
glm::vec4 color;
};
#endif // COLORED_MATERIAL_H

7
compile_linux.sh Executable file
View File

@ -0,0 +1,7 @@
#clang++ main.cpp -Wall -o3 -o ./bin/game -Ilibs/SDL2-linux/include -Llibs/SDL2-linux/lib -lSDL2 -lSDL2main
#g++ main.cpp -Wall -o3 -o ./bin/game -Ilibs/SDL2-linux/include -Llibs/SDL2-linux/lib -lSDL2 -lSDL2main
g++ main.cpp -Wall -o3 -o ./game $(pkg-config --cflags --libs sdl2 glew)

5
compile_mingw_x64.bat Executable file
View File

@ -0,0 +1,5 @@
rem -g -> debug symbols
rem -o[0-3] -> optimization
rem -Wall -> all warning
g++ main.cpp ./libs/glad/src/glad.c -Wall -o3 -o ./game.exe -Ilibs/SDL2-mingw/include -Llibs/SDL2-mingw/lib/x64 -Ilibs/glad/include -lSDL2 -lSDL2main -lOpengl32

5
compile_mingw_x86.bat Executable file
View File

@ -0,0 +1,5 @@
rem -g -> debug symbols
rem -o[0-3] -> optimization
rem -Wall -> all warning
g++ main.cpp ./libs/glad/src/glad.c -Wall -o3 -o ./game.exe -Ilibs/SDL2-mingw/include -Llibs/SDL2-mingw/lib/x86 -Ilibs/glad/include -lSDL2 -lSDL2main -lOpengl32

20
game_application.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef GAME_APPLICATION_H
#define GAME_APPLICATION_H
#include "application.h"
#include "game_scene.h"
class GameApplication : public Application {
public:
GameApplication() : Application() {
scene = new GameScene();
}
~GameApplication() {
delete scene;
}
};
#endif // GAME_APPLICATION_H

141
game_scene.cpp Normal file
View File

@ -0,0 +1,141 @@
#include "game_scene.h"
#include "application.h"
void GameScene::event(const SDL_Event &ev) {
switch (ev.type) {
case SDL_WINDOWEVENT: {
switch (ev.window.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED: {
int width = ev.window.data1;
int height = ev.window.data2;
float ar = static_cast<float>(width) / static_cast<float>(height);
camera->width = camera->height * ar;
glViewport(0, 0, width, height);
} break;
}
} break;
case SDL_KEYDOWN: {
if (ev.key.keysym.scancode == SDL_SCANCODE_A) {
left = true;
} else if (ev.key.keysym.scancode == SDL_SCANCODE_W) {
up = true;
} else if (ev.key.keysym.scancode == SDL_SCANCODE_S) {
down = true;
} else if (ev.key.keysym.scancode == SDL_SCANCODE_D) {
right = true;
}
} break;
case SDL_KEYUP: {
if (ev.key.keysym.scancode == SDL_SCANCODE_A) {
left = false;
} else if (ev.key.keysym.scancode == SDL_SCANCODE_W) {
up = false;
} else if (ev.key.keysym.scancode == SDL_SCANCODE_S) {
down = false;
} else if (ev.key.keysym.scancode == SDL_SCANCODE_D) {
right = false;
}
} break;
}
}
void GameScene::update(float delta) {
if (up) {
sprite->position.y += delta * 3.0;
}
if (down) {
sprite->position.y -= delta * 3.0;
}
if (left) {
sprite->position.x -= delta * 3.0;
}
if (right) {
sprite->position.x += delta * 3.0;
}
if (sprite->position.x < 1.5) {
sprite->position.x = 1.5;
}
if (sprite->position.x > 14.5) {
sprite->position.x = 14.5;
}
if (sprite->position.y < 1.5) {
sprite->position.y = 1.5;
}
if (sprite->position.y > 14.5) {
sprite->position.y = 14.5;
}
}
void GameScene::render() {
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
camera->bind();
sprite->render();
}
GameScene::GameScene() {
left = false;
right = false;
up = false;
down = false;
camera = new OrthographicCamera();
camera->width = 16;
camera->height = 16;
camera->position.x = 8;
camera->position.y = 8;
//camera->position.z = -2;
int w;
int h;
SDL_GetWindowSize(Application::get_singleton()->window, &w, &h);
float ar = static_cast<float>(w) / static_cast<float>(h);
camera->width = camera->height * ar;
texture = new Texture();
texture->load_image("download.bmp");
material = new TextureMaterial();
material->texture = texture;
sprite = new Sprite();
sprite->mesh_instance->material = material;
sprite->height = 1;
sprite->width = 1;
sprite->position.x = 8;
sprite->position.y = 8;
float region_x = 7;
float region_y = 7;
sprite->region_x = region_x * (1.0 / 16.0);
sprite->region_y = region_y * (1.0 / 16.0);
sprite->region_width = 1.0 / 16.0;
sprite->region_height = 1.0 / 16.0;
sprite->update_mesh();
}
GameScene::~GameScene() {
delete camera;
delete sprite;
delete material;
}

35
game_scene.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef GAME_SCENE_H
#define GAME_SCENE_H
#include "scene.h"
#include "colored_material.h"
#include "camera.h"
#include "mesh.h"
#include "mesh_instance.h"
#include "sprite.h"
#include "texture_material.h"
#include "texture.h"
class GameScene : public Scene {
public:
virtual void event(const SDL_Event &ev);
virtual void update(float delta);
virtual void render();
GameScene();
~GameScene();
bool left;
bool right;
bool up;
bool down;
OrthographicCamera *camera;
Sprite *sprite;
Texture *texture;
TextureMaterial *material;
};
#endif // GAME_SCENE_H

37
main.cpp Normal file
View File

@ -0,0 +1,37 @@
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif // __EMSCRIPTEN__
#include "application.h"
#include "game_application.h"
//érdekesség
//https://gist.github.com/reduz/9635c731f0592d7e526367c6063b8f8f
//https://gist.github.com/reduz/9b9d1278848237fd9a9a8b6cc77c8270
//https://github.com/reduz/larvita3
Application *application = NULL;
void handle_frame() {
application->main_loop();
}
int main(int argc, char** argv)
{
application = new GameApplication();
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(handle_frame, 0, 1);
#else
while (application->running) {
application->main_loop();
}
delete application;
#endif // __EMSCRIPTEN__
return 0;
}

63
material.cpp Normal file
View File

@ -0,0 +1,63 @@
#include "material.h"
#include <stdio.h>
void Material::bind() {
//csak main thread!
if (!shader) {
shader = ShaderCache::get_singleton()->get_shader(get_material_id());
if (!shader) {
shader = new Shader();
shader->set_vertex_shader_source(get_vertex_shader_source());
shader->set_fragment_shader_source(get_fragment_shader_source());
shader->compile();
ShaderCache::get_singleton()->add_shader(get_material_id(), shader);
}
setup_uniforms();
}
if (current_material && current_material != this) {
current_material->unbind();
setup_state();
}
current_material = this;
shader->bind();
bind_uniforms();
}
void Material::unbind() {
}
void Material::bind_uniforms() {
}
void Material::setup_uniforms() {
}
void Material::setup_state() {
}
GLint Material::get_uniform(const char* name) {
GLint uniform = glGetUniformLocation(shader->program, name);
if (uniform == -1) {
printf("%s is not a valid glsl program variable!\n", name);
}
return uniform;
}
Material::Material() {
shader = NULL;
}
Material::~Material() {
}
Material *Material::current_material = NULL;

31
material.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef MATERIAL_H
#define MATERIAL_H
#include "opengl.h"
#include "shader.h"
class Material {
public:
void bind();
virtual void unbind();
virtual int get_material_id() = 0;
virtual void bind_uniforms();
virtual void setup_uniforms();
virtual void setup_state();
virtual const GLchar **get_vertex_shader_source() = 0;
virtual const GLchar **get_fragment_shader_source() = 0;
GLint get_uniform(const char* name);
Material();
virtual ~Material();
protected:
static Material *current_material;
Shader * shader;
};
#endif // MATERIAL_H

187
mesh.cpp Normal file
View File

@ -0,0 +1,187 @@
#include "mesh.h"
#include "shader.h"
void Mesh::add_vertex2(float x, float y) {
vertices.push_back(x);
vertices.push_back(y);
}
void Mesh::add_vertex3(float x, float y, float z) {
vertices.push_back(x);
vertices.push_back(y);
vertices.push_back(z);
}
void Mesh::add_normal(float x, float y, float z) {
normals.push_back(x);
normals.push_back(y);
normals.push_back(z);
}
void Mesh::add_color(float r, float g, float b, float a) {
colors.push_back(r);
colors.push_back(g);
colors.push_back(b);
colors.push_back(a);
}
void Mesh::add_uv(float u, float v) {
uvs.push_back(u);
uvs.push_back(v);
}
void Mesh::add_index(uint32_t index) {
indices.push_back(index);
}
void Mesh::add_triangle(uint32_t i1, uint32_t i2, uint32_t i3) {
indices.push_back(i1);
indices.push_back(i2);
indices.push_back(i3);
}
void Mesh::clear() {
vertices.clear();
normals.clear();
colors.clear();
uvs.clear();
indices.clear();
}
void Mesh::upload() {
if (vertices.size() == 0) {
return;
}
if (!VBO) {
glGenBuffers(1, &VBO);
}
vertices_vbo_size = sizeof(float) * vertices.size();
normals_vbo_size = sizeof(float) * normals.size();
colors_vbo_size = sizeof(float) * colors.size();
uvs_vbo_size = sizeof(float) * uvs.size();
indices_vbo_size = sizeof(float) * indices.size();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size + colors_vbo_size + uvs_vbo_size, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_vbo_size, &vertices[0]);
if (normals_vbo_size > 0) {
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size, normals_vbo_size, &normals[0]);
}
if (colors_vbo_size > 0) {
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size, colors_vbo_size, &colors[0]);
}
if (uvs_vbo_size > 0) {
glBufferSubData(GL_ARRAY_BUFFER, vertices_vbo_size + normals_vbo_size + colors_vbo_size, uvs_vbo_size, &uvs[0]);
}
if (indices_vbo_size > 0) {
if (!IBO) {
glGenBuffers(1, &IBO);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_vbo_size, &indices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void Mesh::destroy() {
if (VBO) {
glDeleteBuffers(1, &VBO);
VBO = 0;
}
if (IBO) {
glDeleteBuffers(1, &IBO);
IBO = 0;
}
}
void Mesh::render() {
if (vertices.size() == 0) {
return;
}
if (!Shader::current_shader) {
return;
}
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(Shader::ATTRIBUTE_POSITION, vertex_dimesions, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(Shader::ATTRIBUTE_POSITION);
if (normals_vbo_size > 0) {
glVertexAttribPointer(Shader::ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertices_vbo_size));
glEnableVertexAttribArray(Shader::ATTRIBUTE_NORMAL);
}
if (colors_vbo_size > 0) {
glVertexAttribPointer(Shader::ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_FALSE, 0, (void*)(vertices_vbo_size + normals_vbo_size));
glEnableVertexAttribArray(Shader::ATTRIBUTE_COLOR);
}
if (uvs_vbo_size > 0) {
glVertexAttribPointer(Shader::ATTRIBUTE_UV, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertices_vbo_size + normals_vbo_size + colors_vbo_size));
glEnableVertexAttribArray(Shader::ATTRIBUTE_UV);
}
if (indices_vbo_size > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (GLvoid*)0);
} else {
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
}
glDisableVertexAttribArray(Shader::ATTRIBUTE_POSITION);
if (normals_vbo_size > 0) {
glDisableVertexAttribArray(Shader::ATTRIBUTE_NORMAL);
}
if (colors_vbo_size > 0) {
glDisableVertexAttribArray(Shader::ATTRIBUTE_COLOR);
}
if (uvs_vbo_size > 0) {
glDisableVertexAttribArray(Shader::ATTRIBUTE_UV);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
Mesh::Mesh() {
VBO = 0;
IBO = 0;
vertex_dimesions = 3;
vertices_vbo_size = 0;
normals_vbo_size = 0;
colors_vbo_size = 0;
uvs_vbo_size = 0;
indices_vbo_size = 0;
}
Mesh::Mesh(int vert_dim) {
VBO = 0;
IBO = 0;
vertex_dimesions = vert_dim;
vertices_vbo_size = 0;
normals_vbo_size = 0;
colors_vbo_size = 0;
uvs_vbo_size = 0;
indices_vbo_size = 0;
}
Mesh::~Mesh() {
destroy();
clear();
}

51
mesh.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef MESH_H
#define MESH_H
#include <vector>
#include <inttypes.h>
#include "opengl.h"
class Mesh {
public:
void add_vertex2(float x, float y);
void add_vertex3(float x, float y, float z);
void add_normal(float x, float y, float z);
void add_color(float r = 1, float g = 1, float b = 1, float a = 1);
void add_uv(float u, float v);
void add_index(uint32_t index);
void add_triangle(uint32_t i1, uint32_t i2, uint32_t i3);
void clear();
void upload();
void destroy();
void render();
Mesh();
Mesh(int vert_dim);
virtual ~Mesh();
GLuint VBO;
GLuint IBO;
int vertex_dimesions;
std::vector<float> vertices;
std::vector<float> normals;
std::vector<float> colors;
std::vector<float> uvs;
std::vector<uint32_t> indices;
protected:
uint32_t vertices_vbo_size;
uint32_t normals_vbo_size;
uint32_t colors_vbo_size;
uint32_t uvs_vbo_size;
uint32_t indices_vbo_size;
};
#endif // MESH_H

53
mesh_instance.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "mesh_instance.h"
#include "camera.h"
#include "./libs/glm/vec3.hpp"
#include "./libs/glm/matrix.hpp"
#include "./libs/glm/gtc/matrix_transform.hpp"
void MeshInstance::render() {
if (!mesh) {
return;
}
glm::mat4 mat_orig = Camera::current_camera->model_view_matrix;
Camera::current_camera->model_view_matrix = glm::translate(Camera::current_camera->model_view_matrix, position);
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation.x, glm::vec3(1, 0, 0));
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation.y, glm::vec3(0, 1, 0));
Camera::current_camera->model_view_matrix = glm::rotate(Camera::current_camera->model_view_matrix, rotation.z, glm::vec3(0, 0, 1));
Camera::current_camera->model_view_matrix = glm::scale(Camera::current_camera->model_view_matrix, scale);
if (material) {
material->bind();
}
mesh->render();
for (uint32_t i = 0; i < children.size(); ++i) {
MeshInstance * c = children[i];
if (c) {
c->render();
}
}
Camera::current_camera->model_view_matrix = mat_orig;
}
MeshInstance::MeshInstance() {
material = NULL;
mesh = NULL;
position = glm::vec3(0, 0, 0);
rotation = glm::vec3(0, 0, 0);
scale = glm::vec3(1, 1, 1);
}
MeshInstance::~MeshInstance() {
children.clear();
}

29
mesh_instance.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef MESH_INSTACE_H
#define MESH_INSTACE_H
#include <vector>
#include "opengl.h"
#include "material.h"
#include "mesh.h"
#include "./libs/glm/vec3.hpp"
class MeshInstance {
public:
void render();
MeshInstance();
~MeshInstance();
Material *material;
Mesh *mesh;
glm::vec3 position;
glm::vec3 rotation;
glm::vec3 scale;
std::vector<MeshInstance *> children;
};
#endif // MESH_INSTACE_H

11
object_2d.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "object_2d.h"
Object2D::Object2D() {
position = glm::vec2(0, 0);
rotation = 0;
scale = glm::vec2(1, 1);
}
Object2D::~Object2D() {
}

17
object_2d.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef OBJECT_2D_H
#define OBJECT_2D_H
#include "./libs/glm/vec2.hpp"
class Object2D {
public:
Object2D();
virtual ~Object2D();
glm::vec2 position;
float rotation;
glm::vec2 scale;
};
#endif // OBJECT_2D_h

18
opengl.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef OPENGL_H
#define OPENGL_H
#if defined(__unix__) && !defined(__ANDROID__)
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#endif // __unix__
#if __ANDROID__
#define GL_GLEXT_PROTOTYPES
#include <GLES2/gl2.h>
#endif
#if defined(_WIN64) || defined(_WIN32)
#include <glad/glad.h>
#endif // defined
#endif // OPENGL_H

7
scene.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "scene.h"
Scene::Scene() {
}
Scene::~Scene() {
}

16
scene.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef SCENE_H
#define SCENE_H
#include <SDL.h>
class Scene {
public:
virtual void event(const SDL_Event &ev) = 0;
virtual void update(float delta) = 0;
virtual void render() = 0;
Scene();
virtual ~Scene();
};
#endif // APPLICATION_H

71
sdl_linux.cbp Normal file
View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="sdl_linux" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/sdl_linux" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/sdl_linux" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add option="`pkg-config --cflags sdl2 glew`" />
<Add directory="libs/imgui/" />
</Compiler>
<Linker>
<Add option="`pkg-config --cflags --libs sdl2 glew`" />
</Linker>
<Unit filename="application.cpp" />
<Unit filename="application.h" />
<Unit filename="camera.cpp" />
<Unit filename="camera.h" />
<Unit filename="colored_material.h" />
<Unit filename="game_application.h" />
<Unit filename="game_scene.cpp" />
<Unit filename="game_scene.h" />
<Unit filename="main.cpp" />
<Unit filename="material.cpp" />
<Unit filename="material.h" />
<Unit filename="mesh.cpp" />
<Unit filename="mesh.h" />
<Unit filename="mesh_instance.cpp" />
<Unit filename="mesh_instance.cpp/" />
<Unit filename="mesh_instance.h" />
<Unit filename="object_2d.cpp" />
<Unit filename="object_2d.h" />
<Unit filename="opengl.h" />
<Unit filename="scene.cpp" />
<Unit filename="scene.h" />
<Unit filename="shader.cpp" />
<Unit filename="shader.h" />
<Unit filename="sprite.cpp" />
<Unit filename="sprite.h" />
<Unit filename="texture.cpp" />
<Unit filename="texture.h" />
<Unit filename="texture_material.h" />
<Unit filename="transparent_texture_material.h" />
<Extensions />
</Project>
</CodeBlocks_project_file>

86
sdl_opengl_win_x64.cbp Executable file
View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="sdl_alap_projekt" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/sdl_alap_projekt" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/sdl_alap_projekt" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add directory="libs/SDL2-mingw/include/SDL2/" />
<Add directory="libs/glad/include/" />
</Compiler>
<Linker>
<Add library="mingw32" />
<Add library="SDL2main" />
<Add library="SDL2" />
<Add library="Opengl32" />
<Add library="dxguid" />
<Add library="winmm" />
<Add library="gdi32" />
<Add library="user32" />
<Add directory="libs/SDL2-mingw/lib/x64" />
</Linker>
<ExtraCommands>
<Add after="XCOPY libs\SDL2-mingw\lib\x64\*.dll $(TARGET_OUTPUT_DIR) /D /Y" />
</ExtraCommands>
<Unit filename="application.cpp" />
<Unit filename="application.h" />
<Unit filename="camera.cpp" />
<Unit filename="camera.h" />
<Unit filename="colored_material.h" />
<Unit filename="game_application.h" />
<Unit filename="game_scene.cpp" />
<Unit filename="game_scene.h" />
<Unit filename="libs/glad/src/glad.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="main.cpp" />
<Unit filename="material.cpp" />
<Unit filename="material.h" />
<Unit filename="mesh.cpp" />
<Unit filename="mesh.h" />
<Unit filename="mesh_instance.cpp" />
<Unit filename="mesh_instance.h" />
<Unit filename="object_2d.cpp" />
<Unit filename="object_2d.h" />
<Unit filename="opengl.h" />
<Unit filename="scene.cpp" />
<Unit filename="scene.h" />
<Unit filename="shader.cpp" />
<Unit filename="shader.h" />
<Unit filename="sprite.cpp" />
<Unit filename="sprite.h" />
<Unit filename="texture.cpp" />
<Unit filename="texture.h" />
<Unit filename="texture_material.h" />
<Unit filename="transparent_texture_material.h" />
<Extensions>
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>

84
sdl_windows.cbp Normal file
View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="sdl_windows" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/sdl_windows" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/sdl_windows" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
<Add option="-fexceptions" />
<Add directory="libs/SDL2-mingw/include/SDL2/" />
<Add directory="libs/glad/include/" />
</Compiler>
<Linker>
<Add library="mingw32" />
<Add library="SDL2main" />
<Add library="SDL2.dll" />
<Add library="Opengl32" />
<Add library="dxguid" />
<Add library="winmm" />
<Add library="gdi32" />
<Add library="user32" />
<Add directory="libs/SDL2-mingw/lib/x86/" />
</Linker>
<ExtraCommands>
<Add after="XCOPY libs\SDL2-mingw\lib\x86\*.dll $(TARGET_OUTPUT_DIR) /D /Y" />
</ExtraCommands>
<Unit filename="application.cpp" />
<Unit filename="application.h" />
<Unit filename="camera.cpp" />
<Unit filename="camera.h" />
<Unit filename="colored_material.h" />
<Unit filename="game_application.h" />
<Unit filename="game_scene.cpp" />
<Unit filename="game_scene.h" />
<Unit filename="libs/glad/src/glad.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="main.cpp" />
<Unit filename="material.cpp" />
<Unit filename="material.h" />
<Unit filename="mesh.cpp" />
<Unit filename="mesh.h" />
<Unit filename="mesh_instance.cpp" />
<Unit filename="mesh_instance.h" />
<Unit filename="object_2d.cpp" />
<Unit filename="object_2d.h" />
<Unit filename="opengl.h" />
<Unit filename="scene.cpp" />
<Unit filename="scene.h" />
<Unit filename="shader.cpp" />
<Unit filename="shader.h" />
<Unit filename="sprite.cpp" />
<Unit filename="sprite.h" />
<Unit filename="texture.cpp" />
<Unit filename="texture.h" />
<Unit filename="texture_material.h" />
<Unit filename="transparent_texture_material.h" />
<Extensions />
</Project>
</CodeBlocks_project_file>

171
shader.cpp Normal file
View File

@ -0,0 +1,171 @@
#include "shader.h"
#include <vector>
#include <stdio.h>
bool Shader::bind() {
if (current_shader != this) {
glUseProgram(program);
current_shader = this;
return true;
}
return false;
}
void Shader::unbind() {
if (current_shader == this) {
glUseProgram(0);
current_shader = NULL;
}
}
void Shader::compile() {
if (!program) {
program = glCreateProgram();
}
if (!vertex_shader) {
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
}
if (!fragment_shader) {
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
}
const GLchar **vertex_shader_source = get_vertex_shader_source();
glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
glCompileShader(vertex_shader);
GLint shader_compiled = GL_FALSE;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &shader_compiled);
if (shader_compiled != GL_TRUE) {
print_shader_errors(vertex_shader, "compiling Vertex Shader");
return;
}
glAttachShader(program, vertex_shader);
const GLchar **fragment_shader_source = get_fragment_shader_source();
glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
glCompileShader(fragment_shader);
shader_compiled = GL_FALSE;
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_compiled);
if (shader_compiled != GL_TRUE) {
print_shader_errors(fragment_shader, "compiling Fragment Shader");
return;
}
glAttachShader(program, fragment_shader);
glBindAttribLocation(program, ATTRIBUTE_POSITION, "a_position");
glBindAttribLocation(program, ATTRIBUTE_NORMAL, "a_normal");
glBindAttribLocation(program, ATTRIBUTE_COLOR, "a_color");
glBindAttribLocation(program, ATTRIBUTE_UV, "a_uv");
glLinkProgram(program);
GLint program_compiled = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &program_compiled);
if (program_compiled != GL_TRUE) {
print_program_errors(program);
return;
}
}
void Shader::destroy() {
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
glDeleteProgram(program);
}
const GLchar **Shader::get_vertex_shader_source() {
return vertex_shader_source;
}
void Shader::set_vertex_shader_source(const GLchar **source) {
vertex_shader_source = source;
}
const GLchar **Shader::get_fragment_shader_source() {
return fragment_shader_source;
}
void Shader::set_fragment_shader_source(const GLchar **source) {
fragment_shader_source = source;
}
void Shader::print_shader_errors(const GLuint p_program, const char *name) {
int max_length = 5000;
std::vector<GLchar> error_log(max_length);
glGetShaderInfoLog(p_program, max_length, &max_length, &error_log[0]);
printf("Error %s!\n", name);
printf("%s!\n", &error_log[0]);
}
void Shader::print_program_errors(const GLuint p_program) {
if (glIsProgram(program)) {
int info_length = 0;
int max_length = 5000;
glGetProgramiv(p_program, GL_INFO_LOG_LENGTH, &info_length);
char *info_log = new char[max_length];
glGetProgramInfoLog(p_program, max_length, &info_length, info_log);
if (info_length > 0) {
printf("%s\n", info_log);
}
delete[] info_log;
} else {
printf("print_program_errors: Not a program!\n");
}
}
Shader::Shader() {
vertex_shader = 0;
fragment_shader = 0;
program = 0;
vertex_shader_source = NULL;
fragment_shader_source = NULL;
}
Shader::~Shader() {
destroy();
}
Shader *Shader::current_shader = NULL;
//Meyers singleton
//thread safe
ShaderCache *ShaderCache::get_singleton() {
static ShaderCache instance;
return &instance;
}
Shader *ShaderCache::get_shader(const int id) {
return shaders[id];
}
void ShaderCache::add_shader(const int id, Shader *shader) {
shaders[id] = shader;
}
ShaderCache::ShaderCache() {
}
ShaderCache::~ShaderCache() {
for (const std::pair<int, Shader *> n : shaders) {
delete n.second;
}
shaders.clear();
}

60
shader.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef SHADER_H
#define SHADER_H
#include "opengl.h"
#include <unordered_map>
class Shader {
public:
enum VertexAttributes {
ATTRIBUTE_POSITION = 0,
ATTRIBUTE_NORMAL,
ATTRIBUTE_COLOR,
ATTRIBUTE_UV,
};
bool bind();
void unbind();
void compile();
void destroy();
const GLchar **get_vertex_shader_source();
void set_vertex_shader_source(const GLchar **source);
const GLchar **get_fragment_shader_source();
void set_fragment_shader_source(const GLchar **source);
void print_shader_errors(const GLuint p_program, const char *name);
void print_program_errors(const GLuint p_program);
Shader();
~Shader();
GLuint vertex_shader;
GLuint fragment_shader;
GLuint program;
static Shader * current_shader;
protected:
const GLchar **vertex_shader_source;
const GLchar **fragment_shader_source;
};
class ShaderCache {
public:
static ShaderCache *get_singleton();
Shader *get_shader(const int id);
void add_shader(const int id, Shader *shader);
ShaderCache();
~ShaderCache();
protected:
std::unordered_map<int, Shader *> shaders;
};
#endif // SHADER_H

61
sprite.cpp Normal file
View File

@ -0,0 +1,61 @@
#include "sprite.h"
void Sprite::render() {
mesh_instance->position.x = position.x;
mesh_instance->position.y = position.y;
mesh_instance->rotation.z = rotation;
mesh_instance->scale.x = scale.x;
mesh_instance->scale.y = scale.y;
mesh_instance->render();
}
void Sprite::update_mesh() {
Mesh *mesh = mesh_instance->mesh;
mesh->clear();
float w2 = width / 2.0;
float h2 = height / 2.0;
mesh->add_uv(region_x, region_y);
mesh->add_vertex2(-w2, h2);
mesh->add_uv(region_x + region_width, region_y + region_height);
mesh->add_vertex2(w2, -h2);
mesh->add_uv(region_x, region_y + region_height);
mesh->add_vertex2(-w2, -h2);
mesh->add_uv(region_x + region_width, region_y);
mesh->add_vertex2(w2, h2);
mesh->add_triangle(1, 0, 2);
mesh->add_triangle(0, 1, 3);
mesh->upload();
}
Sprite::Sprite() : Object2D() {
mesh_instance = new MeshInstance();
mesh_instance->mesh = new Mesh(2);
width = 1;
height = 1;
region_x = 0;
region_y = 0;
region_width = 1;
region_height = 1;
}
Sprite::~Sprite() {
delete mesh_instance->mesh;
delete mesh_instance;
}

28
sprite.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef SPRITE_H
#define SPRITE_H
#include "object_2d.h"
#include "mesh_instance.h"
class Sprite : public Object2D {
public:
void render();
void update_mesh();
Sprite();
~Sprite();
MeshInstance *mesh_instance;
float width;
float height;
float region_x;
float region_y;
float region_width;
float region_height;
};
#endif // SPRITE_H

51
texture.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "texture.h"
#include <stdio.h>
void Texture::load_image(const char * file_name, const int format, const int internal_components) {
if (image) {
SDL_FreeSurface(image);
image = NULL;
glDeleteTextures(1, &texture);
}
SDL_Surface *img = SDL_LoadBMP(file_name);
if (!img) {
printf("Couldn't load %s.\n", file_name);
} else {
image = SDL_ConvertSurfaceFormat(img, SDL_PIXELFORMAT_RGBA32, 0);
SDL_FreeSurface(img);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, format, image->w, image->h, 0, internal_components, GL_UNSIGNED_BYTE, image->pixels);
apply_filter();
}
}
void Texture::apply_filter() {
GLint params = GL_NEAREST;
if (filter == TEXTURE_FILTER_LINEAR) {
params = GL_LINEAR;
}
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, params);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, params);
}
Texture::Texture() {
filter = TEXTURE_FILTER_NEAREST;
texture = 0;
image = NULL;
}
Texture::~Texture() {
if (image) {
SDL_FreeSurface(image);
glDeleteTextures(1, &texture);
}
}

25
texture.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef TEXTURE_H
#define TEXTURE_H
#include "opengl.h"
#include <SDL.h>
class Texture {
public:
enum TextureFilter {
TEXTURE_FILTER_NEAREST = 0,
TEXTURE_FILTER_LINEAR,
};
void load_image(const char * file_name, const int format = GL_RGBA, const int internal_components = GL_RGBA);
void apply_filter();
TextureFilter filter;
GLuint texture;
SDL_Surface *image;
Texture();
virtual ~Texture();
};
#endif // TEXTURE_H

94
texture_material.h Normal file
View File

@ -0,0 +1,94 @@
#ifndef TEXTURE_MATERIAL_H
#define TEXTURE_MATERIAL_H
#include "material.h"
#include "texture.h"
#include "./libs/glm/vec4.hpp"
#include "./libs/glm/gtc/type_ptr.hpp"
#include "camera.h"
class TextureMaterial : public Material {
public:
int get_material_id() {
return 3;
}
void bind_uniforms() {
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
if (texture) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->texture);
glUniform1i(texture_location, 0);
}
}
void setup_uniforms() {
projection_matrix_location = get_uniform("u_proj_matrix");
model_view_matrix_location = get_uniform("u_model_view_matrix");
texture_location = get_uniform("u_texture");
}
void unbind() {
glDisable(GL_TEXTURE_2D);
}
void setup_state() {
glEnable(GL_TEXTURE_2D);
}
const GLchar **get_vertex_shader_source() {
static const GLchar *vertex_shader_source[] = {
"uniform mat4 u_proj_matrix;\n"
"uniform mat4 u_model_view_matrix;\n"
"\n"
"attribute vec4 a_position;\n"
"attribute vec2 a_uv;\n"
"\n"
"varying vec2 v_uv;\n"
"\n"
"void main() {\n"
" v_uv = a_uv;\n"
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
"}"
};
return vertex_shader_source;
}
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform sampler2D u_texture;\n"
"\n"
"varying vec2 v_uv;\n"
"\n"
"void main() {\n"
" gl_FragColor = texture2D(u_texture, v_uv);\n"
"}"
};
return fragment_shader_source;
}
TextureMaterial() : Material() {
texture_location = 0;
texture = NULL;
}
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint texture_location;
Texture *texture;
};
#endif // COLORED_MATERIAL_H

View File

@ -0,0 +1,100 @@
#ifndef TRANSPARENT_TEXTURE_MATERIAL_H
#define TRANSPARENT_TEXTURE_MATERIAL_H
#include "material.h"
#include "texture.h"
#include "./libs/glm/vec4.hpp"
#include "./libs/glm/gtc/type_ptr.hpp"
#include "camera.h"
class TransparentTextureMaterial : public Material {
public:
int get_material_id() {
return 4;
}
void bind_uniforms() {
glUniformMatrix4fv(projection_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->projection_matrix));
glUniformMatrix4fv(model_view_matrix_location, 1, GL_FALSE, glm::value_ptr(Camera::current_camera->model_view_matrix));
if (texture) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->texture);
glUniform1i(texture_location, 0);
}
}
void setup_uniforms() {
projection_matrix_location = get_uniform("u_proj_matrix");
model_view_matrix_location = get_uniform("u_model_view_matrix");
texture_location = get_uniform("u_texture");
}
void unbind() {
glDisable(GL_TEXTURE_2D);
}
void setup_state() {
glEnable(GL_TEXTURE_2D);
}
const GLchar **get_vertex_shader_source() {
static const GLchar *vertex_shader_source[] = {
"uniform mat4 u_proj_matrix;\n"
"uniform mat4 u_model_view_matrix;\n"
"\n"
"attribute vec4 a_position;\n"
"attribute vec2 a_uv;\n"
"\n"
"varying vec2 v_uv;\n"
"\n"
"void main() {\n"
" v_uv = a_uv;\n"
" gl_Position = u_proj_matrix * u_model_view_matrix * a_position;\n"
"}"
};
return vertex_shader_source;
}
const GLchar **get_fragment_shader_source() {
static const GLchar *fragment_shader_source[] = {
"precision mediump float;\n"
"\n"
"uniform sampler2D u_texture;\n"
"\n"
"varying vec2 v_uv;\n"
"\n"
"void main() {\n"
" vec4 col = texture2D(u_texture, v_uv);\n"
"\n"
" if (col.a < 0.1) {\n"
" discard;\n"
" }\n"
"\n"
" gl_FragColor = col;\n"
"}"
};
return fragment_shader_source;
}
TransparentTextureMaterial() : Material() {
texture_location = 0;
texture = NULL;
}
GLint projection_matrix_location;
GLint model_view_matrix_location;
GLint texture_location;
Texture *texture;
};
#endif // COLORED_MATERIAL_H