Changed the OpenGL part and the GLSL shaders to use UBO and
authorEleni Maria Stea <estea@igalia.com>
Thu, 15 Mar 2018 01:52:43 +0000 (03:52 +0200)
committerEleni Maria Stea <estea@igalia.com>
Thu, 15 Mar 2018 01:52:43 +0000 (03:52 +0200)
locations inside the shaders. Introduced new abstraction on top
of UBO functions so that both OpenGL and Vulkan can use them
from the renderer

30 files changed:
gl_shaders/default.f.glsl
gl_shaders/default.v.glsl
gl_shaders/morphing.f.glsl
gl_shaders/morphing.v.glsl
gl_shaders/sky.f.glsl
gl_shaders/sky.v.glsl
src/camera.cc
src/camera.h
src/gfxapi.cc
src/gfxapi.h
src/morph_renderer.cc
src/morph_renderer.h
src/opengl/shader-gl.cc
src/opengl/shader-gl.h
src/opengl/uniforms-gl.cc [new file with mode: 0644]
src/opengl/uniforms-gl.h [new file with mode: 0644]
src/renderer.cc
src/renderer.h
src/shader.cc
src/shader.h
src/state_manager.cc [deleted file]
src/state_manager.h [deleted file]
src/uniforms.cc [new file with mode: 0644]
src/uniforms.h [new file with mode: 0644]
src/vulkan/allocator.cc
src/vulkan/mesh-vk.cc
src/vulkan/shader-vk.cc
src/vulkan/shader-vk.h
src/vulkan/uniforms-vk.cc [new file with mode: 0644]
src/vulkan/uniforms-vk.h [new file with mode: 0644]

index ad4b77a..fe78fbc 100644 (file)
@@ -1,45 +1,38 @@
 #version 450
 
-uniform sampler2D tex;
-uniform samplerCube dstex;
+#define SHADING_UNIFORMS 1
 
-uniform vec4 diffuse;
-uniform vec4 specular;
-uniform float shininess;
+layout(binding = 0) uniform sampler2D tex;
+layout(binding = 1) uniform samplerCube dstex;
 
-varying vec3 pos;
-// varying vec3 normal;
-// varying vec3 ldir;
-varying vec2 tex_coord;
-varying vec3 world_normal;
+layout(std140, binding = SHADING_UNIFORMS) uniform fu {
+       vec4 diffuse;
+       vec4 specular;
+       float shininess;
+       float fog_density;
+} s;
 
-// const float fog_density = 0.005;
-uniform float fog_density;
 const vec3 sky_color = vec3(0.35, 0.5, 0.65);
+// const float fog_density = 0.005;
+
+/* varyings */
+layout(location = 4) in vec3 pos;
+layout(location = 5) in vec2 tex_coord;
+layout(location = 6) in vec3 world_normal;
 
-out vec4 color;
+layout(location = 0) out vec4 color;
 
 void main()
 {
        vec4 itexel = textureCube(dstex, normalize(world_normal));
 
-/*     vec3 p = normalize(pos); // view space dir
-       vec3 n = normalize(normal);
-       vec3 l = normalize(ldir);
-
-       vec3 r = normalize(-reflect(l, n));
-       vec3 vdir = normalize(-p);
-
-       float cdiff = max(dot(l, n), 0.0);
-       float cspec = pow(max(dot(r, vdir), 0.0), shininess); */
-
        float dist = -pos.z;
-       float fog = clamp(exp(-fog_density * dist), 0.0, 1.0);
+       float fog = clamp(exp(-s.fog_density * dist), 0.0, 1.0);
 
        vec4 texel = texture2D(tex, tex_coord);
 
        // vec3 object_color = (diffuse.xyz * cdiff * texel.xyz + specular.xyz * cspec) * itexel.xyz;
-       vec3 object_color = diffuse.xyz * texel.xyz * itexel.xyz;
+       vec3 object_color = s.diffuse.xyz * texel.xyz * itexel.xyz;
 
        color.xyz = mix(sky_color, object_color, fog);
        color.w = 1.0;
index 76aae8a..b550308 100644 (file)
@@ -1,15 +1,12 @@
 #version 450
-//#extension GL_ARB_separate_shader_objects : enable
 
-uniform mat4 mview;
-uniform mat4 mmviewproj;
-uniform mat4 mmod;
+#define        MATRIX_UNIFORMS 0
 
-varying vec3 pos;
-// varying vec3 normal;
-// varying vec3 ldir;
-varying vec2 tex_coord;
-varying vec3 world_normal;
+layout(std140, binding = MATRIX_UNIFORMS) uniform vu {
+       mat4 mview;
+       uniform mat4 mmviewproj;
+       uniform mat4 mmod;
+} m;
 
 const vec3 lpos = vec3(-10.0, 100.0, 10.0);
 
@@ -18,16 +15,17 @@ layout(location = 1) in vec3 attr_pos;
 layout(location = 2) in vec3 attr_normal;
 layout(location = 3) in vec2 attr_tex;
 
+/* varyings */
+layout(location = 4) out vec3 pos;
+layout(location = 5) out vec2 tex_coord;
+layout(location = 6) out vec3 world_normal;
+
 void main()
 {
-       gl_Position = mmviewproj * vec4(attr_pos, 1.0);
-
-       pos = (mview * vec4(attr_pos, 1.0)).xyz;
-       // ldir = (mview * vec4(lpos, 1.0)).xyz;
+       gl_Position = m.mmviewproj * vec4(attr_pos, 1.0);
 
-       // mat3 normal_matrix = mat3(mview);
-       // normal = normal_matrix * attr_normal;
+       pos = (m.mview * vec4(attr_pos, 1.0)).xyz;
        tex_coord = attr_tex;
 
-       world_normal = (mmod * vec4(attr_normal, 1.0)).xyz;
-}
\ No newline at end of file
+       world_normal = (m.mmod * vec4(attr_normal, 1.0)).xyz;
+}
index ddb0579..de6dda9 100644 (file)
@@ -1,41 +1,33 @@
 #version 450
 
-uniform sampler2D tex;
-uniform samplerCube dstex;
+#define SHADING_UNIFORMS 1
 
