Compare commits
No commits in common. "7a218edcceb5b582a1d5d2104f30fb1fd4e575a7" and "ce0f93a572c8095e2bd3a165993aae952dbaccaf" have entirely different histories.
7a218edcce
...
ce0f93a572
1
.gitignore
vendored
|
@ -4,4 +4,3 @@ build/
|
|||
*.o
|
||||
compile_commands.json
|
||||
.idea/
|
||||
bin/
|
||||
|
|
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
|||
[submodule "06-monogame/Introduction/themes/hugo-bearcub"]
|
||||
path = 06-monogame/Introduction/themes/hugo-bearcub
|
||||
url = https://github.com/clente/hugo-bearcub
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 44 KiB |
BIN
.imgs/opengl.png
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -1,6 +1,6 @@
|
|||
<p align="center">
|
||||
<img src=".imgs/showcase.png" width="300" />
|
||||
</p>
|
||||
<!-- <p align="center"> -->
|
||||
<!-- <img src=".imgs/showcase.png" width="300" /> -->
|
||||
<!-- </p> -->
|
||||
|
||||
# Map
|
||||
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
CC=g++
|
||||
CFLAGS=-std=c++20 `pkg-config --cflags glfw3 glew glm`
|
||||
LDFLAGS=`pkg-config --libs glfw3 glew glm`
|
||||
INCLUDE=/usr/include/stb/
|
||||
TARGET=opengl
|
||||
SDIR=src
|
||||
ADIR=assets
|
||||
ODIR=build
|
||||
|
||||
SRC=$(shell find $(SDIR) -type f -name *.cpp)
|
||||
OBJ=$(SRC:.cpp=.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
.PHONY: default
|
||||
$(TARGET): $(OBJ)
|
||||
mkdir -p build
|
||||
cp -rf $(ADIR) $(ODIR)/$(ADIR)
|
||||
$(CC) -o $(ODIR)/$@ $^ $(LDFLAGS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
run:
|
||||
$(ODIR)/$(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(ODIR)/$(TARGET) $(OBJ)
|
|
@ -1,3 +0,0 @@
|
|||
# Opengl
|
||||
|
||||
Playing with Opengl because I realized SDL2 is not enough :/
|
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.2 KiB |
|
@ -1,13 +0,0 @@
|
|||
#version 330 core
|
||||
out vec4 color;
|
||||
in vec2 tex_coord;
|
||||
|
||||
uniform sampler2D sampler;
|
||||
|
||||
void main() {
|
||||
color = texture(sampler, tex_coord);
|
||||
// color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if (color.a < 0.1)
|
||||
discard;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texture_coord;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec2 tex_coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * view * vec4(pos.xyz, 1.0);
|
||||
tex_coord = texture_coord;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string read_file(const char *path);
|
|
@ -1,172 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <GL/glew.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 "texture.hpp"
|
||||
#include "sprite.hpp"
|
||||
#include "other/stb_image.h"
|
||||
|
||||
Game::Game(GLFWwindow *window) {
|
||||
this->window = window;
|
||||
this->program = Program();
|
||||
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &this->texture_slots);
|
||||
}
|
||||
|
||||
// code this later lol
|
||||
int Game::setup(int initial_width, int initial_height) {
|
||||
glfwSetKeyCallback(this->window, Game::input_callback);
|
||||
glfwSetFramebufferSizeCallback(this->window, Game::resize_callback);
|
||||
|
||||
Game::resize_callback(this->window, initial_width, initial_height);
|
||||
|
||||
int ret = this->program.add_shader("assets/shaders/vertex.glsl", GL_VERTEX_SHADER);
|
||||
if (ret != 0) {
|
||||
std::cout << "Error: failed adding vertex shader" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = this->program.add_shader("assets/shaders/fragment.glsl", GL_FRAGMENT_SHADER);
|
||||
if (ret != 0) {
|
||||
std::cout << "Error: failed adding fragment shader" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (this->program.link() != 0) {
|
||||
std::cout << "Error: failed linking program" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
glUseProgram(this->program.id);
|
||||
|
||||
glGenVertexArrays(1, &this->vao);
|
||||
glGenBuffers(1, &this->vbo);
|
||||
glGenBuffers(1, &this->ebo);
|
||||
|
||||
glBindVertexArray(this->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Game::run() {
|
||||
this->counter = 0;
|
||||
this->vbo_offset = 0;
|
||||
this->ebo_offset = 0;
|
||||
|
||||
Sprite sprite("assets/player/idle.png", SPLIT_TEXTURE);
|
||||
sprite.bake();
|
||||
this->sprites.push_back(&sprite);
|
||||
|
||||
glBindVertexArray(this->vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(struct vertex) * 4 * this->texture_slots, nullptr, GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 6 * this->texture_slots, 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);
|
||||
|
||||
Game::logic();
|
||||
}
|
||||
|
||||
void Game::input_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
|
||||
if (action != GLFW_PRESS)
|
||||
return;
|
||||
|
||||
switch (key) {
|
||||
case GLFW_KEY_ESCAPE:
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Game::resize_callback(GLFWwindow *window, int new_width, int new_height) {
|
||||
glViewport(0, 0, new_width, new_height);
|
||||
}
|
||||
|
||||
void Game::logic() {
|
||||
while (!glfwWindowShouldClose(this->window)) {
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
|
||||
for (int sprite = 0; sprite < this->sprites.size(); sprite++, counter++) {
|
||||
Game::load(this->sprites[sprite], this->counter);
|
||||
|
||||
std::cout << "Counter: " << counter << " Texture slots: " << this->texture_slots << std::endl;
|
||||
if (counter > 0 && counter % this->texture_slots == 0) {
|
||||
Game::draw();
|
||||
this->counter = 0;
|
||||
this->vbo_offset = 0;
|
||||
this->ebo_offset = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Game::draw();
|
||||
this->counter = 0;
|
||||
this->vbo_offset = 0;
|
||||
this->ebo_offset = 0;
|
||||
|
||||
glfwPollEvents();
|
||||
glfwSwapBuffers(this->window);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Game::load(Sprite *sprite, int count) {
|
||||
unsigned int program = this->program.id;
|
||||
glUseProgram(program);
|
||||
|
||||
glUniform1i(glGetUniformLocation(program, "sampler"), count);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, vbo_offset, sizeof(struct vertex) * sprite->vertices.size(), sprite->vertices.data());
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, ebo_offset, sizeof(int) * sprite->indices.size(), sprite->indices.data());
|
||||
|
||||
vbo_offset += sizeof(struct vertex) * sprite->vertices.size();
|
||||
ebo_offset += sizeof(int) * sprite->indices.size();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + count);
|
||||
glBindTexture(GL_TEXTURE_2D, sprite->texture.texture_id);
|
||||
}
|
||||
|
||||
void Game::draw() {
|
||||
unsigned int program = this->program.id;
|
||||
glUseProgram(program);
|
||||
|
||||
glm::mat4 view = glm::mat4(1.0f);
|
||||
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||
|
||||
glm::mat4 projection = glm::mat4(1.0f);
|
||||
|
||||
int width, height;
|
||||
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,"view"), 1, GL_FALSE, glm::value_ptr(view));
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
|
||||
glDrawElements(GL_TRIANGLES, this->sprites[0]->indices.size(), GL_UNSIGNED_INT, 0);
|
||||
std::cout << "Error: " << glGetError() << std::endl;
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "program.hpp"
|
||||
#include "sprite.hpp"
|
||||
|
||||
class Game {
|
||||
public:
|
||||
Game(GLFWwindow *window);
|
||||
int setup(int initial_width, int initial_height);
|
||||
void run();
|
||||
void logic();
|
||||
void load(Sprite *sprite, int counter);
|
||||
void draw();
|
||||
|
||||
// callbacks
|
||||
static void input_callback(GLFWwindow *window, int key, int scancode, int action, int mods);
|
||||
static void resize_callback(GLFWwindow *window, int new_width, int new_height);
|
||||
|
||||
GLFWwindow *window;
|
||||
Program program;
|
||||
|
||||
std::vector<Sprite *> sprites;
|
||||
|
||||
int texture_slots;
|
||||
unsigned int vao;
|
||||
unsigned int vbo;
|
||||
unsigned int ebo;
|
||||
unsigned int counter;
|
||||
unsigned int vbo_offset;
|
||||
unsigned int ebo_offset;
|
||||
};
|
|
@ -1,40 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <stb/stb_image.h>
|
||||
#include "game.hpp"
|
||||
|
||||
int initial_width = 1000;
|
||||
int initial_height = 600;
|
||||
std::string vertex_shader_location = "assets/shaders/shader.vert";
|
||||
std::string fragment_shader_location = "assets/shaders/shader.frag";
|
||||
|
||||
int main() {
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
GLFWwindow *window = glfwCreateWindow(initial_width, initial_height, "OpenGL", NULL, NULL);
|
||||
if (window == NULL) {
|
||||
std::cout << "Error: failed creating window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
GLenum err = glewInit();
|
||||
if (err != GLEW_OK) {
|
||||
std::cout << "Error: failed initializing glew " << glewGetErrorString(err) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Game main_game(window);
|
||||
main_game.setup(initial_width, initial_height);
|
||||
main_game.run();
|
||||
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
|
@ -1,38 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#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();
|
||||
};
|
|
@ -1,31 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
struct Shader {
|
||||
unsigned int id;
|
||||
unsigned int type;
|
||||
|
||||
unsigned int load(const char *path, unsigned int type);
|
||||
};
|
|
@ -1,59 +0,0 @@
|
|||
#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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#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;
|
||||
|
||||
Game *game;
|
||||
|
||||
Sprite(const char *path, enum TextureType type);
|
||||
void bake();
|
||||
};
|
|
@ -1,29 +0,0 @@
|
|||
#include <GL/glew.h>
|
||||
#include "texture.hpp"
|
||||
|
||||
Texture::Texture(enum TextureType type) {
|
||||
glGenTextures(1, &this->texture_id);
|
||||
this->type = type;
|
||||
this->cell_x = 0;
|
||||
this->cell_y = 0;
|
||||
this->cell_res = 0;
|
||||
}
|
||||
|
||||
void Texture::bind_texture() {
|
||||
glBindTexture(GL_TEXTURE_2D, this->texture_id);
|
||||
|
||||
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_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
void Texture::load_data(unsigned char *bytes, int width, int height, int cell_res) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
this->texture_width = width;
|
||||
this->texture_height = height;
|
||||
this->cell_res = cell_res;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
enum TextureType {
|
||||
FULL_TEXTURE,
|
||||
SPLIT_TEXTURE,
|
||||
DYNAMIC_TEXTURE
|
||||
};
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
unsigned int texture_id;
|
||||
|
||||
Texture(enum TextureType type);
|
||||
void bind_texture();
|
||||
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;
|
||||
};
|
43
06-monogame/.gitignore
vendored
|
@ -1,43 +0,0 @@
|
|||
*.swp
|
||||
*.*~
|
||||
project.lock.json
|
||||
.DS_Store
|
||||
*.pyc
|
||||
nupkg/
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
|
||||
# Rider
|
||||
.idea/
|
||||
|
||||
# Visual Studio
|
||||
.vs/
|
||||
|
||||
# Fleet
|
||||
.fleet/
|
||||
|
||||
# Code Rush
|
||||
.cr/
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
msbuild.log
|
||||
msbuild.err
|
||||
msbuild.wrn
|
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-mgcb": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor-linux": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor-linux"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor-windows": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor-windows"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor-mac": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor-mac"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
|
||||
#----------------------------- Global Properties ----------------------------#
|
||||
|
||||
/outputDir:bin/$(Platform)
|
||||
/intermediateDir:obj/$(Platform)
|
||||
/platform:DesktopGL
|
||||
/config:
|
||||
/profile:Reach
|
||||
/compress:False
|
||||
|
||||
#-------------------------------- References --------------------------------#
|
||||
|
||||
|
||||
#---------------------------------- Content ---------------------------------#
|
||||
|
||||
#begin button-default-texture.png
|
||||
/importer:TextureImporter
|
||||
/processor:TextureProcessor
|
||||
/processorParam:ColorKeyColor=255,0,255,255
|
||||
/processorParam:ColorKeyEnabled=True
|
||||
/processorParam:GenerateMipmaps=False
|
||||
/processorParam:PremultiplyAlpha=True
|
||||
/processorParam:ResizeToPowerOfTwo=False
|
||||
/processorParam:MakeSquare=False
|
||||
/processorParam:TextureFormat=Color
|
||||
/build:button-default-texture.png
|
||||
|
||||
#begin button.png
|
||||
/importer:TextureImporter
|
||||
/processor:TextureProcessor
|
||||
/processorParam:ColorKeyColor=255,0,255,255
|
||||
/processorParam:ColorKeyEnabled=True
|
||||
/processorParam:GenerateMipmaps=False
|
||||
/processorParam:PremultiplyAlpha=True
|
||||
/processorParam:ResizeToPowerOfTwo=False
|
||||
/processorParam:MakeSquare=False
|
||||
/processorParam:TextureFormat=Color
|
||||
/build:button.png
|
||||
|
||||
#begin Fonts/default.spritefont
|
||||
/importer:FontDescriptionImporter
|
||||
/processor:LocalizedFontProcessor
|
||||
/processorParam:PremultiplyAlpha=True
|
||||
/processorParam:TextureFormat=Compressed
|
||||
/build:Fonts/default.spritefont
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file contains an xml description of a font, and will be read by the XNA
|
||||
Framework Content Pipeline. Follow the comments to customize the appearance
|
||||
of the font in your game, and to change the characters which are available to draw
|
||||
with.
|
||||
-->
|
||||
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
|
||||
<Asset Type="Graphics:LocalizedFontDescription">
|
||||
|
||||
<!--
|
||||
Modify this string to change the font that will be imported.
|
||||
-->
|
||||
<FontName>HackNerdFont.ttf</FontName>
|
||||
|
||||
<!--
|
||||
Size is a float value, measured in points. Modify this value to change
|
||||
the size of the font.
|
||||
-->
|
||||
<Size>12</Size>
|
||||
|
||||
<!--
|
||||
Spacing is a float value, measured in pixels. Modify this value to change
|
||||
the amount of spacing in between characters.
|
||||
-->
|
||||
<Spacing>0</Spacing>
|
||||
|
||||
<!--
|
||||
UseKerning controls the layout of the font. If this value is true, kerning information
|
||||
will be used when placing characters.
|
||||
-->
|
||||
<UseKerning>true</UseKerning>
|
||||
|
||||
<!--
|
||||
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
|
||||
and "Bold, Italic", and are case sensitive.
|
||||
-->
|
||||
<Style>Regular</Style>
|
||||
|
||||
<!--
|
||||
If you uncomment this line, the default character will be substituted if you draw
|
||||
or measure text that contains characters which were not included in the font.
|
||||
-->
|
||||
<DefaultCharacter>A</DefaultCharacter>
|
||||
|
||||
<!--
|
||||
CharacterRegions control what letters are available in the font. Every
|
||||
character from Start to End will be built and made available for drawing. The
|
||||
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
|
||||
character set. The characters are ordered according to the Unicode standard.
|
||||
See the documentation for more information.
|
||||
For localized fonts you can leave this empty as the character range will be picked up
|
||||
from the Resource Files.
|
||||
-->
|
||||
<CharacterRegions>
|
||||
<CharacterRegion>
|
||||
<Start> </Start>
|
||||
<End>€</End>
|
||||
</CharacterRegion>
|
||||
</CharacterRegions>
|
||||
<!--
|
||||
ResourceFiles control the characters which will be in the font. It does this
|
||||
by scanning the text in each of the resource files and adding those specific
|
||||
characters to the font.
|
||||
-->
|
||||
<ResourceFiles>
|
||||
<!-- <Resx>Strings.resx</Resx> -->
|
||||
</ResourceFiles>
|
||||
</Asset>
|
||||
</XnaContent>
|
Before Width: | Height: | Size: 545 B |
Before Width: | Height: | Size: 28 KiB |
|
@ -1,29 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RollForward>Major</RollForward>
|
||||
<PublishReadyToRun>false</PublishReadyToRun>
|
||||
<TieredCompilation>false</TieredCompilation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Icon.ico" />
|
||||
<None Remove="Icon.bmp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Icon.ico" />
|
||||
<EmbeddedResource Include="Icon.bmp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
||||
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
||||
</ItemGroup>
|
||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
||||
<Exec Command="dotnet tool restore" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,73 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using GUI.UIElements;
|
||||
|
||||
namespace GUI;
|
||||
|
||||
public class Game1 : Game
|
||||
{
|
||||
private GraphicsDeviceManager _graphics;
|
||||
private SpriteBatch _spriteBatch;
|
||||
private Scene mainScene;
|
||||
|
||||
public Game1()
|
||||
{
|
||||
_graphics = new GraphicsDeviceManager(this);
|
||||
Content.RootDirectory = "Content";
|
||||
IsMouseVisible = true;
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||
|
||||
Scene.graphics = _graphics;
|
||||
Scene.spriteBatch = _spriteBatch;
|
||||
Scene.content = Content;
|
||||
|
||||
mainScene = new Scene();
|
||||
DrawableData drawableData = new DrawableData("button");
|
||||
drawableData.position = new Vector2(100.0f, 100.0f);
|
||||
|
||||
void buttonOnClick(Button obj)
|
||||
{
|
||||
Console.WriteLine("ACTION CALLED SUCCESSFULLY!");
|
||||
}
|
||||
|
||||
ButtonData buttonData = new ButtonData(buttonOnClick);
|
||||
buttonData.text = "Click me!";
|
||||
|
||||
Button mainButton = new Button(drawableData, buttonData);
|
||||
|
||||
mainScene.drawables.Add(mainButton);
|
||||
|
||||
mainScene.Initialize();
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
protected override void LoadContent()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Update(GameTime gameTime)
|
||||
{
|
||||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||
Exit();
|
||||
|
||||
mainScene.Update(gameTime);
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
GraphicsDevice.Clear(Color.Black);
|
||||
|
||||
mainScene.Draw(gameTime);
|
||||
|
||||
base.Draw(gameTime);
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 144 KiB |
|
@ -1,3 +0,0 @@
|
|||
|
||||
using var game = new GUI.Game1();
|
||||
game.Run();
|
|
@ -1,176 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Vector2 = Microsoft.Xna.Framework.Vector2;
|
||||
|
||||
namespace GUI.UIElements;
|
||||
|
||||
public class ButtonData
|
||||
{
|
||||
public Color bgColor;
|
||||
public Color fgColor;
|
||||
|
||||
public Color? hoverBgColor;
|
||||
public Color? hoverFgColor;
|
||||
|
||||
public Color? pressedBgColor;
|
||||
public Color? pressedFgColor;
|
||||
|
||||
public Color idleBgColor = Color.Black;
|
||||
public Color idleFgColor = Color.White;
|
||||
|
||||
public bool isPressed = false;
|
||||
public bool isReleased = false;
|
||||
public bool isHovered = false;
|
||||
public bool isIdle = false;
|
||||
|
||||
public Action<Button>? onClick;
|
||||
|
||||
public string text = "";
|
||||
public Vector2 textPosition;
|
||||
public Vector2 textResolution;
|
||||
public Vector2 textScale;
|
||||
|
||||
public ButtonData(Action<Button>? onClick)
|
||||
{
|
||||
this.onClick = onClick;
|
||||
}
|
||||
}
|
||||
|
||||
public class Button : Drawable
|
||||
{
|
||||
private DrawableData _drawableData;
|
||||
public ButtonData _buttonData;
|
||||
|
||||
private SpriteFont buttonFont;
|
||||
|
||||
public Button(DrawableData data, ButtonData buttonData)
|
||||
{
|
||||
_drawableData = data;
|
||||
_buttonData = buttonData;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
buttonFont = Scene.content.Load<SpriteFont>("Fonts/default");
|
||||
}
|
||||
|
||||
void onPressed()
|
||||
{
|
||||
if (_buttonData.isPressed)
|
||||
return;
|
||||
|
||||
_buttonData.bgColor = _buttonData.pressedBgColor ?? _buttonData.idleBgColor;
|
||||
_buttonData.fgColor = _buttonData.pressedFgColor ?? _buttonData.idleFgColor;
|
||||
|
||||
if (_buttonData.onClick is not null)
|
||||
_buttonData.onClick(this);
|
||||
|
||||
_buttonData.isReleased = false;
|
||||
_buttonData.isPressed = true;
|
||||
}
|
||||
|
||||
void onReleased()
|
||||
{
|
||||
if (!_buttonData.isPressed)
|
||||
return;
|
||||
|
||||
_buttonData.bgColor = _buttonData.hoverBgColor ?? _buttonData.idleBgColor;
|
||||
_buttonData.fgColor = _buttonData.hoverFgColor ?? _buttonData.idleFgColor;
|
||||
|
||||
_buttonData.isPressed = false;
|
||||
_buttonData.isReleased = true;
|
||||
}
|
||||
|
||||
void onHovered()
|
||||
{
|
||||
if (_buttonData.isHovered)
|
||||
return;
|
||||
|
||||
_buttonData.bgColor = _buttonData.hoverBgColor ?? _buttonData.idleBgColor;
|
||||
_buttonData.fgColor = _buttonData.hoverFgColor ?? _buttonData.idleFgColor;
|
||||
|
||||
_buttonData.isHovered = true;
|
||||
}
|
||||
|
||||
void onIdle()
|
||||
{
|
||||
_buttonData.bgColor = _buttonData.idleBgColor;
|
||||
_buttonData.fgColor = _buttonData.idleFgColor;
|
||||
|
||||
_buttonData.isPressed = false;
|
||||
_buttonData.isReleased = false;
|
||||
_buttonData.isHovered = false;
|
||||
}
|
||||
|
||||
public void buttonLogic()
|
||||
{
|
||||
var mstate = Mouse.GetState();
|
||||
Vector2 mousePosition = mstate.Position.ToVector2();
|
||||
|
||||
bool outsideHorizontalBoundary = (mousePosition.X < _drawableData.position.X) || (mousePosition.X > (_drawableData.position.X + _drawableData.scale.X));
|
||||
bool outsideVerticalBoundary = (mousePosition.Y < _drawableData.position.Y) || (mousePosition.Y > (_drawableData.position.Y + _drawableData.scale.Y));
|
||||
|
||||
if (outsideHorizontalBoundary || outsideVerticalBoundary)
|
||||
{
|
||||
onIdle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mstate.LeftButton == ButtonState.Pressed)
|
||||
{
|
||||
onPressed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mstate.LeftButton == ButtonState.Released)
|
||||
{
|
||||
onReleased();
|
||||
}
|
||||
|
||||
onHovered();
|
||||
}
|
||||
|
||||
public override void Update(GameTime gameTime)
|
||||
{
|
||||
buttonLogic();
|
||||
|
||||
_buttonData.textResolution = buttonFont.MeasureString(_buttonData.text);
|
||||
|
||||
// we want to center the text so
|
||||
Vector2 buttonCenter = (_drawableData.position + (Vector2.One / 2.0f));
|
||||
Vector2 textHalfResolution = _buttonData.textResolution / 2.0f;
|
||||
|
||||
_buttonData.textPosition = buttonCenter - textHalfResolution;
|
||||
}
|
||||
|
||||
public override void Draw(GameTime gameTime)
|
||||
{
|
||||
Scene.spriteBatch.Draw(
|
||||
_drawableData.texture,
|
||||
_drawableData.position,
|
||||
null,
|
||||
Color.White,
|
||||
_drawableData.rotation,
|
||||
Vector2.Zero,
|
||||
_drawableData.scale,
|
||||
SpriteEffects.None,
|
||||
0f
|
||||
);
|
||||
|
||||
Scene.spriteBatch.DrawString(
|
||||
buttonFont,
|
||||
_buttonData.text,
|
||||
_buttonData.textPosition,
|
||||
_buttonData.fgColor,
|
||||
_drawableData.rotation,
|
||||
Vector2.Zero,
|
||||
_drawableData.scale,
|
||||
SpriteEffects.None,
|
||||
0f,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
using System;
|
||||
using System.Data;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace GUI.UIElements;
|
||||
|
||||
public class DrawableData
|
||||
{
|
||||
public Texture2D texture;
|
||||
public Vector2 position = Vector2.Zero;
|
||||
private Vector2 scale_multiplier = Vector2.One;
|
||||
public Vector2 scale
|
||||
{
|
||||
get { return scale_multiplier * new Vector2(texture.Width, texture.Height); }
|
||||
set
|
||||
{
|
||||
scale_multiplier = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float rotation = 0.0f;
|
||||
|
||||
public DrawableData(string? texture)
|
||||
{
|
||||
if (texture is not null)
|
||||
{
|
||||
this.texture = Scene.content.Load<Texture2D>(texture);
|
||||
return;
|
||||
}
|
||||
|
||||
this.texture = Scene.content.Load<Texture2D>("button-default-texture");
|
||||
}
|
||||
}
|
||||
|
||||
public enum DrawableType
|
||||
{
|
||||
Container,
|
||||
Text,
|
||||
Button,
|
||||
}
|
||||
|
||||
public abstract class Drawable
|
||||
{
|
||||
public DrawableType drawableType;
|
||||
public abstract void Initialize();
|
||||
public abstract void Update(GameTime gameTime);
|
||||
public abstract void Draw(GameTime gameTime);
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
namespace GUI.UIElements;
|
||||
|
||||
public class Scene
|
||||
{
|
||||
private static ContentManager? _content;
|
||||
public static ContentManager content
|
||||
{
|
||||
get { return _content; }
|
||||
set
|
||||
{
|
||||
if (_content is not null)
|
||||
return;
|
||||
|
||||
_content = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static GraphicsDeviceManager? _graphics;
|
||||
public static GraphicsDeviceManager graphics
|
||||
{
|
||||
get { return _graphics; }
|
||||
set
|
||||
{
|
||||
if (_graphics is not null)
|
||||
return;
|
||||
|
||||
_graphics = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static SpriteBatch? _spriteBatch;
|
||||
|
||||
public static SpriteBatch spriteBatch
|
||||
{
|
||||
get { return _spriteBatch; }
|
||||
set
|
||||
{
|
||||
if (_spriteBatch is not null)
|
||||
return;
|
||||
|
||||
_spriteBatch = value;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Drawable> drawables;
|
||||
|
||||
public Scene()
|
||||
{
|
||||
drawables = new List<Drawable>();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
foreach (Drawable drawable in drawables)
|
||||
drawable.Initialize();
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
foreach (Drawable drawable in drawables)
|
||||
drawable.Update(gameTime);
|
||||
}
|
||||
|
||||
public void Draw(GameTime gameTime)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
|
||||
|
||||
foreach (Drawable drawable in drawables)
|
||||
drawable.Draw(gameTime);
|
||||
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="GUI"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on and is
|
||||
is designed to work with. Uncomment the appropriate elements and Windows will
|
||||
automatically selected the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
|
||||
</assembly>
|
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-mgcb": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor-linux": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor-linux"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor-windows": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor-windows"
|
||||
]
|
||||
},
|
||||
"dotnet-mgcb-editor-mac": {
|
||||
"version": "3.8.1.303",
|
||||
"commands": [
|
||||
"mgcb-editor-mac"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Vector2 = Microsoft.Xna.Framework.Vector2;
|
||||
|
||||
namespace Introduction;
|
||||
|
||||
public class Character
|
||||
{
|
||||
public Texture2D texture;
|
||||
public Texture2D noise;
|
||||
public Vector2 pos;
|
||||
public Vector2 scale;
|
||||
public Vector2 rot;
|
||||
public float angles;
|
||||
public float speed;
|
||||
|
||||
private bool glitchEnabled = false;
|
||||
private Effect glitch;
|
||||
private float time;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
speed = 300.0f;
|
||||
pos = Vector2.Zero;
|
||||
scale = new Vector2(1f);
|
||||
rot = Vector2.UnitX;
|
||||
angles = 0.0f;
|
||||
}
|
||||
|
||||
public void LoadContent(ContentManager content)
|
||||
{
|
||||
texture = content.Load<Texture2D>("player_texture");
|
||||
noise = content.Load<Texture2D>("noise");
|
||||
glitch = content.Load<Effect>("glitch");
|
||||
|
||||
if (glitch.Parameters["NoiseTexture"] is not null)
|
||||
glitch.Parameters["NoiseTexture"].SetValue(texture);
|
||||
|
||||
if (glitch.Parameters["textureSize"] is not null)
|
||||
glitch.Parameters["textureSize"].SetValue(new Vector2(texture.Width, texture.Height));
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
var kstate = Keyboard.GetState();
|
||||
if (kstate.IsKeyDown(Keys.W))
|
||||
{
|
||||
pos.Y -= speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
|
||||
if (kstate.IsKeyDown(Keys.S))
|
||||
{
|
||||
pos.Y += speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
|
||||
if (kstate.IsKeyDown(Keys.A))
|
||||
{
|
||||
pos.X -= speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
|
||||
if (kstate.IsKeyDown(Keys.D))
|
||||
{
|
||||
pos.X += speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
}
|
||||
|
||||
if (kstate.IsKeyDown(Keys.K))
|
||||
{
|
||||
glitchEnabled = !glitchEnabled;
|
||||
}
|
||||
|
||||
var mstate = Mouse.GetState();
|
||||
Vector2 mousePosition = new Vector2(mstate.X, mstate.Y);
|
||||
Vector2 distancePosition = mousePosition - pos;
|
||||
|
||||
angles = (float) (Math.Atan2(distancePosition.Y, distancePosition.X));
|
||||
|
||||
time += (float) gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
if (glitch.Parameters["Time"] is not null)
|
||||
glitch.Parameters["Time"].SetValue(time);
|
||||
}
|
||||
|
||||
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
|
||||
{
|
||||
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
|
||||
Vector2 origin = new Vector2(texture.Width / 2, texture.Height / 2);
|
||||
|
||||
if (glitchEnabled)
|
||||
glitch.CurrentTechnique.Passes[0].Apply();
|
||||
else
|
||||
time = 0;
|
||||
|
||||
spriteBatch.Draw(texture, pos, null, Color.White, angles, origin, scale, SpriteEffects.None, 0.0f);
|
||||
spriteBatch.End();
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
|
||||
#----------------------------- Global Properties ----------------------------#
|
||||
|
||||
/outputDir:bin/$(Platform)
|
||||
/intermediateDir:obj/$(Platform)
|
||||
/platform:DesktopGL
|
||||
/config:
|
||||
/profile:Reach
|
||||
/compress:False
|
||||
|
||||
#-------------------------------- References --------------------------------#
|
||||
|
||||
|
||||
#---------------------------------- Content ---------------------------------#
|
||||
|
||||
#begin glitch.fx
|
||||
/importer:EffectImporter
|
||||
/processor:EffectProcessor
|
||||
/processorParam:DebugMode=Auto
|
||||
/build:glitch.fx
|
||||
|
||||
#begin noise.png
|
||||
/importer:TextureImporter
|
||||
/processor:TextureProcessor
|
||||
/processorParam:ColorKeyColor=255,0,255,255
|
||||
/processorParam:ColorKeyEnabled=True
|
||||
/processorParam:GenerateMipmaps=False
|
||||
/processorParam:PremultiplyAlpha=True
|
||||
/processorParam:ResizeToPowerOfTwo=False
|
||||
/processorParam:MakeSquare=False
|
||||
/processorParam:TextureFormat=Color
|
||||
/build:noise.png
|
||||
|
||||
#begin player_texture.png
|
||||
/importer:TextureImporter
|
||||
/processor:TextureProcessor
|
||||
/processorParam:ColorKeyColor=255,0,255,255
|
||||
/processorParam:ColorKeyEnabled=True
|
||||
/processorParam:GenerateMipmaps=False
|
||||
/processorParam:PremultiplyAlpha=True
|
||||
/processorParam:ResizeToPowerOfTwo=False
|
||||
/processorParam:MakeSquare=False
|
||||
/processorParam:TextureFormat=Color
|
||||
/build:player_texture.png
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#if OPENGL
|
||||
#define SV_POSITION POSITION
|
||||
#define VS_SHADERMODEL vs_3_0
|
||||
#define PS_SHADERMODEL ps_3_0
|
||||
#else
|
||||
#define VS_SHADERMODEL vs_4_0_level_9_1
|
||||
#define PS_SHADERMODEL ps_4_0_level_9_1
|
||||
#endif
|
||||
|
||||
matrix WorldViewProjection;
|
||||
|
||||
sampler s0 : register (s0);
|
||||
float Time;
|
||||
float2 textureSize;
|
||||
|
||||
Texture2D NoiseTexture;
|
||||
sampler2D NoiseSampler = sampler_state
|
||||
{
|
||||
Texture = <NoiseTexture>;
|
||||
};
|
||||
|
||||
float4 MainPS(float2 coords: TEXCOORD0) : COLOR0
|
||||
{
|
||||
float2 up_limit = float2(0.0, 0.0) + float2(Time, Time);
|
||||
float2 down_limit = textureSize - float2(Time, Time);
|
||||
|
||||
float4 output_col;
|
||||
if (coords.x < up_limit.x || coords.y < up_limit.y) {
|
||||
output_col = float4(0.0, 0.0, 0.0, 0.0);
|
||||
return output_col;
|
||||
}
|
||||
|
||||
if (coords.x > down_limit.x || coords.y > down_limit.y) {
|
||||
output_col = float4(0.0, 0.0, 0.0, 0.0);
|
||||
return output_col;
|
||||
}
|
||||
|
||||
return tex2D(s0, coords);
|
||||
}
|
||||
|
||||
technique BasicColorDrawing
|
||||
{
|
||||
pass P0
|
||||
{
|
||||
PixelShader = compile PS_SHADERMODEL MainPS();
|
||||
}
|
||||
};
|
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 39 KiB |
|
@ -1,53 +0,0 @@
|
|||
using System.Data;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Introduction;
|
||||
|
||||
public class Game1 : Game
|
||||
{
|
||||
private GraphicsDeviceManager _graphics;
|
||||
private SpriteBatch _spriteBatch;
|
||||
private Character player;
|
||||
|
||||
public Game1()
|
||||
{
|
||||
_graphics = new GraphicsDeviceManager(this);
|
||||
Content.RootDirectory = "Content";
|
||||
IsMouseVisible = true;
|
||||
player = new Character();
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
player.Initialize();
|
||||
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
protected override void LoadContent()
|
||||
{
|
||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||
player.LoadContent(Content);
|
||||
}
|
||||
|
||||
protected override void Update(GameTime gameTime)
|
||||
{
|
||||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||
Exit();
|
||||
|
||||
player.Update(gameTime);
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||
|
||||
player.Draw(gameTime, _spriteBatch);
|
||||
|
||||
base.Draw(gameTime);
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 144 KiB |
|
@ -1,29 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RollForward>Major</RollForward>
|
||||
<PublishReadyToRun>false</PublishReadyToRun>
|
||||
<TieredCompilation>false</TieredCompilation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<ApplicationIcon>Icon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Icon.ico" />
|
||||
<None Remove="Icon.bmp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Icon.ico" />
|
||||
<EmbeddedResource Include="Icon.bmp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
||||
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
||||
</ItemGroup>
|
||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
||||
<Exec Command="dotnet tool restore" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
using var game = new Introduction.Game1();
|
||||
game.Run();
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="Introduction"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on and is
|
||||
is designed to work with. Uncomment the appropriate elements and Windows will
|
||||
automatically selected the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
|
||||
</assembly>
|
Before Width: | Height: | Size: 5.0 KiB |
|
@ -1,28 +0,0 @@
|
|||
CC=g++
|
||||
CFLAGS=-std=c++20 `pkg-config --cflags glfw3 glew glm`
|
||||
LDFLAGS=`pkg-config --libs glfw3 glew glm`
|
||||
TARGET=boilerplate
|
||||
SDIR=src
|
||||
ADIR=assets
|
||||
ODIR=build
|
||||
|
||||
SRC=$(shell find $(SDIR) -type f -name *.cpp)
|
||||
OBJ=$(SRC:.cpp=.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
.PHONY: default
|
||||
$(TARGET): $(OBJ)
|
||||
mkdir -p build
|
||||
cp -rf $(ADIR) $(ODIR)/$(ADIR)
|
||||
$(CC) -o $(ODIR)/$@ $^ $(LDFLAGS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
run:
|
||||
$(ODIR)/$(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(ODIR)/$(TARGET) $(OBJ)
|
|
@ -1,8 +0,0 @@
|
|||
<p align="center">
|
||||
<img src=".imgs/showcase.png" width="300" />
|
||||
</p>
|
||||
|
||||
# Boilerplate
|
||||
|
||||
Creating a boilerplate API to abstract away OpenGL.
|
||||
- Also added my first ever batch renderer
|
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.2 KiB |
|
@ -1,12 +0,0 @@
|
|||
#version 330 core
|
||||
in vec4 _color;
|
||||
in vec2 _texture_position;
|
||||
in float _ctt;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
// color = texture(sampler, _texture_position);
|
||||
//color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
color = _color;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec4 position;
|
||||
layout (location = 1) in vec4 origin;
|
||||
layout (location = 2) in vec4 color;
|
||||
layout (location = 3) in vec2 texture_position;
|
||||
layout (location = 4) in float ctt;
|
||||
|
||||
uniform mat4 view_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
out vec4 _color;
|
||||
out vec2 _texture_position;
|
||||
out float _ctt;
|
||||
|
||||
void main() {
|
||||
vec3 origined_position = origin.xyz + position.xyz;
|
||||
|
||||
gl_Position = projection_matrix * view_matrix * vec4(origined_position, 1.0);
|
||||
_color = color;
|
||||
_texture_position = texture_position;
|
||||
_ctt = ctt;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 330 core
|
||||
out vec4 color;
|
||||
in vec2 tex_coord;
|
||||
|
||||
uniform sampler2D sampler;
|
||||
|
||||
void main() {
|
||||
color = texture(sampler, tex_coord);
|
||||
// color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if (color.a < 0.1)
|
||||
discard;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texture_coord;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec2 tex_coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * view * vec4(pos.xyz, 1.0);
|
||||
tex_coord = texture_coord;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string read_file(const char *path);
|
|
@ -1,10 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#define DEFAULT_POSITION_ATTRIBUTE 0
|
||||
#define DEFAULT_ORIGIN_ATTRIBUTE 1
|
||||
#define DEFAULT_COLOR_ATTRIBUTE 2
|
||||
#define DEFAULT_TEXTURE_ATTRIBUTE 3
|
||||
#define DEFAULT_CTT_ATTRIBUTE 4
|
||||
|
||||
#define QUAD 6
|
||||
#define DEFAULT_VBO_SIZE QUAD * 1000000 // unit: rows of RenderData
|
|
@ -1,38 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
#include "program.hpp"
|
||||
#include "../macros.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 RET_ERR;
|
||||
|
||||
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);
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <vector>
|
||||
#include "shader.hpp"
|
||||
|
||||
struct Program {
|
||||
GLuint id;
|
||||
std::vector<Shader> shaders;
|
||||
|
||||
Program();
|
||||
int add_shader(const char *path, unsigned int type);
|
||||
int link();
|
||||
};
|
|
@ -1,155 +0,0 @@
|
|||
#include <optional>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "renderer.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "graphics.hpp"
|
||||
|
||||
Renderer::Renderer(Window &window) : window(window) {
|
||||
pack = RendererPack();
|
||||
this->window = window;
|
||||
|
||||
glGenBuffers(1, &this->vertex_buffer_id);
|
||||
glGenVertexArrays(1, &this->array_buffer_id);
|
||||
|
||||
this->view_matrix = glm::mat4(1.0f);
|
||||
this->projection_matrix = glm::mat4(1.0f);
|
||||
}
|
||||
|
||||
int Renderer::setup(std::optional<Program> program) {
|
||||
int ret;
|
||||
|
||||
if (program != std::nullopt)
|
||||
this->program = program.value();
|
||||
else {
|
||||
Program new_program = Program();
|
||||
|
||||
ret = new_program.add_shader("assets/shaders/default_vertex.glsl", GL_VERTEX_SHADER);
|
||||
if (ret != RET_OK) {
|
||||
LOG(LOG_ERR, "Failed adding vertex shader to program");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
ret = new_program.add_shader("assets/shaders/default_fragment.glsl", GL_FRAGMENT_SHADER);
|
||||
if (ret != RET_OK) {
|
||||
LOG(LOG_ERR, "Failed adding fragment shader to program");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
ret = new_program.link();
|
||||
if (ret != RET_OK) {
|
||||
LOG(LOG_ERR, "Failed linking program");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
this->program = new_program;
|
||||
}
|
||||
|
||||
glBindVertexArray(this->array_buffer_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer_id);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(struct RendererData) * DEFAULT_VBO_SIZE, nullptr, GL_DYNAMIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(
|
||||
DEFAULT_POSITION_ATTRIBUTE,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(struct RendererData),
|
||||
(void *) offsetof(RendererData, vertex)
|
||||
);
|
||||
glEnableVertexAttribArray(DEFAULT_POSITION_ATTRIBUTE);
|
||||
|
||||
glVertexAttribPointer(
|
||||
DEFAULT_ORIGIN_ATTRIBUTE,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(struct RendererData),
|
||||
(void *) offsetof(RendererData, origin)
|
||||
);
|
||||
glEnableVertexAttribArray(DEFAULT_ORIGIN_ATTRIBUTE);
|
||||
|
||||
glVertexAttribPointer(
|
||||
DEFAULT_COLOR_ATTRIBUTE,
|
||||
4,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(struct RendererData),
|
||||
(void *) offsetof(RendererData, color)
|
||||
);
|
||||
glEnableVertexAttribArray(DEFAULT_COLOR_ATTRIBUTE);
|
||||
|
||||
glVertexAttribPointer(
|
||||
DEFAULT_TEXTURE_ATTRIBUTE,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(struct RendererData),
|
||||
(void *) offsetof(RendererData, tex)
|
||||
);
|
||||
glEnableVertexAttribArray(DEFAULT_TEXTURE_ATTRIBUTE);
|
||||
|
||||
glVertexAttribPointer(
|
||||
DEFAULT_CTT_ATTRIBUTE,
|
||||
1,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
sizeof(struct RendererData),
|
||||
(void *) offsetof(RendererData, ctt_ratio)
|
||||
);
|
||||
glEnableVertexAttribArray(DEFAULT_CTT_ATTRIBUTE);
|
||||
|
||||
// setup matrices
|
||||
this->view_matrix = glm::translate(this->view_matrix, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void Renderer::draw(struct RendererData data) {
|
||||
if (batch_buffer.size() >= DEFAULT_VBO_SIZE) {
|
||||
LOG(LOG_WARN, "Batch buffer limit reached!");
|
||||
return;
|
||||
}
|
||||
|
||||
batch_buffer.push_back(data);
|
||||
}
|
||||
|
||||
void Renderer::batch() {
|
||||
glBindVertexArray(this->array_buffer_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertex_buffer_id);
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, batch_buffer.size() * sizeof(struct RendererData), batch_buffer.data());
|
||||
|
||||
glUseProgram(this->program.id);
|
||||
|
||||
glUniformMatrix4fv(glGetUniformLocation(this->program.id, "view_matrix"), 1, GL_FALSE, &this->view_matrix[0][0]);
|
||||
glUniformMatrix4fv(glGetUniformLocation(this->program.id, "projection_matrix"), 1, GL_FALSE, &this->projection_matrix[0][0]);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, DEFAULT_VBO_SIZE);
|
||||
|
||||
batch_buffer.clear();
|
||||
}
|
||||
|
||||
void Renderer::logic() {
|
||||
int window_width;
|
||||
int window_height;
|
||||
float half_width;
|
||||
float half_height;
|
||||
|
||||
this->window.get_size(&window_width, &window_height);
|
||||
|
||||
half_width = window_width / 2.0f;
|
||||
half_height = window_height / 2.0f;
|
||||
|
||||
this->projection_matrix = glm::ortho(-half_width/100, half_width/100, -half_height/100, half_height/100, 0.1f, 100.0f);
|
||||
|
||||
}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
glDisableVertexAttribArray(DEFAULT_POSITION_ATTRIBUTE);
|
||||
glDisableVertexAttribArray(DEFAULT_COLOR_ATTRIBUTE);
|
||||
glDisableVertexAttribArray(DEFAULT_TEXTURE_ATTRIBUTE);
|
||||
glDisableVertexAttribArray(DEFAULT_CTT_ATTRIBUTE);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <optional>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include "renderer_pack.hpp"
|
||||
#include "program.hpp"
|
||||
#include "../window/window.hpp"
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
GLuint array_buffer_id;
|
||||
GLuint vertex_buffer_id;
|
||||
Program program;
|
||||
RendererPack pack;
|
||||
|
||||
glm::mat4 view_matrix;
|
||||
glm::mat4 projection_matrix;
|
||||
|
||||
Window &window;
|
||||
|
||||
Renderer(Window &window);
|
||||
~Renderer();
|
||||
|
||||
int setup(std::optional<Program> program = std::nullopt);
|
||||
void logic();
|
||||
|
||||
std::vector<struct RendererData> batch_buffer;
|
||||
|
||||
void draw(struct RendererData data);
|
||||
void batch();
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
#include "renderer_pack.hpp"
|
||||
|
||||
RendererPack::RendererPack() {
|
||||
this->data = std::vector<struct RendererData>();
|
||||
}
|
||||
|
||||
RendererPack::~RendererPack(){
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
|
||||
struct RendererData {
|
||||
glm::vec4 vertex;
|
||||
glm::vec4 origin;
|
||||
glm::vec4 color;
|
||||
glm::vec2 tex;
|
||||
float ctt_ratio; // color to texture ratio (i.e. how much does the color affect the texture)
|
||||
};
|
||||
|
||||
class RendererPack {
|
||||
|
||||
public:
|
||||
std::vector<struct RendererData> data;
|
||||
RendererPack();
|
||||
~RendererPack();
|
||||
};
|
|
@ -1,33 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
#include "shader.hpp"
|
||||
#include "../common.hpp"
|
||||
#include "../macros.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;
|
||||
LOG(LOG_ERR, "Failed compiling new shader");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
this->id = new_shader;
|
||||
this->type = type;
|
||||
|
||||
return new_shader;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
struct Shader {
|
||||
unsigned int id;
|
||||
unsigned int type;
|
||||
|
||||
unsigned int load(const char *path, unsigned int type);
|
||||
};
|
|
@ -1,12 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define LOG_DEBUG "debug"
|
||||
#define LOG_WARN "warning"
|
||||
#define LOG_ERR "error"
|
||||
|
||||
#define LOG(level, ...) std::cout << "[" << __TIME__ << " " << level << "]: " << __VA_ARGS__ << std::endl;
|
||||
|
||||
#define RET_OK 0
|
||||
#define RET_ERR -1
|
|
@ -1,39 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "window.hpp"
|
||||
#include "../macros.hpp"
|
||||
|
||||
int Window::init(int width, int height, std::string title) {
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
this->window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
|
||||
if (this->window == NULL) {
|
||||
LOG(LOG_ERR, "Failed creating window");
|
||||
glfwTerminate();
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(this->window);
|
||||
|
||||
GLenum err = glewInit();
|
||||
if (err != GLEW_OK) {
|
||||
LOG(LOG_ERR, "FAiled initializing Glew");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
glfwSetFramebufferSizeCallback(this->window, this->resize_callback);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void Window::resize_callback(GLFWwindow *window, int new_width, int new_height) {
|
||||
glViewport(0, 0, new_width, new_height);
|
||||
}
|
||||
|
||||
void Window::get_size(int *width, int *height) {
|
||||
glfwGetWindowSize(this->window, width, height);
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class Window {
|
||||
public:
|
||||
int init(int width, int height, std::string title);
|
||||
|
||||
static void resize_callback(GLFWwindow *window, int new_width, int new_height);
|
||||
void get_size(int *width, int *height);
|
||||
|
||||
GLFWwindow *window;
|
||||
};
|
|
@ -1,48 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <stb/stb_image.h>
|
||||
#include "base/window/window.hpp"
|
||||
#include "base/graphics/renderer.hpp"
|
||||
#include "base/macros.hpp"
|
||||
#include "sprites/sprite.hpp"
|
||||
|
||||
const int initial_width = 1000;
|
||||
const int initial_height = 600;
|
||||
|
||||
int main() {
|
||||
Window window;
|
||||
window.init(initial_width, initial_height, "OpenGL");
|
||||
|
||||
Renderer main_renderer(window);
|
||||
int ret = main_renderer.setup();
|
||||
if (ret != RET_OK) {
|
||||
LOG(LOG_ERR, "Failed setting up a new renderer");
|
||||
return RET_ERR;
|
||||
}
|
||||
|
||||
std::vector<Sprite> sprites;
|
||||
|
||||
Sprite sprite(main_renderer);
|
||||
sprite.bake();
|
||||
|
||||
sprite.origin = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
while (!glfwWindowShouldClose(window.window)) {
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
sprite.update();
|
||||
main_renderer.logic();
|
||||
main_renderer.batch();
|
||||
|
||||
glfwPollEvents();
|
||||
glfwSwapBuffers(window.window);
|
||||
}
|
||||
|
||||
|
||||
glfwTerminate();
|
||||
return RET_OK;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
|
@ -1,44 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include "../base/graphics/renderer.hpp"
|
||||
#include "sprite.hpp"
|
||||
|
||||
Sprite::Sprite(Renderer &renderer) : renderer(renderer) {
|
||||
this->vertices = std::vector<glm::vec4>();
|
||||
this->origin = glm::vec4(1.0f);
|
||||
this->color = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
this->texture_position = glm::vec2(0.0f);
|
||||
this->ctt = 1.0f;
|
||||
}
|
||||
|
||||
// prepare data
|
||||
void Sprite::bake() {
|
||||
this->vertices.push_back(glm::vec4(0.5f, 0.5f, 0.0f, 0.0f));
|
||||
this->vertices.push_back(glm::vec4(0.5f, -0.5f, 0.0f, 0.0f));
|
||||
this->vertices.push_back(glm::vec4(-0.5f, -0.5f, 0.0f, 0.0f));
|
||||
|
||||
this->vertices.push_back(glm::vec4(-0.5f, 0.5f, 0.0f, 0.0f));
|
||||
this->vertices.push_back(glm::vec4(0.5f, 0.5f, 0.0f, 0.0f));
|
||||
this->vertices.push_back(glm::vec4(-0.5f, -0.5f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
void Sprite::update() {
|
||||
for (int i = 0; i < this->vertices.size(); i++) {
|
||||
struct RendererData data = {
|
||||
.vertex = this->vertices[i],
|
||||
.origin = this->origin,
|
||||
.color = this->color,
|
||||
.tex = this->texture_position,
|
||||
.ctt_ratio = this->ctt
|
||||
};
|
||||
|
||||
this->renderer.draw(data);
|
||||
}
|
||||
}
|
||||
|
||||
Sprite::~Sprite() {
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <GL/glew.h>
|
||||
#include "../base/graphics/renderer.hpp"
|
||||
|
||||
class Sprite {
|
||||
public:
|
||||
std::vector<glm::vec4> vertices;
|
||||
glm::vec4 origin;
|
||||
glm::vec4 color;
|
||||
glm::vec2 texture_position;
|
||||
float ctt;
|
||||
|
||||
// GLuint vertex_buffer_id;
|
||||
Renderer &renderer;
|
||||
|
||||
Sprite(Renderer &renderer);
|
||||
~Sprite();
|
||||
|
||||
void bake();
|
||||
void update();
|
||||
};
|
Before Width: | Height: | Size: 89 KiB |
|
@ -1,28 +0,0 @@
|
|||
CC=g++
|
||||
CFLAGS=-std=c++20 `pkg-config --cflags glfw3 glew glm`
|
||||
LDFLAGS=`pkg-config --libs glfw3 glew glm`
|
||||
TARGET=boilerplate
|
||||
SDIR=src
|
||||
ADIR=assets
|
||||
ODIR=build
|
||||
|
||||
SRC=$(shell find $(SDIR) -type f -name *.cpp)
|
||||
OBJ=$(SRC:.cpp=.o)
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
.PHONY: default
|
||||
$(TARGET): $(OBJ)
|
||||
mkdir -p build
|
||||
cp -rf $(ADIR) $(ODIR)/
|
||||
$(CC) -o $(ODIR)/$@ $^ $(LDFLAGS)
|
||||
|
||||
%.o: %.cpp
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
run:
|
||||
$(ODIR)/$(TARGET)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(ODIR)/$(TARGET) $(OBJ)
|
|
@ -1,10 +0,0 @@
|
|||
<p align="center">
|
||||
<img src=".imgs/showcase.png" width="300" />
|
||||
</p>
|
||||
|
||||
# Particle System OpenGL
|
||||
|
||||
Contains a particle system abstraction on top of the previous OpenGL boilerplate code (`07-boilerplate`).
|
||||
|
||||
Each particle system is supposed (although not necessary) to have 1 renderer fully for itself.
|
||||
Meaning that all the particles will be batched into 1 draw call.
|
Before Width: | Height: | Size: 3.8 MiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.2 KiB |
|
@ -1,12 +0,0 @@
|
|||
#version 330 core
|
||||
in vec4 _color;
|
||||
in vec2 _texture_position;
|
||||
in float _ctt;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform sampler2D sampler;
|
||||
|
||||
void main() {
|
||||
color = texture(sampler, _texture_position) * (_color * _ctt);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec4 position;
|
||||
layout (location = 1) in vec4 origin;
|
||||
layout (location = 2) in vec4 size;
|
||||
layout (location = 3) in vec4 color;
|
||||
layout (location = 4) in vec2 texture_position;
|
||||
layout (location = 5) in float ctt;
|
||||
|
||||
uniform mat4 view_matrix;
|
||||
uniform mat4 projection_matrix;
|
||||
|
||||
out vec4 _color;
|
||||
out vec2 _texture_position;
|
||||
out float _ctt;
|
||||
|
||||
void main() {
|
||||
vec3 origined_position = origin.xyz + position.xyz;
|
||||
|
||||
origined_position *= size.xyz;
|
||||
|
||||
gl_Position = projection_matrix * view_matrix * vec4(origined_position, 1.0);
|
||||
_color = color;
|
||||
_texture_position = texture_position;
|
||||
_ctt = ctt;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
#version 330 core
|
||||
out vec4 color;
|
||||
in vec2 tex_coord;
|
||||
|
||||
uniform sampler2D sampler;
|
||||
|
||||
void main() {
|
||||
color = texture(sampler, tex_coord);
|
||||
// color = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if (color.a < 0.1)
|
||||
discard;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texture_coord;
|
||||
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec2 tex_coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * view * vec4(pos.xyz, 1.0);
|
||||
tex_coord = texture_coord;
|
||||
}
|
Before Width: | Height: | Size: 119 KiB |
|
@ -1,22 +0,0 @@
|
|||
#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;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string read_file(const char *path);
|