Merge branch 'graphics_api_abstraction_layer' of http://git.cubesoftware.xyz:20524/kacperks/PolyGun into HEAD

This commit is contained in:
{{QWERTYKBGUI}} 2023-04-22 09:49:25 +02:00
commit c1afe4de62
34 changed files with 1551 additions and 322 deletions

View File

@ -14,6 +14,15 @@ include_directories("${CMAKE_BINARY_DIR}")
configure_file("config.hpp.in" "config.hpp")
option(BUILD_CLIENT "Build client" ON)
option(BUILD_SERVER "Build server" ON)
if(APPLE)
set(RENDERER_GL_DEFAULT OFF)
else()
set(RENDERER_GL_DEFAULT ON)
endif()
option(RENDERER_GL "Enable OpenGL renderer" ${RENDERER_GL_DEFAULT})
if(NOT BUILD_CLIENT)
set(RENDERER_GL OFF)
endif()
if(BUILD_CLIENT)
file(GLOB_RECURSE CLIENT_SOURCES "src/game/**.cpp")
@ -21,10 +30,20 @@ endif()
if(BUILD_SERVER)
file(GLOB_RECURSE SERVER_SOURCES "src/server/**.cpp")
endif()
if(RENDERER_GL)
file(GLOB_RECURSE RENDERER_GL_SOURCES "src/game/renderer/gl/**.cpp")
endif()
file(GLOB_RECURSE COMMON_SOURCES "src/common/**.cpp")
file(GLOB_RECURSE VENDOR_SOURCES "src/vendor/**.cpp")
add_executable(${PROJECT_NAME} ${CLIENT_SOURCES} ${SERVER_SOURCES} ${COMMON_SOURCES} ${VENDOR_SOURCES} src/main.cpp)
add_executable(${PROJECT_NAME}
${CLIENT_SOURCES}
${SERVER_SOURCES}
${COMMON_SOURCES}
${VENDOR_SOURCES}
${RENDERER_GL_SOURCES}
src/main.cpp
)
if(NOT OPENGL_INCLUDE_DIR OR NOT OPENGL_LIBRARIES)
find_package(OpenGL REQUIRED)

View File

@ -24,3 +24,4 @@ SOFTWARE.
#cmakedefine BUILD_CLIENT
#cmakedefine BUILD_SERVER
#cmakedefine RENDERER_GL

View File

@ -1,11 +0,0 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D texture_atlas;
void main()
{
FragColor = texture(texture_atlas, TexCoord);
}

View File

@ -1,15 +0,0 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0f);
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

View File

@ -0,0 +1,11 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D uniform_texture_num;
void main()
{
FragColor = texture(uniform_texture_num, TexCoord);
}

View File

@ -0,0 +1,15 @@
#version 330 core
layout (location = 0) in vec3 in_pos;
layout (location = 1) in vec2 in_uv;
out vec2 TexCoord;
uniform mat4 uniform_model;
uniform mat4 uniform_view;
uniform mat4 uniform_projection;
void main()
{
gl_Position = uniform_projection * uniform_view * uniform_model * vec4(in_pos, 1.0f);
TexCoord = vec2(in_uv.x, in_uv.y);
}

View File

