1
0
This commit is contained in:
Niklas Birk 2020-03-08 21:03:48 +01:00
parent 05038da3df
commit 38d326abca
17 changed files with 347 additions and 193 deletions

View File

@ -7043,7 +7043,7 @@ nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args)
num_print--; num_print--;
} }
/* reverse number direction */ /* reverse number velocity */
while (num_len > 0) { while (num_len > 0) {
if (precision && (len < buf_size)) if (precision && (len < buf_size))
buf[len++] = number_buffer[num_len-1]; buf[len++] = number_buffer[num_len-1];
@ -12349,7 +12349,7 @@ nk_tt__oversample_shift(int oversample)
/* The prefilter is a box filter of width "oversample", */ /* The prefilter is a box filter of width "oversample", */
/* which shifts phase by (oversample - 1)/2 pixels in */ /* which shifts phase by (oversample - 1)/2 pixels in */
/* oversampled space. We want to shift in the opposite */ /* oversampled space. We want to shift in the opposite */
/* direction to counter this. */ /* velocity to counter this. */
return (float)-(oversample - 1) / (2.0f * (float)oversample); return (float)-(oversample - 1) / (2.0f * (float)oversample);
} }
NK_INTERN int NK_INTERN int
@ -15959,14 +15959,14 @@ nk_panel_end(struct nk_context *ctx)
delta_x = -delta_x; delta_x = -delta_x;
window->bounds.x += in->mouse.delta.x; window->bounds.x += in->mouse.delta.x;
} }
/* dragging in x-direction */ /* dragging in x-velocity */
if (window->bounds.w + delta_x >= window_size.x) { if (window->bounds.w + delta_x >= window_size.x) {
if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) { if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) {
window->bounds.w = window->bounds.w + delta_x; window->bounds.w = window->bounds.w + delta_x;
scaler.x += in->mouse.delta.x; scaler.x += in->mouse.delta.x;
} }
} }
/* dragging in y-direction (only possible if static window) */ /* dragging in y-velocity (only possible if static window) */
if (!(layout->flags & NK_WINDOW_DYNAMIC)) { if (!(layout->flags & NK_WINDOW_DYNAMIC)) {
if (window_size.y < window->bounds.h + in->mouse.delta.y) { if (window_size.y < window->bounds.h + in->mouse.delta.y) {
if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) { if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) {
@ -25371,7 +25371,7 @@ nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args)
/// - 2016/09/15 (1.21.2)- Fixed panel `close` behavior for deeper panel levels /// - 2016/09/15 (1.21.2)- Fixed panel `close` behavior for deeper panel levels
/// - 2016/09/15 (1.21.1)- Fixed C++ errors and wrong argument to `nk_panel_get_xxxx` /// - 2016/09/15 (1.21.1)- Fixed C++ errors and wrong argument to `nk_panel_get_xxxx`
/// - 2016/09/13 (1.21.0) - !BREAKING! Fixed nonblocking popup behavior in menu, combo, /// - 2016/09/13 (1.21.0) - !BREAKING! Fixed nonblocking popup behavior in menu, combo,
/// and contextual which prevented closing in y-direction if /// and contextual which prevented closing in y-velocity if
/// popup did not reach max height. /// popup did not reach max height.
/// In addition the height parameter was changed into vec2 /// In addition the height parameter was changed into vec2
/// for width and height to have more control over the popup size. /// for width and height to have more control over the popup size.

View File

@ -1665,7 +1665,7 @@ Functions</h2></td></tr>
<tr class="markdownTableRowOdd"> <tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT_DOWN</code> </td><td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT</code> | <code>GLFW_HAT_DOWN</code> </td></tr> <td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT_DOWN</code> </td><td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT</code> | <code>GLFW_HAT_DOWN</code> </td></tr>
</table> </table>
<p>The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction.</p> <p>The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding velocity.</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (hats[2] &amp; <a class="code" href="group__hat__state.html#ga252586e3bbde75f4b0e07ad3124867f5">GLFW_HAT_RIGHT</a>)</div><div class="line">{</div><div class="line"> <span class="comment">// State of hat 2 could be right-up, right or right-down</span></div><div class="line">}</div></div><!-- fragment --><p>If the specified joystick is not present this function will return <code>NULL</code> but will not generate an error. This can be used instead of first calling <a class="el" href="group__input.html#gaed0966cee139d815317f9ffcba64c9f1">glfwJoystickPresent</a>.</p> <div class="fragment"><div class="line"><span class="keywordflow">if</span> (hats[2] &amp; <a class="code" href="group__hat__state.html#ga252586e3bbde75f4b0e07ad3124867f5">GLFW_HAT_RIGHT</a>)</div><div class="line">{</div><div class="line"> <span class="comment">// State of hat 2 could be right-up, right or right-down</span></div><div class="line">}</div></div><!-- fragment --><p>If the specified joystick is not present this function will return <code>NULL</code> but will not generate an error. This can be used instead of first calling <a class="el" href="group__input.html#gaed0966cee139d815317f9ffcba64c9f1">glfwJoystickPresent</a>.</p>
<dl class="params"><dt>Parameters</dt><dd> <dl class="params"><dt>Parameters</dt><dd>
<table class="params"> <table class="params">

View File

@ -260,7 +260,7 @@ Joystick hat states</h2>
<tr class="markdownTableRowOdd"> <tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT_DOWN</code> </td><td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT</code> | <code>GLFW_HAT_DOWN</code> </td></tr> <td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT_DOWN</code> </td><td class="markdownTableBodyNone"><code>GLFW_HAT_LEFT</code> | <code>GLFW_HAT_DOWN</code> </td></tr>
</table> </table>
<p>The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding direction.</p> <p>The diagonal directions are bitwise combinations of the primary (up, right, down and left) directions and you can test for these individually by ANDing it with the corresponding velocity.</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (hats[2] &amp; <a class="code" href="group__hat__state.html#ga252586e3bbde75f4b0e07ad3124867f5">GLFW_HAT_RIGHT</a>)</div><div class="line">{</div><div class="line"> <span class="comment">// State of hat 2 could be right-up, right or right-down</span></div><div class="line">}</div></div><!-- fragment --><p>For backward compatibility with earlier versions that did not have <a class="el" href="group__input.html#ga2d8d0634bb81c180899aeb07477a67ea">glfwGetJoystickHats</a>, all hats are by default also included in the button array. See the reference documentation for <a class="el" href="group__input.html#gadb3cbf44af90a1536f519659a53bddd6">glfwGetJoystickButtons</a> for details.</p> <div class="fragment"><div class="line"><span class="keywordflow">if</span> (hats[2] &amp; <a class="code" href="group__hat__state.html#ga252586e3bbde75f4b0e07ad3124867f5">GLFW_HAT_RIGHT</a>)</div><div class="line">{</div><div class="line"> <span class="comment">// State of hat 2 could be right-up, right or right-down</span></div><div class="line">}</div></div><!-- fragment --><p>For backward compatibility with earlier versions that did not have <a class="el" href="group__input.html#ga2d8d0634bb81c180899aeb07477a67ea">glfwGetJoystickHats</a>, all hats are by default also included in the button array. See the reference documentation for <a class="el" href="group__input.html#gadb3cbf44af90a1536f519659a53bddd6">glfwGetJoystickButtons</a> for details.</p>
<h2><a class="anchor" id="joystick_name"></a> <h2><a class="anchor" id="joystick_name"></a>
Joystick name</h2> Joystick name</h2>

View File

@ -620,7 +620,7 @@ Name | Value
The diagonal directions are bitwise combinations of the primary (up, right, down The diagonal directions are bitwise combinations of the primary (up, right, down
and left) directions and you can test for these individually by ANDing it with and left) directions and you can test for these individually by ANDing it with
the corresponding direction. the corresponding velocity.
@code @code
if (hats[2] & GLFW_HAT_RIGHT) if (hats[2] & GLFW_HAT_RIGHT)

View File

@ -252,7 +252,7 @@ static void init_particle(PARTICLE *p, double t)
// Start velocity is up (Z)... // Start velocity is up (Z)...
p->vz = 0.7f + (0.3f / 4096.f) * (float) (rand() & 4095); p->vz = 0.7f + (0.3f / 4096.f) * (float) (rand() & 4095);
// ...and a randomly chosen X/Y direction // ...and a randomly chosen X/Y velocity
xy_angle = (2.f * (float) M_PI / 4096.f) * (float) (rand() & 4095); xy_angle = (2.f * (float) M_PI / 4096.f) * (float) (rand() & 4095);
p->vx = 0.4f * (float) cos(xy_angle); p->vx = 0.4f * (float) cos(xy_angle);
p->vy = 0.4f * (float) sin(xy_angle); p->vy = 0.4f * (float) sin(xy_angle);

View File

@ -4695,7 +4695,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
* *
* The diagonal directions are bitwise combinations of the primary (up, right, * The diagonal directions are bitwise combinations of the primary (up, right,
* down and left) directions and you can test for these individually by ANDing * down and left) directions and you can test for these individually by ANDing
* it with the corresponding direction. * it with the corresponding velocity.
* *
* @code * @code
* if (hats[2] & GLFW_HAT_RIGHT) * if (hats[2] & GLFW_HAT_RIGHT)

View File

@ -76,3 +76,53 @@ void initVertexArrayBuffer(unsigned int *VAO)
glBindVertexArray(*VAO); glBindVertexArray(*VAO);
} }
GLuint compileShader(const GLchar *shaderSource, GLenum shaderType)
{
GLuint shader;
shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderSource, NULL);
glCompileShader(shader);
int compileSuccess;
char info[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileSuccess);
if (!compileSuccess)
{
glGetShaderInfoLog(shader, 512, NULL, info);
printf("ERROR::SHADER::%d::COMPILATION_FAILED:\n%s", shaderType, info);
}
return shader;
}
GLuint linkShaders(GLuint *shaders, GLsizei count)
{
GLuint program;
program = glCreateProgram();
for (int i = 0; i < count; i++)
{
glAttachShader(program, shaders[i]);
}
glLinkProgram(program);
int successLink;
char infoLogLink[512];
glGetProgramiv(program, GL_LINK_STATUS, &successLink);
if (!successLink)
{
glGetProgramInfoLog(program, 512, NULL, infoLogLink);
printf("ERROR::SHADER::LINKING_FAILED\n%s", infoLogLink);
}
return program;
}
void deleteShaders(GLuint *shaders, GLsizei count)
{
for (int i = 0; i < count; i++)
{
glDeleteShader(shaders[i]);
}
}

View File

@ -21,4 +21,8 @@ void framebufferSizeCallback(GLFWwindow *window, int width, int height);
void initVertexBufferObject(unsigned int *VBO, float *vertices); void initVertexBufferObject(unsigned int *VBO, float *vertices);
void initVertexArrayBuffer(unsigned int *VAO); void initVertexArrayBuffer(unsigned int *VAO);
GLuint compileShader(const GLchar *shaderSource, GLenum shaderType);
GLuint linkShaders(GLuint *shaders, GLsizei count);
void deleteShaders(GLuint *shaders, GLsizei count);
#endif //INFORMATIKPROJEKT_INITOPENGL_H #endif //INFORMATIKPROJEKT_INITOPENGL_H

299
main.c
View File

@ -34,163 +34,136 @@ int main()
initGlad(); initGlad();
/************* PARTICLE SYSTEM *************/ /************* PARTICLE SYSTEM *************/
int particelAmount = 10000; int particleAmount = 10000;
vector3f *epos1 = initVector3f(0, 0, 0); vector3f *epos1 = initVector3f(0, 0, 0);
emitter *e1 = initEmitter(epos1, particelAmount); emitter *e1 = initEmitter(epos1, particleAmount);
particle_system *ps = initParticleSystem(1); particle_system *ps = initParticleSystem(1);
(ps->emitters)[0] = e1; (ps->emitters)[0] = e1;
initRandomParticles(e1); initRandomParticles(e1);
/************* COMPILING SHADER *************/ /************* SHADER *************/
const char *vertexShaderSource = "#version 460 core\n" const GLchar *computeShaderSource = "#version 460 core\n"
"#extension GL_ARB_compute_shader : enable\n"
"#extension GL_ARB_shader_storage_buffer_object : enable\n"
"\n" "\n"
"layout (location = 0) in vec3 pos; // the position variable has attribute position 0\n" "struct particle\n"
"layout (location = 1) in vec3 dir; // the direction variable has attribute position 1\n" "{\n"
"layout (location = 2) in vec3 col; // the color variable has attribute position 2\n" " vec3 pos;\n"
"layout (location = 3) in float age; // the age variable has attribute position 3\n" " vec3 vel;\n"
" vec3 col;\n"
" float age;\n"
"};\n"
"\n" "\n"
"//in vec3 emitterPos; // the emitter pos variable\n" "layout(std430, binding=0) buffer particles\n"
"//in float newAge; // the age variable\n" "{\n"
" particle p[];\n"
"};\n"
"\n" "\n"
"out vec3 outCol; // output a color to the fragment shader\n" "layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n"
"\n" "\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" if (age < 0)\n" " uint gid = gl_GlobalInvocationID.x;\n"
" particle part = p[gid];\n"
"\n"
" if (part.age > 0)\n"
" {\n" " {\n"
" //pos = vec3(0, 0, 0); //emitterPos;\n" " part.pos += part.vel;\n"
" //age = 200; //newAge;\n" " part.age -= 0.01f;\n"
" }\n"
" else\n"
" {\n"
" part.pos = vec3(0, 0, 0);\n"
" }\n" " }\n"
" \n" " \n"
" age -= 0.1f;\n" " p[gid] = part;\n"
" vec3 newPos = pos.xyz + dir.xyz;\n"
" gl_Position = vec4(newPos, 1.0);\n"
"\n"
" outCol = col; // set ourColor to the input color we got from the vertex data\n"
"}"; "}";
unsigned int vertexShader; const GLchar *vertexShaderSource = "#version 460 core\n"
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int successCompileVertex;
char infoLogCompileVertex[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &successCompileVertex);
if (!successCompileVertex)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLogCompileVertex);
printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n%s", infoLogCompileVertex);
}
const char *fragmentShaderSource = "#version 460 core\n"
"\n" "\n"
"in vec3 col; // the input variable from the vertex shader (same name and same type)\n" "layout(location=0) in vec4 pos;\n"
"\n" "\n"
"out vec4 outCol;\n" "void main(void)\n"
"\n"
"void main()\n"
"{\n" "{\n"
" outCol = vec4(col, 1.0);\n" " gl_Position = pos;\n"
"}"; "}";
unsigned int fragmentShader; const GLchar *geometryShaderSource = "#version 460 core\n"
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); "\n"
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); "layout(points) in;\n"
glCompileShader(fragmentShader); "layout(points, max_vertices = 256) out;\n"
"\n"
"void main(void)\n"
"{\n"
"}";
int successCompileFragment; const GLchar *fragmentShaderSource = "#version 460 core\n"
char infoLogCompileFragment[512]; "\n"
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &successCompileFragment); "out vec4 colOut;\n"
if (!successCompileFragment) "\n"
{ "void main(void)\n"
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLogCompileFragment); "{\n"
printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n%s", infoLogCompileFragment); " colOut = vec4(1, 1, 1, 1);\n"
} "}";
/************* LINKING SHADER *************/ GLuint computeShader = compileShader(computeShaderSource, GL_COMPUTE_SHADER);
unsigned int shaderProgram; GLuint vertexShader = compileShader(vertexShaderSource, GL_VERTEX_SHADER);
shaderProgram = glCreateProgram(); GLuint geometryShader = compileShader(geometryShaderSource, GL_GEOMETRY_SHADER);
glAttachShader(shaderProgram, vertexShader); GLuint fragmentShader = compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
int successLink; GLuint computeShaders[] = { computeShader };
char infoLogLink[512]; GLuint computeShaderProgram = linkShaders(computeShaders, 1);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &successLink); GLuint renderShaders[] = { vertexShader, geometryShader, fragmentShader };
if (!successLink) GLuint renderShaderProgram = linkShaders(renderShaders, 3);
{
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLogLink);
printf("ERROR::SHADER::LINKING_FAILED\n%s", infoLogLink);
}
/*************** VAO / VBO ***************/ particle *particles = ps->emitters[0]->particles[0]; // Only this atm
// Init vertex data
unsigned int vao, vbo;
float *vertexData = serializeParticlesystem(ps);
initVertexArrayBuffer(&vao);
initVertexBufferObject(&vbo, vertexData);
// position attribute GLuint particleBuffer;
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)0); glGenBuffers(1, &particleBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, particleBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER, particleAmount * sizeof(particle), particles, GL_STATIC_DRAW);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
GLuint vertexArray;
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, particleBuffer);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
// direction attribute glBindBuffer(GL_ARRAY_BUFFER, particleBuffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)(3 * sizeof(float))); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(particle), 0);
glEnableVertexAttribArray(1); glBindVertexArray(0);
// color attribute
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// age attribute
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)(9 * sizeof(float)));
glEnableVertexAttribArray(3);
/************* RENDER LOOP *************/ /************* RENDER LOOP *************/
double time, tFrame, tLast = 0; double time, tFrame, tLast = 0;
int isFirst = 1;
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
time = glfwGetTime(); time = glfwGetTime();
tFrame = time - tLast; tFrame = time - tLast;
tLast = time; tLast = time;
/*** UPDATE ***/
glUseProgram(computeShaderProgram);
glDispatchCompute((particleAmount / 256) + 1, 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
/*** RENDER ***/
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glfwGetFramebufferSize(window, &width, &height); glfwGetFramebufferSize(window, &width, &height);
glUseProgram(shaderProgram); glUseProgram(renderShaderProgram);
glBindVertexArray(vao); glDrawArrays(GL_POINTS, 0, particleAmount);
glDrawArrays(GL_POINTS, 0, particelAmount); glBindVertexArray(0);
/*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); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
} }
//END //END
glDeleteShader(vertexShader); deleteShaders(renderShaders, 3);
glDeleteShader(fragmentShader); deleteShaders(computeShaders, 1);
terminateGLFW(window); terminateGLFW(window);
freeParticleSystem(ps); freeParticleSystem(ps);
return 0; return 0;
@ -198,9 +171,9 @@ int main()
void calcPos(particle *p, float dt) void calcPos(particle *p, float dt)
{ {
p->position->x += p->direction->x * dt; p->position->x += p->velocity->x * dt;
p->position->y += p->direction->y * dt; p->position->y += p->velocity->y * dt;
p->position->z += p->direction->z * dt; p->position->z += p->velocity->z * dt;
} }
void calcCol(particle *p) void calcCol(particle *p)
@ -226,30 +199,84 @@ void initRandomParticles(emitter *e)
} }
} }
char *printVector(vector3f *v) /// VERY OLD
{ // glUseProgram(shaderProgram);
char *c = malloc(100); // glBindVertexArray(vao);
sprintf(c, "(%f, %f, %f)", v->x, v->y, v->z); // glDrawArrays(GL_POINTS, 0, particleAmount);
return c;
}
void printParticle(particle *v) // updateParticles((float) tFrame, ps, calcPos, calcCol);
{ //
printf(" Particle {\n"); // emitter *e;
printf(" position = %s", printVector(v->position)); // particle *p;
printf("\n direction = %s", printVector(v->direction)); // vector3f *pos;
printf("\n }"); // 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();
// }
// }
void printEmitter(emitter *e) /// FEEDBACK TRANSFORM BEFORE
{ // /*************** NEW ***************/
printf("Emitter {\n"); // 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]);
// }
for (int i = 0; i < e->pamount; i++) // // position attribute
{ // glEnableVertexAttribArray(0);
printParticle((e->particles)[i]); // glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10 * sizeof(float), (void*)0);
printf("\n"); // // 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)));
printf("\n}"); /// 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;

View File

@ -1,6 +1,5 @@
#include <malloc.h> #include <malloc.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include "particlesystem.h" #include "particlesystem.h"
@ -11,7 +10,7 @@ particle *initParticle(vector3f *pos, vector3f *dir, vector3f *color, float age)
{ {
particle *p = malloc(sizeof(particle)); particle *p = malloc(sizeof(particle));
p->position = pos; p->position = pos;
p->direction = dir; p->velocity = dir;
p->color = color; p->color = color;
p->age = age; p->age = age;
return p; return p;
@ -74,9 +73,9 @@ void resetParticle(emitter *e, particle *p)
p->position->y = e->position->y; p->position->y = e->position->y;
p->position->z = e->position->z; p->position->z = e->position->z;
p->direction->x = ((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX; p->velocity->x = ((float) (rand() % 2 ? -1 : 1) * rand()) / RAND_MAX;
p->direction->y = ((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX; p->velocity->y = ((float) (rand() % 2 ? -1 : 1) * rand()) / RAND_MAX;
p->direction->z = ((float) (rand()%2 ? -1 : 1) * rand()) / RAND_MAX; p->velocity->z = ((float) (rand() % 2 ? -1 : 1) * rand()) / RAND_MAX;
p->age = rand() / 10; p->age = rand() / 10;
} }
@ -108,7 +107,7 @@ vector3f *initVector3f(float x, float y, float z)
void freeParticle(particle *p) void freeParticle(particle *p)
{ {
free(p->position); free(p->position);
free(p->direction); free(p->velocity);
free(p->color); free(p->color);
free(p); free(p);
} }
@ -175,9 +174,9 @@ float *serializeParticlesystem(particle_system *ps)
vert[j++] = p->position->z; vert[j++] = p->position->z;
// Direction // Direction
vert[j++] = p->direction->x; vert[j++] = p->velocity->x;
vert[j++] = p->direction->y; vert[j++] = p->velocity->y;
vert[j++] = p->direction->z; vert[j++] = p->velocity->z;
// Color // Color
vert[j++] = p->color->x; vert[j++] = p->color->x;

View File

@ -9,12 +9,12 @@ typedef struct vector3f
} vector3f; } vector3f;
/* /*
* A particle has a position and a direction * A particle has a position and a velocity
*/ */
typedef struct particle typedef struct particle
{ {
vector3f *position; vector3f *position;
vector3f *direction; vector3f *velocity;
vector3f *color; vector3f *color;
float age; float age;
} particle; } particle;

View File

@ -0,0 +1,36 @@
#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[];
};
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
void main()
{
uint gid = gl_GlobalInvocationID.x;
particle part = p[gid];
if (part.age > 0)
{
part.pos += part.vel;
part.age -= 0.01f;
}
else
{
part.pos = vec3(0, 0, 0);
}
p[gid] = part;
}

View File

@ -1,10 +1,9 @@
#version 460 core #version 460 core
in vec3 col; // the input variable from the vertex shader (same name and same type) in vec3 col;
out vec4 colOut;
out vec4 outCol; void main(void)
void main()
{ {
outCol = vec4(vertexColor, 1.0); colOut = vec4(col, 1);
} }

View File

@ -0,0 +1,8 @@
#version 460 core
layout(points) in;
layout(points, max_vertices = 256) out;
void main(void)
{
}

30
shaders/RenderShader.glsl Normal file
View File

@ -0,0 +1,30 @@
#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;
}
}

19
shaders/UpdateShader.glsl Normal file
View File

@ -0,0 +1,19 @@
#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;
}

View File

@ -1,26 +1,8 @@
#version 460 core #version 460 core
layout (location = 0) in vec3 pos; // the position variable has attribute position 0 layout(location=0) in vec3 pos;
layout (location = 1) in vec3 dir; // the direction 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
//in vec3 emitterPos; // the emitter pos variable void main(void)
//in float newAge; // the age variable
out vec3 outCol; // output a color to the fragment shader
void main()
{ {
if (age < 0) gl_Position = vec4(pos, 0);
{
pos = emitterPos;
age = newAge;
}
age -= 0.1f;
vec3 newPos = pos.xyz + dir.xyz;
gl_Position = vec4(newPos, 1.0);
outCol = col; // set ourColor to the input color we got from the vertex data
} }