diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c489c6..2d53b13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,11 @@ add_executable(Informatikprojekt cpuMain.c ${PROJECT_SOURCES_OPENGL}) add_executable(Informatikprojekt_OpenGL openglMain.c ${PROJECT_SOURCES_OPENGL}) add_executable(Informatikprojekt_Vulkan vulkanMain.c ${PROJECT_SOURCES_VULKAN}) +# Copy shader file to output directory +configure_file(./shaders/opengl/ComputeShader.glsl ComputeShader.glsl COPYONLY) +configure_file(./shaders/opengl/VertexShader.glsl VertexShader.glsl COPYONLY) +configure_file(./shaders/opengl/FragmentShader.glsl FragmentShader.glsl COPYONLY) + # Vulkan find_package(Vulkan REQUIRED) target_include_directories(${PROJECT_NAME} PUBLIC ${Vulkan_INCLUDE_DIRS}) diff --git a/openglMain.c b/openglMain.c index 019bd15..f188bda 100644 --- a/openglMain.c +++ b/openglMain.c @@ -29,117 +29,9 @@ int main() initRandomParticles(e1); /************* SHADER *************/ - const GLchar *computeShaderSource = "#version 460\n" - "\n" - "#define FLOAT_MAX 4294967296.0f\n" - "#define FLOAT_FACTOR 0.00000000023283064365386962890625f\n" - "\n" - "struct particle\n" - "{\n" - " float px, py, pz;\n" - " float vx, vy, vz;\n" - " float cx, cy, cz;\n" - " float age;\n" - "};\n" - "\n" - "layout(std430, binding = 0) buffer particles\n" - "{\n" - " particle p[];\n" - "};\n" - "\n" - "layout(location = 0) uniform float dt;\n" - "layout(location = 1) uniform vec3 resetPos;\n" - "layout(location = 2) uniform uint maxParticles;\n" - "\n" - "layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n" - "\n" - "uint hash(uvec3 seed)\n" - "{\n" - " uint hash;\n" - " hash = (seed.x ^ 61u) ^ (seed.y >> 16u);\n" - " hash *= 9u;\n" - " hash = seed.z ^ (seed.x >> 4u);\n" - " hash *= 0x27d4eb2du;\n" - " hash = seed.y ^ (seed.z >> 15u);\n" - " return hash;\n" - "}\n" - "\n" - "uint rand(uint seed)\n" - "{\n" - " seed ^= (seed << 13u);\n" - " seed ^= (seed >> 17u);\n" - " seed ^= (seed << 5u);\n" - " return seed;\n" - "}\n" - "\n" - "int foreSign(uint seed)\n" - "{\n" - " return rand(seed) % 2 == 0 ? 1 : -1;\n" - "}\n" - "\n" - "void main()\n" - "{\n" - " uint gid = gl_GlobalInvocationID.x;\n" - "\n" - " if (gid <= maxParticles)\n" - " {\n" - " particle part = p[gid];\n" - "\n" - " uint hash1 = hash(uvec3(uint(part.px * FLOAT_MAX), uint(part.cy * FLOAT_MAX), uint(part.vz * FLOAT_MAX)));\n" - " uint hash2 = hash(uvec3(uint(part.vx * FLOAT_MAX), uint(part.py * FLOAT_MAX), uint(part.cz * FLOAT_MAX)));\n" - " uint hash3 = hash(uvec3(uint(part.cx * FLOAT_MAX), uint(part.vy * FLOAT_MAX), uint(part.pz * FLOAT_MAX)));\n" - "\n" - " if (part.age < 0 || part.px > 1 || part.py > 1 || part.pz > 1 || part.px < -1 || part.py < -1 || part.pz < -1)\n" - " {\n" - " part.px = resetPos.x;\n" - " part.py = resetPos.y;\n" - " part.pz = resetPos.z;\n" - "\n" - " part.age = rand(hash(uvec3(hash1, hash2, hash3))) % (250 - 60 + 1) + 60;\n" - "\n" - " part.vx = foreSign(hash1) * float(rand(hash2)) * FLOAT_FACTOR;\n" - " part.vy = foreSign(hash3) * float(rand(hash1)) * FLOAT_FACTOR;\n" - " part.vz = foreSign(hash2) * float(rand(hash3)) * FLOAT_FACTOR;\n" - "\n" - " part.cx = float(rand(hash1 ^ hash2)) * FLOAT_FACTOR;\n" - " part.cy = float(rand(hash2 ^ hash3)) * FLOAT_FACTOR;\n" - " part.cz = float(rand(hash3 ^ hash1)) * FLOAT_FACTOR;\n" - " }\n" - " else\n" - " {\n" - " part.px += part.vx * dt;\n" - " part.py += part.vy * dt;\n" - " part.pz += part.vz * dt;\n" - "\n" - " part.age -= 0.01f;\n" - " }\n" - "\n" - " p[gid] = part;\n" - " }\n" - "}"; - - const GLchar *vertexShaderSource = "#version 460\n" - "\n" - "layout(location = 0) in vec3 pos;\n" - "layout(location = 1) in vec3 colIn;\n" - "\n" - "layout(location = 0) out vec3 colV;\n" - "\n" - "void main(void)\n" - "{\n" - " colV = colIn;\n" - " gl_Position = vec4(pos, 1);\n" - "}"; - - const GLchar *fragmentShaderSource = "#version 460\n" - "\n" - "layout(location = 0) in vec3 colV;\n" - "layout(location = 0) out vec4 colOut;\n" - "\n" - "void main(void)\n" - "{\n" - " colOut = vec4(colV, 1);\n" - "}"; + const GLchar *computeShaderSource = readFile("ComputeShader.glsl"); + const GLchar *vertexShaderSource = readFile("VertexShader.glsl"); + const GLchar *fragmentShaderSource = readFile("FragmentShader.glsl"); GLuint computeShader = compileShader(computeShaderSource, GL_COMPUTE_SHADER); GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER); diff --git a/shaders/opengl/FragmentShader.glsl b/shaders/opengl/FragmentShader.glsl new file mode 100644 index 0000000..b007fd9 --- /dev/null +++ b/shaders/opengl/FragmentShader.glsl @@ -0,0 +1,9 @@ +#version 460 + +layout(location = 0) in vec3 colV; +layout(location = 0) out vec4 colOut; + +void main(void) +{ + colOut = vec4(colV, 1); +} diff --git a/utils.c b/utils.c index 56caa05..2cdee3b 100644 --- a/utils.c +++ b/utils.c @@ -1,27 +1,33 @@ #include #include +#include +#include #include "utils.h" #define BUFFER_SIZE 1024 -char *readFile(char *path) +char *readFile(char *filename) { - FILE *file = fopen(path, "r"); - char *str = malloc(BUFFER_SIZE); - int c, i = 0, j = 1; + FILE *file; + char *buffer; + long numbytes; - while ((c = fgetc(file)) != EOF) + if((file = fopen(filename, "r")) == NULL) { - if (i == j * BUFFER_SIZE) - { - str = realloc(str, ++j * BUFFER_SIZE); - } - - str[i++] = (char) c; + printf("ERROR open file %s: %s\n", filename, strerror(errno)); } + fseek(file, 0L, SEEK_END); + numbytes = ftell(file); + fseek(file, 0L, SEEK_SET); + + if((buffer = calloc(numbytes, sizeof(char))) == NULL) + { + printf("ERROR allocating memory: %s\n", strerror(errno)); + } + + fread(buffer, sizeof(char), numbytes, file); fclose(file); - return str; + return buffer; } - diff --git a/utils.h b/utils.h index 1941e85..cff3988 100644 --- a/utils.h +++ b/utils.h @@ -4,4 +4,4 @@ #define UPPER_AGE 250 #define LOWER_AGE 60 -char *readFile(char *path); \ No newline at end of file +char *readFile(char *filename); \ No newline at end of file