-uniform vec4 diffuse;
-// uniform vec4 specular;
-// uniform float shininess;
+layout(binding = 0) uniform sampler2D tex;
+layout(binding = 1) uniform samplerCube dstex;
 
-uniform float fog_density;
-const vec3 sky_color = vec3(0.35, 0.5, 0.65);
+layout(std140, binding = SHADING_UNIFORMS) uniform fu {
+       vec4 diffuse;
+       vec4 specular;
+       float shininess;
+       float fog_density;
+} s;
+
+/* varyings */
+layout(location = 4) in vec3 pos;
+layout(location = 5) in vec2 tex_coord;
+layout(location = 6) in vec3 world_normal; 
 
-varying vec3 pos;
-// varying vec3 normal;
-// varying vec3 ldir;
-varying vec2 tex_coord;
-varying vec3 world_normal;
+layout(location = 0) out vec4 color;
 
-out vec4 color;
+const vec3 sky_color = vec3(0.35, 0.5, 0.65);
 
 void main()
 {
        vec4 itexel = textureCube(dstex, normalize(world_normal));
-       // vec3 p = normalize(pos);
-       // vec3 n = normalize(normal);
-       // vec3 l = normalize(ldir);
-
-       // vec3 r = normalize(-reflect(l, n));
-       // vec3 vdir = normalize(-p);
-
-       // float cdiff = max(dot(l, n), 0.0);
-       // float cspec = pow(max(dot(r, vdir), 0.0), shininess);
-
        vec4 texel = texture2D(tex, tex_coord);
-       // vec3 object_color = diffuse.xyz * cdiff * texel.xyz + specular.xyz * cspec;
-       vec3 object_color = diffuse.xyz * texel.xyz * itexel.xyz;
+       vec3 object_color = s.diffuse.xyz * texel.xyz * itexel.xyz;
        float dist = -pos.z;
-       float fog = clamp(exp(-fog_density * dist), 0.0, 1.0);
+       float fog = clamp(exp(-s.fog_density * dist), 0.0, 1.0);
 
        color.xyz = mix(sky_color, object_color, fog);
        color.w = 1.0;
index d84336f..80b7e39 100644 (file)
@@ -1,25 +1,30 @@
 #version 450
 
-uniform mat4 mview;
-uniform mat4 mmviewproj;
-uniform mat4 mmod;
+#define MATRIX_UNIFORMS 0
+#define MORPHING_UNIFORMS 3
 
-uniform float t;
-const float half_height = 0.855;
-
-varying vec3 pos;
-// varying vec3 normal;
-// varying vec3 ldir;
-varying vec2 tex_coord;
-varying vec3 world_normal;
+layout(std140, binding = MATRIX_UNIFORMS) uniform vu {
+       mat4 mview;
+       uniform mat4 mmviewproj;
+       uniform mat4 mmod;
+} m;
 
-// const vec3 lpos = vec3(0.0, 100.0, -10.0);
+layout(std140, binding = MORPHING_UNIFORMS) uniform mvu {
+       float t;
+} time;
 
 /* attributes */
 layout(location = 1) in vec3 attr_pos;
 layout(location = 2) in vec3 attr_normal;
 layout(location = 3) in vec2 attr_tex;
 
+/* varyings */
+layout(location = 4) out vec3 pos;
+layout(location = 5) out vec2 tex_coord;
+layout(location = 6) out vec3 world_normal; 
+
+const float half_height = 0.855;
+
 void main()
 {
        vec3 sph_pos = normalize(vec3(attr_pos.x, attr_pos.y - half_height, attr_pos.z));
@@ -27,17 +32,13 @@ void main()
        vec3 sph_normal = sph_pos;
        sph_pos.y += half_height;
 
-       vec3 p = mix(attr_pos, sph_pos, t);
-       vec3 n = mix(attr_normal, sph_normal, t);
-
-       gl_Position = mmviewproj * vec4(p, 1.0);
+       vec3 p = mix(attr_pos, sph_pos, time.t);
+       vec3 n = mix(attr_normal, sph_normal, time.t);
 
-       pos = (mview * vec4(p, 1.0)).xyz;
-       // ldir = (mview * vec4(lpos, 1.0)).xyz;
+       gl_Position = m.mmviewproj * vec4(p, 1.0);
 
-       // mat3 normal_matrix = mat3(mview);
-       // normal = normal_matrix * n;
+       pos = (m.mview * vec4(p, 1.0)).xyz;
 
        tex_coord = attr_tex;
-       world_normal = (mmod * vec4(attr_normal, 1.0)).xyz;
-}
\ No newline at end of file
+       world_normal = (m.mmod * vec4(attr_normal, 1.0)).xyz;
+}
index d5009c0..688da43 100644 (file)
@@ -1,6 +1,6 @@
 #version 450
 
-uniform samplerCube stex;
+layout(binding = 0) uniform samplerCube stex;
 
 in vec3 normal;
 out vec4 color;
@@ -11,4 +11,4 @@ void main()
 
        color.rgb = texel.rgb;
        color.a = 1.0;
-}
\ No newline at end of file
+}
index 84097a0..f5ba24f 100644 (file)
@@ -1,6 +1,11 @@
 #version 450
 
-uniform mat4 mviewproj;
+#define SKY_MATRIX_UNIFORMS 2
+
+layout(std140, binding = SKY_MATRIX_UNIFORMS) uniform svu {
+       mat4 mviewproj;
+} s;
+
 
 layout(location = 1) in vec3 attr_pos;
 layout(location = 2) in vec3 attr_normal;
@@ -9,6 +14,6 @@ out vec3 normal;
 
 void main()
 {
-       gl_Position = mviewproj * vec4(attr_pos, 1.0);
+       gl_Position = s.mviewproj * vec4(attr_pos, 1.0);
        normal = attr_normal;
-}
\ No newline at end of file
+}
index b3ad077..7de5501 100644 (file)
@@ -3,16 +3,10 @@
 #include <gmath/gmath.h>
 
 #include "camera.h"
-#include "state_manager.h"
 
 Camera::Camera() {}
 Camera::~Camera() {}
 
