inching slowly towards a renderer
This commit is contained in:
parent
4b695ecaf6
commit
c7c7d5af77
28 changed files with 613 additions and 59 deletions
|
@ -1,11 +1,13 @@
|
|||
|
||||
set(hdrs
|
||||
include/pw/visual/renderer.hpp
|
||||
include/pw/visual/shader.hpp
|
||||
include/pw/visual/context.hpp
|
||||
)
|
||||
|
||||
set(srcs
|
||||
src/renderer.cpp
|
||||
src/shader.cpp
|
||||
src/context.cpp
|
||||
)
|
||||
|
||||
|
@ -21,6 +23,6 @@ target_include_directories(
|
|||
include
|
||||
)
|
||||
|
||||
target_link_libraries(pwvisual pwscene)
|
||||
target_link_libraries(pwvisual pwscene glad)
|
||||
|
||||
#add_subdirectory(tests)
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
#ifndef PW_VISUAL_RENDERER_HPP
|
||||
#define PW_VISUAL_RENDERER_HPP
|
||||
|
||||
#include <pw/scene/component.hpp>
|
||||
//#include <pw/scene/component.hpp>
|
||||
//#include <pw/scene/camera.hpp>
|
||||
|
||||
#include <pw/core/matrix.hpp>
|
||||
#include <pw/core/mesh.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class context;
|
||||
|
||||
class renderer {
|
||||
public:
|
||||
|
||||
void render(context& context);
|
||||
void render(const mesh& mesh,
|
||||
const matrix4x4& model_matrix,
|
||||
const matrix4x4& view_matrix,
|
||||
const matrix4x4& projection_matrix
|
||||
);
|
||||
|
||||
protected:
|
||||
|
||||
struct impl;
|
||||
std::unique_ptr<impl> _impl;
|
||||
|
||||
};
|
||||
|
||||
|
|
41
src/visual/include/pw/visual/shader.hpp
Normal file
41
src/visual/include/pw/visual/shader.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef PW_VISUAL_SHADER_HPP
|
||||
#define PW_VISUAL_SHADER_HPP
|
||||
|
||||
#include <pw/core/globals.hpp>
|
||||
#include <pw/core/matrix.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace pw {
|
||||
|
||||
class shader {
|
||||
public:
|
||||
|
||||
shader();
|
||||
|
||||
enum code_type {
|
||||
vertex, //<
|
||||
fragment,
|
||||
geometry,
|
||||
compute
|
||||
};
|
||||
|
||||
void set_source(const std::string& c,code_type t);
|
||||
std::string source(code_type t) { return _source[t]; }
|
||||
|
||||
// void set_attributes(const std::vector<std::string> > &attributes);
|
||||
|
||||
bool ready() const;
|
||||
|
||||
protected:
|
||||
|
||||
std::map<code_type,std::string> _source;
|
||||
|
||||
struct impl;
|
||||
std::unique_ptr<impl> _impl;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,9 +1,69 @@
|
|||
#include "pw/visual/renderer.hpp"
|
||||
|
||||
#include "pw/core/mesh.hpp"
|
||||
|
||||
#include "glad/glad.h"
|
||||
|
||||
namespace pw {
|
||||
|
||||
void renderer::render(pw::context &context)
|
||||
{
|
||||
}
|
||||
|
||||
struct renderer::impl {
|
||||
|
||||
GLuint _vao = 0;
|
||||
std::vector<GLuint> _vbos;
|
||||
|
||||
impl(renderer& )
|
||||
{
|
||||
}
|
||||
|
||||
void create(std::shared_ptr<mesh> mesh)
|
||||
{
|
||||
glGenVertexArrays(1,&_vao);
|
||||
glBindVertexArray(_vao);
|
||||
|
||||
size_t arrays_needed = 0;
|
||||
|
||||
// should bail out here
|
||||
if (!mesh->vertices().empty()) arrays_needed++;
|
||||
if (!mesh->indices().empty()) arrays_needed++;
|
||||
|
||||
// TODO: implement the other arrays
|
||||
|
||||
_vbos.resize(arrays_needed);
|
||||
|
||||
glGenBuffers(_vbos.size(), _vbos.data());
|
||||
|
||||
// vertices
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(mesh->vertices().front()) * mesh->vertices().size(), mesh->vertices().data(),
|
||||
GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
// indices
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbos[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(mesh->indices().front()) * mesh->indices().size(), mesh->indices().data(),
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
|
||||
// stop binding
|
||||
glBindVertexArray(0);
|
||||
|
||||
}
|
||||
|
||||
void destroy()
|
||||
{
|
||||
glDeleteVertexArrays(1,&_vao);
|
||||
for (auto vbo : _vbos)
|
||||
glDeleteBuffers(1,&vbo);
|
||||
|
||||
_vbos.clear();
|
||||
}
|
||||
};
|
||||
|
||||
//pipeline > n*pass
|
||||
//compositor
|
||||
// render to fbo >
|
||||
|
||||
|
||||
}
|
||||
|
|
177
src/visual/src/shader.cpp
Normal file
177
src/visual/src/shader.cpp
Normal file
|
@ -0,0 +1,177 @@
|
|||
#include "pw/visual/shader.hpp"
|
||||
#include "pw/core/debug.hpp"
|
||||
|
||||
|
||||
|
||||
#include "glad/glad.h"
|
||||
|
||||
namespace pw {
|
||||
|
||||
// TODO: move this to a separate implementation
|
||||
|
||||
struct shader::impl
|
||||
{
|
||||
shader& _shader;
|
||||
|
||||
GLuint _shader_program;
|
||||
std::vector<GLuint> _shader_stages;
|
||||
|
||||
impl(shader& s)
|
||||
: _shader(s)
|
||||
{
|
||||
}
|
||||
|
||||
~impl()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
bool is_valid()
|
||||
{
|
||||
return glIsProgram(_shader_program);
|
||||
}
|
||||
|
||||
void build()
|
||||
{
|
||||
|
||||
for (auto s : _shader._source)
|
||||
{
|
||||
GLuint shader_type = 0;
|
||||
switch (s.first) {
|
||||
case shader::vertex:
|
||||
shader_type = GL_VERTEX_SHADER;
|
||||
break;
|
||||
case shader::compute:
|
||||
shader_type = GL_COMPUTE_SHADER;
|
||||
break;
|
||||
case shader::geometry:
|
||||
shader_type = GL_GEOMETRY_SHADER;
|
||||
break;
|
||||
case shader::fragment:
|
||||
shader_type = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
}
|
||||
|
||||
GLuint shaderId = glCreateShader(shader_type);
|
||||
|
||||
char* src = const_cast<char*>(s.second.c_str());
|
||||
GLint size = static_cast<GLint>(s.second.length());
|
||||
|
||||
glShaderSource(shaderId , 1, &src, &size);
|
||||
|
||||
glCompileShader(shaderId);
|
||||
|
||||
GLint is_compiled = GL_FALSE;
|
||||
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &is_compiled);
|
||||
if(is_compiled == GL_FALSE)
|
||||
{
|
||||
|
||||
GLint log_length;
|
||||
|
||||
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &log_length);
|
||||
|
||||
char* log_buffer = new char[log_length];
|
||||
|
||||
glGetShaderInfoLog(shaderId, log_length, &log_length, log_buffer);
|
||||
|
||||
// TODO - handle errors!
|
||||
|
||||
std::string info_log_string(log_buffer);
|
||||
|
||||
delete [] log_buffer;
|
||||
|
||||
debug::e() << info_log_string;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_shader_stages.push_back(shaderId);
|
||||
|
||||
}
|
||||
|
||||
_shader_program = glCreateProgram();
|
||||
|
||||
|
||||
for (auto s : _shader_stages)
|
||||
glAttachShader(_shader_program,s);
|
||||
|
||||
|
||||
// attribute binding ...
|
||||
|
||||
/* Bind attribute index 0 (coordinates) to in_Position and attribute index 1 (color) to in_Color */
|
||||
/* Attribute locations must be setup before calling glLinkProgram. */
|
||||
// glBindAttribLocation(shaderprogram, 0, "in_Position");
|
||||
// glBindAttribLocation(shaderprogram, 1, "in_Color");
|
||||
|
||||
glLinkProgram(_shader_program);
|
||||
|
||||
GLint is_linked = 0;
|
||||
glGetProgramiv(_shader_program, GL_LINK_STATUS, &is_linked);
|
||||
if(is_linked == GL_FALSE)
|
||||
{
|
||||
|
||||
GLint log_length;
|
||||
|
||||
/* Noticed that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. */
|
||||
glGetProgramiv(_shader_program, GL_INFO_LOG_LENGTH, &log_length);
|
||||
|
||||
/* The maxLength includes the NULL character */
|
||||
char* info_log = new char[log_length];
|
||||
|
||||
/* Notice that glGetProgramInfoLog, not glGetShaderInfoLog. */
|
||||
glGetProgramInfoLog(_shader_program, log_length, &log_length, info_log);
|
||||
|
||||
|
||||
std::string info_log_string;
|
||||
|
||||
debug::e() << info_log_string;
|
||||
|
||||
|
||||
/* Handle the error in an appropriate way such as displaying a message or writing to a log file. */
|
||||
/* In this simple program, we'll just leave */
|
||||
delete [] info_log;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void use()
|
||||
{
|
||||
glUseProgram(_shader_program);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (is_valid()) {
|
||||
glDeleteProgram(_shader_program);
|
||||
|
||||
for (auto s : _shader_stages)
|
||||
{
|
||||
glDeleteShader(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_uniform(const std::string& name,const matrix4x4f& m)
|
||||
{
|
||||
GLint l = glGetUniformLocation(_shader_program,name.c_str());
|
||||
glUniformMatrix4fv(l,1,GL_FALSE,m.data()); // TODO transpose?
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
shader::shader()
|
||||
{
|
||||
_impl = make_unique<impl>(*this);
|
||||
}
|
||||
|
||||
bool shader::ready() const
|
||||
{
|
||||
return _impl->is_valid();
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue