--- /dev/null
+#ifndef GLOBAL_H_
+#define GLOBAL_H_
+
+#include "shader_manager.h"
+extern ShaderManager *sdr_man;
+
+#endif // GLOBAL_H_
\ No newline at end of file
#include <string.h>
#include <vector>
+#include "global.h"
+
/* TODO: fix those */
#include "camera.h"
#include "mesh.h"
#include "object.h"
#include "scene.h"
+#include "shader_manager.h"
#include "opengl/opengl.h"
#include "vulkan/vk.h"
int win_h = 600;
OrbitCamera *camera;
+ShaderManager *sdr_man;
/* variables */
static float phi = 25;
return false;
}
+ sdr_man = new ShaderManager;
+
camera = new OrbitCamera;
camera->set_orbit_params(phi, theta, dist);
static void cleanup()
{
+ delete sdr_man;
+ delete camera;
+
if(use_vulkan) {
cleanup_vulkan();
}
else {
cleanup_opengl();
}
-
- delete camera;
}
static void key_clbk(GLFWwindow *win, int key, int scancode, int action, int mods)
}
else {
display_opengl();
- scene.objects[0]->mesh->update_vertex_data();
scene.objects[0]->mesh->draw();
}
}
\ No newline at end of file
void update_vbo();
-protected:
- virtual void update_vertex_data() override;
-
public:
MeshGL();
MeshGL(const MeshGL &mesh);
virtual ~MeshGL();
virtual void draw() const override;
+ virtual void update_vertex_data() override;
void destroy_vbo();
};
#include "state_manager.h"
#include "opengl/shader-gl.h"
-extern ShaderProgram *current_program;
-
ShaderGL::ShaderGL()
{
sdr = 0;
prog = 0;
memset(shaders, 0, sizeof shaders / sizeof *shaders);
- current_program = 0;
is_linked = false;
}
return status ? true : false;
}
-bool ShaderProgramGL::use()
+bool ShaderProgramGL::use() const
{
- if(!is_linked && !link()) {
+ if(!is_linked) { //&& !link()) {
return false;
}
if(!prog) {
- glUseProgram(0);
- current_program = 0;
+ return false;
}
glUseProgram(prog);
- current_program = this;
-
- static void (*const set_uniform[16])(GLint, GLsizei, const GLfloat *) = {
- 0, glUniform1fv, glUniform2fv, glUniform3fv, glUniform4fv
- };
-
- for(size_t i=0; i<uniforms.size(); i++) {
- const State *st = state_manager.get_state(uniforms[i].state_idx);
- if(st->num < 5) {
- set_uniform[st->num](uniforms[i].location, 1, st->data);
- }
- else if(st->num == 16) {
- glUniformMatrix4fv(uniforms[i].location, 1, GL_TRUE, st->data);
- }
- else {
- fprintf(stderr, "Invalid number of floats in state %s: %d\n", st->name, st->num);
- continue;
- }
- }
return true;
}
int ShaderProgramGL::get_uniform_location(const char *name) const
{
- if(!((ShaderProgramGL *)this)->use())
+ if(!use())
return -1;
return glGetUniformLocation(prog, name);
}
-int ShaderProgramGL::get_attribute_location(const char *name) const
-{
- if(!((ShaderProgramGL *)this)->use())
- return -1;
-
- return glGetAttribLocation(prog, name);
-}
-
-static int get_floats_num(unsigned int utype)
-{
- switch(utype) {
- case GL_FLOAT:
- return 1;
- case GL_FLOAT_VEC2:
- return 2;
- case GL_FLOAT_VEC3:
- return 3;
- case GL_FLOAT_VEC4:
- return 4;
- case GL_FLOAT_MAT2:
- return 4;
- case GL_FLOAT_MAT3:
- return 9;
- case GL_FLOAT_MAT4:
- return 16;
- default:
- break;
- }
-
- return -1;
-}
-
-void ShaderProgramGL::cache_uniforms()
-{
- uniforms.clear();
-
- int num_uniforms;
- glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_uniforms);
-
- int max_ulength;
- glGetProgramiv(prog, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_ulength);
-
- char *name = new char[max_ulength + 1];
- name[max_ulength] = 0;
-
- for(int i=0; i<num_uniforms; i++) {
- int usize;
- unsigned int utype;
- glGetActiveUniform(prog, i, max_ulength, 0, &usize, &utype, name);
-
- if(strstr(name, "gl_") == name)
- continue;
-
- if(strstr(name, "st_") != name)
- continue;
-
- int num_floats = get_floats_num(utype);
- if(num_floats == -1)
- continue;
-
- int idx = state_manager.add_state_element(name, num_floats);
- if(idx == -1)
- continue;
-
- Uniform uniform;
- uniform.name = name;
- uniform.location = glGetUniformLocation(prog, name);
- uniform.state_idx = idx;
-
- uniforms.push_back(uniform);
- }
-
- delete [] name;
-}
-
void ShaderProgramGL::set_uniformi(int location, int value)
{
if(!use() || location == -1) {
ShaderProgramGL();
virtual ~ShaderProgramGL();
- virtual void cache_uniforms() override;
-
virtual bool link() override;
- virtual bool use() override;
+ virtual bool use() const override;
virtual bool create() override;
virtual void destroy() override;
virtual void attach_shader(Shader *shader) override;
- int get_uniform_location(const char *name) const;
- int get_attribute_location(const char *name) const;
+ virtual int get_uniform_location(const char *name) const override;
virtual void set_uniformi(int location, int value) override;
virtual void set_uniformi(int location, int x, int y) override;
+#include "global.h"
+
+#include "camera.h"
+#include "object.h"
#include "renderer.h"
+#include "scene.h"
#include "shader.h"
+#include "shader_manager.h"
Renderer::Renderer()
{
sprog = 0;
}
-Renderer::Renderer(ShaderProgram *sprog, Scene *scene, Camera *camera)
+Renderer::~Renderer()
{
- this->scene = scene;
- this->sprog = sprog;
- this->camera = camera;
}
-Renderer::~Renderer()
+bool Renderer::create()
+{
+ if(!(sprog = sdr_man->create_shader_program("default.v.glsl", "default.f.glsl"))) {
+ return false;
+ }
+ return true;
+}
+
+void Renderer::draw() const
{
+ if(!camera || !scene)
+ return;
+
+ // sprog->set_uniform_matrix(mview_loc, camera->get_view_matrix());
}
-void Renderer::set_program(ShaderProgram *sprog)
+void Renderer::draw_object(Object *object) const
{
- this->sprog = sprog;
}
\ No newline at end of file
#ifndef RENDERER_H_
#define RENDERER_H_
-/*
- this might change:
- atm we are going to have 1 renderer per scene and 1 shader program
- for the scene
- */
-
-
class Camera;
class Object;
class Scene;
class Renderer {
protected:
ShaderProgram *sprog;
- virtual void draw_object(Object *object) const = 0;
+ virtual void draw_object(Object *object) const;
public:
Scene *scene;
Camera *camera;
Renderer();
- Renderer(ShaderProgram *sprog, Scene *scene, Camera *camera);
virtual ~Renderer();
- virtual void set_program(ShaderProgram *sprog);
- virtual bool create() = 0;
- virtual void draw() const = 0;
+ virtual bool create();
+ virtual void draw() const;
};
#endif // RENDERER_H_
\ No newline at end of file
#include <stdio.h>
#include "shader.h"
-ShaderProgram *current_program;
-
Shader::Shader() {}
Shader::~Shader()
{
ShaderProgram::ShaderProgram()
{
- current_program = 0;
-
int len = sizeof shaders / sizeof *shaders;
for(int i=0; i<len; ++i) {
shaders[i] = 0;
for(int i=0; i<len; ++i) {
delete shaders[i];
}
-}
-
-// void ShaderProgram::add_shader(Shader *sdr)
-// {
-// assert(sdr->type < sizeof shaders / sizeof *shaders);
-// shaders[sdr->type] = sdr;
-// }
-
-ShaderProgram *get_current_program()
-{
- return current_program;
}
\ No newline at end of file
ShaderProgram();
virtual ~ShaderProgram();
- virtual void cache_uniforms() = 0;
-
virtual bool create() = 0;
virtual bool link() = 0;
- virtual bool use() = 0;
+ virtual bool use() const = 0;
virtual void destroy() = 0;
virtual void attach_shader(Shader *shader) = 0;
using descriptor sets. The current design is suitable for OpenGL and
it *might* have to be rewritten to work with both APIs later
*/
+ virtual int get_uniform_location(const char *name) const = 0;
virtual void set_uniformi(int location, int value) = 0;
virtual void set_uniformi(int location, int x, int y) = 0;
virtual void set_uniform_matrix(int location, const Mat4 &mat) = 0;
};
-ShaderProgram *get_current_program();
-
#endif // SHADER_H_
sdr = new ShaderGL;
}
- if(!sdr->load(name, type)) {
+ std::string fname = path.empty() ? std::string(name) : path + "/" + std::string(name);
+
+ if(!sdr->load(fname.c_str(), type)) {
delete sdr;
return 0;
}
for(it=shaders.begin(); it != shaders.end(); it++) {
delete it->second;
}
+}
+
+ShaderProgram *ShaderManager::create_shader_program(const char *vname, const char *fname)
+{
+ Shader *vsdr = load_shader(vname, SDR_VERTEX);
+ if(!vsdr)
+ return 0;
+
+ Shader *fsdr = load_shader(fname, SDR_FRAGMENT);
+ if(!fsdr)
+ return 0;
+
+ ShaderProgram *sprog;
+
+ if(use_vulkan) {
+ // TODO
+ return 0;
+ }
+ else {
+ sprog = new ShaderProgramGL;
+ }
+
+ sprog->attach_shader(vsdr);
+ sprog->attach_shader(fsdr);
+
+ if(!sprog->link()) {
+ delete sprog;
+ return 0;
+ }
+
+ return sprog;
+}
+
+void ShaderManager::set_path(const char *path)
+{
+ if(!path)
+ this->path.clear();
+ else
+ this->path = std::string(path);
}
\ No newline at end of file
#ifndef SHADER_MANAGER_H_
#define SHADER_MANAGER_H_
+#include <map>
#include <string>
#include "shader.h"
class ShaderManager {
private:
std::map<std::string, Shader *> shaders;
+ std::string path;
+
public:
ShaderManager();
~ShaderManager();
void add_shader(Shader *sdr, const char *name);
Shader *load_shader(const char *name, SType type);
void delete_shaders();
+
+ ShaderProgram *create_shader_program(const char *vname, const char *fname);
+
+ void set_path(const char *path);
};
#endif // SHADER_MANAGER_H_
\ No newline at end of file