-void Camera::use() const
-{
-       state_manager.set_state("st_view_matrix", get_view_matrix());
-}
-
 OrbitCamera::OrbitCamera()
 {
        phi = theta = distance = 0;
@@ -63,4 +57,4 @@ void OrbitCamera::set_position(float x, float y, float z)
        position.x = x;
        position.y = y;
        position.z = z;
-}
\ No newline at end of file
+}
index 1fbbf9c..0f70040 100644 (file)
@@ -9,7 +9,6 @@ public:
        virtual ~Camera();
 
        virtual Mat4 get_view_matrix() const = 0;
-       virtual void use() const;
 };
 
 class OrbitCamera : public Camera {
@@ -32,4 +31,4 @@ public:
 
 Mat4 calc_projection_matrix(float fov_deg, float aspect, float n, float f);
 
-#endif // CAMERA_H_
\ No newline at end of file
+#endif // CAMERA_H_
index 1b67a36..e9f0f73 100644 (file)
@@ -6,10 +6,12 @@
 #include "opengl/mesh-gl.h"
 #include "opengl/texture-gl.h"
 #include "opengl/shader-gl.h"
+#include "opengl/uniforms-gl.h"
 
 #include "vulkan/shader-vk.h"
 #include "vulkan/mesh-vk.h"
 #include "vulkan/texture-vk.h"
+#include "vulkan/uniforms-vk.h"
 
 static Gfx_API api;
 
@@ -97,6 +99,17 @@ Shader *gfx_create_shader()
        return 0;
 }
 
+UniformBuffer *gfx_create_uniform_buffer()
+{
+       switch(api) {
+       case GFX_GL:
+               return new UniformBufferGL;
+       case GFX_VK:
+               return new UniformBufferVK;
+       }
+       return 0;
+}
+
 char *gfx_get_shader_path()
 {
        switch(api) {
index 80d996a..d6b1fd1 100644 (file)
@@ -2,9 +2,10 @@
 #define GFXAPI_H_
 
 class Mesh;
-class Texture;
 class ShaderProgram;
 class Shader;
+class Texture;
+class UniformBuffer;
 
 enum Gfx_API {
        GFX_GL,
@@ -34,6 +35,8 @@ Mesh *gfx_create_mesh();
 Texture *gfx_create_texture();
 ShaderProgram *gfx_create_shader_program();
 Shader *gfx_create_shader();
+UniformBuffer *gfx_create_uniform_buffer();
+
 char *gfx_get_shader_path();
 
 #endif // GFXAPI_H_
index d076114..a691835 100644 (file)
@@ -1,10 +1,15 @@
 #include "global.h"
+#include "gfxapi.h"
+
 #include "morph_renderer.h"
 #include "object.h"
 #include "scene.h"
 #include "shader.h"
 #include "shader_manager.h"
 #include "texture.h"
+#include "uniforms.h"
+
+#define MVU 5
 
 MorphRenderer::MorphRenderer()
 {
@@ -17,10 +22,13 @@ MorphRenderer::MorphRenderer()
        dskytex = 0;
 
        fog_density = 0;
+
+       mbuf = vbuf = fbuf = svbuf = 0;
 }
 
 MorphRenderer::~MorphRenderer()
 {
+       delete mbuf;
 }
 
 bool MorphRenderer::create()
@@ -29,28 +37,40 @@ bool MorphRenderer::create()
                return false;
        }
 
-       /* getting material uniform locations: diffuse, specular, specular exponent (strength) */
-
-       diff_loc = sprog->get_uniform_location("diffuse");
-       spec_loc = sprog->get_uniform_location("specular");
-       shin_loc = sprog->get_uniform_location("shininess");
-       t_loc = sprog->get_uniform_location("t");
-       fog_loc = sprog->get_uniform_location("fog_density");
+       mbuf = gfx_create_uniform_buffer();
+       if(!mbuf->create(sizeof mu)) {
+               fprintf(stderr, "Failed to create uniform buffer.\n");
+               return false;
+       }
 
-       /* uniform locations for matrices */
+       if(!vbuf) {
+               vbuf = gfx_create_uniform_buffer();
+               if(!vbuf->create(sizeof vu)) {
+                       fprintf(stderr, "Failed to create uniform buffer.\n");
+                       return false;
+               }
+       }
 
-       mmviewproj_loc = sprog->get_uniform_location("mmviewproj");
-       mview_loc = sprog->get_uniform_location("mview");
-       mmod_loc = sprog->get_uniform_location("mmod");
+       if(!fbuf) {
+               fbuf = gfx_create_uniform_buffer();
+               if(!fbuf->create(sizeof fu)) {
+                       fprintf(stderr, "Failed to create uniform buffer.\n");
+                       return false;
+               }
+       }
 
-       dstex_loc = sprog->get_uniform_location("dstex");
-       if(dstex_loc != -1)
-               sprog->set_uniformi(dstex_loc, 1);
+       if(!svbuf) {
+               svbuf = gfx_create_uniform_buffer();
+               if(!svbuf->create(sizeof svu)) {
+                       fprintf(stderr, "Failed to create uniform buffer.\n");
+                       return false;
+               }
+       }
 
        return true;
 }
 
-void MorphRenderer::draw() const
+void MorphRenderer::draw()
 {
        if(!camera || !scene)
                return;
@@ -65,13 +85,14 @@ void MorphRenderer::draw() const
        sprog->use();
 
        for(size_t i=0; i<scene->objects.size(); i++) {
-               float t = (sin(time_sec + 7.3 * noise(i * M_PI)) + 1) * 0.5;
-               if(t_loc != -1)
-                       sprog->set_uniformf(t_loc, t);
+               mu.t = (sin(time_sec + 7.3 * noise(i * M_PI)) + 1) * 0.5;
+               mbuf->update(&mu);
+               mbuf->bind(MORPHING_UNIFORMS);
 
-               if(mmod_loc != -1)
-                       sprog->set_uniform_matrix(mmod_loc, scene->objects[i]->transform.upper3x3());
+               vu.mmod = scene->objects[i]->transform.upper3x3();
+               vbuf->update(&vu);
+               vbuf->bind(MATRIX_UNIFORMS);
 
                draw_object(scene->objects[i]);
        }
-}
\ No newline at end of file
+}
index c939b4b..d4812a9 100644 (file)
@@ -3,16 +3,28 @@
 
 #include "renderer.h"
 
