05: Bootstrap basic OpenGL project

This commit is contained in:
0xdeadbeer 2023-12-01 00:36:23 +01:00
parent ce0f93a572
commit 67aa648299
18 changed files with 8390 additions and 5 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 105 KiB

View File

@ -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

29
05-opengl/Makefile Normal file
View File

@ -0,0 +1,29 @@
CC=g++
CFLAGS=`pkg-config --cflags glfw3 glew`
LDFLAGS=`pkg-config --libs glfw3 glew`
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)

3
05-opengl/README.md Normal file
View File

@ -0,0 +1,3 @@
# Opengl
Playing with Opengl because I realized SDL2 is not enough :/

BIN
05-opengl/assets/linux.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,12 @@
#version 330 core
out vec4 color;
in vec2 tex_coord;
uniform sampler2D texture1;
void main() {
color = texture(texture1, tex_coord);
if (color.a < 0.1)
discard;
}

View File

@ -0,0 +1,11 @@
#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;
}

BIN
05-opengl/assets/wall.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

164
05-opengl/src/game.cpp Normal file
View File

@ -0,0 +1,164 @@
#include <iostream>
#include <fstream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "game.hpp"
#include "texture.hpp"
#include "object.hpp"
#include "other/stb_image.h"
Game::Game(GLFWwindow *window) {
this->window = window;
this->program = glCreateProgram();
}
void Game::setup() {
}
void Game::run(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);
this->vshader = Game::load_shader("assets/shaders/shader.vert", GL_VERTEX_SHADER);
if (!this->vshader)
return;
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;
new_texture.bind_texture();
new_texture.load_data(image_bytes, width, height);
stbi_image_free(image_bytes);
Object new_object(this, new_texture);
new_object.vertices = {
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-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();
}
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 i = 0; i < this->objects.size(); i++)
(*this->objects[i]).draw();
glfwPollEvents();
glfwSwapBuffers(this->window);
}
glBindVertexArray(0);
}
unsigned int Game::load_shader(const char *path, unsigned int type) {
std::string source = Game::read_file(path);
const char *bytes = source.c_str();
unsigned int new_shader = glCreateShader(type);
if (!new_shader)
return 0;
glShaderSource(new_shader, 1, &bytes, 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;
}
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;
}

33
05-opengl/src/game.hpp Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <iostream>
#include <vector>
#include <GLFW/glfw3.h>
#include "object.hpp"
class Game {
public:
Game(GLFWwindow *window);
static std::string read_file(const char *path);
unsigned int load_shader(const char *path, unsigned int type);
int link_program();
void setup();
void run(int initial_width, int initial_height);
void logic();
// 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;
std::vector<Object*> objects;
unsigned int vao;
unsigned int vbo;
unsigned int ebo;
unsigned int vshader;
unsigned int fshader;
unsigned int program;
};

40
05-opengl/src/main.cpp Normal file
View File

@ -0,0 +1,40 @@
#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.run(initial_width, initial_height);
glfwTerminate();
return 0;
}

45
05-opengl/src/object.cpp Normal file
View File

@ -0,0 +1,45 @@
#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);
}

28
05-opengl/src/object.hpp Normal file
View File

@ -0,0 +1,28 @@
#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;
};

View File

@ -0,0 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

File diff suppressed because it is too large Load Diff

21
05-opengl/src/texture.cpp Normal file
View File

@ -0,0 +1,21 @@
#include <GL/glew.h>
#include "texture.hpp"
Texture::Texture() {
glGenTextures(1, &this->texture_id);
}
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_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void Texture::load_data(unsigned char *bytes, int width, int height) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bytes);
glGenerateMipmap(GL_TEXTURE_2D);
}

10
05-opengl/src/texture.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
class Texture {
public:
unsigned int texture_id;
Texture();
void bind_texture();
void load_data(unsigned char *bytes, int width, int height);
};

View File

@ -2,9 +2,9 @@
<img src=".imgs/icon.png" width="200"/>
</p>
# SDL Playground
# Graphics
My little playground for SDL.
My little playground for everything graphics
## License