05: refactor code and implement dynamic buffers
This commit is contained in:
parent
67aa648299
commit
8455ffac2e
|
@ -1,6 +1,6 @@
|
||||||
CC=g++
|
CC=g++
|
||||||
CFLAGS=`pkg-config --cflags glfw3 glew`
|
CFLAGS=-std=c++20 `pkg-config --cflags glfw3 glew glm`
|
||||||
LDFLAGS=`pkg-config --libs glfw3 glew`
|
LDFLAGS=`pkg-config --libs glfw3 glew glm`
|
||||||
INCLUDE=/usr/include/stb/
|
INCLUDE=/usr/include/stb/
|
||||||
TARGET=opengl
|
TARGET=opengl
|
||||||
SDIR=src
|
SDIR=src
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 38 KiB |
BIN
05-opengl/assets/player/idle.png
Normal file
BIN
05-opengl/assets/player/idle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
05-opengl/assets/player/run.png
Normal file
BIN
05-opengl/assets/player/run.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
|
@ -6,6 +6,7 @@ uniform sampler2D texture1;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
color = texture(texture1, tex_coord);
|
color = texture(texture1, tex_coord);
|
||||||
|
// color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
if (color.a < 0.1)
|
if (color.a < 0.1)
|
||||||
discard;
|
discard;
|
|
@ -1,11 +0,0 @@
|
||||||
#version 330 core
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 pos;
|
|
||||||
layout (location = 1) in vec2 texture_coord;
|
|
||||||
|
|
||||||
out vec2 tex_coord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(pos.xyz, 1.0);
|
|
||||||
tex_coord = texture_coord;
|
|
||||||
}
|
|
20
05-opengl/assets/shaders/vertex.glsl
Normal file
20
05-opengl/assets/shaders/vertex.glsl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 pos;
|
||||||
|
layout (location = 1) in vec2 texture_coord;
|
||||||
|
|
||||||
|
uniform vec3 size;
|
||||||
|
uniform ivec3 offset;
|
||||||
|
uniform mat4 model;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
out vec2 tex_coord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 new_pos = pos.xyz + offset.xyz;
|
||||||
|
new_pos = new_pos.xyz * size.xyz;
|
||||||
|
|
||||||
|
gl_Position = projection * view * model * vec4(new_pos.xyz, 1.0);
|
||||||
|
tex_coord = texture_coord;
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 251 KiB |
22
05-opengl/src/common.cpp
Normal file
22
05-opengl/src/common.cpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
std::string read_file(const char *path) {
|
||||||
|
std::string content;
|
||||||
|
std::ifstream fs(path, std::ios::in);
|
||||||
|
|
||||||
|
if(!fs.is_open()) {
|
||||||
|
std::cerr << "Error: Could not read file " << path << ". File does not exist." << std::endl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line = "";
|
||||||
|
while(!fs.eof()) {
|
||||||
|
std::getline(fs, line);
|
||||||
|
content.append(line + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.close();
|
||||||
|
return content;
|
||||||
|
}
|
5
05-opengl/src/common.hpp
Normal file
5
05-opengl/src/common.hpp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string read_file(const char *path);
|
|
@ -2,69 +2,52 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/mat4x4.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
#include "object.hpp"
|
#include "sprite.hpp"
|
||||||
#include "other/stb_image.h"
|
#include "other/stb_image.h"
|
||||||
|
|
||||||
Game::Game(GLFWwindow *window) {
|
Game::Game(GLFWwindow *window) {
|
||||||
this->window = window;
|
this->window = window;
|
||||||
this->program = glCreateProgram();
|
this->program = Program();
|
||||||
|
stbi_set_flip_vertically_on_load(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::setup() {
|
// code this later lol
|
||||||
}
|
int Game::setup(int initial_width, int initial_height) {
|
||||||
|
|
||||||
void Game::run(int initial_width, int initial_height) {
|
|
||||||
glfwSetKeyCallback(this->window, Game::input_callback);
|
glfwSetKeyCallback(this->window, Game::input_callback);
|
||||||
glfwSetFramebufferSizeCallback(this->window, Game::resize_callback);
|
glfwSetFramebufferSizeCallback(this->window, Game::resize_callback);
|
||||||
|
|
||||||
Game::resize_callback(this->window, initial_width, initial_height);
|
Game::resize_callback(this->window, initial_width, initial_height);
|
||||||
|
|
||||||
this->vshader = Game::load_shader("assets/shaders/shader.vert", GL_VERTEX_SHADER);
|
int ret = this->program.add_shader("assets/shaders/vertex.glsl", GL_VERTEX_SHADER);
|
||||||
if (!this->vshader)
|
if (ret != 0) {
|
||||||
return;
|
std::cout << "Error: failed adding vertex shader" << std::endl;
|
||||||
|
return -1;
|
||||||
this->fshader = Game::load_shader("assets/shaders/shader.frag", GL_FRAGMENT_SHADER);
|
|
||||||
if (!this->fshader)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Game::link_program())
|
|
||||||
return;
|
|
||||||
|
|
||||||
stbi_set_flip_vertically_on_load(true);
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int channels;
|
|
||||||
unsigned char *image_bytes = stbi_load("assets/wall.jpg", &width, &height, &channels, 0);
|
|
||||||
if (image_bytes == NULL) {
|
|
||||||
std::cout << "Error: failed loading image data" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture new_texture;
|
ret = this->program.add_shader("assets/shaders/fragment.glsl", GL_FRAGMENT_SHADER);
|
||||||
new_texture.bind_texture();
|
if (ret != 0) {
|
||||||
new_texture.load_data(image_bytes, width, height);
|
std::cout << "Error: failed adding fragment shader" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
stbi_image_free(image_bytes);
|
if (this->program.link() != 0) {
|
||||||
|
std::cout << "Error: failed linking program" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
Object new_object(this, new_texture);
|
glUseProgram(this->program.id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
new_object.vertices = {
|
void Game::run() {
|
||||||
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
Sprite sprite("assets/player/idle.png", SPLIT_TEXTURE);
|
||||||
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
sprite.bake();
|
||||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
this->sprites.push_back(&sprite);
|
||||||
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
new_object.indices = {
|
|
||||||
0, 1, 3,
|
|
||||||
1, 2, 3
|
|
||||||
};
|
|
||||||
|
|
||||||
new_object.bake();
|
|
||||||
this->objects.push_back(&new_object);
|
|
||||||
|
|
||||||
Game::logic();
|
Game::logic();
|
||||||
}
|
}
|
||||||
|
@ -91,8 +74,8 @@ void Game::logic() {
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
for (int i = 0; i < this->objects.size(); i++)
|
for (int i = 0; i < this->sprites.size(); i++)
|
||||||
(*this->objects[i]).draw();
|
Game::draw(this->sprites[i]);
|
||||||
|
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
glfwSwapBuffers(this->window);
|
glfwSwapBuffers(this->window);
|
||||||
|
@ -101,64 +84,44 @@ void Game::logic() {
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Game::load_shader(const char *path, unsigned int type) {
|
void Game::draw(Sprite *sprite) {
|
||||||
std::string source = Game::read_file(path);
|
unsigned int program = this->program.id;
|
||||||
const char *bytes = source.c_str();
|
glUseProgram(program);
|
||||||
|
|
||||||
unsigned int new_shader = glCreateShader(type);
|
glUniform3i(glGetUniformLocation(program, "offset"), sprite->pos.x, sprite->pos.y, sprite->pos.z);
|
||||||
if (!new_shader)
|
glUniform3f(glGetUniformLocation(program, "size"), sprite->size.x, sprite->size.y, sprite->size.z);
|
||||||
return 0;
|
glUniform1i(glGetUniformLocation(program, "texture1"), 0);
|
||||||
|
|
||||||
glShaderSource(new_shader, 1, &bytes, NULL);
|
glm::mat4 model = glm::mat4(1.0f);
|
||||||
glCompileShader(new_shader);
|
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
int success;
|
glm::mat4 view = glm::mat4(1.0f);
|
||||||
char info_log[512];
|
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||||
glGetShaderiv(new_shader, GL_COMPILE_STATUS, &success);
|
|
||||||
|
|
||||||
if (!success) {
|
glm::mat4 projection = glm::mat4(1.0f);
|
||||||
glGetShaderInfoLog(new_shader, 512, NULL, info_log);
|
|
||||||
std::cout << "Error: failed compiling new shader " << info_log << std::endl;
|
int width, height;
|
||||||
return 0;
|
float half_width, half_height;
|
||||||
|
glfwGetWindowSize(this->window, &width, &height);
|
||||||
|
|
||||||
|
half_width = (float) width / 2;
|
||||||
|
half_height = (float) height / 2;
|
||||||
|
|
||||||
|
projection = glm::ortho(-half_width/100, half_width/100, -half_height/100, half_height/100, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(program, "model"), 1, GL_FALSE, glm::value_ptr(model));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(program,"view"), 1, GL_FALSE, glm::value_ptr(view));
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||||
|
|
||||||
|
glBindVertexArray(sprite->vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, sprite->vbo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sprite->ebo);
|
||||||
|
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(struct vertex) * sprite->vertices.size(), sprite->vertices.data());
|
||||||
|
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * sprite->indices.size(), sprite->indices.data());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sprite->texture.texture_id);
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES, sprite->indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Game::link_program() {
|
|
||||||
glAttachShader(this->program, this->vshader);
|
|
||||||
glAttachShader(this->program, this->fshader);
|
|
||||||
glLinkProgram(this->program);
|
|
||||||
|
|
||||||
int success;
|
|
||||||
char info_log[512];
|
|
||||||
glGetProgramiv(this->program, GL_LINK_STATUS, &success);
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
glGetProgramInfoLog(this->program, 512, NULL, info_log);
|
|
||||||
std::cout << "Error: failed linking program " << info_log << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Game::read_file(const char *path) {
|
|
||||||
std::string content;
|
|
||||||
std::ifstream fs(path, std::ios::in);
|
|
||||||
|
|
||||||
if(!fs.is_open()) {
|
|
||||||
std::cerr << "Error: Could not read file " << path << ". File does not exist." << std::endl;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string line = "";
|
|
||||||
while(!fs.eof()) {
|
|
||||||
std::getline(fs, line);
|
|
||||||
content.append(line + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.close();
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,16 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include "object.hpp"
|
#include "program.hpp"
|
||||||
|
#include "sprite.hpp"
|
||||||
|
|
||||||
class Game {
|
class Game {
|
||||||
public:
|
public:
|
||||||
Game(GLFWwindow *window);
|
Game(GLFWwindow *window);
|
||||||
static std::string read_file(const char *path);
|
int setup(int initial_width, int initial_height);
|
||||||
unsigned int load_shader(const char *path, unsigned int type);
|
void run();
|
||||||
int link_program();
|
|
||||||
void setup();
|
|
||||||
void run(int initial_width, int initial_height);
|
|
||||||
void logic();
|
void logic();
|
||||||
|
void draw(Sprite *sprite);
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
static void input_callback(GLFWwindow *window, int key, int scancode, int action, int mods);
|
static void input_callback(GLFWwindow *window, int key, int scancode, int action, int mods);
|
||||||
|
@ -21,13 +20,7 @@ public:
|
||||||
|
|
||||||
GLFWwindow *window;
|
GLFWwindow *window;
|
||||||
|
|
||||||
std::vector<Object*> objects;
|
std::vector<Sprite *> sprites;
|
||||||
|
|
||||||
unsigned int vao;
|
Program program;
|
||||||
unsigned int vbo;
|
|
||||||
unsigned int ebo;
|
|
||||||
|
|
||||||
unsigned int vshader;
|
|
||||||
unsigned int fshader;
|
|
||||||
unsigned int program;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,8 +32,8 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Game main_game(window);
|
Game main_game(window);
|
||||||
|
main_game.setup(initial_width, initial_height);
|
||||||
main_game.run(initial_width, initial_height);
|
main_game.run();
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include <GL/glew.h>
|
|
||||||
#include "game.hpp"
|
|
||||||
#include "object.hpp"
|
|
||||||
|
|
||||||
Object::Object(Game *game, Texture texture) {
|
|
||||||
this->texture = texture;
|
|
||||||
this->game = game;
|
|
||||||
|
|
||||||
glGenVertexArrays(1, &this->vao);
|
|
||||||
glGenBuffers(1, &this->vbo);
|
|
||||||
glGenBuffers(1, &this->ebo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Object::bake() {
|
|
||||||
glBindVertexArray(this->vao);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(float), &this->vertices[0], GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(int), &this->indices[0], GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *) 0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8*sizeof(float), (void *) (6 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Object::draw() {
|
|
||||||
glUseProgram(this->game->program);
|
|
||||||
|
|
||||||
glUniform1i(glGetUniformLocation(this->game->program, "texture1"), 0);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, this->texture.texture_id);
|
|
||||||
|
|
||||||
glBindVertexArray(this->vao);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
|
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "texture.hpp"
|
|
||||||
|
|
||||||
class Game;
|
|
||||||
class Texture;
|
|
||||||
|
|
||||||
class Object {
|
|
||||||
public:
|
|
||||||
Object(Game *game, Texture texture);
|
|
||||||
|
|
||||||
void bake();
|
|
||||||
void draw();
|
|
||||||
|
|
||||||
Texture texture;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
|
|
||||||
std::vector<float> vertices;
|
|
||||||
std::vector<int> indices;
|
|
||||||
|
|
||||||
unsigned int vao;
|
|
||||||
unsigned int vbo;
|
|
||||||
unsigned int ebo;
|
|
||||||
|
|
||||||
Game *game;
|
|
||||||
};
|
|
38
05-opengl/src/program.cpp
Normal file
38
05-opengl/src/program.cpp
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "program.hpp"
|
||||||
|
|
||||||
|
Program::Program() {
|
||||||
|
this->id = glCreateProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Program::add_shader(const char *path, unsigned int type) {
|
||||||
|
Shader new_shader;
|
||||||
|
unsigned int ret = new_shader.load(path, type);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
this->shaders.push_back(new_shader);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Program::link() {
|
||||||
|
for (int shader = 0; shader < this->shaders.size(); shader++)
|
||||||
|
glAttachShader(this->id, this->shaders[shader].id);
|
||||||
|
|
||||||
|
glLinkProgram(this->id);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char info_log[512];
|
||||||
|
glGetProgramiv(this->id, GL_LINK_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
glGetProgramInfoLog(this->id, 512, NULL, info_log);
|
||||||
|
std::cout << "Error: failed linking program. " << info_log << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
13
05-opengl/src/program.hpp
Normal file
13
05-opengl/src/program.hpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "shader.hpp"
|
||||||
|
|
||||||
|
struct Program {
|
||||||
|
unsigned int id;
|
||||||
|
std::vector<Shader> shaders;
|
||||||
|
|
||||||
|
Program();
|
||||||
|
int add_shader(const char *path, unsigned int type);
|
||||||
|
int link();
|
||||||
|
};
|
31
05-opengl/src/shader.cpp
Normal file
31
05-opengl/src/shader.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include "shader.hpp"
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
unsigned int Shader::load(const char *path, unsigned int type) {
|
||||||
|
std::string source_s = read_file(path);
|
||||||
|
const char *source = source_s.c_str();
|
||||||
|
|
||||||
|
unsigned int new_shader = glCreateShader(type);
|
||||||
|
if (!new_shader)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
glShaderSource(new_shader, 1, &source, NULL);
|
||||||
|
glCompileShader(new_shader);
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char info_log[512];
|
||||||
|
glGetShaderiv(new_shader, GL_COMPILE_STATUS, &success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
glGetShaderInfoLog(new_shader, 512, NULL, info_log);
|
||||||
|
std::cout << "Error: failed compiling new shader " << info_log << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->id = new_shader;
|
||||||
|
this->type = type;
|
||||||
|
|
||||||
|
return new_shader;
|
||||||
|
}
|
8
05-opengl/src/shader.hpp
Normal file
8
05-opengl/src/shader.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct Shader {
|
||||||
|
unsigned int id;
|
||||||
|
unsigned int type;
|
||||||
|
|
||||||
|
unsigned int load(const char *path, unsigned int type);
|
||||||
|
};
|
79
05-opengl/src/sprite.cpp
Normal file
79
05-opengl/src/sprite.cpp
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <stb/stb_image.h>
|
||||||
|
#include "game.hpp"
|
||||||
|
#include "sprite.hpp"
|
||||||
|
|
||||||
|
Sprite::Sprite(const char *path, enum TextureType type) : texture(type) {
|
||||||
|
int image_width;
|
||||||
|
int image_height;
|
||||||
|
int image_resolution;
|
||||||
|
int image_channels;
|
||||||
|
|
||||||
|
unsigned char *image_bytes = stbi_load(path, &image_width, &image_height, &image_channels, 0);
|
||||||
|
if (image_bytes == NULL) {
|
||||||
|
std::cout << "Error: failed loading image data" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->texture.bind_texture();
|
||||||
|
this->texture.load_data(image_bytes, image_width, image_height, image_height);
|
||||||
|
|
||||||
|
stbi_image_free(image_bytes);
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &this->vao);
|
||||||
|
glGenBuffers(1, &this->vbo);
|
||||||
|
glGenBuffers(1, &this->ebo);
|
||||||
|
|
||||||
|
this->pos = glm::vec3(0.0f);
|
||||||
|
this->size = glm::vec3(1.0f);
|
||||||
|
this->rot = glm::vec3(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::bake() {
|
||||||
|
struct vertex v1 = { {0.5f, 0.5f, 0.0f}, {1.0f, 1.0f} };
|
||||||
|
struct vertex v2 = { {0.5f, -0.5f, 0.0f}, {1.0f, 0.0f} };
|
||||||
|
struct vertex v3 = { {-0.5f, -0.5f, 0.0f}, {0.0f, 0.0f} };
|
||||||
|
struct vertex v4 = { {-0.5f, 0.5f, 0.0f}, {0.0f, 1.0f} };
|
||||||
|
|
||||||
|
this->vertices.push_back(v1);
|
||||||
|
this->vertices.push_back(v2);
|
||||||
|
this->vertices.push_back(v3);
|
||||||
|
this->vertices.push_back(v4);
|
||||||
|
|
||||||
|
this->indices = {
|
||||||
|
0, 1, 3,
|
||||||
|
1, 2, 3
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture &tex = this->texture;
|
||||||
|
if (tex.type == SPLIT_TEXTURE) {
|
||||||
|
for (int i = 0; i < this->vertices.size(); i++) {
|
||||||
|
struct vertex *v = &this->vertices[i];
|
||||||
|
|
||||||
|
float tex_x = ((tex.cell_x + v->texture[0]) * tex.cell_res) / tex.texture_width;
|
||||||
|
float tex_y = ((tex.cell_y + v->texture[1]) * tex.cell_res) / tex.texture_height;
|
||||||
|
|
||||||
|
v->texture[0] = tex_x;
|
||||||
|
v->texture[1] = tex_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(this->vao);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(struct vertex), nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(int), nullptr, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void *) offsetof(vertex, position));
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void *) offsetof(vertex, texture));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
33
05-opengl/src/sprite.hpp
Normal file
33
05-opengl/src/sprite.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
|
#include "texture.hpp"
|
||||||
|
|
||||||
|
class Game;
|
||||||
|
class Texture;
|
||||||
|
|
||||||
|
struct vertex {
|
||||||
|
float position[3];
|
||||||
|
float texture[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
class Sprite {
|
||||||
|
public:
|
||||||
|
Texture texture;
|
||||||
|
|
||||||
|
glm::vec3 pos;
|
||||||
|
glm::vec3 size;
|
||||||
|
glm::vec3 rot;
|
||||||
|
|
||||||
|
std::vector<struct vertex> vertices;
|
||||||
|
std::vector<int> indices;
|
||||||
|
|
||||||
|
unsigned int vao;
|
||||||
|
unsigned int vbo;
|
||||||
|
unsigned int ebo;
|
||||||
|
|
||||||
|
Game *game;
|
||||||
|
|
||||||
|
Sprite(const char *path, enum TextureType type);
|
||||||
|
void bake();
|
||||||
|
};
|
|
@ -1,8 +1,12 @@
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
|
|
||||||
Texture::Texture() {
|
Texture::Texture(enum TextureType type) {
|
||||||
glGenTextures(1, &this->texture_id);
|
glGenTextures(1, &this->texture_id);
|
||||||
|
this->type = type;
|
||||||
|
this->cell_x = 0;
|
||||||
|
this->cell_y = 0;
|
||||||
|
this->cell_res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::bind_texture() {
|
void Texture::bind_texture() {
|
||||||
|
@ -11,11 +15,15 @@ void Texture::bind_texture() {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::load_data(unsigned char *bytes, int width, int height) {
|
void Texture::load_data(unsigned char *bytes, int width, int height, int cell_res) {
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
this->texture_width = width;
|
||||||
|
this->texture_height = height;
|
||||||
|
this->cell_res = cell_res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
enum TextureType {
|
||||||
|
FULL_TEXTURE,
|
||||||
|
SPLIT_TEXTURE,
|
||||||
|
DYNAMIC_TEXTURE
|
||||||
|
};
|
||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
unsigned int texture_id;
|
unsigned int texture_id;
|
||||||
|
|
||||||
Texture();
|
Texture(enum TextureType type);
|
||||||
void bind_texture();
|
void bind_texture();
|
||||||
void load_data(unsigned char *bytes, int width, int height);
|
void load_data(unsigned char *bytes, int width, int height, int cell_res);
|
||||||
|
|
||||||
|
enum TextureType type;
|
||||||
|
int texture_width;
|
||||||
|
int texture_height;
|
||||||
|
int cell_res;
|
||||||
|
|
||||||
|
int cell_x;
|
||||||
|
int cell_y;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user