Finished shader; split to targets cpu, opengl and vulkan
This commit is contained in:
parent
1b5b6d0f45
commit
8fa5172e3e
@ -2,13 +2,22 @@ cmake_minimum_required(VERSION 3.15)
|
|||||||
project(Informatikprojekt C)
|
project(Informatikprojekt C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(PROJECT_SOURCES particlesystem.h particlesystem.c init.h initOpenGL.h initOpenGL.c glad/src/glad.c)
|
||||||
|
|
||||||
|
add_executable(Informatikprojekt cpuMain.c ${PROJECT_SOURCES})
|
||||||
|
add_executable(Informatikprojekt_OpenGL openglMain.c ${PROJECT_SOURCES})
|
||||||
|
add_executable(Informatikprojekt_Vulkan vulkanMain.c ${PROJECT_SOURCES})
|
||||||
|
|
||||||
|
# Vulkan
|
||||||
|
find_package(Vulkan REQUIRED)
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC ${Vulkan_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_executable(Informatikprojekt main.c particlesystem.h particlesystem.c init.h initOpenGL.h initOpenGL.c glad/src/glad.c)
|
|
||||||
|
|
||||||
# GLFW
|
# GLFW
|
||||||
|
|
||||||
include_directories(./glfw/include)
|
include_directories(./glfw/include)
|
||||||
target_link_libraries(Informatikprojekt ${CMAKE_SOURCE_DIR}/glfw/lib-mingw-w64/libglfw3.a)
|
target_link_libraries(Informatikprojekt ${CMAKE_SOURCE_DIR}/glfw/lib-mingw-w64/libglfw3.a)
|
||||||
|
target_link_libraries(Informatikprojekt_OpenGL ${CMAKE_SOURCE_DIR}/glfw/lib-mingw-w64/libglfw3.a)
|
||||||
|
target_link_libraries(Informatikprojekt_Vulkan Vulkan::Vulkan ${CMAKE_SOURCE_DIR}/glfw/lib-mingw-w64/libglfw3.a)
|
||||||
|
|
||||||
# glad
|
# glad
|
||||||
include_directories(./glad/include)
|
include_directories(./glad/include)
|
||||||
|
93
cpuMain.c
Normal file
93
cpuMain.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "particlesystem.h"
|
||||||
|
#include "initOpenGL.h"
|
||||||
|
|
||||||
|
#define PARTICLE_AMOUNT 1000
|
||||||
|
#define WIDTH 800
|
||||||
|
#define HEIGHT 800
|
||||||
|
|
||||||
|
#define UPPER_AGE 250
|
||||||
|
#define LOWER_AGE 60
|
||||||
|
|
||||||
|
void calcPos(particle *p, float dt);
|
||||||
|
void calcCol(particle *p);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
/************* INIT *************/
|
||||||
|
// Init OpenGL and GLFW
|
||||||
|
initGLFW();
|
||||||
|
setErrorCallbackGL();
|
||||||
|
|
||||||
|
int width = WIDTH, height = HEIGHT;
|
||||||
|
GLFWwindow *window = createGLFWWindow(WIDTH, HEIGHT, "Informatikprojekt - OpenGL CPU");
|
||||||
|
|
||||||
|
setCurrentContextGL(window);
|
||||||
|
setFramebufferSizeCallbackGL(window);
|
||||||
|
|
||||||
|
// glad
|
||||||
|
initGlad();
|
||||||
|
|
||||||
|
/************* PARTICLE SYSTEM *************/
|
||||||
|
vector3f *epos1 = initVector3f(0, 0, 0);
|
||||||
|
emitter *e1 = initEmitter(epos1, PARTICLE_AMOUNT);
|
||||||
|
particle_system *ps = initParticleSystem(1);
|
||||||
|
(ps->emitters)[0] = e1;
|
||||||
|
initRandomParticles(e1);
|
||||||
|
|
||||||
|
/************* RENDER LOOP *************/
|
||||||
|
double time, tFrame, tLast = 0;
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
time = glfwGetTime();
|
||||||
|
tFrame = time - tLast;
|
||||||
|
tLast = time;
|
||||||
|
|
||||||
|
/*** UPDATE ***/
|
||||||
|
updateParticles((float) tFrame, ps, calcPos, calcCol);
|
||||||
|
|
||||||
|
/*** RENDER ***/
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
|
||||||
|
emitter *e;
|
||||||
|
particle *p;
|
||||||
|
vector3f *pos;
|
||||||
|
for (int j = 0; j < ps->eamount; j++)
|
||||||
|
{
|
||||||
|
e = (ps->emitters)[j];
|
||||||
|
for (int i = 0; i < e->pamount; i++)
|
||||||
|
{
|
||||||
|
p = (e->particles)[i];
|
||||||
|
pos = p->position;
|
||||||
|
|
||||||
|
glColor3f(p->color->x, p->color->y, p->color->z);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glVertex3f(pos->x, pos->y, pos->z);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
//END
|
||||||
|
terminateGLFW(window);
|
||||||
|
freeParticleSystem(ps);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calcPos(particle *p, float dt)
|
||||||
|
{
|
||||||
|
p->position->x += p->velocity->x * dt;
|
||||||
|
p->position->y += p->velocity->y * dt;
|
||||||
|
p->position->z += p->velocity->z * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calcCol(particle *p)
|
||||||
|
{
|
||||||
|
p->color->x -= 0.00001f;
|
||||||
|
p->color->y -= 0.00001f;
|
||||||
|
p->color->z -= 0.00001f;
|
||||||
|
}
|
334
main.c
334
main.c
@ -1,334 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "particlesystem.h"
|
|
||||||
#include "initOpenGL.h"
|
|
||||||
|
|
||||||
#define PARTICLE_AMOUNT 10000
|
|
||||||
#define WIDTH 800
|
|
||||||
#define HEIGHT 800
|
|
||||||
|
|
||||||
void printVector(vector3f *v);
|
|
||||||
void printParticle(particle *v);
|
|
||||||
void printEmitter(emitter *e);
|
|
||||||
void initRandomParticles(emitter *e);
|
|
||||||
void error_callback(int error, const char* description);
|
|
||||||
|
|
||||||
void calcPos(particle *p, float dt);
|
|
||||||
void calcCol(particle *p);
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
/************* INIT *************/
|
|
||||||
// Init OpenGL and GLFW
|
|
||||||
initGLFW();
|
|
||||||
setErrorCallbackGL();
|
|
||||||
|
|
||||||
int width = WIDTH, height = HEIGHT;
|
|
||||||
GLFWwindow *window = createGLFWWindow(WIDTH, HEIGHT, "Informatikprojekt - OpenGL");
|
|
||||||
|
|
||||||
setCurrentContextGL(window);
|
|
||||||
setFramebufferSizeCallbackGL(window);
|
|
||||||
|
|
||||||
// glad
|
|
||||||
initGlad();
|
|
||||||
|
|
||||||
/************* PARTICLE SYSTEM *************/
|
|
||||||
vector3f *epos1 = initVector3f(0, 0, 0);
|
|
||||||
emitter *e1 = initEmitter(epos1, PARTICLE_AMOUNT);
|
|
||||||
particle_system *ps = initParticleSystem(1);
|
|
||||||
(ps->emitters)[0] = e1;
|
|
||||||
initRandomParticles(e1);
|
|
||||||
|
|
||||||
/************* SHADER *************/
|
|
||||||
const GLchar *computeShaderSource = "#version 460 core\n"
|
|
||||||
"#extension GL_ARB_compute_shader : enable\n"
|
|
||||||
"#extension GL_ARB_shader_storage_buffer_object : enable\n"
|
|
||||||
"\n"
|
|
||||||
"struct particle\n"
|
|
||||||
"{\n"
|
|
||||||
" vec3 pos;\n"
|
|
||||||
" vec3 vel;\n"
|
|
||||||
" vec3 col;\n"
|
|
||||||
" float age;\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"layout(std430, binding = 0) buffer particles\n"
|
|
||||||
"{\n"
|
|
||||||
" particle p[];\n"
|
|
||||||
"};\n"
|
|
||||||
"\n"
|
|
||||||
"uniform float dt;\n"
|
|
||||||
"uniform vec3 resetPos;\n"
|
|
||||||
"uniform uint seed;\n"
|
|
||||||
"\n"
|
|
||||||
"layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n"
|
|
||||||
"\n"
|
|
||||||
"float rand()\n"
|
|
||||||
"{\n"
|
|
||||||
" uint seedR;\n"
|
|
||||||
" seedR = (seed * 1103515245u + 12345u);\n"
|
|
||||||
" return float(seed) / 4294967296.0;\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"vec3 rand3() {\n"
|
|
||||||
" vec3 result;\n"
|
|
||||||
" uint seedR;\n"
|
|
||||||
" seedR = (seed * 1103515245u + 12345u);\n"
|
|
||||||
" result.x = float(seed);\n"
|
|
||||||
" seedR = (seed * 1103515245u + 12345u);\n"
|
|
||||||
" result.y = float(seed);\n"
|
|
||||||
" seedR = (seed * 1103515245u + 12345u);\n"
|
|
||||||
" result.z = float(seed);\n"
|
|
||||||
" return (result / 2147483648.0) - vec3(1,1,1);\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"void main()\n"
|
|
||||||
"{\n"
|
|
||||||
" uint gid = gl_GlobalInvocationID.x;\n"
|
|
||||||
" particle part = p[gid];\n"
|
|
||||||
"\n"
|
|
||||||
" if (part.age < 0 || part.pos.x > 1 || part.pos.y > 1 || part.pos.z > 1\n"
|
|
||||||
" || part.pos.x < -1 || part.pos.y < -1 || part.pos.z < -1 )\n"
|
|
||||||
" {\n"
|
|
||||||
" part.pos = resetPos;\n"
|
|
||||||
" //part.vel = rand3();\n"
|
|
||||||
" //part.col = vec3(rand(), rand(), rand());\n"
|
|
||||||
" //part.age = rand() * 0x7fff * 0.01f;\n"
|
|
||||||
" \n"
|
|
||||||
" }\n"
|
|
||||||
" else\n"
|
|
||||||
" {\n"
|
|
||||||
" part.pos += part.vel * dt;\n"
|
|
||||||
" part.age -= 0.01f;\n"
|
|
||||||
" }\n"
|
|
||||||
"\n"
|
|
||||||
" p[gid] = part;\n"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
const GLchar *vertexShaderSource = "#version 460\n"
|
|
||||||
"\n"
|
|
||||||
"layout(location = 0) in vec3 pos;\n"
|
|
||||||
"layout(location = 1) in vec3 colIn;\n"
|
|
||||||
"\n"
|
|
||||||
"out vec3 colV;\n"
|
|
||||||
"\n"
|
|
||||||
"void main(void)\n"
|
|
||||||
"{\n"
|
|
||||||
" colV = colIn;\n"
|
|
||||||
" gl_Position = vec4(pos, 1);\n"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
const GLchar *fragmentShaderSource = "#version 460 core\n"
|
|
||||||
"\n"
|
|
||||||
"in vec3 colV;\n"
|
|
||||||
"out vec4 colOut;\n"
|
|
||||||
"\n"
|
|
||||||
"void main(void)\n"
|
|
||||||
"{\n"
|
|
||||||
" colOut = vec4(colV, 1);\n"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
GLuint computeShader = compileShader(computeShaderSource, GL_COMPUTE_SHADER);
|
|
||||||
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
|
||||||
GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
|
||||||
|
|
||||||
GLuint computeShaders[] = { computeShader };
|
|
||||||
GLuint computeShaderProgram = linkShaders(computeShaders, 1);
|
|
||||||
glUseProgram(computeShaderProgram);
|
|
||||||
GLint dtUniformLocation = glGetUniformLocation(computeShaderProgram, "dt");
|
|
||||||
GLint resetPosUniformLocation = glGetUniformLocation(computeShaderProgram, "resetPos");
|
|
||||||
GLint seedUniformLocation = glGetUniformLocation(computeShaderProgram, "seed");
|
|
||||||
glUniform3f(resetPosUniformLocation, e1->position->x, e1->position->y, e1->position->z);
|
|
||||||
|
|
||||||
GLuint renderShaders[] = { vertexShader, fragmentShader };
|
|
||||||
GLuint renderShaderProgram = linkShaders(renderShaders, 2);
|
|
||||||
|
|
||||||
float *particles = serializeParticlesystem(ps);
|
|
||||||
GLsizeiptr sizeOfParticle = 3 * sizeof(vector3f) + sizeof(float);
|
|
||||||
|
|
||||||
GLuint particleBuffer;
|
|
||||||
glGenBuffers(1, &particleBuffer);
|
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleBuffer);
|
|
||||||
glBufferData(GL_SHADER_STORAGE_BUFFER, PARTICLE_AMOUNT * sizeOfParticle, particles, GL_STATIC_DRAW);
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
|
|
||||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
|
||||||
|
|
||||||
GLuint vertexArray;
|
|
||||||
glGenVertexArrays(1, &vertexArray);
|
|
||||||
glBindVertexArray(vertexArray);
|
|
||||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, particleBuffer);
|
|
||||||
// position
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)0);
|
|
||||||
// color
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)24);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
/************* RENDER LOOP *************/
|
|
||||||
double time, tFrame, tLast = 0;
|
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
|
||||||
time = glfwGetTime();
|
|
||||||
tFrame = time - tLast;
|
|
||||||
tLast = time;
|
|
||||||
|
|
||||||
/*** UPDATE ***/
|
|
||||||
glUseProgram(computeShaderProgram);
|
|
||||||
glUniform1f(dtUniformLocation, tFrame);
|
|
||||||
glUniform1ui(seedUniformLocation, rand());
|
|
||||||
glDispatchCompute((PARTICLE_AMOUNT / 256) + 1, 1, 1);
|
|
||||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
|
|
||||||
|
|
||||||
/*** RENDER ***/
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
|
||||||
glBindVertexArray(vertexArray);
|
|
||||||
glUseProgram(renderShaderProgram);
|
|
||||||
glDrawArrays(GL_POINTS, 0, PARTICLE_AMOUNT);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwPollEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
//END
|
|
||||||
deleteShaders(renderShaders, 2);
|
|
||||||
deleteShaders(computeShaders, 1);
|
|
||||||
|
|
||||||
terminateGLFW(window);
|
|
||||||
freeParticleSystem(ps);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calcPos(particle *p, float dt)
|
|
||||||
{
|
|
||||||
p->position->x += p->velocity->x * dt;
|
|
||||||
p->position->y += p->velocity->y * dt;
|
|
||||||
p->position->z += p->velocity->z * dt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void calcCol(particle *p)
|
|
||||||
{
|
|
||||||
// p->color->x -= 0.01f;
|
|
||||||
// p->color->y -= 0.01f;
|
|
||||||
// p->color->z -= 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************************************************************************************/
|
|
||||||
void initRandomParticles(emitter *e)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < e->pamount; i++)
|
|
||||||
{
|
|
||||||
vector3f *pos = initVector3f(e->position->x, e->position->y, e->position->z);
|
|
||||||
vector3f *dir = initVector3f(((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX,
|
|
||||||
((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX,
|
|
||||||
((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX);
|
|
||||||
vector3f *color = initVector3f(((float) (rand() % 255)) / 255,
|
|
||||||
((float) (rand() % 255)) / 255,
|
|
||||||
((float) (rand() % 255)) / 255);
|
|
||||||
(e->particles)[i] = initParticle(pos, dir, color, rand() / 100.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printParticle(particle *v)
|
|
||||||
{
|
|
||||||
printVector(v->position);
|
|
||||||
printf("; ");
|
|
||||||
printVector(v->velocity);
|
|
||||||
printf("; ");
|
|
||||||
printVector(v->color);
|
|
||||||
printf("; %f\n", v->age);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printVector(vector3f *v)
|
|
||||||
{
|
|
||||||
printf("(%f, %f, %f)", v->x, v->y, v->z);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// VERY OLD
|
|
||||||
// glUseProgram(shaderProgram);
|
|
||||||
// glBindVertexArray(vao);
|
|
||||||
// glDrawArrays(GL_POINTS, 0, particleAmount);
|
|
||||||
|
|
||||||
// updateParticles((float) tFrame, ps, calcPos, calcCol);
|
|
||||||
//
|
|
||||||
// emitter *e;
|
|
||||||
// particle *p;
|
|
||||||
// vector3f *pos;
|
|
||||||
// for (int j = 0; j < ps->eamount; j++)
|
|
||||||
// {
|
|
||||||
// e = (ps->emitters)[j];
|
|
||||||
// for (int i = 0; i < e->pamount; i++)
|
|
||||||
// {
|
|
||||||
// p = (e->particles)[i];
|
|
||||||
// pos = p->position;
|
|
||||||
//
|
|
||||||
// glColor3f(p->color->x, p->color->y, p->color->z);
|
|
||||||
// glBegin(GL_POINTS);
|
|
||||||
// glVertex3f(pos->x, pos->y, pos->z);
|
|
||||||
// glEnd();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// FEEDBACK TRANSFORM BEFORE
|
|
||||||
// /*************** NEW ***************/
|
|
||||||
// float *vertexData = serializeParticlesystem(ps);
|
|
||||||
// unsigned int currentVertexBuffer = 0, currentTransformFeedbackBuffer = 1;
|
|
||||||
// int buffersSize = 2;
|
|
||||||
// unsigned int particleBuffers[buffersSize], transformFeedbackBuffers[buffersSize];
|
|
||||||
//
|
|
||||||
// glGenTransformFeedbacks(buffersSize, transformFeedbackBuffers);
|
|
||||||
// glGenBuffers(buffersSize, particleBuffers);
|
|
||||||
//
|
|
||||||
// for (int i = 0; i < buffersSize; i++)
|
|
||||||
// {
|
|
||||||
// glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackBuffers[i]);
|
|
||||||
// glBindBuffer(GL_ARRAY_BUFFER, particleBuffers[i]);
|
|
||||||
// glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_DYNAMIC_DRAW);
|
|
||||||
// glBindBufferBase(GL_TRANSFORM_FEEDBACK, 0, particleBuffers[i]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // position attribute
|
|
||||||
// glEnableVertexAttribArray(0);
|
|
||||||
// glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)0);
|
|
||||||
// // velocity attribute
|
|
||||||
// glEnableVertexAttribArray(1);
|
|
||||||
// glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)(3 * sizeof(float)));
|
|
||||||
// // color attribute
|
|
||||||
// glEnableVertexAttribArray(2);
|
|
||||||
// glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)(6 * sizeof(float)));
|
|
||||||
// // age attribute
|
|
||||||
// glEnableVertexAttribArray(3);
|
|
||||||
// glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)(9 * sizeof(float)));
|
|
||||||
|
|
||||||
/// TRANSFORM FEEDBACK RENDER LOOP
|
|
||||||
///*** UPDATE PARTICLES ***/
|
|
||||||
//glEnable(GL_RASTERIZER_DISCARD);
|
|
||||||
//glBindBuffer(GL_ARRAY_BUFFER, particleBuffers[currentVertexBuffer]);
|
|
||||||
//glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackBuffers[currentTransformFeedbackBuffer]);
|
|
||||||
//glBeginTransformFeedback(GL_POINTS);
|
|
||||||
//if (isFirst)
|
|
||||||
//{
|
|
||||||
//glDrawArrays(GL_POINTS, 0, particleAmount);
|
|
||||||
//isFirst = !isFirst;
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
//glDrawTransformFeedback(GL_POINTS, transformFeedbackBuffers[currentVertexBuffer]);
|
|
||||||
//}
|
|
||||||
//glEndTransformFeedback();
|
|
||||||
//
|
|
||||||
///*** RENDER PARTICLES ***/
|
|
||||||
//glDisable(GL_RASTERIZER_DISCARD);
|
|
||||||
//glBindBuffer(GL_ARRAY_BUFFER, particleBuffers[currentTransformFeedbackBuffer]);
|
|
||||||
//glDrawTransformFeedback(GL_POINTS, transformFeedbackBuffers[currentTransformFeedbackBuffer]);
|
|
||||||
//
|
|
||||||
///***************************************************/
|
|
||||||
//currentVertexBuffer = currentTransformFeedbackBuffer;
|
|
||||||
//currentTransformFeedbackBuffer = !currentTransformFeedbackBuffer;
|
|
216
openglMain.c
Normal file
216
openglMain.c
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
#include "particlesystem.h"
|
||||||
|
#include "initOpenGL.h"
|
||||||
|
|
||||||
|
#define PARTICLE_AMOUNT 1000000
|
||||||
|
#define WIDTH 800
|
||||||
|
#define HEIGHT 800
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
/************* INIT *************/
|
||||||
|
// Init OpenGL and GLFW
|
||||||
|
initGLFW();
|
||||||
|
setErrorCallbackGL();
|
||||||
|
|
||||||
|
int width = WIDTH, height = HEIGHT;
|
||||||
|
GLFWwindow *window = createGLFWWindow(WIDTH, HEIGHT, "Informatikprojekt - OpenGL");
|
||||||
|
|
||||||
|
setCurrentContextGL(window);
|
||||||
|
setFramebufferSizeCallbackGL(window);
|
||||||
|
|
||||||
|
// glad
|
||||||
|
initGlad();
|
||||||
|
|
||||||
|
/************* PARTICLE SYSTEM *************/
|
||||||
|
vector3f *epos1 = initVector3f(0, 0, 0);
|
||||||
|
emitter *e1 = initEmitter(epos1, PARTICLE_AMOUNT);
|
||||||
|
particle_system *ps = initParticleSystem(1);
|
||||||
|
(ps->emitters)[0] = e1;
|
||||||
|
initRandomParticles(e1);
|
||||||
|
|
||||||
|
/************* SHADER *************/
|
||||||
|
const GLchar *computeShaderSource = "#version 460\n"
|
||||||
|
"\n"
|
||||||
|
"#define FLOAT_MAX 4294967296.0f\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"
|
||||||
|
" // Xorshift algorithm from George Marsaglia's paper\n"
|
||||||
|
" seed ^= (seed << 13u);\n"
|
||||||
|
" seed ^= (seed >> 17u);\n"
|
||||||
|
" seed ^= (seed << 5u);\n"
|
||||||
|
" return seed;\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 = (rand(hash1) % 2 == 0 ? 1 : -1) * float(rand(hash2)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
" part.vy = (rand(hash3) % 2 == 0 ? 1 : -1) * float(rand(hash1)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
" part.vz = (rand(hash2) % 2 == 0 ? 1 : -1) * float(rand(hash3)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
"\n"
|
||||||
|
" part.cx = float(rand(hash3)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
" part.cy = float(rand(hash2)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
" part.cz = float(rand(hash1)) * (1.0f / FLOAT_MAX);\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.cx = float(rand(hash1)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
" part.cy = float(rand(hash1)) * (1.0f / FLOAT_MAX);\n"
|
||||||
|
" part.cz = float(rand(hash1)) * (1.0f / FLOAT_MAX);\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"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
GLuint computeShader = compileShader(computeShaderSource, GL_COMPUTE_SHADER);
|
||||||
|
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
||||||
|
GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
GLuint computeShaders[] = { computeShader };
|
||||||
|
GLuint computeShaderProgram = linkShaders(computeShaders, 1);
|
||||||
|
glUseProgram(computeShaderProgram);
|
||||||
|
GLint dtUniformLocation = glGetUniformLocation(computeShaderProgram, "dt");
|
||||||
|
GLint resetPosUniformLocation = glGetUniformLocation(computeShaderProgram, "resetPos");
|
||||||
|
glUniform3f(resetPosUniformLocation, e1->position->x, e1->position->y, e1->position->z);
|
||||||
|
GLint maxParticlesUniformLocation = glGetUniformLocation(computeShaderProgram, "maxParticles");
|
||||||
|
glUniform1ui(maxParticlesUniformLocation, PARTICLE_AMOUNT);
|
||||||
|
|
||||||
|
GLuint renderShaders[] = { vertexShader, fragmentShader };
|
||||||
|
GLuint renderShaderProgram = linkShaders(renderShaders, 2);
|
||||||
|
|
||||||
|
float *particles = serializeParticlesystem(ps);
|
||||||
|
GLsizeiptr sizeOfParticle = 3 * sizeof(vector3f) + sizeof(float);
|
||||||
|
|
||||||
|
GLuint particleBuffer;
|
||||||
|
glGenBuffers(1, &particleBuffer);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleBuffer);
|
||||||
|
glBufferData(GL_SHADER_STORAGE_BUFFER, PARTICLE_AMOUNT * sizeOfParticle, particles, GL_DYNAMIC_DRAW);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
|
||||||
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||||
|
|
||||||
|
GLuint vertexArray;
|
||||||
|
glGenVertexArrays(1, &vertexArray);
|
||||||
|
glBindVertexArray(vertexArray);
|
||||||
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, particleBuffer);
|
||||||
|
// position
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)0);
|
||||||
|
// color
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeOfParticle, (GLvoid *)24); // 32
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
/************* RENDER LOOP *************/
|
||||||
|
double time, tFrame, tLast = 0;
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
time = glfwGetTime();
|
||||||
|
tFrame = time - tLast;
|
||||||
|
tLast = time;
|
||||||
|
|
||||||
|
/*** UPDATE ***/
|
||||||
|
glUseProgram(computeShaderProgram);
|
||||||
|
glUniform1f(dtUniformLocation, tFrame);
|
||||||
|
glDispatchCompute(PARTICLE_AMOUNT / 256, 1, 1);
|
||||||
|
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
|
||||||
|
|
||||||
|
/*** RENDER ***/
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
glBindVertexArray(vertexArray);
|
||||||
|
glUseProgram(renderShaderProgram);
|
||||||
|
glDrawArrays(GL_POINTS, 0, PARTICLE_AMOUNT);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
//END
|
||||||
|
deleteShaders(renderShaders, 2);
|
||||||
|
deleteShaders(computeShaders, 1);
|
||||||
|
|
||||||
|
terminateGLFW(window);
|
||||||
|
freeParticleSystem(ps);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "particlesystem.h"
|
#include "particlesystem.h"
|
||||||
|
|
||||||
@ -158,7 +159,7 @@ float *serializeParticlesystem(particle_system *ps)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned long particleBytesAmount = sizeof(vector3f) * 3 + sizeof(float);
|
unsigned long particleBytesAmount = sizeof(vector3f) * 3 + sizeof(float);
|
||||||
float *vert = malloc(particleBytesAmount * particleAmount);
|
float *vert = malloc(particleAmount * particleBytesAmount);
|
||||||
|
|
||||||
emitter *e;
|
emitter *e;
|
||||||
particle *p;
|
particle *p;
|
||||||
@ -168,6 +169,7 @@ float *serializeParticlesystem(particle_system *ps)
|
|||||||
for (int x = 0; x < e->pamount; x++)
|
for (int x = 0; x < e->pamount; x++)
|
||||||
{
|
{
|
||||||
p = e->particles[x];
|
p = e->particles[x];
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
vert[j++] = p->position->x;
|
vert[j++] = p->position->x;
|
||||||
vert[j++] = p->position->y;
|
vert[j++] = p->position->y;
|
||||||
@ -190,3 +192,21 @@ float *serializeParticlesystem(particle_system *ps)
|
|||||||
|
|
||||||
return vert;
|
return vert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inits random particles
|
||||||
|
*/
|
||||||
|
void initRandomParticles(emitter *e)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < e->pamount; i++)
|
||||||
|
{
|
||||||
|
vector3f *pos = initVector3f(e->position->x, e->position->y, e->position->z);
|
||||||
|
vector3f *dir = initVector3f(((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX,
|
||||||
|
((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX,
|
||||||
|
((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX);
|
||||||
|
vector3f *color = initVector3f(((float) (rand() % 255)) / 255,
|
||||||
|
((float) (rand() % 255)) / 255,
|
||||||
|
((float) (rand() % 255)) / 255);
|
||||||
|
(e->particles)[i] = initParticle(pos, dir, color, (float) (rand() % (UPPER_AGE - LOWER_AGE + 1) + LOWER_AGE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
#define UPPER_AGE 250
|
||||||
|
#define LOWER_AGE 60
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A vector with three floats
|
* A vector with three floats
|
||||||
*/
|
*/
|
||||||
@ -107,4 +110,9 @@ void freeParticleSystem(particle_system *ps);
|
|||||||
/*
|
/*
|
||||||
* Creates float array out of a particle system
|
* Creates float array out of a particle system
|
||||||
*/
|
*/
|
||||||
float *serializeParticlesystem(particle_system *ps);
|
float *serializeParticlesystem(particle_system *ps);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Inits random particle
|
||||||
|
*/
|
||||||
|
void initRandomParticles(emitter *e);
|
@ -1,64 +0,0 @@
|
|||||||
#version 460 core
|
|
||||||
#extension GL_ARB_compute_shader : enable
|
|
||||||
#extension GL_ARB_shader_storage_buffer_object : enable
|
|
||||||
|
|
||||||
struct particle
|
|
||||||
{
|
|
||||||
vec3 pos;
|
|
||||||
vec3 vel;
|
|
||||||
vec3 col;
|
|
||||||
float age;
|
|
||||||
};
|
|
||||||
|
|
||||||
layout(std430, binding = 0) buffer particles
|
|
||||||
{
|
|
||||||
particle p[];
|
|
||||||
};
|
|
||||||
|
|
||||||
uniform float dt;
|
|
||||||
uniform vec3 resetPos;
|
|
||||||
uniform uint seed;
|
|
||||||
|
|
||||||
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
|
|
||||||
|
|
||||||
float rand()
|
|
||||||
{
|
|
||||||
uint seedR;
|
|
||||||
seedR = (seed * 1103515245u + 12345u);
|
|
||||||
return float(seed) / 4294967296.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 rand3() {
|
|
||||||
vec3 result;
|
|
||||||
uint seedR;
|
|
||||||
seedR = (seed * 1103515245u + 12345u);
|
|
||||||
result.x = float(seed);
|
|
||||||
seedR = (seed * 1103515245u + 12345u);
|
|
||||||
result.y = float(seed);
|
|
||||||
seedR = (seed * 1103515245u + 12345u);
|
|
||||||
result.z = float(seed);
|
|
||||||
return (result / 2147483648.0) - vec3(1,1,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
uint gid = gl_GlobalInvocationID.x;
|
|
||||||
particle part = p[gid];
|
|
||||||
|
|
||||||
if (part.age < 0 || part.pos.x > 1 || part.pos.y > 1 || part.pos.z > 1
|
|
||||||
|| part.pos.x < -1 || part.pos.y < -1 || part.pos.z < -1 )
|
|
||||||
{
|
|
||||||
part.pos = resetPos;
|
|
||||||
part.vel = rand3();
|
|
||||||
part.col = vec3(rand(), rand(), rand());
|
|
||||||
part.age = rand() * 0x7fff * 0.01f;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
part.pos += part.vel * dt;
|
|
||||||
part.age -= 0.01f;
|
|
||||||
}
|
|
||||||
|
|
||||||
p[gid] = part;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#version 460 core
|
|
||||||
|
|
||||||
in vec3 colV;
|
|
||||||
out vec4 colOut;
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
colOut = vec4(colV, 1);
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
#version 460 core
|
|
||||||
|
|
||||||
layout(points) in;
|
|
||||||
layout(points, max_vertices = 256) out;
|
|
||||||
|
|
||||||
in vec3 colV;
|
|
||||||
out vec3 colG;
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
colG = colV;
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
#version 460 core
|
|
||||||
|
|
||||||
layout (points) in;
|
|
||||||
layout (points) out;
|
|
||||||
layout (max_vertices = 40) out;
|
|
||||||
|
|
||||||
in vec3 pos0[];
|
|
||||||
in vec3 vel0[];
|
|
||||||
in vec3 col0[];
|
|
||||||
in float age0[];
|
|
||||||
|
|
||||||
out vec3 posOut;
|
|
||||||
out vec3 velOut;
|
|
||||||
out vec3 colOut;
|
|
||||||
out float ageOut;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
if (age0[0] < 0)
|
|
||||||
{
|
|
||||||
posOut = vec3(0, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
posOut = pos0[0];
|
|
||||||
velOut = vel0[0];
|
|
||||||
colOut = col0[0];
|
|
||||||
ageOut = age0[0] - 0.01f;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
#version 460 core
|
|
||||||
|
|
||||||
layout (location = 0) in vec3 pos; // the position variable has attribute position 0
|
|
||||||
layout (location = 1) in vec3 vel; // the velocity variable has attribute position 1
|
|
||||||
layout (location = 2) in vec3 col; // the color variable has attribute position 2
|
|
||||||
layout (location = 3) in float age; // the age variable has attribute position 3
|
|
||||||
|
|
||||||
out vec3 pos0;
|
|
||||||
out vec3 vel0;
|
|
||||||
out vec3 col0;
|
|
||||||
out float age0;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
pos0 = pos;
|
|
||||||
vel0 = vel;
|
|
||||||
col0 = col;
|
|
||||||
age0 = age;
|
|
||||||
}
|
|
87
shaders/opengl/ComputeShader.glsl
Normal file
87
shaders/opengl/ComputeShader.glsl
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
#define FLOAT_MAX 4294967296.0f
|
||||||
|
|
||||||
|
struct particle
|
||||||
|
{
|
||||||
|
float px, py, pz;
|
||||||
|
float vx, vy, vz;
|
||||||
|
float cx, cy, cz;
|
||||||
|
float age;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std430, binding = 0) buffer particles
|
||||||
|
{
|
||||||
|
particle p[];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 0) uniform float dt;
|
||||||
|
layout(location = 1) uniform vec3 resetPos;
|
||||||
|
layout(location = 2) uniform uint maxParticles;
|
||||||
|
|
||||||
|
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
|
uint hash(uvec3 seed)
|
||||||
|
{
|
||||||
|
uint hash;
|
||||||
|
hash = (seed.x ^ 61u) ^ (seed.y >> 16u);
|
||||||
|
hash *= 9u;
|
||||||
|
hash = seed.z ^ (seed.x >> 4u);
|
||||||
|
hash *= 0x27d4eb2du;
|
||||||
|
hash = seed.y ^ (seed.z >> 15u);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint rand(uint seed)
|
||||||
|
{
|
||||||
|
// Xorshift algorithm from George Marsaglia's paper
|
||||||
|
seed ^= (seed << 13u);
|
||||||
|
seed ^= (seed >> 17u);
|
||||||
|
seed ^= (seed << 5u);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
uint gid = gl_GlobalInvocationID.x;
|
||||||
|
|
||||||
|
if (gid <= maxParticles)
|
||||||
|
{
|
||||||
|
particle part = p[gid];
|
||||||
|
|
||||||
|
uint hash1 = hash(uvec3(uint(part.px * FLOAT_MAX), uint(part.cy * FLOAT_MAX), uint(part.vz * FLOAT_MAX)));
|
||||||
|
uint hash2 = hash(uvec3(uint(part.vx * FLOAT_MAX), uint(part.py * FLOAT_MAX), uint(part.cz * FLOAT_MAX)));
|
||||||
|
uint hash3 = hash(uvec3(uint(part.cx * FLOAT_MAX), uint(part.vy * FLOAT_MAX), uint(part.pz * FLOAT_MAX)));
|
||||||
|
|
||||||
|
if (part.age < 0 || part.px > 1 || part.py > 1 || part.pz > 1 || part.px < -1 || part.py < -1 || part.pz < -1)
|
||||||
|
{
|
||||||
|
part.px = resetPos.x;
|
||||||
|
part.py = resetPos.y;
|
||||||
|
part.pz = resetPos.z;
|
||||||
|
|
||||||
|
part.age = rand(hash(uvec3(hash1, hash2, hash3))) % (250 - 60 + 1) + 60;
|
||||||
|
|
||||||
|
part.vx = (rand(hash1) % 2 == 0 ? 1 : -1) * float(rand(hash2)) * (1.0f / FLOAT_MAX);
|
||||||
|
part.vy = (rand(hash3) % 2 == 0 ? -1 : 1) * float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
part.vz = (rand(hash2) % 2 == 0 ? 1 : -1) * float(rand(hash3)) * (1.0f / FLOAT_MAX);
|
||||||
|
|
||||||
|
part.cx = float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
part.cy = float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
part.cz = float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
part.px += part.vx * dt;
|
||||||
|
part.py += part.vy * dt;
|
||||||
|
part.pz += part.vz * dt;
|
||||||
|
|
||||||
|
part.cx = float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
part.cy = float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
part.cz = float(rand(hash1)) * (1.0f / FLOAT_MAX);
|
||||||
|
|
||||||
|
part.age -= 0.01f;
|
||||||
|
}
|
||||||
|
|
||||||
|
p[gid] = part;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
#version 460 core
|
#version 460
|
||||||
|
|
||||||
layout(location = 0) in vec3 pos;
|
layout(location = 0) in vec3 pos;
|
||||||
layout(location = 1) in vec3 colIn;
|
layout(location = 1) in vec3 colIn;
|
||||||
|
|
||||||
out vec3 colV;
|
layout(location = 0) out vec3 colV;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
368
vulkanMain.c
Normal file
368
vulkanMain.c
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
#include <malloc.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "vulkan/vulkan.h"
|
||||||
|
|
||||||
|
#define GLFW_INCLUDE_VULKAN
|
||||||
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
#define APP_NAME "Vulkan Tutorial"
|
||||||
|
#define APP_VERSION VK_MAKE_VERSION(0, 0, 0)
|
||||||
|
#define ENGINE_NAME "Memobio Game Engine"
|
||||||
|
#define ENGINE_VERSION VK_MAKE_VERSION(0, 0, 0)
|
||||||
|
|
||||||
|
#define SUCCESS 0
|
||||||
|
#define FAILURE -1
|
||||||
|
#define ASSERT_SUCCESS(res)\
|
||||||
|
if (res != SUCCESS) { printf("Error-Code: %d", res); return FAILURE; }
|
||||||
|
#define ASSERT_GLFW_SUCCESS(res)\
|
||||||
|
if (res != GLFW_TRUE) { printf("Error-Code: %d", res); return FAILURE; }
|
||||||
|
#define ASSERT_VK_SUCCESS(res)\
|
||||||
|
if (res != VK_SUCCESS) { printf("Error-Code: %d", res); return FAILURE; }
|
||||||
|
#define BOOL_LITERAL(val)\
|
||||||
|
val ? "True" : "False"
|
||||||
|
#define HUMAN_READABLE(val)\
|
||||||
|
val * 9.313226e-10
|
||||||
|
|
||||||
|
#define WIDTH 500
|
||||||
|
#define HEIGHT 500
|
||||||
|
|
||||||
|
int initVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, GLFWwindow *window,
|
||||||
|
VkSwapchainKHR *swapChain, VkImageView *imageViews, uint32_t *amountImages);
|
||||||
|
void initAppInfo(VkApplicationInfo *appInfo);
|
||||||
|
void initCreateInfo(VkApplicationInfo *appInfo, VkInstanceCreateInfo *instanceInfo);
|
||||||
|
void initQueueInfo(VkDeviceQueueCreateInfo *queueInfo);
|
||||||
|
void initDeviceInfo(VkDeviceQueueCreateInfo *queueInfo, VkDeviceCreateInfo *deviceInfo, VkPhysicalDeviceFeatures *features);
|
||||||
|
void initImageViewInfo(VkImageViewCreateInfo *imageViewInfo, VkImage *swapChainImages, int index);
|
||||||
|
void printStats(VkPhysicalDevice *physicalDevice, VkSurfaceKHR *surface);
|
||||||
|
|
||||||
|
void initSwapChainInfo(VkSwapchainCreateInfoKHR *swapChainCreateInfo, VkSurfaceKHR *surface);
|
||||||
|
|
||||||
|
void shutdownVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, VkSwapchainKHR *swapChain,
|
||||||
|
VkImageView *imageViews, uint32_t amountImages);
|
||||||
|
|
||||||
|
void shutdownGLFW(GLFWwindow *window);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
VkInstance vkInstance;
|
||||||
|
VkDevice device;
|
||||||
|
VkSurfaceKHR surface;
|
||||||
|
VkSwapchainKHR swapChain;
|
||||||
|
VkImageView *imageViews = NULL;
|
||||||
|
uint32_t amountImages;
|
||||||
|
|
||||||
|
// GLFW
|
||||||
|
ASSERT_GLFW_SUCCESS(glfwInit())
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||||
|
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan Particlesystem", NULL, NULL);
|
||||||
|
|
||||||
|
// Init Vulkan
|
||||||
|
ASSERT_SUCCESS(initVulkan(&vkInstance, &device, &surface, window, &swapChain, imageViews, &amountImages))
|
||||||
|
|
||||||
|
// Render Loop
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop Vulkan
|
||||||
|
shutdownVulkan(&vkInstance, &device, &surface, &swapChain, imageViews, amountImages);
|
||||||
|
|
||||||
|
// Stop GLFW
|
||||||
|
shutdownGLFW(window);
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int initVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, GLFWwindow *window,
|
||||||
|
VkSwapchainKHR *swapChain, VkImageView *imageViews, uint32_t *amountImages)
|
||||||
|
{
|
||||||
|
// VkApplicationInfo
|
||||||
|
VkApplicationInfo appInfo;
|
||||||
|
initAppInfo(&appInfo);
|
||||||
|
|
||||||
|
// VkInstanceCreateInfo
|
||||||
|
uint32_t amountOfLayers;
|
||||||
|
vkEnumerateInstanceLayerProperties(&amountOfLayers, NULL);
|
||||||
|
VkLayerProperties layers[amountOfLayers];
|
||||||
|
vkEnumerateInstanceLayerProperties(&amountOfLayers, layers);
|
||||||
|
|
||||||
|
VkInstanceCreateInfo instanceInfo;
|
||||||
|
initCreateInfo(&appInfo, &instanceInfo);
|
||||||
|
|
||||||
|
// Vulkan Instance
|
||||||
|
ASSERT_VK_SUCCESS(vkCreateInstance(&instanceInfo, NULL, vkInstance))
|
||||||
|
|
||||||
|
// Get physical device
|
||||||
|
uint32_t amountOfPhysicalDevices = 0;
|
||||||
|
ASSERT_VK_SUCCESS(vkEnumeratePhysicalDevices(*vkInstance, &amountOfPhysicalDevices, NULL)) // Let fill amount first automatically
|
||||||
|
VkPhysicalDevice physicalDevices[amountOfPhysicalDevices]; // create array for physical devices
|
||||||
|
ASSERT_VK_SUCCESS(vkEnumeratePhysicalDevices(*vkInstance, &amountOfPhysicalDevices, physicalDevices)) // Call again with array
|
||||||
|
|
||||||
|
// Create Window Surface
|
||||||
|
ASSERT_VK_SUCCESS(glfwCreateWindowSurface(*vkInstance, window, NULL, surface))
|
||||||
|
|
||||||
|
printStats(&physicalDevices[0], surface);
|
||||||
|
|
||||||
|
// Queue info
|
||||||
|
VkDeviceQueueCreateInfo queueInfo;
|
||||||
|
initQueueInfo(&queueInfo);
|
||||||
|
|
||||||
|
// Device info
|
||||||
|
VkPhysicalDeviceFeatures usedFeatures = {};
|
||||||
|
VkDeviceCreateInfo deviceInfo;
|
||||||
|
initDeviceInfo(&queueInfo, &deviceInfo, &usedFeatures);
|
||||||
|
|
||||||
|
// Logical device
|
||||||
|
ASSERT_VK_SUCCESS(vkCreateDevice(physicalDevices[0], &deviceInfo, NULL, device))
|
||||||
|
|
||||||
|
// Queue
|
||||||
|
VkQueue queue;
|
||||||
|
vkGetDeviceQueue(*device, 0, 0, &queue);
|
||||||
|
|
||||||
|
// Swap chain support
|
||||||
|
VkBool32 swapChainSupport;
|
||||||
|
ASSERT_VK_SUCCESS(vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevices[0], 0, *surface, &swapChainSupport))
|
||||||
|
if (!swapChainSupport)
|
||||||
|
{
|
||||||
|
printf("Swap chain not supported!");
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap chain info
|
||||||
|
VkSwapchainCreateInfoKHR swapChainCreateInfo;
|
||||||
|
initSwapChainInfo(&swapChainCreateInfo, surface);
|
||||||
|
|
||||||
|
// Swap chain
|
||||||
|
ASSERT_VK_SUCCESS(vkCreateSwapchainKHR(*device, &swapChainCreateInfo, NULL, swapChain))
|
||||||
|
|
||||||
|
// Swap chain images
|
||||||
|
vkGetSwapchainImagesKHR(*device, *swapChain, amountImages, NULL);
|
||||||
|
VkImage swapChainImages[*amountImages];
|
||||||
|
ASSERT_VK_SUCCESS(vkGetSwapchainImagesKHR(*device, *swapChain, amountImages, swapChainImages))
|
||||||
|
|
||||||
|
// Image view
|
||||||
|
imageViews = malloc(*amountImages * sizeof(VkImageView));
|
||||||
|
VkImageViewCreateInfo imageViewInfo;
|
||||||
|
for (int i = 0; i < *amountImages; i++)
|
||||||
|
{
|
||||||
|
initImageViewInfo(&imageViewInfo, swapChainImages, i);
|
||||||
|
ASSERT_VK_SUCCESS(vkCreateImageView(*device, &imageViewInfo, NULL, &imageViews[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initAppInfo(VkApplicationInfo *appInfo)
|
||||||
|
{
|
||||||
|
appInfo->sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
appInfo->pNext = NULL;
|
||||||
|
appInfo->pApplicationName = APP_NAME;
|
||||||
|
appInfo->applicationVersion = APP_VERSION;
|
||||||
|
appInfo->pEngineName = ENGINE_NAME;
|
||||||
|
appInfo->engineVersion = ENGINE_VERSION;
|
||||||
|
appInfo->apiVersion = VK_API_VERSION_1_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initCreateInfo(VkApplicationInfo *appInfo, VkInstanceCreateInfo *instanceInfo)
|
||||||
|
{
|
||||||
|
GLuint amountOfGLFWExtensions;
|
||||||
|
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&amountOfGLFWExtensions);
|
||||||
|
|
||||||
|
instanceInfo->sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
instanceInfo->pNext = NULL;
|
||||||
|
instanceInfo->flags = 0;
|
||||||
|
instanceInfo->pApplicationInfo = appInfo;
|
||||||
|
instanceInfo->enabledLayerCount = 0;
|
||||||
|
instanceInfo->ppEnabledLayerNames = NULL;
|
||||||
|
instanceInfo->enabledExtensionCount = amountOfGLFWExtensions;
|
||||||
|
instanceInfo->ppEnabledExtensionNames = glfwExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initQueueInfo(VkDeviceQueueCreateInfo *queueInfo)
|
||||||
|
{
|
||||||
|
queueInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueInfo->pNext = NULL;
|
||||||
|
queueInfo->flags = 0;
|
||||||
|
queueInfo->queueFamilyIndex = 0;
|
||||||
|
queueInfo->queueCount = 1;
|
||||||
|
queueInfo->pQueuePriorities = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initDeviceInfo(VkDeviceQueueCreateInfo *queueInfo, VkDeviceCreateInfo *deviceInfo, VkPhysicalDeviceFeatures *features)
|
||||||
|
{
|
||||||
|
const char *deviceExtensions[1] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
|
||||||
|
|
||||||
|
deviceInfo->sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
deviceInfo->pNext = NULL;
|
||||||
|
deviceInfo->flags = 0;
|
||||||
|
deviceInfo->queueCreateInfoCount = 1;
|
||||||
|
deviceInfo->pQueueCreateInfos = queueInfo;
|
||||||
|
deviceInfo->enabledLayerCount = 0;
|
||||||
|
deviceInfo->ppEnabledLayerNames = NULL;
|
||||||
|
deviceInfo->enabledExtensionCount = 1;
|
||||||
|
deviceInfo->ppEnabledExtensionNames = deviceExtensions;
|
||||||
|
deviceInfo->pEnabledFeatures = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initSwapChainInfo(VkSwapchainCreateInfoKHR *swapChainCreateInfo, VkSurfaceKHR *surface)
|
||||||
|
{
|
||||||
|
VkExtent2D imageExtent = { WIDTH, HEIGHT };
|
||||||
|
|
||||||
|
swapChainCreateInfo->sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
swapChainCreateInfo->pNext = NULL;
|
||||||
|
swapChainCreateInfo->flags = 0;
|
||||||
|
swapChainCreateInfo->surface = *surface;
|
||||||
|
swapChainCreateInfo->minImageCount = 1;
|
||||||
|
swapChainCreateInfo->imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
swapChainCreateInfo->imageColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||||
|
swapChainCreateInfo->imageExtent = imageExtent;
|
||||||
|
swapChainCreateInfo->imageArrayLayers = 1;
|
||||||
|
swapChainCreateInfo->imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
swapChainCreateInfo->imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
swapChainCreateInfo->queueFamilyIndexCount = 0;
|
||||||
|
swapChainCreateInfo->pQueueFamilyIndices = NULL;
|
||||||
|
swapChainCreateInfo->preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||||
|
swapChainCreateInfo->compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
swapChainCreateInfo->presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
|
swapChainCreateInfo->clipped = VK_FALSE;
|
||||||
|
swapChainCreateInfo->oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initImageViewInfo(VkImageViewCreateInfo *imageViewInfo, VkImage *swapChainImages, int index)
|
||||||
|
{
|
||||||
|
VkComponentMapping componentMapping = {
|
||||||
|
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
VK_COMPONENT_SWIZZLE_IDENTITY,
|
||||||
|
VK_COMPONENT_SWIZZLE_IDENTITY
|
||||||
|
};
|
||||||
|
VkImageSubresourceRange subresourceRange = {
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,0, 1, 0, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
imageViewInfo->sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
|
imageViewInfo->pNext = NULL;
|
||||||
|
imageViewInfo->flags = 0;
|
||||||
|
imageViewInfo->image = swapChainImages[index];
|
||||||
|
imageViewInfo->viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
imageViewInfo->format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
imageViewInfo->components = componentMapping;
|
||||||
|
imageViewInfo->subresourceRange = subresourceRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdownVulkan(VkInstance *vkInstance, VkDevice *device, VkSurfaceKHR *surface, VkSwapchainKHR *swapChain,
|
||||||
|
VkImageView *imageViews, uint32_t amountImages)
|
||||||
|
{
|
||||||
|
vkDeviceWaitIdle(*device);
|
||||||
|
|
||||||
|
for (int i = 0; i < amountImages; i++)
|
||||||
|
{
|
||||||
|
vkDestroyImageView(*device, imageViews[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroySwapchainKHR(*device, *swapChain, NULL);
|
||||||
|
vkDestroySurfaceKHR(*vkInstance, *surface, NULL);
|
||||||
|
vkDestroyDevice(*device, NULL);
|
||||||
|
vkDestroyInstance(*vkInstance, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdownGLFW(GLFWwindow *window)
|
||||||
|
{
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void printStats(VkPhysicalDevice *physicalDevice, VkSurfaceKHR *surface)
|
||||||
|
{
|
||||||
|
// Device Properties
|
||||||
|
VkPhysicalDeviceProperties properties;
|
||||||
|
vkGetPhysicalDeviceProperties(*physicalDevice, &properties);
|
||||||
|
|
||||||
|
printf("--------- DEVICE PROPERTIES ---------\n");
|
||||||
|
uint32_t apiVersion = properties.apiVersion;
|
||||||
|
printf("Name: %s\n", properties.deviceName);
|
||||||
|
printf("API Version: %d.%d.%d\n", VK_VERSION_MAJOR(apiVersion), VK_VERSION_MINOR(apiVersion), VK_VERSION_PATCH(apiVersion));
|
||||||
|
|
||||||
|
// Features
|
||||||
|
VkPhysicalDeviceFeatures features;
|
||||||
|
vkGetPhysicalDeviceFeatures(*physicalDevice, &features);
|
||||||
|
|
||||||
|
printf("\n--------- FEATURES ---------\n");
|
||||||
|
printf("Geometry Shader: %s\n", (BOOL_LITERAL(features.geometryShader)));
|
||||||
|
printf("Tessellation Shader: %s\n", (BOOL_LITERAL(features.tessellationShader)));
|
||||||
|
|
||||||
|
// Memory Properties
|
||||||
|
VkPhysicalDeviceMemoryProperties memoryProperties;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(*physicalDevice, &memoryProperties);
|
||||||
|
|
||||||
|
printf("\n--------- MEMORY PROPERTIES ---------\n");
|
||||||
|
printf("Heapsize: %llu Byte / %f GiB\n", memoryProperties.memoryHeaps->size,
|
||||||
|
(HUMAN_READABLE(memoryProperties.memoryHeaps->size)));
|
||||||
|
|
||||||
|
// Queue Properties
|
||||||
|
uint32_t amountQueueFamilies = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(*physicalDevice, &amountQueueFamilies, NULL);
|
||||||
|
VkQueueFamilyProperties familyProperties[amountQueueFamilies];
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(*physicalDevice, &amountQueueFamilies, familyProperties);
|
||||||
|
|
||||||
|
printf("\n--------- QUEUE PROPERTIES ---------\n");
|
||||||
|
printf("Queue Families Amount: %d\n", amountQueueFamilies);
|
||||||
|
|
||||||
|
for (int i = 0; i < amountQueueFamilies; i++)
|
||||||
|
{
|
||||||
|
printf("-- Queue Family #%d --\n", i);
|
||||||
|
printf(" Graphics bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)));
|
||||||
|
printf(" Compute bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_COMPUTE_BIT) != 0)));
|
||||||
|
printf(" Transfer bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_TRANSFER_BIT) != 0)));
|
||||||
|
printf(" Sparse Binding bit: %s\n", (BOOL_LITERAL((familyProperties[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) != 0)));
|
||||||
|
printf(" Queue Count: %d\n", familyProperties[i].queueCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Surface Capabilities
|
||||||
|
VkSurfaceCapabilitiesKHR surfaceCapabilities;
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(*physicalDevice, *surface, &surfaceCapabilities);
|
||||||
|
printf("\n--------- SURFACE CAPABILITIES ---------\n");
|
||||||
|
printf(" Min Image Count: %d\n", surfaceCapabilities.minImageCount);
|
||||||
|
printf(" Max Image Count: %d\n", surfaceCapabilities.maxImageCount);
|
||||||
|
printf(" Current Extent: (%d; %d)\n", surfaceCapabilities.currentExtent.width, surfaceCapabilities.currentExtent.height);
|
||||||
|
printf(" Min Image Extent: (%d; %d)\n", surfaceCapabilities.minImageExtent.width, surfaceCapabilities.minImageExtent.height);
|
||||||
|
printf(" Max Image Extent: (%d; %d)\n", surfaceCapabilities.maxImageExtent.width, surfaceCapabilities.maxImageExtent.height);
|
||||||
|
printf(" Max Image Array Layers: %d\n", surfaceCapabilities.maxImageArrayLayers);
|
||||||
|
printf(" Supported Transforms: %d\n", surfaceCapabilities.supportedTransforms);
|
||||||
|
printf(" Current Transform: %d\n", surfaceCapabilities.currentTransform);
|
||||||
|
printf(" Supported Composite Alpha: %d\n", surfaceCapabilities.supportedCompositeAlpha);
|
||||||
|
printf(" Supported Usage Flags: %d\n", surfaceCapabilities.supportedUsageFlags);
|
||||||
|
|
||||||
|
// Surface Formats
|
||||||
|
uint32_t amountFormats;
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(*physicalDevice, *surface, &amountFormats, NULL);
|
||||||
|
VkSurfaceFormatKHR formats[amountFormats];
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(*physicalDevice, *surface, &amountFormats, formats);
|
||||||
|
|
||||||
|
printf("\n--------- SURFACE FORMATS ---------\n");
|
||||||
|
printf("Surface Formats Amount: %d\n", amountFormats);
|
||||||
|
|
||||||
|
for (int i = 0; i < amountFormats; i++)
|
||||||
|
{
|
||||||
|
printf("-- Surface Format #%d --\n", i);
|
||||||
|
printf(" Format: %d\n", formats[i].format);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Presentation Modes
|
||||||
|
uint32_t amountPresentModes;
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(*physicalDevice, *surface, &amountPresentModes, NULL);
|
||||||
|
VkPresentModeKHR presentModes[amountPresentModes];
|
||||||
|
vkGetPhysicalDeviceSurfacePresentModesKHR(*physicalDevice, *surface, &amountPresentModes, presentModes);
|
||||||
|
|
||||||
|
printf("\n--------- PRESENTATION MODES ---------\n");
|
||||||
|
printf("Presentation Modes Amount: %d\n", amountPresentModes);
|
||||||
|
|
||||||
|
for (int i = 0; i < amountPresentModes; ++i)
|
||||||
|
{
|
||||||
|
printf("-- Present Mode #%d --\n", i);
|
||||||
|
printf(" Mode: %d\n", presentModes[i]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user