+class UniformBuffer;
+
+struct MorphVertUniforms {
+       float t;
+};
+
+struct MorphFragUniforms {
+       float fog_density;
+       Vec4 diffuse;
+};
+
 class MorphRenderer : public Renderer {
 protected:
-       int t_loc;
+       MorphVertUniforms mu;
+       UniformBuffer *mbuf;
 
 public:
        MorphRenderer();
        virtual ~MorphRenderer();
 
        virtual bool create() override;
-       virtual void draw() const override;
+       virtual void draw() override;
 };
 
-#endif // MORPH_RENDERER_H_
\ No newline at end of file
+#endif // MORPH_RENDERER_H_
index 374673f..296a67c 100644 (file)
@@ -2,7 +2,6 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "state_manager.h"
 #include "opengl/shader-gl.h"
 
 ShaderGL::ShaderGL()
@@ -156,92 +155,3 @@ void ShaderProgramGL::attach_shader(Shader *shader)
        glAttachShader(prog, ((ShaderGL *)shader)->sdr);
        is_linked = false;
 }
-
-int ShaderProgramGL::get_uniform_location(const char *name) const
-{
-       if(!use())
-               return -1;
-
-       return glGetUniformLocation(prog, name);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int value)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform1i(location, value);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int x, int y)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform2i(location, x, y);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int x, int y, int z)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform3i(location, x, y, z);
-}
-
-void ShaderProgramGL::set_uniformi(int location, int x, int y, int z, int w)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform4i(location, x, y, z, w);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float value)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform1f(location, value);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float x, float y)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform2f(location, x, y);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float x, float y, float z)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform3f(location, x, y, z);
-}
-
-void ShaderProgramGL::set_uniformf(int location, float x, float y, float z, float w)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniform4f(location, x, y, z, w);
-}
-
-void ShaderProgramGL::set_uniform_matrix(int location, const Mat4 &mat)
-{
-       if(!use() || location == -1) {
-               return;
-       }
-
-       glUniformMatrix4fv(location, 1, GL_FALSE, mat[0]);
-}
index d8136f4..4ee4a57 100644 (file)
@@ -31,20 +31,6 @@ public:
        virtual bool create() override;
        virtual void destroy() override;
        virtual void attach_shader(Shader *shader) override;
-
-       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;
-       virtual void set_uniformi(int location, int x, int y, int z) override;
-       virtual void set_uniformi(int location, int x, int y, int z, int w) override;
-
-       virtual void set_uniformf(int location, float value) override;
-       virtual void set_uniformf(int location, float x, float y) override;
-       virtual void set_uniformf(int location, float x, float y, float z) override;
-       virtual void set_uniformf(int location, float x, float y, float z, float w) override;
-
-       virtual void set_uniform_matrix(int location, const Mat4 &mat) override;
 };
 
-#endif // SHADER_GL_H_
\ No newline at end of file
+#endif // SHADER_GL_H_
diff --git a/src/opengl/uniforms-gl.cc b/src/opengl/uniforms-gl.cc
new file mode 100644 (file)
index 0000000..c4d82d2
--- /dev/null
@@ -0,0 +1,39 @@
+#include <GL/glew.h>
+
+#include "uniforms-gl.h"
+
+UniformBufferGL::UniformBufferGL()
+{
+       ubo = 0;
+}
+
+UniformBufferGL::~UniformBufferGL()
+{
+       destroy();
+}
+
+bool UniformBufferGL::create(int size)
+{
+       glGenBuffers(1, &ubo);
+       glBindBuffer(GL_UNIFORM_BUFFER, ubo);
+       glBufferData(GL_UNIFORM_BUFFER, size, 0, GL_STREAM_DRAW);
+
+       return UniformBuffer::create(size);
+}
+
+void UniformBufferGL::destroy()
+{
+       glDeleteBuffers(1, &ubo);
+}
+
+void UniformBufferGL::bind(int binding) const
+{
+       //glBindBuffer(GL_UNIFORM_BUFFER, ubo);
+       glBindBufferBase(GL_UNIFORM_BUFFER, binding, ubo);
+}
+
+void UniformBufferGL::update(void *data)
+{
+       glBindBuffer(GL_UNIFORM_BUFFER, ubo);
+       glBufferSubData(GL_UNIFORM_BUFFER, 0, size, data);
+}
diff --git a/src/opengl/uniforms-gl.h b/src/opengl/uniforms-gl.h
new file mode 100644 (file)
index 0000000..cfa724e
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef UNIFORMS_GL_H_
+#define UNIFORMS_GL_H_
+
+#include "uniforms.h"
+
+class UniformBufferGL : public UniformBuffer {
+private:
+       unsigned int ubo;
+
+public:
+       UniformBufferGL();
+       virtual ~UniformBufferGL();
+
+       virtual bool create(int size);
+       virtual void destroy() override;
+
+       virtual void bind(int binding) const override;
+       virtual void update(void *data) override;
+};
+
+#endif // UNIFORMS_GL_H_
index fd18d55..11cfb93 100644 (file)
@@ -1,5 +1,4 @@
 #include <GL/glew.h>
-#include <gmath/gmath.h>
 
 #include "global.h"
 #include "gfxapi.h"
@@ -13,6 +12,7 @@
 #include "shader.h"
 #include "shader_manager.h"
 #include "texture.h"
+#include "uniforms.h"
 
 #undef DRAW_NORMALS
 
@@ -20,7 +20,6 @@
 
 static Mesh *skymesh; /* it will be used by many renderers => no destroy */
 static ShaderProgram *skyprog;
