case GFX_GL:
return (char *)"gl_shaders";
case GFX_VK:
- return (char *)"vk_shaders";
+ return (char *)"vk_shaders/spirv";
}
return (char *)"";
}
void ShaderProgramGL::set_uniform_matrix(int location, const Mat4 &mat)
{
if(!use() || location == -1) {
- fprintf(stderr, "FOO\n");
return;
}
glUniformMatrix4fv(location, 1, GL_FALSE, mat[0]);
-}
\ No newline at end of file
+}
unsigned int fsz;
if(!(fp = fopen(fname, "rb"))) {
- fprintf(stderr, "Failed to open shader: %s.\n", fname);
+ fprintf(stderr, "Failed to open shader: %s\n", fname);
return false;
}
fsz = ftell(fp);
rewind(fp);
- char *buf;
- if(!(buf = new char[fsz + 1])) {
- fprintf(stderr, "Failed to allocate %u buffers.\n", fsz + 1);
- fclose(fp);
-
- return false;
- }
+ char *buf = new char[fsz + 1];
if(fread(buf, 1, fsz, fp) < fsz) {
- fprintf(stderr, "Failed to read shader: %s.\n", fname);
+ fprintf(stderr, "Failed to read shader: %s\n", fname);
delete buf;
fclose(fp);
return true;
}
+SType Shader::get_type()
+{
+ return type;
+}
+
ShaderProgram::ShaderProgram()
{
int len = sizeof shaders / sizeof *shaders;
for(int i=0; i<len; ++i) {
delete shaders[i];
}
-}
\ No newline at end of file
+}
#ifndef SHADER_H_
#define SHADER_H_
+#include <vulkan/vulkan.h>
+
#include <vector>
#include <string>
virtual bool load(const char *fname, SType type);
virtual void destroy() = 0;
+ virtual SType get_type();
};
/* Shader Program */
std::string fname = path.empty() ? std::string(name) : path + "/" + std::string(name);
if(!sdr->load(fname.c_str(), type)) {
- fprintf(stderr, "Failed to load shader: %s.\n", fname.c_str());
delete sdr;
return 0;
}
this->path.clear();
else
this->path = std::string(path);
-}
\ No newline at end of file
+}
+#include <vulkan/vulkan.h>
#include "mesh-vk.h"
MeshVK::MeshVK() {}
void MeshVK::update_vertex_data()
{
+ if(vertices.empty()) {
+ printf("empty vertices!\n");
+ return;
+ }
+
+// if(num_vertices != vertices.size()) {
+// }
}
void MeshVK::draw() const
void MeshVK::draw_normals(float scale) const
{
-}
\ No newline at end of file
+}
class MeshVK : public Mesh {
private:
+ VkBuffer vk_vertices;
+ VkBuffer vk_normals;
+ VkBuffer vk_tex_coords;
+ VkBuffer vk_indices;
+
virtual void update_vertex_data() override;
public:
MeshVK();
virtual void draw_normals(float scale) const override;
};
-#endif // MESH_VK_H_
\ No newline at end of file
+#endif // MESH_VK_H_
#include "shader-vk.h"
/* static variables */
-static vku_buffer ubo;
-
ShaderVK::ShaderVK()
{
}
destroy();
}
-bool ShaderVK::create(char *buf, unsigned int bsz, const char *fname)
+bool ShaderVK::load(const char *fname, SType type)
{
- return true;
+ char *vk_fname = new char[strlen(fname) + strlen(".spirv") + 1];
+ strcpy(vk_fname, fname);
+
+ char *suffix = strrchr(vk_fname, '.');
+
+ if(suffix) {
+ *suffix = 0;
+ }
+
+ strcat(vk_fname, ".spirv");
+
+ bool res = Shader::load(vk_fname, type);
+ delete [] vk_fname;
+
+ return res;
}
-bool ShaderVK::load(const char *fname, SType type)
+bool ShaderVK::create(char *buf, unsigned int bsz, const char *fname)
{
+ name = std::string(fname);
+
+ VkShaderModuleCreateInfo sminf;
+ memset(&sminf, 0, sizeof sminf);
+ sminf.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+
+ sminf.codeSize = bsz;
+ sminf.pCode = (uint32_t*)buf;
+
+ if(vkCreateShaderModule(vk_device, &sminf, 0, &sm) != VK_SUCCESS) {
+ delete [] buf;
+
+ fprintf(stderr, "Failed to create vertex shader module.\n");
+ return false;
+ }
+
+ delete [] buf;
return true;
}
void ShaderVK::destroy()
{
+ vkDestroyShaderModule(vk_device, sm, 0);
}
ShaderProgramVK::ShaderProgramVK()
bool ShaderProgramVK::create()
{
+ /* pipeline cache */
+ VkPipelineCacheCreateInfo pcinf;
+ memset(&pcinf, 0, sizeof pcinf);
+ pcinf.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+
+ VkPipelineCache pcache;
+ if(!vkCreatePipelineCache(vk_device, &pcinf, 0, &pcache) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to create pipeline cache.\n");
+ return false;
+ }
+
+ /* pipeline */
+ VkGraphicsPipelineCreateInfo gpinf;
+ memset(&gpinf, 0, sizeof gpinf);
+ gpinf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ gpinf.stageCount = 2;
+
+ VkPipelineShaderStageCreateInfo ssinf[2];
+ for(int i=0; i<2; i++) {
+ memset(&ssinf[i], 0, sizeof ssinf[i]);
+ ssinf[i].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+
+ switch(shaders[i]->get_type()) {
+ case SDR_VERTEX:
+ ssinf[i].stage = VK_SHADER_STAGE_VERTEX_BIT;
+ break;
+ case SDR_FRAGMENT:
+ ssinf[i].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
+ break;
+ default:
+ fprintf(stderr, "Failed to create graphics pipeline: Invalid shader type.\n");
+ return false;
+ }
+ ssinf[i].module = ((ShaderVK*)shaders[i])->sm;
+ }
+
+ gpinf.pStages = ssinf;
+
return true;
}
void ShaderProgramVK::set_uniform_matrix(int location, const Mat4 &mat)
{
-}
\ No newline at end of file
+}
/* each shader program will correspond to a pipeline. The pipeline
* must have the cull, zbuffer etc since they can't be dynamic states */
-struct Pipeline {
-
-};
-
-class ShaderVK : public Shader
-{
+class ShaderVK : public Shader {
protected:
SType type;
std::string name;
virtual bool create(char *buf, unsigned int bsz, const char *fname) override;
public:
+ VkShaderModule sm;
+
ShaderVK();
virtual ~ShaderVK();
- virtual bool load(const char *fname, SType type);
+ virtual bool load(const char *fname, SType type) override;
virtual void destroy() override;
};
class ShaderProgramVK : public ShaderProgram
{
+private:
+ VkPipeline gpipeline;
+
protected:
- Pipeline pipeline;
- /*ubo*/
public:
ShaderProgramVK();
virtual ~ShaderProgramVK();
virtual bool create() override;
+
virtual bool use() const override;
virtual bool link() override;
virtual void destroy() override;
static bool create_zbuffer();
static bool create_renderpass();
static bool create_framebuffers();
+static bool create_pipelines();
static bool begin_init_command_buffer(VkCommandBuffer *cb);
static bool end_init_command_buffer(VkCommandBuffer *cb);
static bool allocate_rendering_command_buffers(VkCommandBuffer *bufs);
return false;
}
+ if(!create_pipelines()) {
+ fprintf(stderr, "Failed to create the pipelines.\n");
+ return false;
+ }
+
if(!end_init_command_buffer(&init_buf)) {
fprintf(stderr, "Failed to end the command buffer.\n");
return false;
return true;
}
+static bool create_pipelines()
+{
+ VkDescriptorSetLayoutBinding dslb[1];
+ memset(&dslb[0], 0, sizeof dslb[0]);
+ dslb[0].binding = 0;
+ dslb[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ dslb[0].descriptorCount = 1;
+ dslb[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
+
+ VkDescriptorSetLayoutCreateInfo dslinf;
+ memset(&dslinf, 0, sizeof dslinf);
+ dslinf.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ dslinf.bindingCount = 1; //dslb.size();
+ dslinf.pBindings = dslb;
+
+ VkDescriptorSetLayout dsl;
+ if(vkCreateDescriptorSetLayout(vk_device, &dslinf, 0, &dsl) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to create descriptor set layout.\n");
+ return false;
+ }
+
+ VkPipelineLayoutCreateInfo pinf;
+ memset(&pinf, 0, sizeof pinf);
+ pinf.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+ pinf.setLayoutCount = 1;
+ pinf.pSetLayouts = &dsl;
+
+ VkPipelineLayout pl;
+ if(vkCreatePipelineLayout(vk_device, &pinf, 0, &pl) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to create pipeline layout.\n");
+ return false;
+ }
+
+ VkPipelineCacheCreateInfo pcinf;
+ memset(&pcinf, 0, sizeof pcinf);
+ pcinf.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+
+ VkPipelineCache pcache;
+ if(vkCreatePipelineCache(vk_device, &pcinf, 0, &pcache) != VK_SUCCESS) {
+ fprintf(stderr, "Failed to create pipeline cache.\n");
+ return false;
+ }
+
+ VkGraphicsPipelineCreateInfo ginf;
+ memset(&ginf, 0, sizeof ginf);
+ ginf.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ ginf.stageCount = 2;
+
+ return true;
+}
+
static bool end_init_command_buffer(VkCommandBuffer *cb)
{
if(vkEndCommandBuffer(*cb) != VK_SUCCESS) {
--- /dev/null
+#version 450
+
+out vec4 color;
+
+void main()
+{
+ color = vec4(1.0, 0.0, 1.0, 1.0);
+}
--- /dev/null
+#version 450
+
+uniform mat4 mmviewproj;
+
+layout(location = 1) in vec3 attr_pos;
+
+void main()
+{
+ gl_Position = mmviewproj * vec4(attr_pos, 1.0);
+}
--- /dev/null
+#version 450
+
+layout(binding = 0) uniform sampler2D tex;
+layout(binding = 0) uniform samplerCube dstex;
+
+layout(std140, binding = 0) uniform shading_state {
+ vec4 diffuse;
+ vec4 specular;
+ float shininess;
+ float fog_density;
+} s;
+
+layout(location = 0) in vec3 pos;
+layout(location = 1) in vec2 tex_coord;
+layout(location = 2) in vec3 world_normal;
+
+// const float fog_density = 0.005;
+const vec3 sky_color = vec3(0.35, 0.5, 0.65);
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ /*vec4 itexel = textureCube(dstex, normalize(world_normal)); */
+ vec4 itexel = texture(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(-s.fog_density * dist), 0.0, 1.0);
+
+ vec4 texel = texture(tex, tex_coord);
+
+ // vec3 object_color = (diffuse.xyz * cdiff * texel.xyz + specular.xyz * cspec) * itexel.xyz;
+ vec3 object_color = s.diffuse.xyz * texel.xyz * itexel.xyz;
+
+ color.xyz = mix(sky_color, object_color, fog);
+ color.w = 1.0;
+}
--- /dev/null
+#version 450
+//#extension GL_ARB_separate_shader_objects : enable
+
+layout(std140, binding = 0) uniform matrix_state {
+ uniform mat4 mview;
+ uniform mat4 mmviewproj;
+ uniform mat4 mmod;
+} m;
+
+layout(location = 0) out vec3 pos;
+layout(location = 1) out vec2 tex_coord;
+layout(location = 2) out vec3 world_normal;
+
+const vec3 lpos = vec3(-10.0, 100.0, 10.0);
+
+/* attributes */
+layout(location = 1) in vec3 attr_pos;
+layout(location = 2) in vec3 attr_normal;
+layout(location = 3) in vec2 attr_tex;
+
+void main()
+{
+ gl_Position = m.mmviewproj * vec4(attr_pos, 1.0);
+
+ pos = (m.mview * vec4(attr_pos, 1.0)).xyz;
+ tex_coord = attr_tex;
+
+ world_normal = (m.mmod * vec4(attr_normal, 1.0)).xyz;
+}
--- /dev/null
+#version 450
+
+layout(binding = 0) uniform sampler2D tex;
+layout(binding = 0) uniform samplerCube dstex;
+
+layout(std140, binding = 0) uniform shading_state {
+ vec4 diffuse;
+ float fog_density;
+} s;
+
+const vec3 sky_color = vec3(0.35, 0.5, 0.65);
+
+layout(location = 0) in vec3 pos;
+layout(location = 1) in vec2 tex_coord;
+layout(location = 2) in vec3 world_normal;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+ vec4 itexel = texture(dstex, normalize(world_normal));
+ vec4 texel = texture(tex, tex_coord);
+
+ vec3 object_color = s.diffuse.xyz * texel.xyz * itexel.xyz;
+ float dist = -pos.z;
+ float fog = clamp(exp(-s.fog_density * dist), 0.0, 1.0);
+
+ color.xyz = mix(sky_color, object_color, fog);
+ color.w = 1.0;
+}
--- /dev/null
+#version 450
+
+layout(std140, binding = 0) uniform matrix_state {
+ mat4 mview;
+ mat4 mmviewproj;
+ mat4 mmod;
+ float t;
+} m;
+
+const float half_height = 0.855;
+
+layout(location = 0) out vec3 pos;
+layout(location = 1) out vec2 tex_coord;
+layout(location = 2) out vec3 world_normal;
+
+/* attributes */
+layout(location = 1) in vec3 attr_pos;
+layout(location = 2) in vec3 attr_normal;
+layout(location = 3) in vec2 attr_tex;
+
+void main()
+{
+ vec3 sph_pos = normalize(vec3(attr_pos.x, attr_pos.y - half_height, attr_pos.z));
+
+ vec3 sph_normal = sph_pos;
+ sph_pos.y += half_height;
+
+ vec3 p = mix(attr_pos, sph_pos, m.t);
+ vec3 n = mix(attr_normal, sph_normal, m.t);
+
+ gl_Position = m.mmviewproj * vec4(p, 1.0);
+
+ pos = (m.mview * vec4(p, 1.0)).xyz;
+ // ldir = (mview * vec4(lpos, 1.0)).xyz;
+
+ // mat3 normal_matrix = mat3(mview);
+ // normal = normal_matrix * n;
+
+ tex_coord = attr_tex;
+ world_normal = (m.mmod * vec4(attr_normal, 1.0)).xyz;
+}
--- /dev/null
+#version 450
+
+layout(binding = 0) uniform samplerCube stex;
+
+layout (location = 0) in vec3 normal;
+layout (location = 0) out vec4 color;
+
+void main()
+{
+ vec4 texel = texture(stex, normalize(normal));
+
+ color.rgb = texel.rgb;
+ color.a = 1.0;
+}
--- /dev/null
+#version 450
+
+layout(binding = 0) uniform matrix_state {
+ mat4 mviewproj;
+} m;
+
+layout(location = 1) in vec3 attr_pos;
+layout(location = 2) in vec3 attr_normal;
+
+layout(location = 0) out vec3 normal;
+
+void main()
+{
+ gl_Position = m.mviewproj * vec4(attr_pos, 1.0);
+ normal = attr_normal;
+}