@ -19,7 +19,9 @@ namespace polygun::engine {
void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); glfwGetWindowSize(window, &sizex, &sizey);}
Engine::Engine() :
m_screen_manager(*this)
m_screen_manager(*this),
m_window(nullptr),
m_master_renderer()
{}
void Engine::init() {

View File

@ -6,6 +6,7 @@
#include "game/core.hpp"
#include "game/engine/screen_manager.hpp"
#include "game/renderer/master_renderer.hpp"
namespace polygun::engine {
@ -13,6 +14,7 @@ namespace polygun::engine {
private:
ScreenManager m_screen_manager;
GLFWwindow* m_window;
renderer::MasterRenderer m_master_renderer;
public:
Engine();
@ -24,6 +26,8 @@ namespace polygun::engine {
ScreenManager& get_screen_manager() { return m_screen_manager; }
GLFWwindow* get_window() { return m_window; }
renderer::MasterRenderer& get_master_renderer() { return m_master_renderer; }
renderer::MeshRenderer* get_mesh_renderer() { return m_master_renderer.get_mesh_renderer(); }
static int get_screen_width();
static int get_screen_height();

View File

@ -1,11 +1,13 @@
#include "game/engine/player_camera.hpp"
#include "game/engine/engine.hpp"
using namespace polygun::engine;
static float mx,my;
float pitch_cos;
Camera::Camera(glm::vec3 position, glm::vec3 up, float yaw, float pitch) :
PlayerCamera::PlayerCamera(glm::vec3 position, glm::vec3 up, float yaw, float pitch) :
m_position(position),
m_front(glm::vec3(0.0f, 0.0f, -1.0f)),
m_movement_front(),
@ -24,7 +26,7 @@ Camera::Camera(glm::vec3 position, glm::vec3 up, float yaw, float pitch) :
update_camera_vectors();
}
Camera::Camera(float pos_x, float pos_y, float pos_z, float up_x, float up_y, float up_z, float yaw, float pitch) :
PlayerCamera::PlayerCamera(float pos_x, float pos_y, float pos_z, float up_x, float up_y, float up_z, float yaw, float pitch) :
m_position(pos_x, pos_y, pos_z),
m_front(glm::vec3(0.0f, 0.0f, -1.0f)),
m_movement_front(),
@ -43,7 +45,7 @@ Camera::Camera(float pos_x, float pos_y, float pos_z, float up_x, float up_y, fl
update_camera_vectors();
}
void Camera::update(bool reset) {
void PlayerCamera::update(bool reset) {
if (m_first_mouse || reset) {
m_last_x = mx;
m_last_y = my;
@ -62,7 +64,7 @@ void Camera::update(bool reset) {
}
void Camera::process_movement(camera_movement direction, float delta_time) {
void PlayerCamera::process_movement(camera_movement direction, float delta_time) {
float velocity = m_movement_speed * delta_time;
if (direction == FORWARD)
m_position += glm::vec3(m_movement_front.x, 0.0f, m_movement_front.y) * velocity;
@ -76,9 +78,11 @@ void Camera::process_movement(camera_movement direction, float delta_time) {
m_position += glm::vec3(0.0f, 1.0f, 0.0f) * velocity;
if (direction == DOWN)
m_position += glm::vec3(0.0f, -1.0f, 0.0f) * velocity;
m_view = glm::lookAt(m_position, m_position + m_front, m_up);
}
void Camera::process_mouse_movement(float x_offset, float y_offset, GLboolean constrain_pitch) {
void PlayerCamera::process_mouse_movement(float x_offset, float y_offset, GLboolean constrain_pitch) {
x_offset *= m_mouse_sensitivity;
y_offset *= m_mouse_sensitivity;
@ -95,7 +99,7 @@ void Camera::process_mouse_movement(float x_offset, float y_offset, GLboolean co
update_camera_vectors();
}
void Camera::process_mouse_scroll(float y_offset) {
void PlayerCamera::process_mouse_scroll(float y_offset) {
m_fov -= y_offset;
if (m_fov < 1.0f)
m_fov = 1.0f;
@ -103,12 +107,12 @@ void Camera::process_mouse_scroll(float y_offset) {
m_fov = 45.0f;
}
void Camera::mouse_callback(GLFWwindow* window, double x_pos_in, double y_pos_in) {
void PlayerCamera::mouse_callback(GLFWwindow* window, double x_pos_in, double y_pos_in) {
mx = static_cast<float>(x_pos_in);
my = static_cast<float>(y_pos_in);
}
void Camera::update_camera_vectors() {
void PlayerCamera::update_camera_vectors() {
glm::vec3 front;
pitch_cos = cos(glm::radians(m_pitch));
@ -122,4 +126,7 @@ void Camera::update_camera_vectors() {
m_front = glm::normalize(front);
m_right = glm::normalize(glm::cross(m_front, m_worldup));
m_up = glm::normalize(glm::cross(m_right, m_front));
m_view = glm::lookAt(m_position, m_position + m_front, m_up);
m_projection = glm::perspective(glm::radians(m_fov), (float)engine::Engine::get_screen_width() / (float)engine::Engine::get_screen_height(), 0.1f, 100.0f);
}

View File

@ -1,6 +1,8 @@
#ifndef POLYGUN_ENGINE_CAMERA_H
#define POLYGUN_ENGINE_CAMERA_H
#include "game/renderer/camera.hpp"
#include "game/core.hpp"
namespace polygun::engine {
@ -19,7 +21,7 @@ namespace polygun::engine {
const float SENSITIVITY = 0.1f;
const float FOV = 90.0f;
class Camera {
class PlayerCamera final : public renderer::Camera {
public:
glm::vec3 m_position;
glm::vec3 m_front;
@ -33,12 +35,9 @@ namespace polygun::engine {
float m_mouse_sensitivity;
float m_fov;
Camera(glm::vec3 position = glm::vec3(-0.5f, 0.25f, -0.5f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
Camera(float pos_x, float pos_y, float pos_z, float up_x, float up_y, float up_z, float yaw, float pitch);
glm::mat4 get_view_matrix() const {
return glm::lookAt(m_position, m_position + m_front, m_up);
}
public:
PlayerCamera(glm::vec3 position = glm::vec3(-0.5f, 0.25f, -0.5f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), float yaw = YAW, float pitch = PITCH);
PlayerCamera(float pos_x, float pos_y, float pos_z, float up_x, float up_y, float up_z, float yaw, float pitch);
void update(bool reset);
void process_movement(camera_movement direction, float delta_time);

View File

@ -0,0 +1,44 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_CAMERA_HPP
#define POLYGUN_RENDERER_CAMERA_HPP
#include <glm/glm.hpp>
namespace polygun::renderer {
class Camera {
public:
Camera() = default;
virtual ~Camera(){}
const glm::mat4& get_view() const { return m_view; }
const glm::mat4& get_projection() const { return m_projection; }
protected:
glm::mat4 m_view, m_projection;
};
}
#endif // POLYGUN_RENDERER_CAMERA_HPP

View File

@ -0,0 +1,96 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/gl/gl_mesh.hpp"
#include "game/renderer/gl/opengl.hpp"
using namespace polygun::renderer;
GLMesh::GLMesh() :
m_vao(0),
m_vbo(0),
m_tbo(0),
m_ebo(0),
m_nbo(0),
m_element_count(0)
{
if(GLEW_ARB_vertex_array_object)
glGenVertexArrays(1, &m_vao);
}
GLMesh::~GLMesh() {
if(GLEW_ARB_vertex_array_object)
glDeleteVertexArrays(1, &m_vao);
if(m_vbo>0)
glDeleteBuffers(1, &m_vbo);
if(m_ebo>0)
glDeleteBuffers(1, &m_ebo);
if(m_nbo>0)
glDeleteBuffers(1, &m_nbo);
}
void GLMesh::load_vertices(const std::vector<float>& vertices) {
if(GLEW_ARB_vertex_array_object)
glBindVertexArray(m_vao);
if(m_vbo==0)
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(float), vertices.data(), GL_STATIC_DRAW);
if(GLEW_ARB_vertex_array_object) {
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
}
void GLMesh::load_indices(const std::vector<unsigned>& indices) {
if(m_ebo==0)
glGenBuffers(1, &m_ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned), indices.data(), GL_STATIC_DRAW);
m_element_count = indices.size();
}
void GLMesh::load_uvs(const std::vector<float>& uvs) {
if(m_tbo==0)
glGenBuffers(1, &m_tbo);
glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
glBufferData(GL_ARRAY_BUFFER, uvs.size()*sizeof(float), uvs.data(), GL_STATIC_DRAW);
if(GLEW_ARB_vertex_array_object) {
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
}
}
void GLMesh::load_normals(const std::vector<float>& normals) {
if(m_nbo==0)
glGenBuffers(1, &m_nbo);
glBindBuffer(GL_ARRAY_BUFFER, m_nbo);
glBufferData(GL_ARRAY_BUFFER, normals.size()*sizeof(float), normals.data(), GL_STATIC_DRAW);
if(GLEW_ARB_vertex_array_object) {
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(2);
}
}

View File

@ -0,0 +1,49 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_GL_MESH_HPP
#define POLYGUN_RENDERER_GL_MESH_HPP
#include "game/renderer/mesh.hpp"
namespace polygun::renderer {
class GLMesh final : public Mesh {
friend class GLMeshRenderer;
public:
GLMesh();
virtual ~GLMesh() override;
private:
unsigned m_vao, m_vbo, m_tbo, m_nbo, m_ebo;
unsigned m_element_count;
protected:
virtual void load_vertices(const std::vector<float>& vertices) override;
virtual void load_indices(const std::vector<unsigned>& indices) override;
virtual void load_uvs(const std::vector<float>& uvs) override;
virtual void load_normals(const std::vector<float>& normals) override;
};
}
#endif // POLYGUN_RENDERER_GL_MESH_HPP

View File

@ -0,0 +1,187 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/gl/gl_mesh_renderer.hpp"
#include "game/renderer/gl/gl_mesh.hpp"
#include "game/renderer/gl/gl_shader.hpp"
#include "game/renderer/gl/gl_texture.hpp"
#include "game/renderer/camera.hpp"
#include "common/logger.hpp"
using namespace polygun::renderer;
GLMeshRenderer::GLMeshRenderer() :
m_shader(nullptr),
m_prev_mesh(nullptr),
m_prev_texture(nullptr)
{}
void GLMeshRenderer::render(Mesh* mesh, const glm::vec4& color) {
if(!m_shader) {
LOG_ERROR("Attempt to render mesh without active shader!");
return;
}
GLMesh* gl_mesh = static_cast<GLMesh*>(mesh);
if(mesh!=m_prev_mesh) {
if(m_prev_mesh && !GLEW_ARB_vertex_array_object) {
glDisableVertexAttribArray(m_shader->get_attrib_location("in_pos"));
check_gl();
if(mesh->has_normals()) {
glDisableVertexAttribArray(m_shader->get_attrib_location("in_normal"));
check_gl();
}
}
if(GLEW_ARB_vertex_array_object) {
glBindVertexArray(gl_mesh->m_vao);
check_gl();
}
if(!GLEW_ARB_vertex_array_object) {
legacy_prepare_mesh_array_buffer(gl_mesh->m_vbo, 3, "in_pos");
if(mesh->has_normals())
legacy_prepare_mesh_array_buffer(gl_mesh->m_nbo, 3, "in_normal");
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_mesh->m_ebo);
check_gl();
m_prev_mesh = mesh;
}
m_shader->set_uniform("uniform_model", m_transform);
check_gl();
m_shader->set_uniform("uniform_view", m_camera->get_view());
check_gl();
m_shader->set_uniform("uniform_projection", m_camera->get_projection());
check_gl();
m_shader->set_uniform("uniform_color", color);
check_gl();
glDrawElements(GL_TRIANGLES, gl_mesh->m_element_count, GL_UNSIGNED_INT, nullptr);
check_gl();
m_transform = glm::mat4(1);
}
void GLMeshRenderer::render_textured(Mesh* mesh, Texture* texture) {
if(!m_shader) {
LOG_ERROR("Attempt to render mesh without active shader!");
return;
}
GLMesh* gl_mesh = static_cast<GLMesh*>(mesh);
if(mesh!=m_prev_mesh) {
if(!mesh->has_texture_uvs()) {
LOG_ERROR("Attempt to render mesh without texture as textured!");
return;
}
if(m_prev_mesh && !GLEW_ARB_vertex_array_object) {
glDisableVertexAttribArray(m_shader->get_attrib_location("in_pos"));
glDisableVertexAttribArray(m_shader->get_attrib_location("in_uv"));
if(mesh->has_normals())
glDisableVertexAttribArray(m_shader->get_attrib_location("in_normal"));
}
if(GLEW_ARB_vertex_array_object) {
glBindVertexArray(gl_mesh->m_vao);
check_gl();
}
if(!GLEW_ARB_vertex_array_object) {
legacy_prepare_mesh_array_buffer(gl_mesh->m_vbo, 3, "in_pos");
legacy_prepare_mesh_array_buffer(gl_mesh->m_tbo, 2, "in_uv");
if(mesh->has_normals())
legacy_prepare_mesh_array_buffer(gl_mesh->m_nbo, 3, "in_normal");
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl_mesh->m_ebo);
check_gl();
m_prev_mesh = mesh;
}
if(texture!=m_prev_texture) {
GLTexture* gl_texture = static_cast<GLTexture*>(texture);
glActiveTexture(GL_TEXTURE0);
gl_texture->bind();
m_shader->set_uniform("uniform_texture_num", 0);
check_gl();
m_prev_texture = texture;
}
m_shader->set_uniform("uniform_model", m_transform);
check_gl();
glDrawElements(GL_TRIANGLES, gl_mesh->m_element_count, GL_UNSIGNED_INT, nullptr);
check_gl();
m_transform = glm::mat4(1);
}
void GLMeshRenderer::render_with_multiple_textures(Mesh* mesh, const std::vector<Texture*>& textures) {
// TODO
}
void GLMeshRenderer::set_shader(Shader* shader) {
m_shader = static_cast<GLShader*>(shader);
m_shader->bind();
check_gl();
}
void GLMeshRenderer::set_camera(Camera* camera) {
m_camera = camera;
if(m_shader) {
m_shader->set_uniform("uniform_view", m_camera->get_view());
check_gl();
m_shader->set_uniform("uniform_projection", m_camera->get_projection());
check_gl();
}
}
void GLMeshRenderer::set_3d_rendering_mode(bool enable) {
if(enable)
glEnable(GL_DEPTH_TEST);
else
glDisable(GL_DEPTH_TEST);
check_gl();
}
void GLMeshRenderer::legacy_prepare_mesh_array_buffer(unsigned buffer, unsigned attrib_size, const std::string& attrib_name) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
check_gl();
glVertexAttribPointer(m_shader->get_attrib_location(attrib_name.c_str()), attrib_size, GL_FLOAT, GL_FALSE, 0, (void*)0);
check_gl();
glEnableVertexAttribArray(m_shader->get_attrib_location(attrib_name.c_str()));
check_gl();
}
void GLMeshRenderer::check_gl() {
GLenum error = glGetError();
if(error!=GL_NO_ERROR)
LOG_ERROR("Previous OpenGL operation failed with code: %d", error);
}

View File

@ -0,0 +1,56 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_GL_MESH_RENDERER_HPP
#define POLYGUN_RENDERER_GL_MESH_RENDERER_HPP
#include "game/renderer/mesh_renderer.hpp"
#include <string>
namespace polygun::renderer {
class GLShader;
class GLMeshRenderer final : public MeshRenderer {
public:
GLMeshRenderer();
virtual void render(Mesh* mesh, const glm::vec4& color) override;
virtual void render_textured(Mesh* mesh, Texture* texture) override;
virtual void render_with_multiple_textures(Mesh* mesh, const std::vector<Texture*>& textures) override;
virtual void set_shader(Shader* shader) override;
virtual void set_camera(Camera* camera) override;
virtual void set_3d_rendering_mode(bool enable) override;
private:
GLShader* m_shader;
Mesh* m_prev_mesh;
Texture* m_prev_texture;
private:
void legacy_prepare_mesh_array_buffer(unsigned buffer, unsigned attrib_size, const std::string& attrib_name);
static void check_gl();
};
}
#endif // POLYGUN_RENDERER_GL_MESH_RENDERER_HPP

View File

@ -0,0 +1,183 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
2023 kacperks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/gl/gl_shader.hpp"
#include <fstream>
#include <sstream>
#include "common/logger.hpp"
using namespace polygun::renderer;
GLShader::GLShader() :
m_program(glCreateProgram()),
m_uniform_locations(),
m_attrib_locations()
{}
GLShader::~GLShader() {
glDeleteProgram(m_program);
}
void GLShader::bind() {
glUseProgram(m_program);
}
void GLShader::set_uniform(const GLchar* u_name, unsigned int value) {
glUniform1i(get_uniform_location(u_name), value);
}
void GLShader::set_uniform(const GLchar* u_name, int value) {
glUniform1i(get_uniform_location(u_name), value);
}
void GLShader::set_uniform(const GLchar* u_name, GLfloat value) {
glUniform1i(get_uniform_location(u_name), value);
}
void GLShader::set_uniform(const GLchar* u_name, GLfloat x, GLfloat y) {
glUniform2f(get_uniform_location(u_name), x, y);
}
void GLShader::set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z) {
glUniform3f(get_uniform_location(u_name), x, y, z);
}
void GLShader::set_uniform(const GLchar* u_name, const glm::vec3& vector) {
glUniform3f(get_uniform_location(u_name), vector.x, vector.y, vector.z);
}
void GLShader::set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
glUniform4f(get_uniform_location(u_name), x, y, z, w);
}
void GLShader::set_uniform(const GLchar* name, const glm::mat4 &mat) {
glUniformMatrix4fv(get_uniform_location(name), 1, GL_FALSE, &mat[0][0]);
}
void GLShader::set_uniform(const GLchar* u_name, const glm::vec2& vector) {
glUniform2f(get_uniform_location(u_name), vector.x, vector.y);
}
void GLShader::set_uniform(const GLchar* u_name, const glm::vec4& vector){
glUniform4f(get_uniform_location(u_name), vector.x, vector.y, vector.z, vector.w);
}
void GLShader::set_uniform(const GLchar* u_name, GLuint tex2d, GLint unit){ // sample 2d
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, tex2d);
glUniform1i(get_uniform_location(u_name), unit);
}
GLuint GLShader::get_attrib_location(const GLchar* a_name) {
if(GLEW_ARB_vertex_array_object)
LOG_WARNING("get_attrib_location used even if VAO is available");
std::string name(a_name);
if(m_attrib_locations.count(name))
return m_attrib_locations[name];
return (m_attrib_locations[name] = glGetAttribLocation(m_program, a_name));
}
bool GLShader::load_from_file(const std::string& name) {
std::string base_shader_path;
// if VAO is available use shaders which use it
if(GLEW_ARB_vertex_array_object)
base_shader_path = "shaders/gl/";
else
base_shader_path = "shaders/gl2/";
std::string vertex_code;
std::string fragment_code;
std::ifstream v_shader_file;
std::ifstream f_shader_file;
v_shader_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
f_shader_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
v_shader_file.open(base_shader_path+name+"_vertex.glsl");
f_shader_file.open(base_shader_path+name+"_fragment.glsl");
std::stringstream v_shader_stream, f_shader_stream;
v_shader_stream << v_shader_file.rdbuf();
f_shader_stream << f_shader_file.rdbuf();
v_shader_file.close();
f_shader_file.close();
vertex_code = v_shader_stream.str();
fragment_code = f_shader_stream.str();
}
catch (std::ifstream::failure& e) {
LOG_ERROR("Shader file wasn't successfuly read: %s", e.what());
return false;
}
const char* v_shader_code = vertex_code.c_str();
const char * f_shader_code = fragment_code.c_str();
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &v_shader_code, NULL);
glCompileShader(vertex);
if(!check_compile_errors(vertex, "VERTEX"))
return false;
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &f_shader_code, NULL);
glCompileShader(fragment);
if(!check_compile_errors(fragment, "FRAGMENT"))
return false;
m_program = glCreateProgram();
glAttachShader(m_program, vertex);
glAttachShader(m_program, fragment);
glLinkProgram(m_program);
if(!check_compile_errors(m_program, "PROGRAM"))
return false;
glDeleteShader(vertex);
glDeleteShader(fragment);
return true;
}
GLint GLShader::get_uniform_location(const GLchar* u_name) {
std::string name(u_name);
if(m_uniform_locations.count(name))
return m_uniform_locations[name];
return (m_uniform_locations[name] = glGetUniformLocation(m_program, u_name));
}
bool GLShader::check_compile_errors(GLuint shader, const std::string& type) {
GLint success;
GLchar info_log[1024];
if(type != "PROGRAM") {
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(shader, 1024, NULL, info_log);
LOG_ERROR("%s shader compilation error:\n%s", type.c_str(), info_log);
return false;
}
}
else {
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(shader, 1024, NULL, info_log);
LOG_ERROR("%s compilation error:\n%s", type.c_str(), info_log);
return false;
}
}
return true;
}

View File

@ -0,0 +1,70 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
2023 kacperks
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_GL_SHADER_HPP
#define POLYGUN_RENDERER_GL_SHADER_HPP
#include "game/renderer/shader.hpp"
#include <glm/glm.hpp>
#include <map>
#include "game/renderer/gl/opengl.hpp"
namespace polygun::renderer {
class GLShader final : public Shader {
public:
GLShader();
virtual ~GLShader() override;
void bind();
void set_uniform(const GLchar* u_name, unsigned int value);
void set_uniform(const GLchar* u_name, int value);
void set_uniform(const GLchar* u_name, GLfloat value);
void set_uniform(const GLchar* u_name, GLfloat x, GLfloat y);
void set_uniform(const GLchar* u_name, const glm::vec2& vector);
void set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z);
void set_uniform(const GLchar* u_name, const glm::vec3& vector);
void set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void set_uniform(const GLchar* u_name, const glm::vec4& vector);
void set_uniform(const GLchar* u_name, const glm::mat4& mtx);
void set_uniform(const GLchar* u_name, GLuint tex2d, GLint unit); // sample 2d
GLuint get_attrib_location(const GLchar* a_name);
virtual bool load_from_file(const std::string& name) override;
private:
GLuint m_program;
std::map<std::string, GLint> m_uniform_locations;
std::map<std::string, GLuint> m_attrib_locations;
private:
GLint get_uniform_location(const GLchar* u_name);
bool check_compile_errors(GLuint shader, const std::string& type);
};
}
#endif // POLYGUN_RENDERER_GL_SHADER_HPP

View File

@ -0,0 +1,65 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/gl/gl_texture.hpp"
#include "common/logger.hpp"
#include "game/renderer/gl/opengl.hpp"
using namespace polygun::renderer;
GLTexture::GLTexture() :
m_id(0)
{
glGenTextures(1, &m_id);
}
GLTexture::~GLTexture() {
glDeleteTextures(1, &m_id);
}
void GLTexture::bind() {
glBindTexture(GL_TEXTURE_2D, m_id);
}
bool GLTexture::load_from_pixel_data(const uint8_t* data, unsigned width, unsigned height, unsigned pixel_size) {
bind();
int format;
switch(pixel_size) {
case 3:
format = GL_RGB;
break;
case 4:
format = GL_RGBA;
break;
default:
LOG_ERROR("Invalid pixel size: %d", pixel_size);
return false;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}

View File

@ -0,0 +1,45 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_GL_TEXTURE_HPP
#define POLYGUN_RENDERER_GL_TEXTURE_HPP
#include "game/renderer/texture.hpp"
namespace polygun::renderer {
class GLTexture final : public Texture {
public:
GLTexture();
virtual ~GLTexture() override;
void bind();
virtual bool load_from_pixel_data(const uint8_t* data, unsigned width, unsigned height, unsigned pixel_size) override;
private:
unsigned m_id;
};
}
#endif // POLYGUN_RENDERER_GL_TEXTURE_HPP

View File

@ -0,0 +1,36 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_OPENGL_HPP
#define POLYGUN_RENDERER_OPENGL_HPP
#if defined(__apple__)
#include <OpenGL/glew.h>
#include <OpenGL/gl.h>
#else
#include <GL/glew.h>
#include <GL/gl.h>
#endif
#endif

View File

@ -0,0 +1,105 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/master_renderer.hpp"
#include <config.hpp>
#include "common/logger.hpp"
#if defined(RENDERER_GL)
#include "game/renderer/gl/gl_mesh_renderer.hpp"
#include "game/renderer/gl/gl_shader.hpp"
#include "game/renderer/gl/gl_mesh.hpp"
#include "game/renderer/gl/gl_texture.hpp"
#endif
using namespace polygun::renderer;
#if defined(RENDERER_GL)
static void clear_screen_impl_gl(float r, float g, float b) {
glClearColor(r, g, b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
#endif
MasterRenderer::MasterRenderer() :
m_renderer_type(RendererType::RENDERER_TYPE_GL),
m_clear_screen_impl(),
#if defined(RENDERER_GL)
m_mesh_renderer(new GLMeshRenderer)
#else
m_mesh_renderer()
#endif
{
switch(m_renderer_type) {
case RendererType::RENDERER_TYPE_GL:
#if defined(RENDERER_GL)
m_clear_screen_impl = clear_screen_impl_gl;
#endif
break;
}
// TODO: Load requested renderer from config or determine by platform
}
void MasterRenderer::clear_screen(float r, float g, float b) {
m_clear_screen_impl(r, g, b);
}
Shader* MasterRenderer::create_shader() const {
switch(m_renderer_type) {
case RendererType::RENDERER_TYPE_GL:
#if defined(RENDERER_GL)
return new GLShader;
#else
LOG_FATAL("Requested creating GLShader while OpenGL renderer is not available!");
break;
#endif
}
return nullptr;
}
Mesh* MasterRenderer::create_mesh() const {
switch(m_renderer_type) {
case RendererType::RENDERER_TYPE_GL:
#if defined(RENDERER_GL)
return new GLMesh;
#else
LOG_FATAL("Requested creating GLMesh while OpenGL renderer is not available!");
break;
#endif
}
return nullptr;
}
Texture* MasterRenderer::create_texture() const {
switch(m_renderer_type) {
case RendererType::RENDERER_TYPE_GL:
#if defined(RENDERER_GL)
return new GLTexture;
#else
LOG_FATAL("Requested creating GLTexture while OpenGL renderer is not available!");
break;
#endif
}
return nullptr;
}

View File

@ -0,0 +1,61 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_MASTER_RENDERER_HPP
#define POLYGUN_RENDERER_MASTER_RENDERER_HPP
#include <memory>
#include <functional>
#include "game/renderer/mesh_renderer.hpp"
namespace polygun::renderer {
class Shader;
class Mesh;
class Texture;
enum RendererType {
RENDERER_TYPE_GL
};
class MasterRenderer final {
public:
MasterRenderer();
~MasterRenderer() = default;
// FIXME: Move clear_screen to UIRenderer
void clear_screen(float r, float g, float b);
MeshRenderer* get_mesh_renderer() { return m_mesh_renderer.get(); }
Shader* create_shader() const;
Mesh* create_mesh() const;
Texture* create_texture() const;
private:
RendererType m_renderer_type;
std::function<void(float, float, float)> m_clear_screen_impl;
std::unique_ptr<MeshRenderer> m_mesh_renderer;
};
}
#endif // POLYGUN_RENDERER_MASTER_RENDERER_HPP

View File

@ -0,0 +1,51 @@
/*
PolyGun
Copyright (c) 2023 kacperks
2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/mesh.hpp"
using namespace polygun::renderer;
Mesh::Mesh() :
m_has_texture_uvs(false),
m_has_normals(false)
{}
void Mesh::load_from_memory(const std::vector<float>& vertices, const std::vector<unsigned>& indices) {
load_vertices(vertices);
load_indices(indices);
}
void Mesh::load_from_memory(const std::vector<float>& vertices, const std::vector<unsigned>& indices, const std::vector<float>& uvs) {
load_from_memory(vertices, indices);
load_uvs(uvs);
m_has_texture_uvs = true;
}
void Mesh::load_from_memory(const std::vector<float>& vertices, const std::vector<unsigned>& indices, const std::vector<float>& uvs, const std::vector<float>& normals) {
load_from_memory(vertices, indices, uvs);
load_normals(normals);
m_has_texture_uvs = true;
m_has_normals = true;
}

View File

@ -1,10 +1,55 @@
/*
PolyGun
Copyright (c) 2023 kacperks
2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLUGUN_RENDERER_MESH_HPP
#define POLUGUN_RENDERER_MESH_HPP
#include "../core.hpp"
#include <vector>
namespace polygun::renderer {
class Mesh {
public:
Mesh();
virtual ~Mesh(){}
void load_from_memory(const std::vector<float>& vertices, const std::vector<unsigned>& indices);
void load_from_memory(const std::vector<float>& vertices, const std::vector<unsigned>& indices, const std::vector<float>& uvs);
void load_from_memory(const std::vector<float>& vertices, const std::vector<unsigned>& indices, const std::vector<float>& uvs, const std::vector<float>& normals);
bool has_texture_uvs() const { return m_has_texture_uvs; }
bool has_normals() const { return m_has_normals; }
private:
bool m_has_texture_uvs, m_has_normals;
protected:
virtual void load_vertices(const std::vector<float>& vertices) = 0;
virtual void load_indices(const std::vector<unsigned>& indices) = 0;
virtual void load_uvs(const std::vector<float>& uvs) = 0;
virtual void load_normals(const std::vector<float>& normals) = 0;
};
}
#endif // POLUGUN_RENDERER_MESH_HPP

View File

@ -0,0 +1,58 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/mesh_renderer.hpp"
#include <glm/gtc/matrix_transform.hpp>
using namespace polygun::renderer;
MeshRenderer::MeshRenderer() :
m_camera(nullptr),
m_transform(1)
{}
void MeshRenderer::translate(const glm::vec3& pos) {
m_transform = glm::translate(m_transform, pos);
}
void MeshRenderer::translate(const glm::vec2& pos) {
translate(glm::vec3(pos.x, pos.y, 0));
}
void MeshRenderer::rotate(const glm::vec3& rot, float angle) {
m_transform = glm::rotate(m_transform, angle, rot);
}
void MeshRenderer::rotate(const glm::vec2& rot, float angle) {
rotate(glm::vec3(rot.x, rot.y, 0), angle);
}
void MeshRenderer::scale(const glm::vec3& scl) {
m_transform = glm::scale(m_transform, scl);
}
void MeshRenderer::scale(const glm::vec2& scl) {
scale(glm::vec3(scl.x, scl.y, 1));
}

View File

@ -0,0 +1,61 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_MESH_RENDERER_HPP
#define POLYGUN_RENDERER_MESH_RENDERER_HPP
#include <glm/glm.hpp>
#include <vector>
namespace polygun::renderer {
class Mesh;
class Texture;
class Camera;
class Shader;
class MeshRenderer {
public:
MeshRenderer();
virtual ~MeshRenderer(){}
void translate(const glm::vec3& pos);
void translate(const glm::vec2& pos);
void rotate(const glm::vec3& rot, float angle);
void rotate(const glm::vec2& rot, float angle);
void scale(const glm::vec3& scl);
void scale(const glm::vec2& scl);
virtual void render(Mesh* mesh, const glm::vec4& color) = 0;
virtual void render_textured(Mesh* mesh, Texture* texture) = 0;
virtual void render_with_multiple_textures(Mesh* mesh, const std::vector<Texture*>& textures) = 0;
virtual void set_shader(Shader* shader) = 0;
virtual void set_camera(Camera* camera) = 0;
virtual void set_3d_rendering_mode(bool enable) = 0;
protected:
Camera* m_camera;
glm::mat4 m_transform;
};
}
#endif // POLYGUN_RENDERER_MESH_RENDERER_HPP

View File

@ -1,130 +0,0 @@
#include "game/renderer/shader.hpp"
namespace polygun::renderer {
Shader::Shader() :
m_program(0)
{}
Shader::Shader(const GLuint id) :
m_program(id)
{}
Shader::Shader(const char* vertex_path, const char* fragment_path) {
std::string vertex_code;
std::string fragment_code;
std::ifstream v_shader_file;
std::ifstream f_shader_file;
v_shader_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
f_shader_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
v_shader_file.open(vertex_path);
f_shader_file.open(fragment_path);
std::stringstream v_shader_stream, f_shader_stream;
v_shader_stream << v_shader_file.rdbuf();
f_shader_stream << f_shader_file.rdbuf();
v_shader_file.close();
f_shader_file.close();
vertex_code = v_shader_stream.str();
fragment_code = f_shader_stream.str();
}
catch (std::ifstream::failure& e) {
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: " << e.what() << std::endl;
}
const char* v_shader_code = vertex_code.c_str();
const char * f_shader_code = fragment_code.c_str();
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &v_shader_code, NULL);
glCompileShader(vertex);
check_compile_errors(vertex, "VERTEX");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &f_shader_code, NULL);
glCompileShader(fragment);
check_compile_errors(fragment, "FRAGMENT");
m_program = glCreateProgram();
glAttachShader(m_program, vertex);
glAttachShader(m_program, fragment);
glLinkProgram(m_program);
check_compile_errors(m_program, "PROGRAM");
glDeleteShader(vertex);
glDeleteShader(fragment);
}
Shader::~Shader() {
glDeleteProgram(m_program);
}
void Shader::bind() {
glUseProgram(m_program);
}
void Shader::unbind() {
glUseProgram(0);
}
void Shader::set_uniform(const GLchar* u_name, unsigned int value) {
glUniform1i(glGetUniformLocation(m_program, u_name), value);
}
void Shader::set_uniform(const GLchar* u_name, int value) {
glUniform1i(glGetUniformLocation(m_program, u_name), value);
}
void Shader::set_uniform(const GLchar* u_name, GLfloat value) {
glUniform1i(glGetUniformLocation(m_program, u_name), value);
}
void Shader::set_uniform(const GLchar* u_name, GLfloat x, GLfloat y) {
glUniform2f(glGetUniformLocation(m_program, u_name), x, y);
}
void Shader::set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z) {
glUniform3f(glGetUniformLocation(m_program, u_name), x, y, z);
}
void Shader::set_uniform(const GLchar* u_name, const glm::vec3& vector) {
glUniform3f(glGetUniformLocation(m_program, u_name), vector.x, vector.y, vector.z);
}
void Shader::set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
glUniform4f(glGetUniformLocation(m_program, u_name), x, y, z, w);
}
void Shader::set_uniform(const GLchar* name, const glm::mat4 &mat) {
glUniformMatrix4fv(glGetUniformLocation(m_program, name), 1, GL_FALSE, &mat[0][0]);
}
void Shader::set_uniform(const GLchar* u_name, const glm::vec2& vector) {
glUniform2f(glGetUniformLocation(m_program, u_name), vector.x, vector.y);
}
void Shader::set_uniform(const GLchar* u_name, const glm::vec4& vector){
glUniform4f(glGetUniformLocation(m_program, u_name), vector.x, vector.y, vector.z, vector.w);
}
void Shader::set_uniform(const GLchar* u_name, GLuint tex2d, GLint unit){ // sample 2d
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, tex2d);
glUniform1i(glGetUniformLocation(m_program, u_name), unit);
}
void Shader::check_compile_errors(GLuint shader, const std::string& type) {
GLint success;
GLchar info_log[1024];
if(type != "PROGRAM") {
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(shader, 1024, NULL, info_log);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << info_log << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
else {
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if(!success) {
glGetProgramInfoLog(shader, 1024, NULL, info_log);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << info_log << "\n -- --------------------------------------------------- -- " << std::endl;
}
}
}
}

View File

@ -1,38 +1,18 @@
#ifndef POLYGUN_RENDERER_SHADER_H
#define POLYGUN_RENDERER_SHADER_H
#ifndef POLYGUN_RENDERER_SHADER_HPP
#define POLYGUN_RENDERER_SHADER_HPP
#include "game/core.hpp"
#include <string>
namespace polygun::renderer {
class Shader {
public:
Shader();
Shader(const GLuint id);
Shader(const char* vertex_path, const char* fragment_path);
~Shader();
Shader() = default;
virtual ~Shader(){}
void bind();
void unbind();
void set_uniform(const GLchar* u_name, unsigned int value);
void set_uniform(const GLchar* u_name, int value);
void set_uniform(const GLchar* u_name, GLfloat value);
void set_uniform(const GLchar* u_name, GLfloat x, GLfloat y);
void set_uniform(const GLchar* u_name, const glm::vec2& vector);
void set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z);
void set_uniform(const GLchar* u_name, const glm::vec3& vector);
void set_uniform(const GLchar* u_name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void set_uniform(const GLchar* u_name, const glm::vec4& vector);
void set_uniform(const GLchar* u_name, const glm::mat4& mtx);
void set_uniform(const GLchar* u_name, GLuint tex2d, GLint unit); // sample 2d
GLuint get_uniform(const char* name) const;
GLuint get_program() const { return m_program; }
private:
void check_compile_errors(GLuint shader, const std::string& type);
GLuint m_program;
// Note: name is name of shader i.e. for example 'chunk' and not
// filename i.e. 'shaders/gl/chunk_fragment.glsl'
virtual bool load_from_file(const std::string& name) = 0;
};
}
#endif
#endif // POLYGUN_RENDERER_SHADER_HPP

View File

@ -0,0 +1,32 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "game/renderer/texture.hpp"
using namespace polygun::renderer;
bool Texture::load_from_file(const std::string& path) {
// TODO: loading PNG files with libpng
return false;
}

View File

@ -0,0 +1,48 @@
/*
PolyGun
Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef POLYGUN_RENDERER_TEXTURE_HPP
#define POLYGUN_RENDERER_TEXTURE_HPP
#include <string>
namespace polygun::renderer {
class Texture {
public:
Texture() = default;
virtual ~Texture(){}
unsigned get_width() const { return m_width; }
unsigned get_height() const { return m_height; }
bool load_from_file(const std::string& path);
virtual bool load_from_pixel_data(const uint8_t* data, unsigned width, unsigned height, unsigned pixel_size) = 0;
protected:
unsigned m_width, m_height;
};
}
#endif // POLYGUN_RENDERER_TEXTURE_HPP

View File

@ -6,6 +6,7 @@ Copyright (c) 2023 mrkubax10 <mrkubax10@onet.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
@ -25,65 +26,110 @@ SOFTWARE.
#include "game/screens/game_session_screen.hpp"
#include <GL/gl.h>
#include "common/network/network_manager.hpp"
#include "common/logger.hpp"
#include "game/engine/engine.hpp"
#include "game/renderer/shader.hpp"
#include "game/renderer/mesh.hpp"
#include "game/renderer/texture.hpp"
using namespace polygun::screens;
static const float vertices[] = {
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
0.1f, -0.1f, -0.1f, 1.0f, 0.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 0.0f,
static const std::vector<float> vertices = {
-0.1f , -0.1f, -0.1f,
0.1f , -0.1f, -0.1f,
0.1f , 0.1f, -0.1f,
0.1f , 0.1f, -0.1f,
-0.1f , 0.1f, -0.1f,
-0.1f , -0.1f, -0.1f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
0.1f, 0.1f, 0.1f, 1.0f, 1.0f,
-0.1f, 0.1f, 0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
-0.1f , -0.1f, 0.1f,
0.1f , -0.1f, 0.1f,
0.1f , 0.1f, 0.1f,
0.1f , 0.1f, 0.1f,
-0.1f , 0.1f, 0.1f,
-0.1f , -0.1f, 0.1f,
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
-0.1f , 0.1f, 0.1f,
-0.1f , 0.1f, -0.1f,
-0.1f , -0.1f, -0.1f,
-0.1f , -0.1f, -0.1f,
-0.1f , -0.1f, 0.1f,
-0.1f , 0.1f, 0.1f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
0.1f , 0.1f, 0.1f,
0.1f , 0.1f, -0.1f,
0.1f , -0.1f, -0.1f,
0.1f , -0.1f, -0.1f,
0.1f , -0.1f, 0.1f,
0.1f , 0.1f, 0.1f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
0.1f, -0.1f, -0.1f, 1.0f, 1.0f,
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
0.1f, -0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, -0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, -0.1f, -0.1f, 0.0f, 1.0f,
-0.1f , -0.1f, -0.1f,
0.1f , -0.1f, -0.1f,
0.1f , -0.1f, 0.1f,
0.1f , -0.1f, 0.1f,
-0.1f , -0.1f, 0.1f,
-0.1f , -0.1f, -0.1f,
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f,
0.1f, 0.1f, -0.1f, 1.0f, 1.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
0.1f, 0.1f, 0.1f, 1.0f, 0.0f,
-0.1f, 0.1f, 0.1f, 0.0f, 0.0f,
-0.1f, 0.1f, -0.1f, 0.0f, 1.0f
-0.1f , 0.1f, -0.1f,
0.1f , 0.1f, -0.1f,
0.1f , 0.1f, 0.1f,
0.1f , 0.1f, 0.1f,
-0.1f , 0.1f, 0.1f,
-0.1f , 0.1f, -0.1f,
};
static std::vector<unsigned> indices;
static const std::vector<float> uvs={
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
};
GameSessionScreen::GameSessionScreen() :
m_chunk_shader("shaders/chunk_vertex.glsl", "shaders/chunk_fragment.glsl"),
m_chunk_shader(nullptr),
m_node_mesh(nullptr),
m_chnk(),
m_camera(),
m_vbo(0),
m_vao(0),
m_texture_atlas(0),
m_texture_atlas(nullptr),
m_is_esc_pressed(false),
m_was_camera_locked(false),
m_connection_thread(),
@ -91,80 +137,50 @@ GameSessionScreen::GameSessionScreen() :
{}
void GameSessionScreen::begin() {
glEnable(GL_DEPTH_TEST);
m_chunk_shader = m_engine->get_master_renderer().create_shader();
m_chunk_shader->load_from_file("chunk");
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
m_node_mesh = m_engine->get_master_renderer().create_mesh();
for(size_t i = 0; i<vertices.size(); i+=3)
indices.push_back((int)i/3);
m_node_mesh->load_from_memory(vertices, indices, uvs);
glBindVertexArray(m_vao);
m_texture_atlas = m_engine->get_master_renderer().create_texture();
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
m_engine->get_mesh_renderer()->set_3d_rendering_mode(true);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glGenTextures(1, &m_texture_atlas);
glBindTexture(GL_TEXTURE_2D, m_texture_atlas);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char *data = stbi_load("res/textures/gold.png", &width, &height, &nrChannels, 0);
if (data) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
m_texture_atlas->load_from_pixel_data(data, width, height, nrChannels);
}
else {
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);
m_chunk_shader.bind();
m_chunk_shader.set_uniform("texture_atlas", 0);
glfwSetCursorPosCallback(m_engine->get_window(), m_camera.mouse_callback);
glfwSetInputMode(m_engine->get_window(), GLFW_CURSOR, GLFW_CURSOR_DISABLED);
m_engine->get_mesh_renderer()->set_camera(&m_camera);
// Note: uncomment to test connection with server
// m_connection_thread.reset(new std::thread(&GameSessionScreen::connection_thread_func, this));
}
void GameSessionScreen::render() {
m_engine->get_master_renderer().clear_screen(1,1,1);
// rendering
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// bind textures on corresponding texture units
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_texture_atlas);
// activate shader
m_chunk_shader.bind();
glm::mat4 projection = glm::perspective(glm::radians(m_camera.m_fov), (float)engine::Engine::get_screen_width() / (float)engine::Engine::get_screen_height(), 0.1f, 100.0f);
m_chunk_shader.set_uniform("projection", projection);
glm::mat4 view = m_camera.get_view_matrix();
m_chunk_shader.set_uniform("view", view);
glBindVertexArray(m_vao);
renderer::MeshRenderer* mesh_renderer = m_engine->get_mesh_renderer();
mesh_renderer->set_shader(m_chunk_shader);
for (unsigned int x = 0; x < 32; x++) {
for (unsigned int y = 0; y < 32; y++) {
for (unsigned int z = 0; z < 32; z++) {
if (m_chnk.get_node(glm::vec3(x,y,z))!= 0) {
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(x/5.0f, y/5.0f, z/5.0f));
m_chunk_shader.set_uniform("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
mesh_renderer->translate(glm::vec3(x/5.0f, y/5.0f, z/5.0f));
mesh_renderer->render_textured(m_node_mesh, m_texture_atlas);
}
}
}
@ -227,18 +243,30 @@ void GameSessionScreen::update(double delta) {
m_is_esc_pressed = false;
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_W) == GLFW_PRESS)
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_W) == GLFW_PRESS) {
m_camera.process_movement(polygun::engine::FORWARD, delta);
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_S) == GLFW_PRESS)
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_S) == GLFW_PRESS) {
m_camera.process_movement(polygun::engine::BACKWARD, delta);
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_A) == GLFW_PRESS)
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_A) == GLFW_PRESS) {
m_camera.process_movement(polygun::engine::LEFT, delta);
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_D) == GLFW_PRESS)
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_D) == GLFW_PRESS) {
m_camera.process_movement(polygun::engine::RIGHT, delta);
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_SPACE) == GLFW_PRESS)
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_SPACE) == GLFW_PRESS) {
m_camera.process_movement(polygun::engine::UP, delta);
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
if (glfwGetKey(m_engine->get_window(), GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) {
m_camera.process_movement(polygun::engine::DOWN, delta);
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
if(glfwGetInputMode(m_engine->get_window(), GLFW_CURSOR) == GLFW_CURSOR_DISABLED) {
if(m_was_camera_locked) {
@ -247,12 +275,13 @@ void GameSessionScreen::update(double delta) {
}
else
m_camera.update(false);
m_engine->get_mesh_renderer()->set_camera(&m_camera);
}
}
void GameSessionScreen::finish() {
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
delete m_chunk_shader;
delete m_node_mesh;
m_running = false;
if(m_connection_thread.get() && m_connection_thread->joinable()) {

View File

@ -32,14 +32,18 @@ SOFTWARE.
#include <thread>
#include "game/engine/player_camera.hpp"
#include "game/renderer/shader.hpp"
#include "game/world/chunk.hpp"
namespace polygun::renderer {
class Shader;
class Mesh;
class Texture;
}
namespace polygun::screens {
class GameSessionScreen final : public engine::Screen {
public:
GameSessionScreen();
~GameSessionScreen() = default;
virtual void begin() override;
virtual void render() override;
@ -47,11 +51,11 @@ namespace polygun::screens {
virtual void finish() override;
private:
renderer::Shader m_chunk_shader;
renderer::Shader* m_chunk_shader;
renderer::Mesh* m_node_mesh;
world::Chunk m_chnk;
engine::Camera m_camera;
unsigned int m_vbo, m_vao;
unsigned int m_texture_atlas;
engine::PlayerCamera m_camera;
renderer::Texture* m_texture_atlas;
bool m_is_esc_pressed, m_was_camera_locked;
std::unique_ptr<std::thread> m_connection_thread;
std::atomic<bool> m_running;

View File

@ -1,10 +1,23 @@
#include "chunk_renderer.hpp"
#include "game/world/chunk_renderer.hpp"
#include "common/logger.hpp"
#include "game/renderer/shader.hpp"
#include "game/renderer/mesh.hpp"
#include "game/engine/engine.hpp"
namespace polygun::world {
ChunkRenderer::ChunkRenderer() : chunk_shader("shaders/chunk_vertex.glsl", "shaders/chunk_fragment.glsl") {}
ChunkRenderer::ChunkRenderer(engine::Engine& engine) :
texture(0),
chunk_shader(engine.get_master_renderer().create_shader()),
mesh(engine.get_master_renderer().create_mesh())
{
chunk_shader->load_from_file("chunk");
}
ChunkRenderer::~ChunkRenderer() {}
ChunkRenderer::~ChunkRenderer() {
delete chunk_shader;
delete mesh;
}
void ChunkRenderer::init() {/*
float vertices[] = {
@ -25,7 +38,9 @@ namespace polygun::world {
}
void ChunkRenderer::render(const glm::mat4& view, const glm::mat4& projection) {
glActiveTexture(GL_TEXTURE0);
/*
Note: Temporarily commented out ~mrkubax10
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
chunk_shader.bind();
@ -33,6 +48,6 @@ namespace polygun::world {
chunk_shader.set_uniform("projection", projection);
chunk_shader.set_uniform("view", view);
vertex_array.draw_elements();
vertex_array.draw_elements();*/
}
}

View File

@ -2,15 +2,22 @@
#define POLYGUN_ENGINE_CHUNK_RENDERER_HPP
#include <glm/glm.hpp>
#include "chunk.hpp"
#include "../renderer/shader.hpp"
#include "../renderer/vertex_array.hpp"
#include "game/world/chunk.hpp"
namespace polygun::renderer {
class Shader;
class Mesh;
}
namespace polygun::engine {
class Engine;
}
namespace polygun::world {
class ChunkRenderer {
public:
ChunkRenderer();
ChunkRenderer(engine::Engine& engine);
~ChunkRenderer();
void init();
@ -18,8 +25,8 @@ namespace polygun::world {
private:
unsigned int texture;
renderer::Shader chunk_shader;
renderer::VertexArray vertex_array;
renderer::Shader* chunk_shader;
renderer::Mesh* mesh;
};
}