-static int viewproj_loc;
 
 Renderer::Renderer()
 {
@@ -32,51 +31,50 @@ Renderer::Renderer()
        dskytex = 0;
 
        fog_density = 0;
+
+       vbuf = fbuf = svbuf = 0;
 }
 
 Renderer::~Renderer()
 {
+       delete vbuf;
+       delete fbuf;
+       delete svbuf;
 }
 
 bool Renderer::create()
 {
        //debug
        // if(!(nprog = sdr_man->create_shader_program("debug.v.glsl", "debug.f.glsl"))) {
-       //      fprintf(stderr, "Failed to load debug shaders.\n");
+       //      fprintf(stderr, "Failed to load debug shaders.\n");
        // }
 
        if(!(sprog = sdr_man->create_shader_program("default.v.glsl", "default.f.glsl"))) {
                return false;
        }
 
-       /* getting material uniform locations: diffuse, specular, specular exponent (strength) */
-
-       diff_loc = sprog->get_uniform_location("diffuse");
-       spec_loc = sprog->get_uniform_location("specular");
-       shin_loc = sprog->get_uniform_location("shininess");
-       fog_loc = sprog->get_uniform_location("fog_density");
-
-       /* uniform locations for matrices */
-
-       mmviewproj_loc = sprog->get_uniform_location("mmviewproj");
-       mview_loc = sprog->get_uniform_location("mview");
-       mmod_loc = sprog->get_uniform_location("mmod");
-
-       /* skybox, irradiance map uniforms */
-
-       stex_loc = sprog->get_uniform_location("stex");
-       dstex_loc = sprog->get_uniform_location("dstex");
+       vbuf = gfx_create_uniform_buffer();
+       if(!vbuf->create(sizeof vu)) {
+               fprintf(stderr, "Failed to create uniform buffer.\n");
+               return false;
+       }
 
-       if(stex_loc != -1)
-               sprog->set_uniformi(stex_loc, 0);
+       fbuf = gfx_create_uniform_buffer();
+       if(!fbuf->create(sizeof fu)) {
+               fprintf(stderr, "Failed to create uniform buffer.\n");
+               return false;
+       }
 
-       if(dstex_loc != -1)
-               sprog->set_uniformi(dstex_loc, 1);
+       svbuf = gfx_create_uniform_buffer();
+       if(!svbuf->create(sizeof svu)) {
+               fprintf(stderr, "Failed to create uniform buffer.\n");
+               return false;
+       }
 
        return true;
 }
 
-void Renderer::draw() const
+void Renderer::draw()
 {
        if(!camera || !scene)
                return;
@@ -99,23 +97,19 @@ void Renderer::draw() const
        }
 }
 
-void Renderer::draw_object(Object *object) const
+void Renderer::draw_object(Object *object)
 {
        Material *m = object->material;
 
        /* setting uniforms for material */
 
-       if(diff_loc != -1)
-               sprog->set_uniformf(diff_loc, m->diffuse.x, m->diffuse.y, m->diffuse.z, 1);
-
-       if(spec_loc != -1)
-               sprog->set_uniformf(spec_loc, m->specular.x, m->specular.y, m->specular.z, 1);
+       fu.diffuse = Vec4(m->diffuse.x, m->diffuse.y, m->diffuse.z, 1.0);
+       fu.specular = Vec4(m->specular.x, m->specular.y, m->specular.z, 1.0);
+       fu.shininess = m->shininess;
+       fu.fog_density = fog_density;
 
-       if(shin_loc != -1)
-               sprog->set_uniformf(shin_loc, m->shininess);
-
-       if(fog_loc != -1)
-               sprog->set_uniformf(fog_loc, fog_density);
+       fbuf->update(&fu);
+       fbuf->bind(SHADING_UNIFORMS);
 
        /* texture */
 
@@ -124,27 +118,22 @@ void Renderer::draw_object(Object *object) const
 
        /* setting uniforms for matrices */
 
-       Mat4 mmviewproj = object->transform * camera->get_view_matrix() * mprojection;
-       if(mmviewproj_loc != -1)
-               sprog->set_uniform_matrix(mmviewproj_loc, mmviewproj);
-
-       Mat4 mview = object->transform * camera->get_view_matrix();
-       if(mview_loc != -1)
-               sprog->set_uniform_matrix(mview_loc, mview);
+       vu.mview = object->transform * camera->get_view_matrix();
+       vu.mmviewproj = object->transform * camera->get_view_matrix() * mprojection;
+       vu.mmod = object->transform.upper3x3();
 
-       Mat4 mmod = object->transform.upper3x3();
-       if(mmod_loc != -1)
-               sprog->set_uniform_matrix(mmod_loc, mmod);
+       vbuf->update(&vu);
+       vbuf->bind(MATRIX_UNIFORMS);
 
        object->mesh->draw();
 
        // debug
 #ifdef DRAW_NORMALS
        if(nprog) {
-               int loc = nprog->get_uniform_location("mmviewproj");
-               if(loc != -1) {
-                       nprog->set_uniform_matrix(loc, mmviewproj);
-               }
+               vu.mmviewproj = mmviewproj;
+               vbuf->update(&vu);
+               vbuf->bind(MATRIX_UNIFORMS);
+
                nprog->use();
                object->mesh->draw_normals(1.0);
        }
@@ -160,8 +149,6 @@ void Renderer::set_sky_tex(Texture *stex)
        if(!skyprog) {
                if(!(skyprog = sdr_man->create_shader_program("sky.v.glsl", "sky.f.glsl")))
                        return;
-               if((viewproj_loc = skyprog->get_uniform_location("mviewproj") == -1))
-                       return;
        }
        skytex = stex;
 }
@@ -171,7 +158,7 @@ void Renderer::set_diffuse_sky_tex(Texture *dstex)
        dskytex = dstex;
 }
 
-void Renderer::draw_skybox() const
+void Renderer::draw_skybox()
 {
        if(!skymesh || !skytex)
                return;
@@ -182,12 +169,12 @@ void Renderer::draw_skybox() const
        skytex->bind();
        skyprog->use();
 
-       Mat4 mviewproj;
-       mviewproj = camera->get_view_matrix().upper3x3() * mprojection;
-       skyprog->set_uniform_matrix(viewproj_loc, mviewproj);
+       svu.mviewproj = camera->get_view_matrix().upper3x3() * mprojection;
+       svbuf->update(&svu);
+       svbuf->bind(SKY_MATRIX_UNIFORMS);
 
        skymesh->draw();
 
        gfx_cull_face(GFX_CULL_BACK);
        gfx_zbuffer(true);
-}
\ No newline at end of file
+}
index 23471f5..9605aa3 100644 (file)
@@ -1,23 +1,50 @@
 #ifndef RENDERER_H_
 #define RENDERER_H_
 
