05: Bootstrap basic OpenGL project
This commit is contained in:
parent
ce0f93a572
commit
67aa648299
Binary file not shown.
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 105 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<!-- <p align="center"> -->
|
<p align="center">
|
||||||
<!-- <img src=".imgs/showcase.png" width="300" /> -->
|
<img src=".imgs/showcase.png" width="300" />
|
||||||
<!-- </p> -->
|
</p>
|
||||||
|
|
||||||
# Map
|
# Map
|
||||||
|
|
||||||
|
|
29
05-opengl/Makefile
Normal file
29
05-opengl/Makefile
Normal 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
3
05-opengl/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Opengl
|
||||||
|
|
||||||
|
Playing with Opengl because I realized SDL2 is not enough :/
|
BIN
05-opengl/assets/linux.png
Normal file
BIN
05-opengl/assets/linux.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
12
05-opengl/assets/shaders/shader.frag
Normal file
12
05-opengl/assets/shaders/shader.frag
Normal 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;
|
||||||
|
}
|
11
05-opengl/assets/shaders/shader.vert
Normal file
11
05-opengl/assets/shaders/shader.vert
Normal 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
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
164
05-opengl/src/game.cpp
Normal 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
33
05-opengl/src/game.hpp
Normal 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
40
05-opengl/src/main.cpp
Normal 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
45
05-opengl/src/object.cpp
Normal 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
28
05-opengl/src/object.hpp
Normal 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;
|
||||||
|
};
|
2
05-opengl/src/other/stb_image.cpp
Normal file
2
05-opengl/src/other/stb_image.cpp
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
7987
05-opengl/src/other/stb_image.h
Normal file
7987
05-opengl/src/other/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
21
05-opengl/src/texture.cpp
Normal file
21
05-opengl/src/texture.cpp
Normal 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
10
05-opengl/src/texture.hpp
Normal 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);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user