Shader
This commit is contained in:
parent
05038da3df
commit
38d326abca
@ -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.
|
||||||
|
@ -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] & <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] & <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">
|
||||||
|
@ -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] & <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] & <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>
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
50
initOpenGL.c
50
initOpenGL.c
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
319
main.c
319
main.c
@ -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"
|
||||||
"\n"
|
"#extension GL_ARB_compute_shader : enable\n"
|
||||||
"layout (location = 0) in vec3 pos; // the position variable has attribute position 0\n"
|
"#extension GL_ARB_shader_storage_buffer_object : enable\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"
|
"struct particle\n"
|
||||||
"layout (location = 3) in float age; // the age variable has attribute position 3\n"
|
"{\n"
|
||||||
"\n"
|
" vec3 pos;\n"
|
||||||
"//in vec3 emitterPos; // the emitter pos variable\n"
|
" vec3 vel;\n"
|
||||||
"//in float newAge; // the age variable\n"
|
" vec3 col;\n"
|
||||||
"\n"
|
" float age;\n"
|
||||||
"out vec3 outCol; // output a color to the fragment shader\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void main()\n"
|
"layout(std430, binding=0) buffer particles\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" if (age < 0)\n"
|
" particle p[];\n"
|
||||||
" {\n"
|
"};\n"
|
||||||
" //pos = vec3(0, 0, 0); //emitterPos;\n"
|
"\n"
|
||||||
" //age = 200; //newAge;\n"
|
"layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;\n"
|
||||||
" }\n"
|
"\n"
|
||||||
"\n"
|
"void main()\n"
|
||||||
" age -= 0.1f;\n"
|
"{\n"
|
||||||
" vec3 newPos = pos.xyz + dir.xyz;\n"
|
" uint gid = gl_GlobalInvocationID.x;\n"
|
||||||
" gl_Position = vec4(newPos, 1.0);\n"
|
" particle part = p[gid];\n"
|
||||||
"\n"
|
"\n"
|
||||||
" outCol = col; // set ourColor to the input color we got from the vertex data\n"
|
" if (part.age > 0)\n"
|
||||||
"}";
|
" {\n"
|
||||||
|
" part.pos += part.vel;\n"
|
||||||
|
" part.age -= 0.01f;\n"
|
||||||
|
" }\n"
|
||||||
|
" else\n"
|
||||||
|
" {\n"
|
||||||
|
" part.pos = vec3(0, 0, 0);\n"
|
||||||
|
" }\n"
|
||||||
|
" \n"
|
||||||
|
" p[gid] = part;\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;
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
36
shaders/ComputeShader.glsl
Normal file
36
shaders/ComputeShader.glsl
Normal 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;
|
||||||
|
}
|
@ -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);
|
||||||
}
|
}
|
8
shaders/GeometryShader.glsl
Normal file
8
shaders/GeometryShader.glsl
Normal 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
30
shaders/RenderShader.glsl
Normal 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
19
shaders/UpdateShader.glsl
Normal 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;
|
||||||
|
}
|
@ -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
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user