+#include <gmath/gmath.h>
+
 class OrbitCamera;
 class Object;
 class Scene;
 class ShaderProgram;
 class Texture;
+class UniformBuffer;
+
+enum {
+       MATRIX_UNIFORMS = 0,
+       SHADING_UNIFORMS = 1,
+       SKY_MATRIX_UNIFORMS = 2,
+       MORPHING_UNIFORMS = 3,
+       MORPHING_SHADING_UNIFORMS = 4,
+};
+
+struct BaseVertUniforms {
+       Mat4 mview;
+       Mat4 mmviewproj;
+       Mat4 mmod;
+};
+
+struct BaseFragUniforms {
+       Vec4 diffuse;
+       Vec4 specular;
+       float shininess;
+       float fog_density;
+};
+
+struct SkyVertUniforms {
+       Mat4 mviewproj;
+};
 
 class Renderer {
 protected:
-       int diff_loc;
-       int spec_loc;
-       int shin_loc;
-       int mmviewproj_loc;
-       int mview_loc;
-       int mmod_loc;
-       int fog_loc;
-       int dstex_loc;
-       int stex_loc;
+       BaseVertUniforms vu;
+       UniformBuffer *vbuf;
+
+       BaseFragUniforms fu;
+       UniformBuffer *fbuf;
+
+       SkyVertUniforms svu;
+       UniformBuffer *svbuf;
 
        ShaderProgram *sprog;
 
@@ -26,8 +53,8 @@ protected:
 
        Texture *skytex, *dskytex;
 
-       virtual void draw_object(Object *object) const;
-       virtual void draw_skybox() const;
+       virtual void draw_object(Object *object);
+       virtual void draw_skybox();
 
 public:
        float fog_density;
@@ -39,10 +66,10 @@ public:
        virtual ~Renderer();
 
        virtual bool create();
-       virtual void draw() const;
+       virtual void draw();
 
        virtual void set_sky_tex(Texture *stex);
        virtual void set_diffuse_sky_tex(Texture *dstex);
 };
 
-#endif // RENDERER_H_
\ No newline at end of file
+#endif // RENDERER_H_
index 39fa0de..b39401f 100644 (file)
@@ -25,7 +25,6 @@ bool Shader::load(const char *fname, SType type)
 
        if(!(fp = fopen(fname, "rb"))) {
                fprintf(stderr, "Failed to open shader: %s\n", fname);
-
                return false;
        }
        fseek(fp, 0, SEEK_END);
@@ -44,8 +43,7 @@ bool Shader::load(const char *fname, SType type)
        buf[fsz] = '\0';
        fclose(fp);
 
-       create(buf, fsz, fname);
-       return true;
+       return create(buf, fsz, fname);
 }
 
 SType Shader::get_type()
index 6e9509a..5a79b7f 100644 (file)
@@ -37,16 +37,9 @@ public:
 
 /* Shader Program */
 
