summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-12-06 19:13:20 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-12-06 19:13:20 -0500
commit2227e40af76aa10d87bbcce0f7df73d98407881b (patch)
tree02509a67a6095474cdd60df6a26b3dd4c80373de
parent950b3c95590aea7420e7dd4c7ae21ba0a0805ea6 (diff)
finish platform shader & ball shader
-rw-r--r--assets/ball_f.glsl19
-rw-r--r--assets/ball_v.glsl9
-rw-r--r--assets/platform_f.glsl2
-rw-r--r--assets/platform_v.glsl3
-rw-r--r--sim.c78
-rw-r--r--sim.h17
6 files changed, 113 insertions, 15 deletions
diff --git a/assets/ball_f.glsl b/assets/ball_f.glsl
new file mode 100644
index 0000000..e3dfdb3
--- /dev/null
+++ b/assets/ball_f.glsl
@@ -0,0 +1,19 @@
+varying vec4 color;
+varying vec2 pos;
+uniform vec2 center;
+uniform float radius;
+
+void main() {
+ float dist_squared = dot(pos - center, pos - center);
+ float threshold = 0.9 * radius; // radius border starts at
+ float thickness = radius - threshold;
+
+ if (dist_squared > threshold * threshold && dist_squared < radius * radius) {
+ float dist = sqrt(dist_squared);
+ float v = (dist - threshold) / thickness;
+ v = 2.0 * v - 1.0;
+ gl_FragColor = color * (1.0 - v * v);
+ } else {
+ discard;
+ }
+}
diff --git a/assets/ball_v.glsl b/assets/ball_v.glsl
new file mode 100644
index 0000000..7908bc7
--- /dev/null
+++ b/assets/ball_v.glsl
@@ -0,0 +1,9 @@
+varying vec4 color;
+varying vec2 pos;
+uniform mat4 transform;
+
+void main() {
+ gl_Position = transform * gl_Vertex;
+ pos = gl_Vertex.xy;
+ color = gl_Color;
+}
diff --git a/assets/platform_f.glsl b/assets/platform_f.glsl
index 1969a46..82c8740 100644
--- a/assets/platform_f.glsl
+++ b/assets/platform_f.glsl
@@ -5,11 +5,13 @@ uniform float thickness;
void main() {
// thanks to https://www.youtube.com/watch?v=PMltMdi1Wzg
+ // (calculates distance to line segment p1-p2)
float h = clamp(dot(pos-p1, p2-p1) / dot(p2-p1, p2-p1), 0.0, 1.0);
float d = length(pos - p1 - (p2-p1) * h);
float v = max(thickness - d, 0.0);
v /= thickness;
+ v *= v;
gl_FragColor = color * v;
}
diff --git a/assets/platform_v.glsl b/assets/platform_v.glsl
index 472f9df..8f57aab 100644
--- a/assets/platform_v.glsl
+++ b/assets/platform_v.glsl
@@ -4,9 +4,10 @@ varying vec4 color;
varying vec2 p1, p2;
varying vec2 pos;
uniform float thickness;
+uniform mat4 transform;
void main() {
- gl_Position = gl_Vertex;
+ gl_Position = transform * gl_Vertex;
pos = gl_Vertex.xy;
color = gl_Color;
#if 1
diff --git a/sim.c b/sim.c
index 2c0f67d..29b45c2 100644
--- a/sim.c
+++ b/sim.c
@@ -22,7 +22,7 @@
// compile a vertex or fragment shader
static GLuint shader_compile_from_file(GL *gl, char const *filename, GLenum shader_type) {
FILE *fp = fopen(filename, "rb");
- if (filename) {
+ if (fp) {
char code[16384] = {0};
char log[4096] = {0};
char const *const_code = code;
@@ -41,6 +41,7 @@ static GLuint shader_compile_from_file(GL *gl, char const *filename, GLenum shad
}
return shader;
} else {
+ logln("File does not exist: %s.", filename);
return 0;
}
}
@@ -124,16 +125,26 @@ static bool shader_needs_reloading(ShaderBase *shader) {
#endif
static void shader_platform_load(GL *gl, ShaderPlatform *shader) {
- shader_load(gl, &shader->base, "assets/platform_v.glsl", "assets/platform_f.glsl");
- shader->vertex_p1 = shader_attrib_location(gl, &shader->base, "vertex_p1");
- shader->vertex_p2 = shader_attrib_location(gl, &shader->base, "vertex_p2");
- shader->uniform_thickness = shader_uniform_location(gl, &shader->base, "thickness");
- // @TODO: transform matrix
+ ShaderBase *base = &shader->base;
+ shader_load(gl, base, "assets/platform_v.glsl", "assets/platform_f.glsl");
+ shader->vertex_p1 = shader_attrib_location(gl, base, "vertex_p1");
+ shader->vertex_p2 = shader_attrib_location(gl, base, "vertex_p2");
+ shader->uniform_thickness = shader_uniform_location(gl, base, "thickness");
+ shader->uniform_transform = shader_uniform_location(gl, base, "transform");
+}
+
+static void shader_ball_load(GL *gl, ShaderBall *shader) {
+ ShaderBase *base = &shader->base;
+ shader_load(gl, base, "assets/ball_v.glsl", "assets/ball_f.glsl");
+ shader->uniform_transform = shader_uniform_location(gl, base, "transform");
+ shader->uniform_center = shader_uniform_location(gl, base, "center");
+ shader->uniform_radius = shader_uniform_location(gl, base, "radius");
}
static void shaders_load(State *state) {
GL *gl = &state->gl;
shader_platform_load(gl, &state->shader_platform);
+ shader_ball_load(gl, &state->shader_ball);
}
#if DEBUG
@@ -141,18 +152,24 @@ static void shaders_reload_if_necessary(State *state) {
GL *gl = &state->gl;
if (shader_needs_reloading(&state->shader_platform.base))
shader_platform_load(gl, &state->shader_platform);
+ if (shader_needs_reloading(&state->shader_ball.base))
+ shader_ball_load(gl, &state->shader_ball);
}
#endif
-
+// render the given platforms
static void platforms_render(State *state, Platform *platforms, u32 nplatforms) {
GL *gl = &state->gl;
ShaderPlatform *shader = &state->shader_platform;
- glColor3f(1,0,1);
- float thickness = 0.01f;
+ float thickness = 0.005f;
+
shader_start_using(gl, &shader->base);
+
gl->Uniform1f(shader->uniform_thickness, thickness);
+ gl->UniformMatrix4fv(shader->uniform_transform, 1, GL_FALSE, state->transform.e);
+
glBegin(GL_QUADS);
+ glColor3f(1,0,1);
for (Platform *platform = platforms, *end = platform + nplatforms; platform != end; ++platform) {
// calculate endpoints of platform
maybe_unused float radius = platform->size * 0.5f;
@@ -176,6 +193,29 @@ static void platforms_render(State *state, Platform *platforms, u32 nplatforms)
shader_stop_using(gl);
}
+// render the ball
+static void ball_render(State *state) {
+ GL *gl = &state->gl;
+ float ball_x = 0.5f, ball_y = 0.8f;
+ float ball_r = 0.02f;
+ ShaderBall *shader = &state->shader_ball;
+
+ shader_start_using(gl, &shader->base);
+
+ gl->UniformMatrix4fv(shader->uniform_transform, 1, GL_FALSE, state->transform.e);
+ gl->Uniform2f(shader->uniform_center, ball_x, ball_y);
+ gl->Uniform1f(shader->uniform_radius, ball_r);
+
+ glBegin(GL_QUADS);
+ glColor3f(1,1,1);
+ glVertex2f(ball_x-ball_r, ball_y-ball_r);
+ glVertex2f(ball_x-ball_r, ball_y+ball_r);
+ glVertex2f(ball_x+ball_r, ball_y+ball_r);
+ glVertex2f(ball_x+ball_r, ball_y-ball_r);
+ glEnd();
+ shader_stop_using(gl);
+}
+
#ifdef _WIN32
__declspec(dllexport)
#endif
@@ -197,16 +237,24 @@ void sim_frame(Frame *frame) {
state->win_width = width;
state->win_height = height;
+ state->gl_width = (float)width / (float)height;
+ state->dt = (float)frame->dt;
+ state->transform = m4_ortho(0, state->gl_width, 0, 1, -1, +1);
+
// set up GL
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- //glOrtho(, -1, +1);
+ glOrtho(0, state->gl_width, 0, 1, -1, +1);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
+
+ if (keys_pressed[KEY_F5]) {
+ memset(state, 0, sizeof *state);
+ }
if (!state->initialized) {
@@ -252,11 +300,16 @@ void sim_frame(Frame *frame) {
shaders_load(state);
- state->nplatforms = 1;
+ state->nplatforms = 2;
Platform *p = &state->platforms[0];
p->center = V2(0.5f, 0.5f);
- p->angle = 0;//PIf * 0.3f;
+ p->angle = PIf * 0.3f;
p->size = 0.2f;
+ ++p;
+ p->center = V2(0.2f, 0.5f);
+ p->angle = PIf * 0.6f;
+ p->size = 0.1f;
+
state->initialized = true;
#if DEBUG
@@ -273,6 +326,7 @@ void sim_frame(Frame *frame) {
#endif
platforms_render(state, state->platforms, state->nplatforms);
+ ball_render(state);
#if DEBUG
GLuint error = glGetError();
diff --git a/sim.h b/sim.h
index e52023a..124efe5 100644
--- a/sim.h
+++ b/sim.h
@@ -90,12 +90,19 @@ typedef struct {
typedef GLuint VertexAttributeLocation;
typedef GLint UniformLocation;
+// shader for platforms
typedef struct {
ShaderBase base;
- VertexAttributeLocation vertex_p1, vertex_p2;
- UniformLocation uniform_thickness;
+ VertexAttributeLocation vertex_p1, vertex_p2; // endpoints of platform
+ UniformLocation uniform_thickness; // this is half the "width" of the platform
+ UniformLocation uniform_transform; // 4x4 matrix position is multiplied by
} ShaderPlatform;
+typedef struct {
+ ShaderBase base;
+ UniformLocation uniform_transform, uniform_center, uniform_radius;
+} ShaderBall;
+
typedef struct {
v2 center;
float size;
@@ -104,10 +111,16 @@ typedef struct {
typedef struct {
bool initialized;
+
i32 win_width, win_height; // width,height of window
+ float gl_width; // width of window in GL coordinates; height is always 1
+
+ float dt; // time in seconds since last frame
+ m4 transform; // the transform for converting our coordinates to GL coordinates
GL gl; // gl functions
ShaderPlatform shader_platform;
+ ShaderBall shader_ball;
u32 nplatforms;
Platform platforms[1000];