1
0

334 lines
14 KiB
C
Raw Normal View History

2019-12-16 19:12:24 +01:00
#include <stdio.h>
2019-12-17 22:29:36 +01:00
#include <malloc.h>
#include <stdlib.h>
#include <stddef.h>
2019-12-18 18:18:55 +01:00
2019-12-17 22:29:36 +01:00
#include "particlesystem.h"
#include "initOpenGL.h"
2019-12-17 22:29:36 +01:00
2020-03-13 17:11:07 +01:00
#define PARTICLE_AMOUNT 10000
#define WIDTH 800
#define HEIGHT 800
void printVector(vector3f *v);
2019-12-17 22:29:36 +01:00
void printParticle(particle *v);
void printEmitter(emitter *e);
void initRandomParticles(emitter *e);
2019-12-18 18:18:55 +01:00
void error_callback(int error, const char* description);
2019-12-16 19:12:24 +01:00
void calcPos(particle *p, float dt);
void calcCol(particle *p);
2019-12-16 19:12:24 +01:00
int main()
{
2020-02-11 19:01:50 +01:00
/************* INIT *************/
// Init OpenGL and GLFW
initGLFW();
setErrorCallbackGL();
2019-12-18 18:18:55 +01:00
2020-03-13 17:11:07 +01:00
int width = WIDTH, height = HEIGHT;
GLFWwindow *window = createGLFWWindow(WIDTH, HEIGHT, "Informatikprojekt - OpenGL");
2019-12-18 18:18:55 +01:00
setCurrentContextGL(window);
setFramebufferSizeCallbackGL(window);
2019-12-18 18:18:55 +01:00
// glad
initGlad();
2019-12-18 18:18:55 +01:00
2020-02-11 19:01:50 +01:00
/************* PARTICLE SYSTEM *************/
vector3f *epos1 = initVector3f(0, 0, 0);
2020-03-13 17:11:07 +01:00
emitter *e1 = initEmitter(epos1, PARTICLE_AMOUNT);
2019-12-20 14:24:52 +01:00
particle_system *ps = initParticleSystem(1);
2020-02-11 19:01:50 +01:00
(ps->emitters)[0] = e1;
initRandomParticles(e1);
2020-03-08 21:03:48 +01:00
/************* SHADER *************/
2020-03-13 17:11:07 +01:00
const GLchar *computeShaderSource = "#version 460 core\n"
"#extension GL_ARB_compute_shader : enable\n"
"#extension GL_ARB_shader_storage_buffer_object : enable\n"
2020-03-08 21:03:48 +01:00
"\n"
"struct particle\n"
"{\n"
" vec3 pos;\n"
" vec3 vel;\n"
" vec3 col;\n"
" float age;\n"
"};\n"
"\n"
2020-03-13 17:11:07 +01:00
"layout(std430, binding = 0) buffer particles\n"
2020-03-08 21:03:48 +01:00
"{\n"
" particle p[];\n"
"};\n"
"\n"
"uniform float dt;\n"
2020-03-13 17:11:07 +01:00
"uniform vec3 resetPos;\n"
"uniform uint seed;\n"
"\n"
2020-03-08 21:03:48 +01:00
"layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n"
"\n"
2020-03-13 17:11:07 +01:00
"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"
2020-03-08 21:03:48 +01:00
"void main()\n"
"{\n"
" uint gid = gl_GlobalInvocationID.x;\n"
" particle part = p[gid];\n"
"\n"
2020-03-13 17:11:07 +01:00
" 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"
2020-03-08 21:03:48 +01:00
" {\n"
2020-03-13 17:11:07 +01:00
" part.pos = resetPos;\n"
" //part.vel = rand3();\n"
" //part.col = vec3(rand(), rand(), rand());\n"
" //part.age = rand() * 0x7fff * 0.01f;\n"
" \n"
2020-03-08 21:03:48 +01:00
" }\n"
" else\n"
" {\n"
2020-03-13 17:11:07 +01:00
" part.pos += part.vel * dt;\n"
" part.age -= 0.01f;\n"
2020-03-08 21:03:48 +01:00
" }\n"
"\n"
2020-03-08 21:03:48 +01:00
" 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"
2020-02-11 19:01:50 +01:00
"\n"
2020-03-13 17:11:07 +01:00
"out vec3 colV;\n"
2020-02-11 19:01:50 +01:00
"\n"
2020-03-08 21:03:48 +01:00
"void main(void)\n"
2020-02-11 19:01:50 +01:00
"{\n"
2020-03-13 17:11:07 +01:00
" colV = colIn;\n"
" gl_Position = vec4(pos, 1);\n"
2020-02-11 19:01:50 +01:00
"}";
2020-03-13 17:11:07 +01:00
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"
"}";
2020-03-08 21:03:48 +01:00
GLuint computeShader = compileShader(computeShaderSource, GL_COMPUTE_SHADER);
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
2020-03-13 17:11:07 +01:00
GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
2020-03-08 21:03:48 +01:00
GLuint computeShaders[] = { computeShader };
GLuint computeShaderProgram = linkShaders(computeShaders, 1);
glUseProgram(computeShaderProgram);
GLint dtUniformLocation = glGetUniformLocation(computeShaderProgram, "dt");
2020-03-13 17:11:07 +01:00
GLint resetPosUniformLocation = glGetUniformLocation(computeShaderProgram, "resetPos");
GLint seedUniformLocation = glGetUniformLocation(computeShaderProgram, "seed");
glUniform3f(resetPosUniformLocation, e1->position->x, e1->position->y, e1->position->z);
2020-03-13 17:11:07 +01:00
GLuint renderShaders[] = { vertexShader, fragmentShader };
GLuint renderShaderProgram = linkShaders(renderShaders, 2);
2020-03-08 21:03:48 +01:00
float *particles = serializeParticlesystem(ps);
GLsizeiptr sizeOfParticle = 3 * sizeof(vector3f) + sizeof(float);
2020-03-08 21:03:48 +01:00
GLuint particleBuffer;
glGenBuffers(1, &particleBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleBuffer);
2020-03-13 17:11:07 +01:00
glBufferData(GL_SHADER_STORAGE_BUFFER, PARTICLE_AMOUNT * sizeOfParticle, particles, GL_STATIC_DRAW);
2020-03-08 21:03:48 +01:00
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
2020-03-08 21:03:48 +01:00
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);
2020-03-08 21:03:48 +01:00
glBindVertexArray(0);
2020-02-11 19:01:50 +01:00
/************* RENDER LOOP *************/
2019-12-28 13:54:53 +01:00
double time, tFrame, tLast = 0;
2019-12-18 18:18:55 +01:00
while (!glfwWindowShouldClose(window))
{
2019-12-28 13:54:53 +01:00
time = glfwGetTime();
tFrame = time - tLast;
tLast = time;
2019-12-18 18:18:55 +01:00
2020-03-08 21:03:48 +01:00
/*** UPDATE ***/
glUseProgram(computeShaderProgram);
glUniform1f(dtUniformLocation, tFrame);
2020-03-13 17:11:07 +01:00
glUniform1ui(seedUniformLocation, rand());
glDispatchCompute((PARTICLE_AMOUNT / 256) + 1, 1, 1);
2020-03-08 21:03:48 +01:00
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
/*** RENDER ***/
glClear(GL_COLOR_BUFFER_BIT);
2019-12-18 18:18:55 +01:00
glfwGetFramebufferSize(window, &width, &height);
glBindVertexArray(vertexArray);
2020-03-08 21:03:48 +01:00
glUseProgram(renderShaderProgram);
2020-03-13 17:11:07 +01:00
glDrawArrays(GL_POINTS, 0, PARTICLE_AMOUNT);
2020-03-08 21:03:48 +01:00
glBindVertexArray(0);
2019-12-18 18:18:55 +01:00
glfwSwapBuffers(window);
glfwPollEvents();
}
//END
2020-03-13 17:11:07 +01:00
deleteShaders(renderShaders, 2);
2020-03-08 21:03:48 +01:00
deleteShaders(computeShaders, 1);
2020-02-11 19:01:50 +01:00
terminateGLFW(window);
2019-12-28 13:54:53 +01:00
freeParticleSystem(ps);
2019-12-18 18:18:55 +01:00
2019-12-16 19:12:24 +01:00
return 0;
}
2019-12-17 22:29:36 +01:00
void calcPos(particle *p, float dt)
{
2020-03-08 21:03:48 +01:00
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)
2019-12-18 18:18:55 +01:00
{
2020-02-11 19:01:50 +01:00
// p->color->x -= 0.01f;
// p->color->y -= 0.01f;
// p->color->z -= 0.01f;
2019-12-18 18:18:55 +01:00
}
/*************************************************************************************************************/
2019-12-17 22:29:36 +01:00
void initRandomParticles(emitter *e)
{
for (int i = 0; i < e->pamount; i++)
{
vector3f *pos = initVector3f(e->position->x, e->position->y, e->position->z);
2020-01-08 17:33:01 +01:00
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);
2020-02-11 19:01:50 +01:00
vector3f *color = initVector3f(((float) (rand() % 255)) / 255,
((float) (rand() % 255)) / 255,
((float) (rand() % 255)) / 255);
2020-01-08 17:33:01 +01:00
(e->particles)[i] = initParticle(pos, dir, color, rand() / 100.0f);
2019-12-17 22:29:36 +01:00
}
}
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);
}
2020-03-08 21:03:48 +01:00
/// 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;