-struct Uniform {
-       int location;
-       std::string name;
-       int state_idx;
-};
-
 class ShaderProgram {
 protected:
        Shader *shaders[2];
-       std::vector<Uniform> uniforms;
 
 public:
        ShaderProgram();
@@ -57,25 +50,6 @@ public:
        virtual bool use() const = 0;
        virtual void destroy() = 0;
        virtual void attach_shader(Shader *shader) = 0;
-
-       /*
-               THIS PART MIGHT NEED SEVERAL CHANGES: on vulkan we set the uniforms
-               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_uniformi(int location, int x, int y, int z) = 0;
-       virtual void set_uniformi(int location, int x, int y, int z, int w) = 0;
-
-       virtual void set_uniformf(int location, float value) = 0;
-       virtual void set_uniformf(int location, float x, float y) = 0;
-       virtual void set_uniformf(int location, float x, float y, float z) = 0;
-       virtual void set_uniformf(int location, float x, float y, float z, float w) = 0;
-
-       virtual void set_uniform_matrix(int location, const Mat4 &mat) = 0;
 };
 
 #endif // SHADER_H_
diff --git a/src/state_manager.cc b/src/state_manager.cc
deleted file mode 100644 (file)
index a375cff..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#include <stdio.h>
-#include <map>
-#include <string>
-
-#include <gmath/gmath.h>
-
-#include "state_manager.h"
-
-StateManager state_manager;
-
-State *StateManager::get_state(const char *name)
-{
-       std::map<std::string, int>::iterator it;
-       it = statemap.find(name);
-       return it == statemap.end() ? 0 : &states[it->second];
-}
-
-int StateManager::add_state_element(const char *name, int num_floats)
-{
-       State *st = get_state(name);
-       if(st) {
-               if(st->num != num_floats) {
-                       fprintf(stderr, "Uniform %s, type mismatch!\n", name);
-                       return -1;
-               }
-
-               return st - &states[0];
-       }
-
-       State state;
-       state.num = num_floats;
-
-       state.name = new char[strlen(name) + 1];
-       strcpy(state.name, name);
-
-       int sz = sizeof *state.data * num_floats;
-       state.data = new float[sz];
-       memset(state.data, 0, sz);
-
-       int idx = (int)states.size();
-       states.push_back(state);
-
-       statemap[name] = idx;
-
-       printf("State manager: added state %s with %d float data.\n", name, num_floats);
-       return idx;
-}
-
-void StateManager::set_state(const char *name, float value)
-{
-       set_state(name, Vec4(value, 0, 0, 1));
-}
-
-void StateManager::set_state(const char *name, const Vec3 &vec)
-{
-       set_state(name, Vec4(vec.x, vec.y, vec.z, 1));
-}
-
-void StateManager::set_state(const char *name, const Vec4 &vec)
-{
-       State *state = get_state(name);
-       if(!state)
-               return;
-
-       switch(state->num) {
-       case 4:
-               state->data[3] = vec.w;
-       case 3:
-               state->data[2] = vec.z;
-       case 2:
-               state->data[1] = vec.y;
-       case 1:
-               state->data[0] = vec.x;
-       default:
-               break;
-       }
-}
-
-void StateManager::set_state(const char *name, const Mat4 &mat)
-{
-       State *state = get_state(name);
-
-       if(!state)
-               return;
-
-       if(state->num != 16) {
-               fprintf(stderr, "State manager: state %s can only be a 4x4 matrix.\n", name);
-               return;
-       }
-
-       for(int j=0; j<4; j++) {
-               for(int i=0; i<4; i++) {
-                       state->data[4 * i + j] = mat.m[i][j];
-               }
-       }
-}
-
-const State *StateManager::get_state(const char *name) const
-{
-       return ((StateManager *)this)->get_state(name);
-}
-
-const State *StateManager::get_state(int idx) const
-{
-       return &states[idx];
-}
\ No newline at end of file
diff --git a/src/state_manager.h b/src/state_manager.h
deleted file mode 100644 (file)
index 4894644..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef STATE_MANAGER_H_
-#define STATE_MANAGER_H_
-
-#include <gmath/gmath.h>
-#include <map>
-
-#include <string>
-#include <vector>
-
-struct State {
-       int num;
-       char *name;
-       float *data;
-};
-
-class StateManager {
-private:
-       std::map<std::string, int> statemap;
-       State *get_state(const char *name);
-
-public:
-       std::vector<State> states;
-
-       /*
-               adds a state returns an idx:
-               the num_floats indicates the number of floats that form
-               the state element.
-               For example:
-               a float value consists of 1 float => num_floats = 1,
-               a Vec2 consists of 2 floats, a Vec3 from 3, a Vec4 from 4
-
-               see also:
-               set_state(const char *name, const Mat4 &mat implementation)
-       */
-       int add_state_element(const char *name, int num_floats);
-
-       void set_state(const char *name, float value);
-       void set_state(const char *name, const Vec3 &vec);
-       void set_state(const char *name, const Vec4 &vec);
-       void set_state(const char *name, const Mat4 &mat);
-
-       const State *get_state(const char *name) const;
-       const State *get_state(int idx) const;
-};
-
-extern StateManager state_manager;
-
-#endif // STATE_MANAGER_H_
\ No newline at end of file
diff --git a/src/uniforms.cc b/src/uniforms.cc
new file mode 100644 (file)
index 0000000..765a5b0
--- /dev/null
@@ -0,0 +1,16 @@
+#include "uniforms.h"
+
+UniformBuffer::UniformBuffer()
+{
+       size = -1;
+}
+
+UniformBuffer::~UniformBuffer()
+{
+}
+
+bool UniformBuffer::create(int size)
+{
+       this->size = size;
+       return true;
+}
diff --git a/src/uniforms.h b/src/uniforms.h
new file mode 100644 (file)
index 0000000..9117135
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef UNIFORMS_H_
+#define UNIFORMS_H_
+
+class UniformBuffer {
+protected:
+       int size;
+
+public:
+       UniformBuffer();
+       virtual ~UniformBuffer();
+
+       virtual bool create(int size);
+       virtual void destroy() = 0;
+
+       virtual void bind(int binding) const = 0;
+       virtual void update(void *data) = 0;
+};
+
+#endif // UNIFORMS_H_
index ba1b47b..60da2c8 100644 (file)
@@ -34,7 +34,7 @@ void vku_free(VkDeviceMemory gpu_memory)
 bool vku_write_memory(VkDeviceMemory gpu_mem, int size, void *data)
 {
        uint8_t *pdata;
-       VkResult res = vkMapMemory(vk_device, gpu_mem, 0, size, 0, (void**)&pdata);
+       VkResult res = vkMapMemory(vk_device, gpu_mem, 0, size, 0, (void **)&pdata);
        if(res != VK_SUCCESS) {
                fprintf(stderr, "Failed to map memory to write data.\n");
                return false;
index 729e24c..540501e 100644 (file)
@@ -52,14 +52,14 @@ bool MeshVK::update_vertex_data()
 
        int vsz = vertices.size() * sizeof(Vec3);
        if(!(vk_vertices = vku_create_buffer(vsz,
-                                       VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))) {
+                                            VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))) {
                fprintf(stderr, "Failed to create the buffer for the vertices.\n");
                return false;
        }
 
        int nsz = normals.size() * sizeof(Vec3);
        if(!(vk_normals = vku_create_buffer(nsz,
-                                       VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))) {
+                                           VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))) {
                vku_destroy_buffer(vk_vertices);
 
                fprintf(stderr, "Failed to create the buffer for the normals.\n");
@@ -68,18 +68,18 @@ bool MeshVK::update_vertex_data()
 
        int tsz = tex_coords.size() * sizeof(Vec2);
        if(!(vk_tex_coords = vku_create_buffer(tsz,
-                                       VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))) {
+                                              VK_BUFFER_USAGE_VERTEX_BUFFER_BIT))) {
                vku_destroy_buffer(vk_vertices);
                vku_destroy_buffer(vk_normals);
 
                fprintf(stderr,
-                               "Failed to create the buffer for the texture coordinates.\n");
+                       "Failed to create the buffer for the texture coordinates.\n");
                return false;
        }
 
        int isz = indices.size() * 2;
        if(!(vk_indices = vku_create_buffer(isz,
-                                       VK_BUFFER_USAGE_INDEX_BUFFER_BIT))) {
+                                           VK_BUFFER_USAGE_INDEX_BUFFER_BIT))) {
                vku_destroy_buffer(vk_vertices);
                vku_destroy_buffer(vk_normals);
                vku_destroy_buffer(vk_tex_coords);
@@ -90,43 +90,43 @@ bool MeshVK::update_vertex_data()
 
        /* write the buffers */
 
-       if(!vku_write_memory(vk_vertices->mem_pool, vsz, (void*)vertices.data())) {
+       if(!vku_write_memory(vk_vertices->mem_pool, vsz, (void *)vertices.data())) {
                fprintf(stderr, "Failed to write the vertices to GPU.\n");
                return false;
        }
        if(vkBindBufferMemory(vk_device, vk_vertices->buf, vk_vertices->mem_pool,
-                               0) != VK_SUCCESS) {
+                             0) != VK_SUCCESS) {
                fprintf(stderr, "Failed to bind the vertex buffer memory\n");
                return false;
        }
 
-       if(!vku_write_memory(vk_normals->mem_pool, nsz, (void*)normals.data())) {
+       if(!vku_write_memory(vk_normals->mem_pool, nsz, (void *)normals.data())) {
                fprintf(stderr, "Failed to write the normals to GPU.\n");
                return false;
        }
        if(vkBindBufferMemory(vk_device, vk_normals->buf, vk_normals->mem_pool, 0)
-                       != VK_SUCCESS) {
+               != VK_SUCCESS) {
                fprintf(stderr, "Failed to bind the normal buffer memory\n");
                return false;
        }
 
        if(!vku_write_memory(vk_tex_coords->mem_pool, tsz,
-                               (void*)tex_coords.data())) {
+                            (void *)tex_coords.data())) {
                fprintf(stderr, "Failed to write the texture coordinates to GPU.\n");
                return false;
        }
        if(vkBindBufferMemory(vk_device, vk_tex_coords->buf,
-                               vk_tex_coords->mem_pool, 0) != VK_SUCCESS) {
+                             vk_tex_coords->mem_pool, 0) != VK_SUCCESS) {
                fprintf(stderr, "Failed to bind the tex coordinates buffer memory.\n");
                return false;
        }
 
