337 lines
13 KiB
C
337 lines
13 KiB
C
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
|
|
#include "particlesystem.h"
|
|
#include "initOpenGL.h"
|
|
|
|
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 = 800, height = 800;
|
|
GLFWwindow *window = createGLFWWindow(width, height, "Informatikprojekt - OpenGL");
|
|
|
|
setCurrentContextGL(window);
|
|
setFramebufferSizeCallbackGL(window);
|
|
|
|
// glad
|
|
initGlad();
|
|
|
|
/************* PARTICLE SYSTEM *************/
|
|
int particleAmount = 10000;
|
|
vector3f *epos1 = initVector3f(0, 0, 0);
|
|
emitter *e1 = initEmitter(epos1, particleAmount);
|
|
particle_system *ps = initParticleSystem(1);
|
|
(ps->emitters)[0] = e1;
|
|
initRandomParticles(e1);
|
|
|
|
/************* SHADER *************/
|
|
const GLchar *computeShaderSource = "#version 460\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"
|
|
"\n"
|
|
"layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\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"
|
|
" {\n"
|
|
" part.pos += part.vel * dt;\n"
|
|
" part.age -= 0.01f;\n"
|
|
" }\n"
|
|
" else\n"
|
|
" {\n"
|
|
" part.pos = vec3(0, 0, 0);\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, 0);\n"
|
|
"}";
|
|
|
|
// const GLchar *geometryShaderSource = "#version 460 core\n"
|
|
// "\n"
|
|
// "layout(points) in;\n"
|
|
// "layout(points, max_vertices = 256) out;\n"
|
|
// "\n"
|
|
// "in vec3 colV;\n"
|
|
// "out vec3 colG;\n"
|
|
// "\n"
|
|
// "void main(void)\n"
|
|
// "{\n"
|
|
// " colG = colV;\n"
|
|
// "}";
|
|
|
|
// const GLchar *fragmentShaderSource = "#version 460 core\n"
|
|
// "\n"
|
|
// "in vec3 colG;\n"
|
|
// "out vec4 colOut;\n"
|
|
// "\n"
|
|
// "void main(void)\n"
|
|
// "{\n"
|
|
// " colOut = vec4(colG, 1);\n"
|
|
// "}";
|
|
|
|
GLuint computeShader = compileShader(computeShaderSource, GL_COMPUTE_SHADER);
|
|
GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
|
|
// GLuint geometryShader = compileShader(geometryShaderSource, GL_GEOMETRY_SHADER);
|
|
// GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
|
|
|
|
GLuint computeShaders[] = { computeShader };
|
|
GLuint computeShaderProgram = linkShaders(computeShaders, 1);
|
|
glUseProgram(computeShaderProgram);
|
|
GLint dtUniformLocation = glGetUniformLocation(computeShaderProgram, "dt");
|
|
|
|
GLuint renderShaders[] = { vertexShader/*, geometryShader, fragmentShader*/ };
|
|
GLuint renderShaderProgram = linkShaders(renderShaders, 1/*3*/);
|
|
|
|
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, particleAmount * 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);
|
|
glDispatchCompute((particleAmount / 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);
|
|
|
|
glColor3f(1, 1, 1);
|
|
glBindVertexArray(vertexArray);
|
|
glUseProgram(renderShaderProgram);
|
|
glDrawArrays(GL_POINTS, 0, particleAmount);
|
|
glBindVertexArray(0);
|
|
|
|
// glClear(GL_COLOR_BUFFER_BIT);
|
|
// glfwGetFramebufferSize(window, &width, &height);
|
|
// 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();
|
|
// }
|
|
// }
|
|
|
|
glfwSwapBuffers(window);
|
|
glfwPollEvents();
|
|
}
|
|
|
|
//END
|
|
deleteShaders(renderShaders, 3);
|
|
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;
|