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"> -->
|
||||
<!-- <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
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