-       if(!vku_write_memory(vk_indices->mem_pool, isz, (void*)indices.data())) {
+       if(!vku_write_memory(vk_indices->mem_pool, isz, (void *)indices.data())) {
                fprintf(stderr, "Failed to write the indices to GPU.\n");
                return false;
        }
        if(vkBindBufferMemory(vk_device, vk_indices->buf, vk_indices->mem_pool, 0)
-                       != VK_SUCCESS) {
+               != VK_SUCCESS) {
                fprintf(stderr, "Failed to bind the index buffer memory.\n");
                return false;
        }
index d53883d..1fa9fb3 100644 (file)
@@ -39,7 +39,7 @@ bool ShaderVK::create(char *buf, unsigned int bsz, const char *fname)
        sminf.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
 
        sminf.codeSize = bsz;
-       sminf.pCode = (uint32_t*)buf;
+       sminf.pCode = (uint32_t *)buf;
 
        if(vkCreateShaderModule(vk_device, &sminf, 0, &sm) != VK_SUCCESS) {
                delete [] buf;
@@ -100,7 +100,7 @@ bool ShaderProgramVK::create()
                        fprintf(stderr, "Failed to create graphics pipeline: Invalid shader type.\n");
                        return false;
                }
-               ssinf[i].module = ((ShaderVK*)shaders[i])->sm;
+               ssinf[i].module = ((ShaderVK *)shaders[i])->sm;
        }
 
        gpinf.pStages = ssinf;
@@ -125,45 +125,3 @@ void ShaderProgramVK::destroy()
 void ShaderProgramVK::attach_shader(Shader *shader)
 {
 }
-
-int ShaderProgramVK::get_uniform_location(const char *name) const
-{
-       return 0;
-}
-
-void ShaderProgramVK::set_uniformi(int location, int value)
-{
-}
-
-void ShaderProgramVK::set_uniformi(int location, int x, int y)
-{
-}
-
-void ShaderProgramVK::set_uniformi(int location, int x, int y, int z)
-{
-}
-
-void ShaderProgramVK::set_uniformi(int location, int x, int y, int z, int w)
-{
-}
-
-
-void ShaderProgramVK::set_uniformf(int location, float value)
-{
-}
-
-void ShaderProgramVK::set_uniformf(int location, float x, float y)
-{
-}
-
-void ShaderProgramVK::set_uniformf(int location, float x, float y, float z)
-{
-}
-
-void ShaderProgramVK::set_uniformf(int location, float x, float y, float z, float w)
-{
-}
-
-void ShaderProgramVK::set_uniform_matrix(int location, const Mat4 &mat)
-{
-}
index b9e4681..efc576f 100644 (file)
@@ -41,19 +41,5 @@ public:
        virtual bool link() override;
        virtual void destroy() override;
        virtual void attach_shader(Shader *shader) override;
-
-       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;
-       virtual void set_uniformi(int location, int x, int y, int z) override;
-       virtual void set_uniformi(int location, int x, int y, int z, int w) override;
-
-       virtual void set_uniformf(int location, float value) override;
-       virtual void set_uniformf(int location, float x, float y) override;
-       virtual void set_uniformf(int location, float x, float y, float z) override;
-       virtual void set_uniformf(int location, float x, float y, float z, float w) override;
-
-       virtual void set_uniform_matrix(int location, const Mat4 &mat) override;
 };
 #endif // SHADER_VK_H_
diff --git a/src/vulkan/uniforms-vk.cc b/src/vulkan/uniforms-vk.cc
new file mode 100644 (file)
index 0000000..1c87a55
--- /dev/null
@@ -0,0 +1,26 @@
+#include "uniforms-vk.h"
+
+UniformBufferVK::UniformBufferVK()
+{
+}
+
+UniformBufferVK::~UniformBufferVK()
+{
+}
+
+bool UniformBufferVK::create(int size)
+{
+       return true;
+}
+
+void UniformBufferVK::destroy()
+{
+}
+
+void UniformBufferVK::bind(int binding) const
+{
+}
+
+void UniformBufferVK::update(void *data)
+{
+}
diff --git a/src/vulkan/uniforms-vk.h b/src/vulkan/uniforms-vk.h
new file mode 100644 (file)
index 0000000..68847ce
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef UNIFORMS_VK_H_
+#define UNIFORMS_VK_H_
+
+#include "uniforms.h"
+
+class UniformBufferVK : public UniformBuffer {
+public:
+       UniformBufferVK();
+       virtual ~UniformBufferVK();
+
+       virtual bool create(int size);
+       virtual void destroy() override;
+
+       virtual void bind(int binding) const override;
+       virtual void update(void *data) override;
+};
+
+#endif //UNIFORMS_VK_H_