[RELEASE] u22-v03
This version is submitted to U22 breau.
This commit is contained in:
63
core/loshader/CMakeLists.txt
Normal file
63
core/loshader/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
add_library(loshader
|
||||
backwall.c
|
||||
bullet.c
|
||||
character.c
|
||||
cinescope.c
|
||||
combat_ring.c
|
||||
event_line.c
|
||||
fog.c
|
||||
ground.c
|
||||
hud_bar.c
|
||||
hud_text.c
|
||||
menu_background.c
|
||||
menu_stance.c
|
||||
menu_text.c
|
||||
pixsort.c
|
||||
posteffect.c
|
||||
set.c
|
||||
uniblock.c
|
||||
)
|
||||
target_any_sources(loshader
|
||||
backwall.vshader
|
||||
backwall.fshader
|
||||
bullet.vshader
|
||||
bullet.fshader
|
||||
character.vshader
|
||||
character.fshader
|
||||
cinescope.vshader
|
||||
cinescope.fshader
|
||||
combat_ring.vshader
|
||||
combat_ring.fshader
|
||||
event_line.vshader
|
||||
event_line.fshader
|
||||
fog.vshader
|
||||
fog.fshader
|
||||
ground.vshader
|
||||
ground.fshader
|
||||
header.shader
|
||||
hud_bar.vshader
|
||||
hud_bar.fshader
|
||||
hud_text.vshader
|
||||
hud_text.fshader
|
||||
menu_background.vshader
|
||||
menu_background.fshader
|
||||
menu_stance.vshader
|
||||
menu_stance.fshader
|
||||
menu_text.vshader
|
||||
menu_text.fshader
|
||||
pixsort.vshader
|
||||
pixsort.fshader
|
||||
posteffect.vshader
|
||||
posteffect.fshader
|
||||
)
|
||||
target_link_libraries(loshader
|
||||
GLEW::GLEW
|
||||
OpenGL::GL
|
||||
|
||||
gleasy
|
||||
glyphas
|
||||
math
|
||||
memory
|
||||
|
||||
locommon
|
||||
)
|
118
core/loshader/backwall.c
Normal file
118
core/loshader/backwall.c
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "./backwall.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/backwall.vshader.h"
|
||||
#include "anysrc/backwall.fshader.h"
|
||||
|
||||
struct loshader_backwall_drawer_t {
|
||||
const loshader_backwall_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
gleasy_buffer_uniform_t param;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
float type;
|
||||
float prev_type;
|
||||
float transition;
|
||||
} loshader_backwall_drawer_internal_param_t;
|
||||
_Static_assert(
|
||||
sizeof(float)*3 ==
|
||||
sizeof(loshader_backwall_drawer_internal_param_t));
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_BACKWALL_UNIBLOCK_INDEX 0
|
||||
#define LOSHADER_BACKWALL_PARAM_INDEX 1
|
||||
|
||||
#define LOSHADER_BACKWALL_PRIMITIVE_COUNT 6
|
||||
|
||||
void loshader_backwall_program_initialize(loshader_backwall_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_backwall_vshader_, sizeof(loshader_backwall_vshader_),
|
||||
loshader_backwall_fshader_, sizeof(loshader_backwall_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_BACKWALL_UNIBLOCK_INDEX);
|
||||
|
||||
const GLuint param = glGetUniformBlockIndex(*prog, "param");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, param, LOSHADER_BACKWALL_PARAM_INDEX);
|
||||
}
|
||||
|
||||
void loshader_backwall_program_deinitialize(loshader_backwall_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_backwall_drawer_t* loshader_backwall_drawer_new(
|
||||
const loshader_backwall_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_backwall_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glGenBuffers(1, &drawer->param);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(loshader_backwall_drawer_internal_param_t), NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_backwall_drawer_delete(loshader_backwall_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->param);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_backwall_drawer_set_param(
|
||||
loshader_backwall_drawer_t* drawer,
|
||||
const loshader_backwall_drawer_param_t* param) {
|
||||
assert(drawer != NULL);
|
||||
assert(param != NULL);
|
||||
|
||||
const loshader_backwall_drawer_internal_param_t p = {
|
||||
.type = param->type,
|
||||
.prev_type = param->prev_type,
|
||||
.transition = param->transition,
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(p), &p);
|
||||
}
|
||||
|
||||
void loshader_backwall_drawer_draw(const loshader_backwall_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_BACKWALL_UNIBLOCK_INDEX);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,
|
||||
LOSHADER_BACKWALL_PARAM_INDEX, drawer->param);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, LOSHADER_BACKWALL_PRIMITIVE_COUNT);
|
||||
}
|
220
core/loshader/backwall.fshader
Normal file
220
core/loshader/backwall.fshader
Normal file
@@ -0,0 +1,220 @@
|
||||
layout(std140) uniform param {
|
||||
float type;
|
||||
float prev_type;
|
||||
float transition;
|
||||
} p;
|
||||
|
||||
in vec2 v_uv;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
const float EPSILON = 1e-4;
|
||||
const float INF = 1e+2;
|
||||
|
||||
/* ---- UTILITY FUNCTIONS ---- */
|
||||
vec3 get_ray_direction(in vec2 p, in vec2 s, float fov) {
|
||||
return normalize(vec3(p*s/2., s.y/tan(radians(fov)/2.)));
|
||||
}
|
||||
mat2 rot(in float theta) {
|
||||
float c = cos(theta);
|
||||
float s = sin(theta);
|
||||
return mat2(c, -s, s, c);
|
||||
}
|
||||
#define get_normal(sdf, d, p) \
|
||||
normalize(d - vec3( \
|
||||
sdf(p-vec3(EPSILON, 0., 0.)), \
|
||||
sdf(p-vec3(0., EPSILON, 0.)), \
|
||||
sdf(p-vec3(0., 0., EPSILON))))
|
||||
|
||||
/* ---- SIGNED DISTANCE FUNCTIONS ---- */
|
||||
/* https://iquilezles.org/www/articles/distfunctions/distfunctions.htm */
|
||||
float sd_box( vec3 p, vec3 b ) {
|
||||
vec3 q = abs(p) - b;
|
||||
return length(max(q,0.)) + min(max(q.x,max(q.y,q.z)),0.);
|
||||
}
|
||||
float sd_round_box( vec3 p, vec3 b, float r ) {
|
||||
vec3 q = abs(p) - b;
|
||||
return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;
|
||||
}
|
||||
|
||||
/* ---- SCENE: infinite boxes ---- */
|
||||
float infinite_boxes_sd_scene(in vec3 p) {
|
||||
p = abs(p);
|
||||
p = mod(p, 2.) - 1.;
|
||||
return sd_box(p, vec3(.5));
|
||||
}
|
||||
vec3 infinite_boxes_raymarch(in vec2 uv, in vec3 eye) {
|
||||
vec3 dir = get_ray_direction(uv, uni.resolution, 60.);
|
||||
|
||||
float h = 2., d, i;
|
||||
for (i = 0.; i < 100.; ++i) {
|
||||
d = infinite_boxes_sd_scene(eye + dir*h);
|
||||
if (d < EPSILON || h > 100.) break;
|
||||
h += d;
|
||||
}
|
||||
float a = 45./(i+1.)/h;
|
||||
return mix(vec3(.3, .3, .4), vec3(.6, .8, .7), clamp(a, 0., 1.));
|
||||
}
|
||||
vec4 infinite_boxes(void) {
|
||||
vec2 e2 = vec2(0., 1.) / uni.resolution;
|
||||
|
||||
vec3 eye = vec3(0., fract(uni.time/60.)*2., 0.);
|
||||
|
||||
eye.xy += fract(uni.pos.xy/2.)*2. + uni.pos.zw - vec2(.5, .5);
|
||||
|
||||
vec3 col = infinite_boxes_raymarch(v_uv, eye);
|
||||
vec3 scol =
|
||||
infinite_boxes_raymarch(v_uv + e2, eye) +
|
||||
infinite_boxes_raymarch(v_uv - e2, eye);
|
||||
scol /= 2.;
|
||||
return vec4(mix(col, scol, .5), 1.);
|
||||
}
|
||||
|
||||
/* ---- SCENE: HOLLOW MOUNTAINS ---- */
|
||||
float hollow_mountains_sd_scene(in vec3 p, in vec3 v) {
|
||||
float s = 8., r;
|
||||
p = abs(mod(p, 2.) - 1.)*2.;
|
||||
for (float i = 0.; i < 5.; ++i) {
|
||||
p = 1. - abs(p-v);
|
||||
r = 1.4/dot(p, p);
|
||||
s *= r;
|
||||
p *= r;
|
||||
}
|
||||
return length(p)/s;
|
||||
}
|
||||
vec4 hollow_mountains(in vec3 color) {
|
||||
vec3 dir = get_ray_direction(v_uv, uni.resolution, 60.);
|
||||
|
||||
vec3 eye = vec3(0., 0., 0.);
|
||||
eye.xy = fract(uni.pos.xy/2.)*2. + uni.pos.zw;
|
||||
|
||||
float t = abs(fract(uni.time/20.)*2.-1.);
|
||||
t = t*t*(3.-2.*t);
|
||||
vec3 v = vec3(.9, 1., .94+t*.1);
|
||||
|
||||
float h = 1.3, d, i;
|
||||
for (i = 0.; i < 60.; ++i) {
|
||||
d = hollow_mountains_sd_scene(eye + dir*h, v);
|
||||
if (d < EPSILON || h > 100.) break;
|
||||
h += d;
|
||||
}
|
||||
|
||||
float a = 200./(i+1.)/h;
|
||||
return vec4(mix(vec3(.2, .2, .2), color, a), 1.);
|
||||
}
|
||||
|
||||
/* ---- SCENE: JAIL ---- */
|
||||
float jail_sd_scene(in vec3 p) {
|
||||
p = mod(p, 2.) - 1.;
|
||||
|
||||
float dist = INF;
|
||||
for (float i = 0.; i < 7.; ++i) {
|
||||
float t = PI/6.*i*2.;
|
||||
|
||||
vec3 p2 = p;
|
||||
p2.x += cos(t)*.1;
|
||||
p2.xz *= rot(t);
|
||||
p2.y += .4*(i-3.);
|
||||
|
||||
dist = min(dist, sd_box(p2, vec3(.19)));
|
||||
}
|
||||
return dist;
|
||||
}
|
||||
vec3 jail_raymarch(in vec2 uv, in vec3 eye) {
|
||||
vec3 dir = get_ray_direction(uv, uni.resolution.xy, 60.);
|
||||
|
||||
float h = 1.6, d, i;
|
||||
for (i = 0.; i < 20.; ++i) {
|
||||
d = jail_sd_scene(eye + dir*h);
|
||||
if (d < EPSILON || h > INF) break;
|
||||
h += d;
|
||||
}
|
||||
vec3 p = eye + dir*h;
|
||||
vec3 norm = get_normal(jail_sd_scene, d, p);
|
||||
|
||||
float diffuse = clamp(dot(vec3(0., 0., 1.), norm), 0., 1.);
|
||||
|
||||
float a = 3. + diffuse*.7;
|
||||
|
||||
a /= pow(h*.3, 2.) * (i*.2+1.);
|
||||
a = clamp(a, 0., 1.);
|
||||
|
||||
return mix(vec3(.2, .3, .3), vec3(.4, .4, .5), a) + vec3(.7, .4, .4)*a;
|
||||
}
|
||||
vec4 jail(void) {
|
||||
vec2 e1 = vec2(1., 0.)/uni.resolution.xy;
|
||||
vec2 e2 = vec2(0., 1.)/uni.resolution.xy;
|
||||
|
||||
vec3 eye = vec3(0., 0., -4.);
|
||||
|
||||
eye.xy += fract(uni.pos.xy/2.)*2. + uni.pos.zw + vec2(.5, .5);
|
||||
|
||||
vec3 col = jail_raymarch(v_uv, eye);
|
||||
vec3 scol =
|
||||
jail_raymarch(v_uv + e1 + e2, eye) +
|
||||
jail_raymarch(v_uv + e1 - e2, eye) +
|
||||
jail_raymarch(v_uv - e1 + e2, eye) +
|
||||
jail_raymarch(v_uv - e1 - e2, eye);
|
||||
scol /= 4.;
|
||||
return vec4(mix(col, scol, .5), 1.);
|
||||
}
|
||||
|
||||
/* ---- SCENE: fabric ---- */
|
||||
float fabric_sd_rope(in vec3 p) {
|
||||
p.yz *= rot(PI/8. + p.x*PI);
|
||||
return sd_round_box(p, vec3(2.5, .2, .2), .03);
|
||||
}
|
||||
float fabric_sd_scene(in vec3 p) {
|
||||
p = mod(p, 4.) - 2.;
|
||||
|
||||
vec3 p2 = p/sqrt(2.);
|
||||
p2.xy *= rot(PI/4.);
|
||||
p2.y = mod(p2.y, 2.) - 1.;
|
||||
float dist = fabric_sd_rope(p2);
|
||||
|
||||
p2 = p/sqrt(2.);
|
||||
p2.xy *= rot(-PI/4.);
|
||||
p2.y = mod(p2.y, 2.) - 1.;
|
||||
dist = min(dist, fabric_sd_rope(p2));
|
||||
|
||||
return dist;
|
||||
}
|
||||
vec4 fabric(void) {
|
||||
vec3 dir = get_ray_direction(v_uv, uni.resolution.xy, 80.);
|
||||
vec3 eye = vec3(0., 0., -4.);
|
||||
|
||||
eye.xy += uni.pos.zw*4.;
|
||||
|
||||
float h = 4.5, d, i;
|
||||
for (i = 0.; i < 50.; ++i) {
|
||||
d = fabric_sd_scene(eye + dir*h);
|
||||
if (d < EPSILON || h > INF) break;
|
||||
h += d;
|
||||
}
|
||||
|
||||
vec3 norm = get_normal(fabric_sd_scene, h, eye + dir*h);
|
||||
float diffuse = clamp(dot(vec3(0., 0., -1.), norm), .5, 1.);
|
||||
|
||||
float a = diffuse*.9 - .3;
|
||||
a /= pow(h*.08, 2.) * (i*.3+.5);
|
||||
a = clamp(a, 0., 1.);
|
||||
|
||||
vec3 col = mix(vec3(.25, .3, .2), vec3(.4, .6, .7), a) + vec3(1., .0, .0)*a;
|
||||
return vec4(col, 1.);
|
||||
}
|
||||
|
||||
vec4 scene(in float type) {
|
||||
return
|
||||
type == 1.? infinite_boxes():
|
||||
type == 2.? hollow_mountains(vec3(.1, .4, .1)):
|
||||
type == 3.? hollow_mountains(vec3(.4, .1, .1)):
|
||||
type == 4.? jail():
|
||||
type == 5.? fabric():
|
||||
vec4(1.);
|
||||
}
|
||||
void main(void) {
|
||||
vec4 prev = vec4(0.), next = vec4(0.);
|
||||
if (p.transition > 0.) next = clamp(scene(p.type), 0., 1.);
|
||||
if (p.transition < 1.) prev = clamp(scene(p.prev_type), 0., 1.);
|
||||
o_color = mix(prev, next, p.transition);
|
||||
}
|
60
core/loshader/backwall.h
Normal file
60
core/loshader/backwall.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_backwall_program_t;
|
||||
|
||||
struct loshader_backwall_drawer_t;
|
||||
typedef struct loshader_backwall_drawer_t loshader_backwall_drawer_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_BACKWALL_TYPE_WHITE = 0,
|
||||
LOSHADER_BACKWALL_TYPE_INFINITE_BOXES = 1,
|
||||
LOSHADER_BACKWALL_TYPE_HOLLOW_MOUNTAINS = 2,
|
||||
LOSHADER_BACKWALL_TYPE_HOLLOW_MOUNTAINS_RED = 3,
|
||||
LOSHADER_BACKWALL_TYPE_JAIL = 4,
|
||||
LOSHADER_BACKWALL_TYPE_FABRIC = 5,
|
||||
} loshader_backwall_type_t;
|
||||
|
||||
typedef struct {
|
||||
loshader_backwall_type_t type;
|
||||
loshader_backwall_type_t prev_type;
|
||||
|
||||
float transition;
|
||||
} loshader_backwall_drawer_param_t;
|
||||
|
||||
void
|
||||
loshader_backwall_program_initialize(
|
||||
loshader_backwall_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_backwall_program_deinitialize(
|
||||
loshader_backwall_program_t* prog
|
||||
);
|
||||
|
||||
loshader_backwall_drawer_t*
|
||||
loshader_backwall_drawer_new(
|
||||
const loshader_backwall_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_backwall_drawer_delete(
|
||||
loshader_backwall_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_backwall_drawer_set_param(
|
||||
loshader_backwall_drawer_t* drawer,
|
||||
const loshader_backwall_drawer_param_t* param
|
||||
);
|
||||
|
||||
void
|
||||
loshader_backwall_drawer_draw(
|
||||
const loshader_backwall_drawer_t* drawer
|
||||
);
|
11
core/loshader/backwall.vshader
Normal file
11
core/loshader/backwall.vshader
Normal file
@@ -0,0 +1,11 @@
|
||||
out vec2 v_uv;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., -1.),
|
||||
vec2(-1., 1.), vec2( 1., -1.), vec2( 1., 1.)
|
||||
);
|
||||
v_uv = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
|
||||
gl_Position = vec4(v_uv, 0., 1.);
|
||||
}
|
191
core/loshader/bullet.c
Normal file
191
core/loshader/bullet.c
Normal file
@@ -0,0 +1,191 @@
|
||||
#include "./bullet.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/bullet.vshader.h"
|
||||
#include "anysrc/bullet.fshader.h"
|
||||
|
||||
#define LOSHADER_BULLET_VSHADER_IN_BULLET_ID 0
|
||||
#define LOSHADER_BULLET_VSHADER_IN_POS 1
|
||||
#define LOSHADER_BULLET_VSHADER_IN_SIZE 2
|
||||
#define LOSHADER_BULLET_VSHADER_IN_THETA 3
|
||||
#define LOSHADER_BULLET_VSHADER_IN_TIME 4
|
||||
#define LOSHADER_BULLET_VSHADER_IN_COLOR 5
|
||||
|
||||
struct loshader_bullet_drawer_t {
|
||||
const loshader_bullet_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint16_t bullet_id;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
float theta;
|
||||
float time;
|
||||
|
||||
vec4_t color;
|
||||
} loshader_bullet_drawer_internal_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_BULLET_UNIBLOCK_INDEX 0
|
||||
|
||||
#define LOSHADER_BULLET_PRIMITIVE_COUNT 6
|
||||
|
||||
static void loshader_bullet_program_setup_vao_(
|
||||
gleasy_buffer_array_t instances) {
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
# define enable_attrib_(NAME, name, dim, type) do { \
|
||||
glEnableVertexAttribArray(LOSHADER_BULLET_VSHADER_IN_##NAME); \
|
||||
glVertexAttribPointer( \
|
||||
LOSHADER_BULLET_VSHADER_IN_##NAME, dim, type, GL_FALSE, \
|
||||
sizeof(loshader_bullet_drawer_internal_instance_t), \
|
||||
NULL + offsetof(loshader_bullet_drawer_internal_instance_t, name)); \
|
||||
glVertexAttribDivisor(LOSHADER_BULLET_VSHADER_IN_##NAME, 1); \
|
||||
} while (0)
|
||||
|
||||
enable_attrib_(BULLET_ID, bullet_id, 1, GL_UNSIGNED_SHORT);
|
||||
|
||||
enable_attrib_(POS, pos, 2, GL_FLOAT);
|
||||
enable_attrib_(SIZE, size, 2, GL_FLOAT);
|
||||
enable_attrib_(THETA, theta, 1, GL_FLOAT);
|
||||
enable_attrib_(TIME, time, 1, GL_FLOAT);
|
||||
|
||||
enable_attrib_(COLOR, color, 4, GL_FLOAT);
|
||||
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
void loshader_bullet_program_initialize(loshader_bullet_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_bullet_vshader_, sizeof(loshader_bullet_vshader_),
|
||||
loshader_bullet_fshader_, sizeof(loshader_bullet_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_BULLET_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_bullet_program_deinitialize(loshader_bullet_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_bullet_drawer_t* loshader_bullet_drawer_new(
|
||||
const loshader_bullet_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_bullet_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
loshader_bullet_program_setup_vao_(drawer->instances);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_bullet_drawer_delete(loshader_bullet_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_bullet_drawer_clear(
|
||||
loshader_bullet_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
drawer->instances_length = 0;
|
||||
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
reserve * sizeof(loshader_bullet_drawer_internal_instance_t),
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
|
||||
void loshader_bullet_drawer_add_instance(
|
||||
loshader_bullet_drawer_t* drawer,
|
||||
const loshader_bullet_drawer_instance_t* instance) {
|
||||
assert(drawer != NULL);
|
||||
assert(instance != NULL);
|
||||
|
||||
if (drawer->instances_length >= drawer->instances_reserved) {
|
||||
fprintf(stderr, "bullet drawer instance overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const loshader_bullet_drawer_internal_instance_t insta = {
|
||||
.bullet_id = instance->bullet_id,
|
||||
.pos = instance->pos,
|
||||
.size = instance->size,
|
||||
.theta = instance->theta,
|
||||
.time = instance->time,
|
||||
.color = instance->color,
|
||||
};
|
||||
|
||||
const size_t offset = drawer->instances_length * sizeof(insta);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(insta), &insta);
|
||||
|
||||
++drawer->instances_length;
|
||||
}
|
||||
|
||||
void loshader_bullet_drawer_draw(const loshader_bullet_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->instances_length == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_BULLET_UNIBLOCK_INDEX);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES,
|
||||
0, LOSHADER_BULLET_PRIMITIVE_COUNT, drawer->instances_length);
|
||||
}
|
53
core/loshader/bullet.fshader
Normal file
53
core/loshader/bullet.fshader
Normal file
@@ -0,0 +1,53 @@
|
||||
in vec2 v_aa;
|
||||
in float v_bullet_id;
|
||||
in vec2 v_uv;
|
||||
in vec2 v_size;
|
||||
in float v_time;
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
float dot(in vec2 p, in vec2 q) {
|
||||
return p.x*q.y - p.y*q.x;
|
||||
}
|
||||
|
||||
vec4 light(void) {
|
||||
vec4 color = v_color;
|
||||
color.a *= 1.-pow(length(v_uv), 1.5);
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 square(void) {
|
||||
vec4 color = v_color;
|
||||
|
||||
float t = 1.-v_time;
|
||||
|
||||
vec2 uv = abs(v_uv);
|
||||
color.a *= max(step(t-v_aa.x, uv.x), step(t-v_aa.y, uv.y));
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 triangle(void) {
|
||||
const vec2 disp = vec2(-1./12., 0.);
|
||||
|
||||
float t = 1. - v_time;
|
||||
vec2 v1 = vec2( 1., 0.)*t + disp*v_time;
|
||||
vec2 v2 = vec2(-1., -1.)*t + disp*v_time;
|
||||
vec2 v3 = vec2(-1., 1.)*t + disp*v_time;
|
||||
|
||||
float b1 = dot(v_uv-v2, v1-v2);
|
||||
float b2 = dot(v_uv-v3, v2-v3);
|
||||
float b3 = dot(v_uv-v1, v3-v1);
|
||||
|
||||
vec4 color = v_color;
|
||||
color.a *= b1*b2 > 0. && b2*b3 > 0.? 0.: 1.;
|
||||
return color;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
o_color =
|
||||
v_bullet_id == 0.? light():
|
||||
v_bullet_id == 1.? square():
|
||||
v_bullet_id == 2.? triangle():
|
||||
vec4(0.);
|
||||
}
|
68
core/loshader/bullet.h
Normal file
68
core/loshader/bullet.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_bullet_program_t;
|
||||
|
||||
struct loshader_bullet_drawer_t;
|
||||
typedef struct loshader_bullet_drawer_t loshader_bullet_drawer_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_BULLET_ID_LIGHT = 0,
|
||||
LOSHADER_BULLET_ID_SQUARE = 1,
|
||||
LOSHADER_BULLET_ID_TRIANGLE = 2,
|
||||
} loshader_bullet_id_t;
|
||||
|
||||
typedef struct {
|
||||
loshader_bullet_id_t bullet_id;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
float theta;
|
||||
float time;
|
||||
|
||||
vec4_t color;
|
||||
} loshader_bullet_drawer_instance_t;
|
||||
|
||||
void
|
||||
loshader_bullet_program_initialize(
|
||||
loshader_bullet_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_bullet_program_deinitialize(
|
||||
loshader_bullet_program_t* prog
|
||||
);
|
||||
|
||||
loshader_bullet_drawer_t*
|
||||
loshader_bullet_drawer_new(
|
||||
const loshader_bullet_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_bullet_drawer_delete(
|
||||
loshader_bullet_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_bullet_drawer_clear(
|
||||
loshader_bullet_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_bullet_drawer_add_instance(
|
||||
loshader_bullet_drawer_t* drawer,
|
||||
const loshader_bullet_drawer_instance_t* instance
|
||||
);
|
||||
|
||||
void
|
||||
loshader_bullet_drawer_draw(
|
||||
const loshader_bullet_drawer_t* drawer
|
||||
);
|
52
core/loshader/bullet.vshader
Normal file
52
core/loshader/bullet.vshader
Normal file
@@ -0,0 +1,52 @@
|
||||
layout (location = 0) in float i_bullet_id;
|
||||
layout (location = 1) in vec2 i_pos;
|
||||
layout (location = 2) in vec2 i_size;
|
||||
layout (location = 3) in float i_theta;
|
||||
layout (location = 4) in float i_time;
|
||||
layout (location = 5) in vec4 i_color;
|
||||
|
||||
out vec2 v_aa;
|
||||
out float v_bullet_id;
|
||||
out vec2 v_uv;
|
||||
out vec2 v_size;
|
||||
out float v_time;
|
||||
out vec4 v_color;
|
||||
|
||||
mat2 rot(in float theta) {
|
||||
float c = cos(theta);
|
||||
float s = sin(theta);
|
||||
return mat2(c, -s, s, c);
|
||||
}
|
||||
|
||||
vec2 square(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., -1.),
|
||||
vec2(-1., 1.), vec2( 1., -1.), vec2( 1., 1.)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
|
||||
vec2 triangle(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., 0.)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
v_bullet_id = i_bullet_id;
|
||||
v_time = i_time;
|
||||
v_color = i_color;
|
||||
|
||||
v_aa = uni.aa / (uni.proj * uni.cam * vec4(i_size, 0., 0.)).xy;
|
||||
|
||||
v_uv =
|
||||
i_bullet_id == 0.? square():
|
||||
i_bullet_id == 1.? square():
|
||||
i_bullet_id == 2.? triangle():
|
||||
vec2(0.);
|
||||
v_size = i_size;
|
||||
|
||||
gl_Position = uni.proj * uni.cam *
|
||||
vec4(rot(-i_theta)*(v_uv*i_size) + i_pos, 0., 1.);
|
||||
}
|
205
core/loshader/character.c
Normal file
205
core/loshader/character.c
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "./character.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/character.vshader.h"
|
||||
#include "anysrc/character.fshader.h"
|
||||
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_CHARACTER_ID 0
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_FROM_MOTION_ID 1
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_TO_MOTION_ID 2
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_MOTION_TIME 3
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_MARKER 4
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_MARKER_OFFSET 5
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_POS 6
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_SIZE 7
|
||||
#define LOSHADER_CHARACTER_VSHADER_IN_COLOR 8
|
||||
|
||||
struct loshader_character_drawer_t {
|
||||
const loshader_character_program_t* prog;
|
||||
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint16_t character_id;
|
||||
|
||||
uint16_t from_motion_id;
|
||||
uint16_t to_motion_id;
|
||||
float motion_time;
|
||||
|
||||
float marker;
|
||||
vec2_t marker_offset;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
vec4_t color;
|
||||
} loshader_character_drawer_internal_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_CHARACTER_UNIBLOCK_INDEX 0
|
||||
|
||||
#define LOSHADER_CHARACTER_PRIMITIVE_COUNT 54
|
||||
|
||||
static void loshader_character_program_setup_vao_(
|
||||
const loshader_character_program_t* prog, gleasy_buffer_array_t instances) {
|
||||
assert(prog != NULL);
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
# define enable_attrib_(NAME, name, dim, type) do { \
|
||||
glEnableVertexAttribArray(LOSHADER_CHARACTER_VSHADER_IN_##NAME); \
|
||||
glVertexAttribPointer( \
|
||||
LOSHADER_CHARACTER_VSHADER_IN_##NAME, dim, type, GL_FALSE, \
|
||||
sizeof(loshader_character_drawer_internal_instance_t), \
|
||||
NULL + offsetof(loshader_character_drawer_internal_instance_t, name)); \
|
||||
glVertexAttribDivisor(LOSHADER_CHARACTER_VSHADER_IN_##NAME, 1); \
|
||||
} while (0)
|
||||
|
||||
enable_attrib_(CHARACTER_ID, character_id, 1, GL_UNSIGNED_SHORT);
|
||||
enable_attrib_(FROM_MOTION_ID, from_motion_id, 1, GL_UNSIGNED_SHORT);
|
||||
enable_attrib_(TO_MOTION_ID, to_motion_id, 1, GL_UNSIGNED_SHORT);
|
||||
enable_attrib_(MOTION_TIME, motion_time, 1, GL_FLOAT);
|
||||
enable_attrib_(MARKER, marker, 1, GL_FLOAT);
|
||||
enable_attrib_(MARKER_OFFSET, marker_offset, 2, GL_FLOAT);
|
||||
|
||||
enable_attrib_(POS, pos, 2, GL_FLOAT);
|
||||
enable_attrib_(SIZE, size, 2, GL_FLOAT);
|
||||
enable_attrib_(COLOR, color, 4, GL_FLOAT);
|
||||
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
void loshader_character_program_initialize(loshader_character_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_character_vshader_, sizeof(loshader_character_vshader_),
|
||||
loshader_character_fshader_, sizeof(loshader_character_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_CHARACTER_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_character_program_deinitialize(
|
||||
loshader_character_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_character_drawer_t* loshader_character_drawer_new(
|
||||
const loshader_character_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_character_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
loshader_character_program_setup_vao_(drawer->prog, drawer->instances);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_character_drawer_delete(loshader_character_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_character_drawer_clear(
|
||||
loshader_character_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
drawer->instances_length = 0;
|
||||
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
reserve * sizeof(loshader_character_drawer_internal_instance_t),
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
|
||||
void loshader_character_drawer_add_instance(
|
||||
loshader_character_drawer_t* drawer,
|
||||
const loshader_character_drawer_instance_t* instance) {
|
||||
assert(drawer != NULL);
|
||||
assert(instance != NULL);
|
||||
|
||||
if (drawer->instances_length >= drawer->instances_reserved) {
|
||||
fprintf(stderr, "character drawer instance overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const loshader_character_drawer_internal_instance_t insta = {
|
||||
.character_id = instance->character_id,
|
||||
.from_motion_id = instance->from_motion_id,
|
||||
.to_motion_id = instance->to_motion_id,
|
||||
.motion_time = instance->motion_time,
|
||||
.marker = instance->marker,
|
||||
.marker_offset = instance->marker_offset,
|
||||
.pos = instance->pos,
|
||||
.size = instance->size,
|
||||
.color = instance->color,
|
||||
};
|
||||
|
||||
const size_t offset = drawer->instances_length * sizeof(insta);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(insta), &insta);
|
||||
|
||||
++drawer->instances_length;
|
||||
}
|
||||
|
||||
void loshader_character_drawer_draw(const loshader_character_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->instances_length == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_CHARACTER_UNIBLOCK_INDEX);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES,
|
||||
0, LOSHADER_CHARACTER_PRIMITIVE_COUNT, drawer->instances_length);
|
||||
}
|
7
core/loshader/character.fshader
Normal file
7
core/loshader/character.fshader
Normal file
@@ -0,0 +1,7 @@
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
o_color = v_color;
|
||||
}
|
85
core/loshader/character.h
Normal file
85
core/loshader/character.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_character_program_t;
|
||||
|
||||
struct loshader_character_drawer_t;
|
||||
typedef struct loshader_character_drawer_t loshader_character_drawer_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_CHARACTER_ID_PLAYER = 0,
|
||||
LOSHADER_CHARACTER_ID_ENCEPHALON = 1,
|
||||
LOSHADER_CHARACTER_ID_CAVIA = 2,
|
||||
LOSHADER_CHARACTER_ID_SCIENTIST = 3,
|
||||
LOSHADER_CHARACTER_ID_WARDER = 4,
|
||||
} loshader_character_id_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_CHARACTER_MOTION_ID_STAND1 = 0,
|
||||
LOSHADER_CHARACTER_MOTION_ID_STAND2 = 1,
|
||||
LOSHADER_CHARACTER_MOTION_ID_WALK = 2,
|
||||
LOSHADER_CHARACTER_MOTION_ID_ATTACK1 = 3,
|
||||
LOSHADER_CHARACTER_MOTION_ID_ATTACK2 = 4,
|
||||
LOSHADER_CHARACTER_MOTION_ID_SIT = 5,
|
||||
LOSHADER_CHARACTER_MOTION_ID_DOWN = 6,
|
||||
} loshader_character_motion_id_t;
|
||||
|
||||
typedef struct {
|
||||
loshader_character_id_t character_id;
|
||||
|
||||
uint32_t from_motion_id;
|
||||
uint32_t to_motion_id;
|
||||
float motion_time;
|
||||
|
||||
float marker;
|
||||
vec2_t marker_offset;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
vec4_t color;
|
||||
} loshader_character_drawer_instance_t;
|
||||
|
||||
void
|
||||
loshader_character_program_initialize(
|
||||
loshader_character_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_character_program_deinitialize(
|
||||
loshader_character_program_t* prog
|
||||
);
|
||||
|
||||
loshader_character_drawer_t* /* OWNERSHIP */
|
||||
loshader_character_drawer_new(
|
||||
const loshader_character_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_character_drawer_delete(
|
||||
loshader_character_drawer_t* drawer /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loshader_character_drawer_clear(
|
||||
loshader_character_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_character_drawer_add_instance(
|
||||
loshader_character_drawer_t* drawer,
|
||||
const loshader_character_drawer_instance_t* instance
|
||||
);
|
||||
|
||||
void
|
||||
loshader_character_drawer_draw(
|
||||
const loshader_character_drawer_t* drawer
|
||||
);
|
375
core/loshader/character.vshader
Normal file
375
core/loshader/character.vshader
Normal file
@@ -0,0 +1,375 @@
|
||||
layout (location = 0) in float i_character_id;
|
||||
layout (location = 1) in float i_from_motion_id;
|
||||
layout (location = 2) in float i_to_motion_id;
|
||||
layout (location = 3) in float i_motion_time;
|
||||
layout (location = 4) in float i_marker;
|
||||
layout (location = 5) in vec2 i_marker_offset;
|
||||
layout (location = 6) in vec2 i_pos;
|
||||
layout (location = 7) in vec2 i_size;
|
||||
layout (location = 8) in vec4 i_color;
|
||||
|
||||
out vec4 v_color;
|
||||
|
||||
const int vertex_count_ = 54;
|
||||
|
||||
const vec2[] marker_ = vec2[](
|
||||
vec2( 0., 1.), vec2(-1., -1.), vec2( 1., -1.)
|
||||
);
|
||||
const vec4 marker_color_ = vec4(1., 1., 1., .6);
|
||||
|
||||
vec2 player_stand1(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.125, 0.986), vec2(-0.125, 0.957), vec2( 0.250, 0.900),
|
||||
vec2(-0.125, 0.957), vec2(-0.175, 0.857), vec2( 0.250, 0.900),
|
||||
vec2(-0.175, 0.857), vec2(-0.275, 0.571), vec2( 0.075, 0.886),
|
||||
vec2(-0.050, 0.843), vec2(-0.275, 0.571), vec2( 0.000, 0.371),
|
||||
vec2( 0.150, 0.843), vec2( 0.150, 0.757), vec2( 0.225, 0.843),
|
||||
vec2( 0.075, 0.871), vec2( 0.125, 0.757), vec2( 0.125, 0.886),
|
||||
vec2( 0.075, 0.871), vec2( 0.025, 0.814), vec2( 0.125, 0.757),
|
||||
vec2( 0.000, 0.786), vec2( 0.000, 0.729), vec2( 0.075, 0.771),
|
||||
vec2( 0.025, 0.714), vec2( 0.025, 0.386), vec2( 0.200, 0.571),
|
||||
vec2( 0.125, 0.457), vec2( 0.025, 0.371), vec2( 0.200, 0.157),
|
||||
vec2(-0.025, 0.371), vec2(-0.200, 0.186), vec2( 0.225, 0.086),
|
||||
vec2(-0.200, 0.157), vec2( 0.150, -0.371), vec2( 0.225, 0.071),
|
||||
vec2( 0.150, -0.371), vec2(-0.075, -0.571), vec2( 0.100, -0.857),
|
||||
vec2( 0.100, -0.857), vec2( 0.000, -1.000), vec2( 0.500, -1.000),
|
||||
vec2(-0.200, 0.157), vec2( 0.150, -0.371), vec2( 0.225, 0.071),
|
||||
vec2( 0.150, -0.371), vec2(-0.075, -0.571), vec2( 0.100, -0.857),
|
||||
vec2( 0.100, -0.857), vec2( 0.000, -1.000), vec2( 0.500, -1.000)
|
||||
);
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
return p*vec2(4./7., 1.);
|
||||
}
|
||||
vec2 player_stand2(void) {
|
||||
return player_stand1()*vec2(1., .95) + vec2(0., -.05);
|
||||
}
|
||||
vec2 player_walk(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.125, 0.986), vec2(-0.125, 0.957), vec2( 0.250, 0.900),
|
||||
vec2(-0.125, 0.957), vec2(-0.175, 0.857), vec2( 0.250, 0.900),
|
||||
vec2(-0.175, 0.857), vec2(-0.275, 0.571), vec2( 0.075, 0.886),
|
||||
vec2(-0.050, 0.843), vec2(-0.275, 0.571), vec2( 0.000, 0.371),
|
||||
vec2( 0.150, 0.843), vec2( 0.150, 0.757), vec2( 0.225, 0.843),
|
||||
vec2( 0.075, 0.871), vec2( 0.125, 0.757), vec2( 0.125, 0.886),
|
||||
vec2( 0.075, 0.871), vec2( 0.025, 0.814), vec2( 0.125, 0.757),
|
||||
vec2( 0.000, 0.786), vec2( 0.000, 0.729), vec2( 0.075, 0.771),
|
||||
vec2( 0.025, 0.714), vec2( 0.025, 0.386), vec2( 0.200, 0.571),
|
||||
vec2( 0.125, 0.457), vec2( 0.025, 0.371), vec2( 0.200, 0.157),
|
||||
vec2(-0.025, 0.371), vec2(-0.200, 0.186), vec2( 0.225, 0.086),
|
||||
vec2(-0.200, 0.157), vec2( 0.450, -0.371), vec2( 0.225, 0.071),
|
||||
vec2( 0.450, -0.371), vec2( 0.325, -0.571), vec2( 0.350, -0.857),
|
||||
vec2( 0.350, -0.857), vec2( 0.275, -1.000), vec2( 0.950, -1.000),
|
||||
vec2(-0.200, 0.157), vec2(-0.200, -0.371), vec2( 0.225, 0.071),
|
||||
vec2(-0.200, -0.371), vec2(-0.450, -0.471), vec2(-0.600, -0.857),
|
||||
vec2(-0.625, -0.857), vec2(-0.625, -1.000), vec2(-0.250, -1.000)
|
||||
);
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
return p*vec2(4./7., .95) + vec2(0., -.05);
|
||||
}
|
||||
vec2 player(in float motion_id) {
|
||||
return
|
||||
(motion_id == 0.)? player_stand1():
|
||||
(motion_id == 1.)? player_stand2():
|
||||
(motion_id == 2.)? player_walk():
|
||||
vec2(0.);
|
||||
}
|
||||
|
||||
vec2 encephalon(in float motion_id) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.833, -0.783), vec2(-1.000, -1.000), vec2( 1.000, -1.000),
|
||||
vec2(-.8333, -0.783), vec2( 1.000, -1.000), vec2( 0.833, -0.783),
|
||||
vec2( 0.117, -0.367), vec2( 0.000, -0.750), vec2( 0.300, -0.533),
|
||||
vec2( 0.117, 0.050), vec2(-0.083, -0.117), vec2( 0.367, -0.517),
|
||||
vec2(-0.050, 0.283), vec2(-0.133, -0.117), vec2( 0.117, 0.083),
|
||||
vec2( 0.500, 0.500), vec2(-0.050, 0.333), vec2( 0.150, 0.133),
|
||||
vec2( 0.250, 0.917), vec2(-0.233, 0.317), vec2( 0.500, 0.533),
|
||||
vec2( 0.217, 0.917), vec2(-0.300, 0.817), vec2(-0.283, 0.333),
|
||||
vec2(-0.333, 0.783), vec2(-0.500, 0.567), vec2(-0.333, 0.333)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
|
||||
vec2 cavia_stand1(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.06, 1.00), vec2(-0.16, 0.72), vec2( 0.36, 0.58),
|
||||
vec2( 0.00, 0.66), vec2(-0.20, 0.46), vec2(-0.04, 0.20),
|
||||
vec2( 0.02, 0.58), vec2( 0.00, 0.20), vec2( 0.14, 0.42),
|
||||
vec2(-0.20, 0.40), vec2(-0.20, 0.12), vec2( 0.12, -0.04),
|
||||
vec2( 0.06, 0.24), vec2( 0.00, 0.16), vec2( 0.06, 0.08),
|
||||
vec2(-0.18, 0.08), vec2( 0.06, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.06, -0.44), vec2(-0.06, -0.58), vec2( 0.08, -0.90),
|
||||
vec2( 0.08, -0.90), vec2( 0.00, -1.00), vec2( 0.30, -1.00),
|
||||
vec2(-0.18, 0.08), vec2( 0.06, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.06, -0.44), vec2(-0.06, -0.58), vec2( 0.08, -0.90),
|
||||
vec2( 0.08, -0.90), vec2( 0.00, -1.00), vec2( 0.30, -1.00)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 cavia_walk(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.06, 1.00), vec2(-0.16, 0.72), vec2( 0.36, 0.58),
|
||||
vec2( 0.00, 0.66), vec2(-0.20, 0.46), vec2(-0.04, 0.20),
|
||||
vec2( 0.02, 0.58), vec2( 0.00, 0.20), vec2( 0.14, 0.42),
|
||||
vec2(-0.20, 0.40), vec2(-0.20, 0.12), vec2( 0.12, -0.04),
|
||||
vec2( 0.06, 0.24), vec2( 0.00, 0.16), vec2( 0.06, 0.08),
|
||||
vec2(-0.18, 0.08), vec2(-0.18, -0.40), vec2( 0.06, -0.04),
|
||||
vec2(-0.20, -0.42), vec2(-0.36, -0.42), vec2(-0.58, -0.90),
|
||||
vec2(-0.58, -0.90), vec2(-0.62, -1.00), vec2(-0.32, -1.00),
|
||||
vec2(-0.18, 0.08), vec2( 0.28, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.28, -0.40), vec2( 0.20, -0.56), vec2( 0.42, -0.90),
|
||||
vec2( 0.42, -0.90), vec2( 0.40, -1.00), vec2( 0.70, -1.00)
|
||||
);
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
return p*vec2(1., .95) + vec2(0., -.05);
|
||||
}
|
||||
vec2 cavia_attack1(void) {
|
||||
return cavia_stand1()*vec2(1., 1.05) + vec2(0., .05);
|
||||
}
|
||||
vec2 cavia_attack2(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.18, 0.94), vec2(-0.08, 0.70), vec2( 0.34, 0.46),
|
||||
vec2( 0.06, 0.64), vec2(-0.20, 0.46), vec2(-0.04, 0.20),
|
||||
vec2( 0.08, 0.56), vec2( 0.00, 0.20), vec2( 0.14, 0.42),
|
||||
vec2(-0.20, 0.40), vec2(-0.20, 0.12), vec2( 0.12, -0.04),
|
||||
vec2( 0.06, 0.24), vec2( 0.00, 0.16), vec2( 0.06, 0.08),
|
||||
vec2(-0.18, 0.08), vec2( 0.06, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.06, -0.44), vec2(-0.06, -0.58), vec2( 0.08, -0.90),
|
||||
vec2( 0.08, -0.90), vec2( 0.00, -1.00), vec2( 0.30, -1.00),
|
||||
vec2(-0.18, 0.08), vec2( 0.06, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.06, -0.44), vec2(-0.06, -0.58), vec2( 0.08, -0.90),
|
||||
vec2( 0.08, -0.90), vec2( 0.00, -1.00), vec2( 0.30, -1.00)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 cavia_sit(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.30, 0.40), vec2( 0.00, 0.18), vec2( 0.58, -0.02),
|
||||
vec2( 0.12, 0.10), vec2(-0.22, -0.08), vec2(-0.10, -0.28),
|
||||
vec2( 0.10, -0.02), vec2(-0.08, -0.30), vec2( 0.12, -0.20),
|
||||
vec2(-0.24, -0.10), vec2(-0.28, -0.38), vec2(-0.04, -0.48),
|
||||
vec2( 0.04, -0.26), vec2(-0.10, -0.32), vec2(-0.04, -0.42),
|
||||
vec2(-0.26, -0.42), vec2( 0.00, -1.00), vec2(-0.06, -0.50),
|
||||
vec2( 0.00, -1.00), vec2(-0.08, -0.86), vec2(-0.50, -0.92),
|
||||
vec2(-0.50, -0.92), vec2(-0.54, -0.80), vec2(-0.76, -1.00),
|
||||
vec2(-0.26, -0.42), vec2( 0.00, -1.00), vec2(-0.06, -0.50),
|
||||
vec2( 0.00, -1.00), vec2(-0.08, -0.86), vec2(-0.50, -0.92),
|
||||
vec2(-0.50, -0.92), vec2(-0.54, -0.80), vec2(-0.76, -1.00)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 cavia_down(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.78, -0.50), vec2( 0.46, -0.44), vec2( 0.66, -1.00),
|
||||
vec2( 0.50, -0.58), vec2(-0.16, -0.38), vec2(-0.10, -0.54),
|
||||
vec2( 0.38, -0.60), vec2(-0.02, -0.56), vec2( 0.24, -0.70),
|
||||
vec2(-0.20, -0.40), vec2(-0.28, -0.60), vec2(-0.14, -0.60),
|
||||
vec2(-0.02, -0.60), vec2(-0.10, -0.58), vec2(-0.08, -0.60),
|
||||
vec2(-0.38, -0.62), vec2( 0.00, -1.00), vec2(-0.16, -0.62),
|
||||
vec2( 0.00, -1.00), vec2(-0.18, -0.86), vec2(-0.50, -0.92),
|
||||
vec2(-0.50, -0.92), vec2(-0.54, -0.80), vec2(-0.76, -1.00),
|
||||
vec2(-0.38, -0.62), vec2( 0.00, -1.00), vec2(-0.16, -0.62),
|
||||
vec2( 0.00, -1.00), vec2(-0.18, -0.86), vec2(-0.50, -0.92),
|
||||
vec2(-0.50, -0.92), vec2(-0.54, -0.80), vec2(-0.76, -1.00)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 cavia(in float motion_id) {
|
||||
return
|
||||
(motion_id == 0.)? cavia_stand1():
|
||||
(motion_id == 2.)? cavia_walk():
|
||||
(motion_id == 3.)? cavia_attack1():
|
||||
(motion_id == 4.)? cavia_attack2():
|
||||
(motion_id == 5.)? cavia_sit():
|
||||
(motion_id == 6.)? cavia_down():
|
||||
vec2(0.);
|
||||
}
|
||||
|
||||
vec2 scientist_stand1(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.050, 0.982), vec2(-0.150, 0.764), vec2( 0.400, 0.655),
|
||||
vec2(-0.050, 0.727), vec2(-0.475, 0.436), vec2( 0.225, 0.143),
|
||||
vec2(-0.475, 0.418), vec2(-0.400, -0.709), vec2( 0.225, 0.127),
|
||||
vec2( 0.225, 0.111), vec2(-0.400, -0.725), vec2( 0.225, -0.709),
|
||||
vec2( 0.025, 0.673), vec2( 0.200, 0.255), vec2( 0.175, 0.636),
|
||||
vec2( 0.000, -0.418), vec2(-0.150, -0.509), vec2(-0.075, -0.909),
|
||||
vec2(-0.075, -0.909), vec2(-0.150, -1.000), vec2( 0.200, -1.000),
|
||||
vec2( 0.000, -0.418), vec2(-0.150, -0.509), vec2(-0.075, -0.909),
|
||||
vec2(-0.075, -0.909), vec2(-0.150, -1.000), vec2( 0.200, -1.000)
|
||||
);
|
||||
return gl_VertexID < verts.length()?
|
||||
verts[gl_VertexID]*vec2(.8, 1.): vec2(0.);
|
||||
}
|
||||
vec2 scientist_stand2(void) {
|
||||
return scientist_stand1() + (gl_VertexID < 5*3? vec2(0., -.05): vec2(0.));
|
||||
}
|
||||
vec2 scientist_attack1(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.475, 0.982), vec2(-0.400, 0.727), vec2( 0.225, 0.927),
|
||||
vec2(-0.225, 0.764), vec2(-0.675, 0.455), vec2( 0.225, 0.127),
|
||||
vec2(-0.700, 0.418), vec2(-0.400, -0.709), vec2( 0.225, 0.127),
|
||||
vec2( 0.225, 0.127), vec2(-0.400, -0.709), vec2( 0.350, -0.709),
|
||||
vec2(-0.125, 0.727), vec2( 0.150, 0.309), vec2( 0.050, 0.691),
|
||||
vec2( 0.000, -0.418), vec2(-0.150, -0.509), vec2(-0.075, -0.909),
|
||||
vec2(-0.075, -0.909), vec2(-0.150, -1.000), vec2( 0.200, -1.000),
|
||||
vec2( 0.000, -0.418), vec2(-0.150, -0.509), vec2(-0.075, -0.909),
|
||||
vec2(-0.075, -0.909), vec2(-0.150, -1.000), vec2( 0.200, -1.000)
|
||||
);
|
||||
return gl_VertexID < verts.length()?
|
||||
verts[gl_VertexID]*vec2(.8, 1.): vec2(0.);
|
||||
}
|
||||
vec2 scientist_sit(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.050, 0.782), vec2(-0.150, 0.564), vec2( 0.400, 0.455),
|
||||
vec2(-0.050, 0.527), vec2(-0.475, 0.236), vec2( 0.225, -0.143),
|
||||
vec2(-0.475, 0.218), vec2(-0.400, -0.909), vec2( 0.225, -0.127),
|
||||
vec2( 0.225, -0.111), vec2(-0.400, -0.925), vec2( 0.225, -0.909),
|
||||
vec2( 0.025, 0.473), vec2( 0.200, 0.055), vec2( 0.175, 0.436),
|
||||
vec2( 0.000, -0.418), vec2(-0.150, -0.509), vec2(-0.075, -0.909),
|
||||
vec2(-0.075, -0.909), vec2(-0.150, -1.000), vec2( 0.200, -1.000),
|
||||
vec2( 0.000, -0.418), vec2(-0.150, -0.509), vec2(-0.075, -0.909),
|
||||
vec2(-0.075, -0.909), vec2(-0.150, -1.000), vec2( 0.200, -1.000)
|
||||
);
|
||||
return gl_VertexID < verts.length()?
|
||||
verts[gl_VertexID]*vec2(.8, 1.): vec2(0.);
|
||||
}
|
||||
vec2 scientist(in float motion_id) {
|
||||
return
|
||||
(motion_id == 0.)? scientist_stand1():
|
||||
(motion_id == 1.)? scientist_stand2():
|
||||
(motion_id == 3.)? scientist_attack1():
|
||||
(motion_id == 5.)? scientist_sit():
|
||||
vec2(0.);
|
||||
}
|
||||
|
||||
vec2 warder_stand1(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.10, 0.96), vec2(-0.24, 0.76), vec2( 0.22, 0.94),
|
||||
vec2( 0.08, 0.84), vec2(-0.20, 0.70), vec2( 0.04, 0.70),
|
||||
vec2(-0.10, 0.68), vec2(-0.24, 0.48), vec2(-0.08, 0.10),
|
||||
vec2(-0.08, 0.60), vec2(-0.04, 0.12), vec2( 0.06, 0.42),
|
||||
vec2(-0.22, 0.32), vec2(-0.26, 0.16), vec2(-0.06, 0.04),
|
||||
vec2( 0.02, 0.20), vec2(-0.04, 0.04), vec2( 0.04, 0.00),
|
||||
vec2(-0.24, 0.12), vec2( 0.00, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.00, -0.42), vec2(-0.14, -0.54), vec2( 0.00, -0.90),
|
||||
vec2( 0.00, -0.90), vec2(-0.04, -1.00), vec2( 0.24, -1.00),
|
||||
vec2(-0.24, 0.12), vec2( 0.00, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.00, -0.42), vec2(-0.14, -0.54), vec2( 0.00, -0.90),
|
||||
vec2( 0.00, -0.90), vec2(-0.04, -1.00), vec2( 0.24, -1.00),
|
||||
vec2(-0.26, -0.04), vec2(-0.24, -0.08), vec2( 0.58, 0.20)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 warder_walk(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.10, 0.96), vec2(-0.24, 0.76), vec2( 0.22, 0.94),
|
||||
vec2( 0.08, 0.84), vec2(-0.20, 0.70), vec2( 0.04, 0.70),
|
||||
vec2(-0.10, 0.68), vec2(-0.24, 0.48), vec2(-0.08, 0.10),
|
||||
vec2(-0.08, 0.60), vec2(-0.04, 0.12), vec2( 0.06, 0.42),
|
||||
vec2(-0.22, 0.32), vec2(-0.26, 0.16), vec2(-0.06, 0.04),
|
||||
vec2( 0.02, 0.20), vec2(-0.04, 0.04), vec2( 0.04, 0.00),
|
||||
vec2(-0.24, 0.12), vec2(-0.34, -0.40), vec2( 0.06, -0.04),
|
||||
vec2(-0.34, -0.42), vec2(-0.50, -0.46), vec2(-0.62, -0.90),
|
||||
vec2(-0.62, -0.90), vec2(-0.66, -1.00), vec2(-0.40, -1.00),
|
||||
vec2(-0.24, 0.12), vec2( 0.30, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.30, -0.40), vec2( 0.22, -0.56), vec2( 0.44, -0.90),
|
||||
vec2( 0.44, -0.90), vec2( 0.40, -1.00), vec2( 0.66, -1.00),
|
||||
vec2(-0.08, -0.08), vec2(-0.06, -0.12), vec2( 0.74, 0.20)
|
||||
);
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
return p*vec2(1., .95) + vec2(0., -.05);
|
||||
}
|
||||
vec2 warder_attack1(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.10, 0.96), vec2(-0.24, 0.76), vec2( 0.22, 0.94),
|
||||
vec2( 0.08, 0.84), vec2(-0.20, 0.70), vec2( 0.04, 0.70),
|
||||
vec2(-0.10, 0.68), vec2(-0.24, 0.48), vec2(-0.08, 0.10),
|
||||
vec2(-0.08, 0.60), vec2(-0.04, 0.12), vec2( 0.06, 0.42),
|
||||
vec2(-0.22, 0.32), vec2(-0.26, 0.16), vec2(-0.06, 0.04),
|
||||
vec2( 0.02, 0.20), vec2(-0.04, 0.04), vec2( 0.04, 0.00),
|
||||
vec2(-0.24, 0.12), vec2(-0.34, -0.40), vec2( 0.06, -0.04),
|
||||
vec2(-0.34, -0.42), vec2(-0.50, -0.46), vec2(-0.62, -0.90),
|
||||
vec2(-0.62, -0.90), vec2(-0.66, -1.00), vec2(-0.40, -1.00),
|
||||
vec2(-0.24, 0.12), vec2( 0.30, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.30, -0.40), vec2( 0.22, -0.56), vec2( 0.44, -0.90),
|
||||
vec2( 0.44, -0.90), vec2( 0.40, -1.00), vec2( 0.66, -1.00),
|
||||
vec2(-0.56, 0.32), vec2(-0.56, 0.28), vec2( 0.30, 0.30)
|
||||
);
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
return p*vec2(1., .95) + vec2(0., -.05);
|
||||
}
|
||||
vec2 warder_attack2(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.10, 0.96), vec2(-0.24, 0.76), vec2( 0.22, 0.94),
|
||||
vec2( 0.08, 0.84), vec2(-0.20, 0.70), vec2( 0.04, 0.70),
|
||||
vec2(-0.10, 0.68), vec2(-0.24, 0.48), vec2(-0.08, 0.10),
|
||||
vec2(-0.08, 0.60), vec2(-0.04, 0.12), vec2( 0.06, 0.42),
|
||||
vec2(-0.22, 0.32), vec2(-0.26, 0.16), vec2(-0.06, 0.04),
|
||||
vec2( 0.02, 0.20), vec2(-0.04, 0.04), vec2( 0.04, 0.00),
|
||||
vec2(-0.24, 0.12), vec2(-0.34, -0.40), vec2( 0.06, -0.04),
|
||||
vec2(-0.34, -0.42), vec2(-0.50, -0.46), vec2(-0.62, -0.90),
|
||||
vec2(-0.62, -0.90), vec2(-0.66, -1.00), vec2(-0.40, -1.00),
|
||||
vec2(-0.24, 0.12), vec2( 0.30, -0.40), vec2( 0.06, -0.04),
|
||||
vec2( 0.30, -0.40), vec2( 0.22, -0.56), vec2( 0.44, -0.90),
|
||||
vec2( 0.44, -0.90), vec2( 0.40, -1.00), vec2( 0.66, -1.00),
|
||||
vec2( 0.12, 0.32), vec2( 0.12, 0.28), vec2( 0.96, 0.30)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 warder_down(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.80, -1.00), vec2(-0.64, -1.00), vec2(-0.86, -0.62),
|
||||
vec2(-0.76, -0.72), vec2(-0.58, -1.00), vec2(-0.64, -0.72),
|
||||
vec2(-0.58, -0.86), vec2(-0.44, -0.98), vec2( 0.00, -0.82),
|
||||
vec2(-0.50, -0.82), vec2( 0.00, -0.80), vec2(-0.36, -0.70),
|
||||
vec2(-0.18, -0.92), vec2( 0.04, -1.00), vec2( 0.04, -0.82),
|
||||
vec2(-0.12, -0.72), vec2( 0.04, -0.80), vec2( 0.04, -0.52),
|
||||
vec2( 0.06, -1.00), vec2( 0.30, -0.46), vec2( 0.06, -0.54),
|
||||
vec2( 0.30, -0.46), vec2( 0.30, -0.74), vec2( 0.50, -0.90),
|
||||
vec2( 0.50, -0.90), vec2( 0.46, -1.00), vec2( 0.70, -1.00),
|
||||
vec2( 0.06, -1.00), vec2( 0.30, -0.46), vec2( 0.06, -0.54),
|
||||
vec2( 0.30, -0.46), vec2( 0.30, -0.74), vec2( 0.50, -0.90),
|
||||
vec2( 0.50, -0.90), vec2( 0.46, -1.00), vec2( 0.70, -1.00),
|
||||
vec2(-0.06, -0.96), vec2(-0.06, -1.00), vec2( 0.80, -1.00)
|
||||
);
|
||||
return gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
}
|
||||
vec2 warder(in float motion_id) {
|
||||
return
|
||||
(motion_id == 0.)? warder_stand1():
|
||||
(motion_id == 2.)? warder_walk():
|
||||
(motion_id == 3.)? warder_attack1():
|
||||
(motion_id == 4.)? warder_attack2():
|
||||
(motion_id == 6.)? warder_down():
|
||||
vec2(0.);
|
||||
}
|
||||
|
||||
vec2 get_vert(in float motion_id) {
|
||||
return
|
||||
(i_character_id == 0.)? player(motion_id):
|
||||
(i_character_id == 1.)? encephalon(motion_id):
|
||||
(i_character_id == 2.)? cavia(motion_id):
|
||||
(i_character_id == 3.)? scientist(motion_id):
|
||||
(i_character_id == 4.)? warder(motion_id):
|
||||
vec2(0.);
|
||||
}
|
||||
void main(void) {
|
||||
if (gl_VertexID < vertex_count_-3) {
|
||||
v_color = i_color;
|
||||
|
||||
vec2 p = mix(
|
||||
get_vert(i_from_motion_id),
|
||||
get_vert(i_to_motion_id),
|
||||
i_motion_time);
|
||||
gl_Position = uni.proj * uni.cam * vec4(p*i_size+i_pos, 0., 1.);
|
||||
|
||||
} else {
|
||||
v_color = marker_color_;
|
||||
v_color.a *= i_marker;
|
||||
|
||||
vec2 p = marker_[gl_VertexID - (vertex_count_-3)];
|
||||
p *= uni.dpi*.03 / uni.resolution * 2.;
|
||||
|
||||
gl_Position = uni.proj * uni.cam * vec4(i_pos+i_marker_offset, 0., 1.);
|
||||
gl_Position.xy += p;
|
||||
}
|
||||
}
|
116
core/loshader/cinescope.c
Normal file
116
core/loshader/cinescope.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "./cinescope.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/cinescope.vshader.h"
|
||||
#include "anysrc/cinescope.fshader.h"
|
||||
|
||||
struct loshader_cinescope_drawer_t {
|
||||
const loshader_cinescope_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
gleasy_buffer_uniform_t param;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
vec4_t color;
|
||||
float size;
|
||||
} loshader_cinescope_drawer_internal_param_t;
|
||||
_Static_assert(
|
||||
sizeof(float)*5 ==
|
||||
sizeof(loshader_cinescope_drawer_internal_param_t));
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_CINESCOPE_UNIBLOCK_INDEX 0
|
||||
#define LOSHADER_CINESCOPE_PARAM_INDEX 1
|
||||
|
||||
#define LOSHADER_CINESCOPE_PRIMITIVE_COUNT 12
|
||||
|
||||
void loshader_cinescope_program_initialize(loshader_cinescope_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_cinescope_vshader_, sizeof(loshader_cinescope_vshader_),
|
||||
loshader_cinescope_fshader_, sizeof(loshader_cinescope_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_CINESCOPE_UNIBLOCK_INDEX);
|
||||
|
||||
const GLuint param = glGetUniformBlockIndex(*prog, "param");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, param, LOSHADER_CINESCOPE_PARAM_INDEX);
|
||||
}
|
||||
|
||||
void loshader_cinescope_program_deinitialize(loshader_cinescope_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_cinescope_drawer_t* loshader_cinescope_drawer_new(
|
||||
const loshader_cinescope_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_cinescope_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glGenBuffers(1, &drawer->param);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(loshader_cinescope_drawer_internal_param_t), NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_cinescope_drawer_delete(loshader_cinescope_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->param);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_cinescope_drawer_set_param(
|
||||
loshader_cinescope_drawer_t* drawer,
|
||||
const loshader_cinescope_drawer_param_t* param) {
|
||||
assert(drawer != NULL);
|
||||
assert(param != NULL);
|
||||
|
||||
const loshader_cinescope_drawer_internal_param_t p = {
|
||||
.size = param->size,
|
||||
.color = param->color,
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(p), &p);
|
||||
}
|
||||
|
||||
void loshader_cinescope_drawer_draw(const loshader_cinescope_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_CINESCOPE_UNIBLOCK_INDEX);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,
|
||||
LOSHADER_CINESCOPE_PARAM_INDEX, drawer->param);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, LOSHADER_CINESCOPE_PRIMITIVE_COUNT);
|
||||
}
|
10
core/loshader/cinescope.fshader
Normal file
10
core/loshader/cinescope.fshader
Normal file
@@ -0,0 +1,10 @@
|
||||
layout(std140) uniform param {
|
||||
vec4 color;
|
||||
float size;
|
||||
} p;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
o_color = p.color;
|
||||
}
|
48
core/loshader/cinescope.h
Normal file
48
core/loshader/cinescope.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_cinescope_program_t;
|
||||
|
||||
struct loshader_cinescope_drawer_t;
|
||||
typedef struct loshader_cinescope_drawer_t loshader_cinescope_drawer_t;
|
||||
|
||||
typedef struct {
|
||||
float size;
|
||||
vec4_t color;
|
||||
} loshader_cinescope_drawer_param_t;
|
||||
|
||||
void
|
||||
loshader_cinescope_program_initialize(
|
||||
loshader_cinescope_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_cinescope_program_deinitialize(
|
||||
loshader_cinescope_program_t* prog
|
||||
);
|
||||
|
||||
loshader_cinescope_drawer_t*
|
||||
loshader_cinescope_drawer_new(
|
||||
const loshader_cinescope_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_cinescope_drawer_delete(
|
||||
loshader_cinescope_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_cinescope_drawer_set_param(
|
||||
loshader_cinescope_drawer_t* drawer,
|
||||
const loshader_cinescope_drawer_param_t* param
|
||||
);
|
||||
|
||||
void
|
||||
loshader_cinescope_drawer_draw(
|
||||
const loshader_cinescope_drawer_t* drawer
|
||||
);
|
22
core/loshader/cinescope.vshader
Normal file
22
core/loshader/cinescope.vshader
Normal file
@@ -0,0 +1,22 @@
|
||||
layout(std140) uniform param {
|
||||
vec4 color;
|
||||
float size;
|
||||
} p;
|
||||
|
||||
const vec2[6] rect_ = vec2[](
|
||||
vec2(-1., 1.),
|
||||
vec2(-1., 0.),
|
||||
vec2( 1., 0.),
|
||||
vec2(-1., 1.),
|
||||
vec2( 1., 0.),
|
||||
vec2( 1., 1.)
|
||||
);
|
||||
|
||||
void main(void) {
|
||||
int id = gl_VertexID < 6? gl_VertexID: gl_VertexID-6;
|
||||
|
||||
vec2 p = rect_[id]*vec2(1., p.size) + vec2(0., 1.-p.size);
|
||||
p.y *= (id == gl_VertexID? 1.: -1.);
|
||||
|
||||
gl_Position = vec4(p, 0., 1.);
|
||||
}
|
183
core/loshader/combat_ring.c
Normal file
183
core/loshader/combat_ring.c
Normal file
@@ -0,0 +1,183 @@
|
||||
#include "./combat_ring.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/math/constant.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/combat_ring.vshader.h"
|
||||
#include "anysrc/combat_ring.fshader.h"
|
||||
|
||||
#define LOSHADER_COMBAT_RING_VSHADER_IN_RANGE 0
|
||||
#define LOSHADER_COMBAT_RING_VSHADER_IN_PERIOD 1
|
||||
#define LOSHADER_COMBAT_RING_VSHADER_IN_COLOR 2
|
||||
|
||||
struct loshader_combat_ring_drawer_t {
|
||||
const loshader_combat_ring_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
float range;
|
||||
vec2_t period; /* x~y */
|
||||
vec4_t color;
|
||||
} loshader_combat_ring_drawer_internal_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_COMBAT_RING_UNIBLOCK_INDEX 0
|
||||
|
||||
#define LOSHADER_COMBAT_RING_PRIMITIVE_COUNT 6
|
||||
|
||||
static void loshader_combat_ring_program_setup_vao_(
|
||||
gleasy_buffer_array_t instances) {
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
glEnableVertexAttribArray(LOSHADER_COMBAT_RING_VSHADER_IN_RANGE);
|
||||
glVertexAttribPointer(
|
||||
LOSHADER_COMBAT_RING_VSHADER_IN_RANGE, 1, GL_FLOAT, GL_FALSE,
|
||||
sizeof(loshader_combat_ring_drawer_internal_instance_t),
|
||||
NULL + offsetof(loshader_combat_ring_drawer_internal_instance_t, range));
|
||||
glVertexAttribDivisor(LOSHADER_COMBAT_RING_VSHADER_IN_RANGE, 1);
|
||||
|
||||
glEnableVertexAttribArray(LOSHADER_COMBAT_RING_VSHADER_IN_PERIOD);
|
||||
glVertexAttribPointer(
|
||||
LOSHADER_COMBAT_RING_VSHADER_IN_PERIOD, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(loshader_combat_ring_drawer_internal_instance_t),
|
||||
NULL + offsetof(loshader_combat_ring_drawer_internal_instance_t, period));
|
||||
glVertexAttribDivisor(LOSHADER_COMBAT_RING_VSHADER_IN_PERIOD, 1);
|
||||
|
||||
glEnableVertexAttribArray(LOSHADER_COMBAT_RING_VSHADER_IN_COLOR);
|
||||
glVertexAttribPointer(
|
||||
LOSHADER_COMBAT_RING_VSHADER_IN_COLOR, 4, GL_FLOAT, GL_FALSE,
|
||||
sizeof(loshader_combat_ring_drawer_internal_instance_t),
|
||||
NULL + offsetof(loshader_combat_ring_drawer_internal_instance_t, color));
|
||||
glVertexAttribDivisor(LOSHADER_COMBAT_RING_VSHADER_IN_COLOR, 1);
|
||||
}
|
||||
|
||||
void loshader_combat_ring_program_initialize(
|
||||
loshader_combat_ring_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_combat_ring_vshader_, sizeof(loshader_combat_ring_vshader_),
|
||||
loshader_combat_ring_fshader_, sizeof(loshader_combat_ring_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_COMBAT_RING_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_combat_ring_program_deinitialize(
|
||||
loshader_combat_ring_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_combat_ring_drawer_t* loshader_combat_ring_drawer_new(
|
||||
const loshader_combat_ring_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_combat_ring_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
loshader_combat_ring_program_setup_vao_(drawer->instances);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_combat_ring_drawer_delete(loshader_combat_ring_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_combat_ring_drawer_clear(
|
||||
loshader_combat_ring_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
drawer->instances_length = 0;
|
||||
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
reserve * sizeof(loshader_combat_ring_drawer_internal_instance_t),
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
|
||||
void loshader_combat_ring_drawer_add_instance(
|
||||
loshader_combat_ring_drawer_t* drawer,
|
||||
const loshader_combat_ring_drawer_instance_t* instance) {
|
||||
assert(drawer != NULL);
|
||||
assert(instance != NULL);
|
||||
|
||||
if (drawer->instances_length >= drawer->instances_reserved) {
|
||||
fprintf(stderr, "combat ring drawer instance overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const size_t offset = drawer->instances_length *
|
||||
sizeof(loshader_combat_ring_drawer_internal_instance_t);
|
||||
|
||||
const loshader_combat_ring_drawer_internal_instance_t i = {
|
||||
.range = instance->range,
|
||||
.period = vec2(instance->start, instance->end),
|
||||
.color = instance->color,
|
||||
};
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(i), &i);
|
||||
|
||||
++drawer->instances_length;
|
||||
}
|
||||
|
||||
void loshader_combat_ring_drawer_draw(
|
||||
const loshader_combat_ring_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->instances_length == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_COMBAT_RING_UNIBLOCK_INDEX);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES,
|
||||
0, LOSHADER_COMBAT_RING_PRIMITIVE_COUNT, drawer->instances_length);
|
||||
}
|
91
core/loshader/combat_ring.fshader
Normal file
91
core/loshader/combat_ring.fshader
Normal file
@@ -0,0 +1,91 @@
|
||||
in vec2 v_uv;
|
||||
in float v_aa;
|
||||
in float v_range;
|
||||
in vec2 v_period;
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
vec2 uv_;
|
||||
float len_;
|
||||
float theta_;
|
||||
|
||||
float atan2(in vec2 p) {
|
||||
return p.x == 0.? PI/2.*sign(p.y): atan(p.y, p.x);
|
||||
}
|
||||
float thetadist(in vec2 p, in float t) {
|
||||
float a = tan(t);
|
||||
float b = 1.;
|
||||
if (cos(t) == 0.) {
|
||||
a = 1.;
|
||||
b = 0.;
|
||||
}
|
||||
return abs(b*p.y-a*p.x)/sqrt(a*a+b*b);
|
||||
}
|
||||
|
||||
float grid(in float n, in float ri, in float ro) {
|
||||
float u = PI/n;
|
||||
float t = floor(theta_/u)*u;
|
||||
|
||||
float d = min(thetadist(uv_, t), thetadist(uv_, t+u));
|
||||
return
|
||||
step(ri, len_)*step(len_, ro)*
|
||||
smoothstep(v_aa, .0, d);
|
||||
}
|
||||
|
||||
float belt(in float t1, in float t2, in float r) {
|
||||
float t1a = smoothstep(v_aa, 0., thetadist(uv_, t1))*step(abs(theta_-t1), .1);
|
||||
float t2a = smoothstep(v_aa, 0., thetadist(uv_, t2))*step(abs(theta_-t2), .1);
|
||||
|
||||
float a = t1a + t2a + step(t1, theta_)*step(theta_, t2);
|
||||
a *=
|
||||
(t1a + t2a)*smoothstep(.4, .45, len_) +
|
||||
smoothstep(r-v_aa, r, len_)*
|
||||
(1.-max(len_-r, 0.)/.2) +
|
||||
smoothstep(v_aa, 0., abs(len_-.7*r));
|
||||
return clamp(a, 0., 1.);
|
||||
}
|
||||
|
||||
float circle(in float r) {
|
||||
return
|
||||
smoothstep(v_aa, 0., abs(len_-r));
|
||||
}
|
||||
|
||||
float clockhand(in float t) {
|
||||
float r = smoothstep(.25, .3, len_)*smoothstep(1., .85, len_);
|
||||
float a =
|
||||
r *
|
||||
smoothstep(v_aa, 0., thetadist(uv_, t)) *
|
||||
step(abs(theta_-t), .1);
|
||||
float b =
|
||||
r * max(1.-abs(theta_-t)/(PI/12.), 0.)*.7;
|
||||
|
||||
return a + b;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
uv_ = v_uv.yx;
|
||||
len_ = length(uv_);
|
||||
theta_ = atan2(uv_);
|
||||
theta_ = theta_ < 0.? theta_+2.*PI: theta_;
|
||||
|
||||
if (v_range <= -1.) {
|
||||
o_color = v_color;
|
||||
float a =
|
||||
grid( 2., .4, 1.) +
|
||||
grid(60., .75, .8) +
|
||||
grid(10., .65, .8) +
|
||||
grid(8., .5, .55) +
|
||||
grid( 4., .3, .4) +
|
||||
circle(.8);
|
||||
o_color.a *= clamp(a, 0., 1.);
|
||||
|
||||
} else if (v_range <= 0.) {
|
||||
o_color = v_color*clockhand(v_period.x*PI*2.);
|
||||
o_color.a = pow(o_color.a, 2.);
|
||||
|
||||
} else {
|
||||
o_color = v_color;
|
||||
o_color.a *= belt(v_period.x*PI*2., v_period.y*PI*2., v_range);
|
||||
}
|
||||
}
|
58
core/loshader/combat_ring.h
Normal file
58
core/loshader/combat_ring.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_combat_ring_program_t;
|
||||
|
||||
struct loshader_combat_ring_drawer_t;
|
||||
typedef struct loshader_combat_ring_drawer_t loshader_combat_ring_drawer_t;
|
||||
|
||||
typedef struct {
|
||||
float range;
|
||||
float start;
|
||||
float end;
|
||||
vec4_t color;
|
||||
} loshader_combat_ring_drawer_instance_t;
|
||||
|
||||
void
|
||||
loshader_combat_ring_program_initialize(
|
||||
loshader_combat_ring_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_combat_ring_program_deinitialize(
|
||||
loshader_combat_ring_program_t* prog
|
||||
);
|
||||
|
||||
loshader_combat_ring_drawer_t* /* OWNERSHIP */
|
||||
loshader_combat_ring_drawer_new(
|
||||
const loshader_combat_ring_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_combat_ring_drawer_delete(
|
||||
loshader_combat_ring_drawer_t* drawer /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loshader_combat_ring_drawer_clear(
|
||||
loshader_combat_ring_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_combat_ring_drawer_add_instance(
|
||||
loshader_combat_ring_drawer_t* drawer,
|
||||
const loshader_combat_ring_drawer_instance_t* instance
|
||||
);
|
||||
|
||||
void
|
||||
loshader_combat_ring_drawer_draw(
|
||||
const loshader_combat_ring_drawer_t* drawer
|
||||
);
|
31
core/loshader/combat_ring.vshader
Normal file
31
core/loshader/combat_ring.vshader
Normal file
@@ -0,0 +1,31 @@
|
||||
layout (location = 0) in float i_range;
|
||||
layout (location = 1) in vec2 i_period;
|
||||
layout (location = 2) in vec4 i_color;
|
||||
|
||||
out vec2 v_uv;
|
||||
out float v_aa;
|
||||
out float v_range;
|
||||
out vec2 v_period;
|
||||
out vec4 v_color;
|
||||
|
||||
void main() {
|
||||
v_uv =
|
||||
(gl_VertexID == 0)? vec2(-1., 1.):
|
||||
(gl_VertexID == 1)? vec2(-1., -1.):
|
||||
(gl_VertexID == 2)? vec2( 1., 1.):
|
||||
(gl_VertexID == 3)? vec2(-1., -1.):
|
||||
(gl_VertexID == 4)? vec2( 1., -1.):
|
||||
(gl_VertexID == 5)? vec2( 1., 1.):
|
||||
vec2(0, 0);
|
||||
|
||||
vec2 scale = uni.dpi*5. / uni.resolution;
|
||||
scale /= max(scale.x, 1.);
|
||||
scale /= max(scale.y, 1.);
|
||||
|
||||
|
||||
gl_Position = vec4(v_uv*scale, 0., 1.);
|
||||
v_aa = length(uni.aa / scale)*2.;
|
||||
v_range = i_range;
|
||||
v_period = i_period;
|
||||
v_color = i_color;
|
||||
}
|
91
core/loshader/event_line.c
Normal file
91
core/loshader/event_line.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "./event_line.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/glyphas/block.h"
|
||||
#include "util/glyphas/drawer.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/event_line.vshader.h"
|
||||
#include "anysrc/event_line.fshader.h"
|
||||
|
||||
#define LOSHADER_EVENT_LINE_UNIBLOCK_INDEX 0
|
||||
|
||||
void loshader_event_line_program_initialize(
|
||||
loshader_event_line_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_event_line_vshader_, sizeof(loshader_event_line_vshader_),
|
||||
loshader_event_line_fshader_, sizeof(loshader_event_line_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_EVENT_LINE_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_event_line_program_deinitialize(
|
||||
loshader_event_line_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
void loshader_event_line_drawer_initialize(
|
||||
loshader_event_line_drawer_t* drawer,
|
||||
const loshader_event_line_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
gleasy_texture_2d_t tex) {
|
||||
assert(drawer != NULL);
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
assert(tex != 0);
|
||||
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
.tex = tex,
|
||||
|
||||
.glyphas = glyphas_drawer_new(),
|
||||
};
|
||||
}
|
||||
|
||||
void loshader_event_line_drawer_deinitialize(
|
||||
loshader_event_line_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glyphas_drawer_delete(drawer->glyphas);
|
||||
}
|
||||
|
||||
void loshader_event_line_drawer_clear(
|
||||
loshader_event_line_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
glyphas_drawer_clear(drawer->glyphas, drawer->tex, reserve);
|
||||
}
|
||||
|
||||
void loshader_event_line_drawer_add_block(
|
||||
loshader_event_line_drawer_t* drawer, const glyphas_block_t* block) {
|
||||
assert(drawer != NULL);
|
||||
assert(block != NULL);
|
||||
|
||||
glyphas_drawer_add_block(drawer->glyphas, block);
|
||||
}
|
||||
|
||||
void loshader_event_line_drawer_draw(const loshader_event_line_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_EVENT_LINE_UNIBLOCK_INDEX);
|
||||
|
||||
glyphas_drawer_draw(drawer->glyphas);
|
||||
}
|
11
core/loshader/event_line.fshader
Normal file
11
core/loshader/event_line.fshader
Normal file
@@ -0,0 +1,11 @@
|
||||
layout (location = 0) uniform sampler2D u_tex;
|
||||
|
||||
in vec2 v_uv;
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
float a = texture(u_tex, v_uv).r;
|
||||
o_color = vec4(v_color.rgb, v_color.a*a);
|
||||
}
|
63
core/loshader/event_line.h
Normal file
63
core/loshader/event_line.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/glyphas/block.h"
|
||||
#include "util/glyphas/drawer.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_event_line_program_t;
|
||||
|
||||
typedef struct {
|
||||
/* injected deps */
|
||||
const loshader_event_line_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
gleasy_texture_2d_t tex;
|
||||
|
||||
/* owned objects */
|
||||
glyphas_drawer_t* glyphas;
|
||||
} loshader_event_line_drawer_t;
|
||||
|
||||
void
|
||||
loshader_event_line_program_initialize(
|
||||
loshader_event_line_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_event_line_program_deinitialize(
|
||||
loshader_event_line_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_event_line_drawer_initialize(
|
||||
loshader_event_line_drawer_t* drawer,
|
||||
const loshader_event_line_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
gleasy_texture_2d_t tex
|
||||
);
|
||||
|
||||
void
|
||||
loshader_event_line_drawer_deinitialize(
|
||||
loshader_event_line_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_event_line_drawer_clear(
|
||||
loshader_event_line_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_event_line_drawer_add_block(
|
||||
loshader_event_line_drawer_t* drawer,
|
||||
const glyphas_block_t* block
|
||||
);
|
||||
|
||||
void
|
||||
loshader_event_line_drawer_draw(
|
||||
const loshader_event_line_drawer_t* drawer
|
||||
);
|
22
core/loshader/event_line.vshader
Normal file
22
core/loshader/event_line.vshader
Normal file
@@ -0,0 +1,22 @@
|
||||
layout (location = 0) in vec2 i_pos;
|
||||
layout (location = 1) in vec2 i_size;
|
||||
layout (location = 2) in vec2 i_uv_pos;
|
||||
layout (location = 3) in vec2 i_uv_size;
|
||||
layout (location = 4) in vec4 i_color;
|
||||
|
||||
out vec2 v_uv;
|
||||
out vec4 v_color;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0., 0.), vec2( 0., -1.), vec2( 1., -1.),
|
||||
vec2( 0., 0.), vec2( 1., -1.), vec2( 1., 0.)
|
||||
);
|
||||
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
vec2 dp = p*i_size + i_pos;
|
||||
|
||||
gl_Position = vec4(dp, 0, 1);
|
||||
v_uv = p*i_uv_size + i_uv_pos;
|
||||
v_color = i_color;
|
||||
}
|
131
core/loshader/fog.c
Normal file
131
core/loshader/fog.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "./fog.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/fog.vshader.h"
|
||||
#include "anysrc/fog.fshader.h"
|
||||
|
||||
struct loshader_fog_drawer_t {
|
||||
const loshader_fog_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
gleasy_buffer_uniform_t param;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
float type;
|
||||
float prev_type;
|
||||
float transition;
|
||||
|
||||
float bounds_fog;
|
||||
vec4_t bounds_pos;
|
||||
vec2_t bounds_size;
|
||||
} loshader_fog_drawer_internal_param_t;
|
||||
_Static_assert(
|
||||
sizeof(float)*10 ==
|
||||
sizeof(loshader_fog_drawer_internal_param_t));
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_FOG_UNIBLOCK_INDEX 0
|
||||
#define LOSHADER_FOG_PARAM_INDEX 1
|
||||
|
||||
#define LOSHADER_FOG_PRIMITIVE_COUNT 6
|
||||
|
||||
void loshader_fog_program_initialize(loshader_fog_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_fog_vshader_, sizeof(loshader_fog_vshader_),
|
||||
loshader_fog_fshader_, sizeof(loshader_fog_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_FOG_UNIBLOCK_INDEX);
|
||||
|
||||
const GLuint param = glGetUniformBlockIndex(*prog, "param");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, param, LOSHADER_FOG_PARAM_INDEX);
|
||||
}
|
||||
|
||||
void loshader_fog_program_deinitialize(loshader_fog_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_fog_drawer_t* loshader_fog_drawer_new(
|
||||
const loshader_fog_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_fog_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glGenBuffers(1, &drawer->param);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(loshader_fog_drawer_internal_param_t), NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_fog_drawer_delete(loshader_fog_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->param);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_fog_drawer_set_param(
|
||||
loshader_fog_drawer_t* drawer,
|
||||
const loshader_fog_drawer_param_t* param) {
|
||||
assert(drawer != NULL);
|
||||
assert(param != NULL);
|
||||
|
||||
const loshader_fog_drawer_internal_param_t p = {
|
||||
.type = param->type,
|
||||
.prev_type = param->prev_type,
|
||||
.transition = param->transition,
|
||||
.bounds_fog = param->bounds_fog,
|
||||
.bounds_pos = vec4(
|
||||
param->bounds_pos.chunk.x,
|
||||
param->bounds_pos.chunk.y,
|
||||
param->bounds_pos.fract.x,
|
||||
param->bounds_pos.fract.y),
|
||||
.bounds_size = param->bounds_size,
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(p), &p);
|
||||
}
|
||||
|
||||
void loshader_fog_drawer_draw(const loshader_fog_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_FOG_UNIBLOCK_INDEX);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,
|
||||
LOSHADER_FOG_PARAM_INDEX, drawer->param);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, LOSHADER_FOG_PRIMITIVE_COUNT);
|
||||
}
|
104
core/loshader/fog.fshader
Normal file
104
core/loshader/fog.fshader
Normal file
@@ -0,0 +1,104 @@
|
||||
layout(std140) uniform param {
|
||||
float type;
|
||||
float prev_type;
|
||||
float transition;
|
||||
|
||||
float bounds_fog;
|
||||
vec4 bounds_pos; /* xy: chunk, zw: fract */
|
||||
vec2 bounds_size;
|
||||
} p;
|
||||
|
||||
in vec2 v_pos;
|
||||
in vec2 v_uv;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
const float EPSILON = 1e-4;
|
||||
|
||||
/* ---- UTILITY FUNCTIONS ---- */
|
||||
vec3 get_ray_direction(in vec2 p, in vec2 s, float fov) {
|
||||
return normalize(vec3(p*s/2., s.y/tan(radians(fov)/2.)));
|
||||
}
|
||||
float rand(in vec2 p) {
|
||||
/* https://qiita.com/shimacpyon/items/d15dee44a0b8b3883f76 */
|
||||
return fract(sin(dot(p ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
float noise(in vec3 p) {
|
||||
/* https://www.shadertoy.com/view/4dS3Wd */
|
||||
const vec3 step = vec3(110, 241, 171);
|
||||
|
||||
vec3 i = floor(p);
|
||||
vec3 f = fract(p);
|
||||
|
||||
float n = dot(i, step);
|
||||
|
||||
vec3 u = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
const vec3 e1 = vec3(1., 0., 0.);
|
||||
const vec3 e2 = vec3(0., 1., 0.);
|
||||
const vec3 e3 = vec3(0., 0., 1.);
|
||||
return mix(mix(mix(rand(dot(step, vec3(0.))+vec2(n)), rand(dot(step, e1 )+vec2(n)), u.x),
|
||||
mix(rand(dot(step, e2)+vec2(n)), rand(dot(step, e1+e2 )+vec2(n)), u.x), u.y),
|
||||
mix(mix(rand(dot(step, e3)+vec2(n)), rand(dot(step, e1+e3 )+vec2(n)), u.x),
|
||||
mix(rand(dot(step, e2+e3)+vec2(n)), rand(dot(step, e1+e2+e3)+vec2(n)), u.x), u.y), u.z);
|
||||
}
|
||||
float fbm15(in vec3 p) {
|
||||
float v = 0., a = .5, f = 0.;
|
||||
|
||||
for (int i = 0; i < 15; ++i) {
|
||||
v += a*noise(p);
|
||||
p *= 2.;
|
||||
a *= .5;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/* ---- SCENE: white cloud ---- */
|
||||
vec4 white_cloud(void) {
|
||||
vec3 dir = get_ray_direction(v_uv, uni.resolution, 60.);
|
||||
vec3 eye = vec3(0.);
|
||||
|
||||
eye.xy += uni.pos.xy + uni.pos.zw;
|
||||
|
||||
float a = 0.;
|
||||
for (float i = 1.; i <= 5.; ++i) {
|
||||
a += fbm15(eye + dir*i/3.) / pow(i, 2.);
|
||||
}
|
||||
return vec4(.6, .6, .5, clamp(pow(a, 8.), 0., .8));
|
||||
}
|
||||
|
||||
/* ---- SCENE: bounds fog ---- */
|
||||
vec4 bounds_fog(void) {
|
||||
float aa = uni.aa * 100;
|
||||
|
||||
vec2 pos;
|
||||
pos.x = (p.bounds_pos.x - uni.pos.x) + (p.bounds_pos.z - uni.pos.z);
|
||||
pos.y = (p.bounds_pos.y - uni.pos.y) + (p.bounds_pos.y - uni.pos.y);
|
||||
pos = (uni.proj * uni.cam * vec4(pos, 0., 1.)).xy;
|
||||
|
||||
vec2 size = (uni.proj * uni.cam * vec4(p.bounds_size, 0., 0.)).xy;
|
||||
|
||||
vec2 area_pos = v_uv - pos;
|
||||
|
||||
float r =
|
||||
smoothstep(size.x-aa, size.x+aa, abs(area_pos.x)) +
|
||||
smoothstep(size.y-aa, size.y+aa, abs(area_pos.y));
|
||||
|
||||
float a = fbm15(vec3(area_pos, abs(fract(uni.time/60.)*2.-1.)));
|
||||
|
||||
return vec4(1.) * a * r * p.bounds_fog;
|
||||
}
|
||||
|
||||
vec4 scene(in float type) {
|
||||
return
|
||||
type == 1.? white_cloud():
|
||||
vec4(0.);
|
||||
}
|
||||
void main(void) {
|
||||
vec4 prev = vec4(0.), next = vec4(0.);
|
||||
if (p.transition > 0.) next = clamp(scene(p.type), 0., 1.);
|
||||
if (p.transition < 1.) prev = clamp(scene(p.prev_type), 0., 1.);
|
||||
o_color = mix(prev, next, p.transition);
|
||||
|
||||
o_color += bounds_fog();
|
||||
}
|
59
core/loshader/fog.h
Normal file
59
core/loshader/fog.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_fog_program_t;
|
||||
|
||||
typedef struct loshader_fog_drawer_t loshader_fog_drawer_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_FOG_TYPE_NONE = 0,
|
||||
LOSHADER_FOG_TYPE_WHITE_CLOUD = 1,
|
||||
} loshader_fog_type_t;
|
||||
|
||||
typedef struct {
|
||||
loshader_fog_type_t type;
|
||||
loshader_fog_type_t prev_type;
|
||||
|
||||
float transition;
|
||||
|
||||
float bounds_fog;
|
||||
locommon_position_t bounds_pos;
|
||||
vec2_t bounds_size;
|
||||
} loshader_fog_drawer_param_t;
|
||||
|
||||
void
|
||||
loshader_fog_program_initialize(
|
||||
loshader_fog_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_fog_program_deinitialize(
|
||||
loshader_fog_program_t* prog
|
||||
);
|
||||
|
||||
loshader_fog_drawer_t*
|
||||
loshader_fog_drawer_new(
|
||||
const loshader_fog_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_fog_drawer_delete(
|
||||
loshader_fog_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_fog_drawer_set_param(
|
||||
loshader_fog_drawer_t* drawer,
|
||||
const loshader_fog_drawer_param_t* param
|
||||
);
|
||||
|
||||
void
|
||||
loshader_fog_drawer_draw(
|
||||
const loshader_fog_drawer_t* drawer
|
||||
);
|
15
core/loshader/fog.vshader
Normal file
15
core/loshader/fog.vshader
Normal file
@@ -0,0 +1,15 @@
|
||||
out vec2 v_uv;
|
||||
|
||||
const vec2[6] square_ = vec2[](
|
||||
vec2(-1., 1.),
|
||||
vec2(-1., -1.),
|
||||
vec2( 1., -1.),
|
||||
vec2(-1., 1.),
|
||||
vec2( 1., -1.),
|
||||
vec2( 1., 1.)
|
||||
);
|
||||
|
||||
void main(void) {
|
||||
v_uv = square_[gl_VertexID];
|
||||
gl_Position = vec4(v_uv, 0., 1.);
|
||||
}
|
174
core/loshader/ground.c
Normal file
174
core/loshader/ground.c
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "./ground.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/math/matrix.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/ground.vshader.h"
|
||||
#include "anysrc/ground.fshader.h"
|
||||
|
||||
#define LOSHADER_GROUND_VSHADER_IN_GROUND_ID 0
|
||||
#define LOSHADER_GROUND_VSHADER_IN_POS 1
|
||||
#define LOSHADER_GROUND_VSHADER_IN_SIZE 2
|
||||
|
||||
struct loshader_ground_drawer_t {
|
||||
const loshader_ground_program_t* prog;
|
||||
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint16_t ground_id;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
} loshader_ground_drawer_internal_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_GROUND_UNIBLOCK_INDEX 0
|
||||
|
||||
#define LOSHADER_GROUND_PRIMITIVE_COUNT 6
|
||||
|
||||
static void loshader_ground_program_setup_vao_(
|
||||
gleasy_buffer_array_t instances) {
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
# define enable_attrib_(NAME, name, dim, type) do { \
|
||||
glEnableVertexAttribArray(LOSHADER_GROUND_VSHADER_IN_##NAME); \
|
||||
glVertexAttribPointer( \
|
||||
LOSHADER_GROUND_VSHADER_IN_##NAME, \
|
||||
dim, type, GL_FALSE, sizeof(loshader_ground_drawer_internal_instance_t), \
|
||||
NULL + offsetof(loshader_ground_drawer_internal_instance_t, name)); \
|
||||
glVertexAttribDivisor(LOSHADER_GROUND_VSHADER_IN_##NAME, 1); \
|
||||
} while (0)
|
||||
enable_attrib_(GROUND_ID, ground_id, 1, GL_UNSIGNED_SHORT);
|
||||
enable_attrib_(POS, pos, 2, GL_FLOAT);
|
||||
enable_attrib_(SIZE, size, 2, GL_FLOAT);
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
void loshader_ground_program_initialize(loshader_ground_program_t* prog) {
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_ground_vshader_, sizeof(loshader_ground_vshader_),
|
||||
loshader_ground_fshader_, sizeof(loshader_ground_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_GROUND_UNIBLOCK_INDEX);
|
||||
}
|
||||
void loshader_ground_program_deinitialize(loshader_ground_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_ground_drawer_t* loshader_ground_drawer_new(
|
||||
const loshader_ground_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_ground_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
loshader_ground_program_setup_vao_(drawer->instances);
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_ground_drawer_delete(loshader_ground_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_ground_drawer_clear(
|
||||
loshader_ground_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
drawer->instances_length = 0;
|
||||
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
reserve * sizeof(loshader_ground_drawer_instance_t),
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
|
||||
void loshader_ground_drawer_add_instance(
|
||||
loshader_ground_drawer_t* drawer,
|
||||
const loshader_ground_drawer_instance_t* instance) {
|
||||
assert(drawer != NULL);
|
||||
assert(instance != NULL);
|
||||
|
||||
if (drawer->instances_length >= drawer->instances_reserved) {
|
||||
fprintf(stderr, "ground drawer instance overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const loshader_ground_drawer_internal_instance_t inst = {
|
||||
.ground_id = instance->ground_id,
|
||||
.pos = instance->pos,
|
||||
.size = instance->size,
|
||||
};
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferSubData(GL_ARRAY_BUFFER,
|
||||
drawer->instances_length*sizeof(inst), sizeof(inst), &inst);
|
||||
|
||||
++drawer->instances_length;
|
||||
}
|
||||
|
||||
void loshader_ground_drawer_draw(const loshader_ground_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->instances_length == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
loshader_uniblock_bind(
|
||||
drawer->uniblock, LOSHADER_GROUND_UNIBLOCK_INDEX);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES,
|
||||
0, LOSHADER_GROUND_PRIMITIVE_COUNT, drawer->instances_length);
|
||||
}
|
||||
|
9
core/loshader/ground.fshader
Normal file
9
core/loshader/ground.fshader
Normal file
@@ -0,0 +1,9 @@
|
||||
in float v_ground_id;
|
||||
in vec2 v_size;
|
||||
in vec2 v_uv;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
o_color = vec4(0., 0., 0., .6);
|
||||
}
|
62
core/loshader/ground.h
Normal file
62
core/loshader/ground.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_ground_program_t;
|
||||
|
||||
struct loshader_ground_drawer_t;
|
||||
typedef struct loshader_ground_drawer_t loshader_ground_drawer_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_GROUND_ID_ISLAND = 0,
|
||||
} loshader_ground_id_t;
|
||||
|
||||
typedef struct {
|
||||
loshader_ground_id_t ground_id;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
} loshader_ground_drawer_instance_t;
|
||||
|
||||
void
|
||||
loshader_ground_program_initialize(
|
||||
loshader_ground_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_ground_program_deinitialize(
|
||||
loshader_ground_program_t* prog
|
||||
);
|
||||
|
||||
loshader_ground_drawer_t*
|
||||
loshader_ground_drawer_new(
|
||||
const loshader_ground_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_ground_drawer_delete(
|
||||
loshader_ground_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_ground_drawer_clear(
|
||||
loshader_ground_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_ground_drawer_add_instance(
|
||||
loshader_ground_drawer_t* drawer,
|
||||
const loshader_ground_drawer_instance_t* instance
|
||||
);
|
||||
|
||||
void
|
||||
loshader_ground_drawer_draw(
|
||||
const loshader_ground_drawer_t* drawer
|
||||
);
|
20
core/loshader/ground.vshader
Normal file
20
core/loshader/ground.vshader
Normal file
@@ -0,0 +1,20 @@
|
||||
layout (location = 0) in float i_ground_id;
|
||||
layout (location = 1) in vec2 i_pos;
|
||||
layout (location = 2) in vec2 i_size;
|
||||
|
||||
out float v_ground_id;
|
||||
out vec2 v_size;
|
||||
out vec2 v_uv;
|
||||
|
||||
const vec2[] square_ = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., -1.),
|
||||
vec2(-1., 1.), vec2( 1., -1.), vec2( 1., 1.)
|
||||
);
|
||||
|
||||
void main(void) {
|
||||
v_ground_id = i_ground_id;
|
||||
v_size = i_size;
|
||||
v_uv = square_[gl_VertexID];
|
||||
gl_Position = uni.proj * uni.cam * vec4(v_uv*i_size+i_pos, 0., 1.);
|
||||
}
|
||||
|
22
core/loshader/header.shader
Normal file
22
core/loshader/header.shader
Normal file
@@ -0,0 +1,22 @@
|
||||
#version 330
|
||||
#extension GL_ARB_explicit_uniform_location : enable
|
||||
|
||||
#define PI radians(180.)
|
||||
|
||||
precision mediump float;
|
||||
|
||||
layout(std140) uniform uniblock {
|
||||
vec2 resolution;
|
||||
vec2 dpi;
|
||||
float aa;
|
||||
|
||||
mat4 proj;
|
||||
mat4 cam;
|
||||
vec4 pos; /* chunk x, chunk y, fract x, fract y*/
|
||||
|
||||
float time; /* %60sec */
|
||||
} uni;
|
||||
|
||||
/* To make it explicit which errors happened in header or body,
|
||||
adds 10000 to body's line number. */
|
||||
#line 100001
|
187
core/loshader/hud_bar.c
Normal file
187
core/loshader/hud_bar.c
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "./hud_bar.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/hud_bar.vshader.h"
|
||||
#include "anysrc/hud_bar.fshader.h"
|
||||
|
||||
#define LOSHADER_HUD_BAR_VSHADER_IN_POS 0
|
||||
#define LOSHADER_HUD_BAR_VSHADER_IN_SIZE 1
|
||||
#define LOSHADER_HUD_BAR_VSHADER_IN_BGCOLOR 2
|
||||
#define LOSHADER_HUD_BAR_VSHADER_IN_FGCOLOR 3
|
||||
#define LOSHADER_HUD_BAR_VSHADER_IN_VALUE 4
|
||||
#define LOSHADER_HUD_BAR_VSHADER_IN_PREV_VALUE 5
|
||||
|
||||
struct loshader_hud_bar_drawer_t {
|
||||
const loshader_hud_bar_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_reserved;
|
||||
size_t instances_length;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
|
||||
vec4_t bgcolor;
|
||||
vec4_t fgcolor;
|
||||
|
||||
float value;
|
||||
float prev_value;
|
||||
} loshader_hud_bar_drawer_internal_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_HUD_BAR_UNIBLOCK_INDEX 0
|
||||
|
||||
#define LOSHADER_HUD_BAR_PRIMITIVE_COUNT 18
|
||||
|
||||
static void loshader_hud_bar_program_setup_vao_(
|
||||
gleasy_buffer_array_t instances) {
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
# define enable_attrib_(NAME, name, dim, type) do { \
|
||||
glEnableVertexAttribArray(LOSHADER_HUD_BAR_VSHADER_IN_##NAME); \
|
||||
glVertexAttribPointer( \
|
||||
LOSHADER_HUD_BAR_VSHADER_IN_##NAME, dim, type, GL_FALSE, \
|
||||
sizeof(loshader_hud_bar_drawer_internal_instance_t), \
|
||||
NULL + offsetof(loshader_hud_bar_drawer_internal_instance_t, name)); \
|
||||
glVertexAttribDivisor(LOSHADER_HUD_BAR_VSHADER_IN_##NAME, 1); \
|
||||
} while (0)
|
||||
|
||||
enable_attrib_(POS, pos, 2, GL_FLOAT);
|
||||
enable_attrib_(SIZE, size, 2, GL_FLOAT);
|
||||
enable_attrib_(BGCOLOR, bgcolor, 4, GL_FLOAT);
|
||||
enable_attrib_(FGCOLOR, fgcolor, 4, GL_FLOAT);
|
||||
enable_attrib_(VALUE, value, 1, GL_FLOAT);
|
||||
enable_attrib_(PREV_VALUE, prev_value, 1, GL_FLOAT);
|
||||
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
void loshader_hud_bar_program_initialize(loshader_hud_bar_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_hud_bar_vshader_, sizeof(loshader_hud_bar_vshader_),
|
||||
loshader_hud_bar_fshader_, sizeof(loshader_hud_bar_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_HUD_BAR_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_hud_bar_program_deinitialize(loshader_hud_bar_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_hud_bar_drawer_t* loshader_hud_bar_drawer_new(
|
||||
const loshader_hud_bar_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_hud_bar_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
loshader_hud_bar_program_setup_vao_(drawer->instances);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_hud_bar_drawer_delete(loshader_hud_bar_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_hud_bar_drawer_clear(
|
||||
loshader_hud_bar_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
drawer->instances_length = 0;
|
||||
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
sizeof(loshader_hud_bar_drawer_internal_instance_t) * reserve,
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
|
||||
void loshader_hud_bar_drawer_add_instance(
|
||||
loshader_hud_bar_drawer_t* drawer,
|
||||
const loshader_hud_bar_drawer_instance_t* instance) {
|
||||
assert(drawer != NULL);
|
||||
assert(instance != NULL);
|
||||
|
||||
if (drawer->instances_length >= drawer->instances_reserved) {
|
||||
fprintf(stderr, "hud bar drawer instance overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const loshader_hud_bar_drawer_internal_instance_t insta = {
|
||||
.pos = instance->pos,
|
||||
.size = instance->size,
|
||||
.bgcolor = instance->bgcolor,
|
||||
.fgcolor = instance->fgcolor,
|
||||
.value = instance->value,
|
||||
.prev_value = instance->prev_value,
|
||||
};
|
||||
|
||||
const size_t offset = drawer->instances_length * sizeof(insta);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(insta), &insta);
|
||||
|
||||
++drawer->instances_length;
|
||||
}
|
||||
|
||||
void loshader_hud_bar_drawer_draw(const loshader_hud_bar_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->instances_length == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_HUD_BAR_UNIBLOCK_INDEX);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES,
|
||||
0, LOSHADER_HUD_BAR_PRIMITIVE_COUNT, drawer->instances_length);
|
||||
}
|
21
core/loshader/hud_bar.fshader
Normal file
21
core/loshader/hud_bar.fshader
Normal file
@@ -0,0 +1,21 @@
|
||||
in vec2 v_pos;
|
||||
in vec2 v_size;
|
||||
in vec2 v_aa;
|
||||
in vec2 v_dp;
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main() {
|
||||
vec2 dp = v_dp;
|
||||
dp *= pow(length(dp), .1);
|
||||
|
||||
vec2 diff = abs(dp - v_pos);
|
||||
float aa = uni.aa * 4.;
|
||||
float a =
|
||||
(1.-smoothstep(v_size.x-aa, v_size.x, diff.x)) *
|
||||
(1.-smoothstep(v_size.y-aa, v_size.y, diff.y));
|
||||
|
||||
o_color = v_color;
|
||||
o_color.a *= a;
|
||||
}
|
60
core/loshader/hud_bar.h
Normal file
60
core/loshader/hud_bar.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_hud_bar_program_t;
|
||||
|
||||
struct loshader_hud_bar_drawer_t;
|
||||
typedef struct loshader_hud_bar_drawer_t loshader_hud_bar_drawer_t;
|
||||
|
||||
typedef struct {
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
|
||||
vec4_t bgcolor;
|
||||
vec4_t fgcolor;
|
||||
|
||||
float value;
|
||||
float prev_value;
|
||||
} loshader_hud_bar_drawer_instance_t;
|
||||
|
||||
void
|
||||
loshader_hud_bar_program_initialize(
|
||||
loshader_hud_bar_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_bar_program_deinitialize(
|
||||
loshader_hud_bar_program_t* prog
|
||||
);
|
||||
|
||||
loshader_hud_bar_drawer_t* /* OWNERSHIP */
|
||||
loshader_hud_bar_drawer_new(
|
||||
const loshader_hud_bar_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_bar_drawer_delete(
|
||||
loshader_hud_bar_drawer_t* drawer /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_bar_drawer_clear(
|
||||
loshader_hud_bar_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_bar_drawer_add_instance(
|
||||
loshader_hud_bar_drawer_t* drawer,
|
||||
const loshader_hud_bar_drawer_instance_t* instance
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_bar_drawer_draw(
|
||||
const loshader_hud_bar_drawer_t* drawer
|
||||
);
|
56
core/loshader/hud_bar.vshader
Normal file
56
core/loshader/hud_bar.vshader
Normal file
@@ -0,0 +1,56 @@
|
||||
layout (location = 0) in vec2 i_pos;
|
||||
layout (location = 1) in vec2 i_size;
|
||||
layout (location = 2) in vec4 i_bgcolor;
|
||||
layout (location = 3) in vec4 i_fgcolor;
|
||||
layout (location = 4) in float i_value;
|
||||
layout (location = 5) in float i_prev_value;
|
||||
|
||||
out vec2 v_pos;
|
||||
out vec2 v_size;
|
||||
out vec2 v_aa;
|
||||
out vec2 v_dp;
|
||||
out vec4 v_color;
|
||||
|
||||
void main() {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.),
|
||||
vec2(-1., -1.),
|
||||
vec2( 1., -1.),
|
||||
vec2(-1., 1.),
|
||||
vec2( 1., -1.),
|
||||
vec2( 1., 1.)
|
||||
);
|
||||
|
||||
float scale = (uni.cam * vec4(1., 0., 0., 0.)).x;
|
||||
scale = pow(1.2, scale-1.);
|
||||
|
||||
v_pos = i_pos;
|
||||
v_size = i_size;
|
||||
|
||||
int id = 0;
|
||||
if (gl_VertexID < 6) {
|
||||
id = gl_VertexID;
|
||||
v_size += vec2(2.)/uni.resolution;
|
||||
v_color = i_bgcolor;
|
||||
} else if (gl_VertexID < 12) {
|
||||
id = gl_VertexID - 6;
|
||||
v_pos.x -= v_size.x*(1.-i_prev_value);
|
||||
v_size.x *= i_prev_value;
|
||||
v_color = mix(i_bgcolor, i_fgcolor, .5);
|
||||
} else {
|
||||
id = gl_VertexID - 12;
|
||||
v_pos.x -= v_size.x*(1.-i_value);
|
||||
v_size.x *= i_value;
|
||||
v_color = i_fgcolor;
|
||||
}
|
||||
v_pos *= scale;
|
||||
v_size *= scale;
|
||||
|
||||
v_size = abs(v_size);
|
||||
v_aa = uni.aa / v_size;
|
||||
|
||||
v_dp = verts[id]*1.5*v_size + v_pos;
|
||||
v_dp /= pow(length(v_dp), .1);
|
||||
|
||||
gl_Position = vec4(v_dp, 0., 1.);
|
||||
}
|
95
core/loshader/hud_text.c
Normal file
95
core/loshader/hud_text.c
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "./hud_text.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/glyphas/block.h"
|
||||
#include "util/glyphas/drawer.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/hud_text.vshader.h"
|
||||
#include "anysrc/hud_text.fshader.h"
|
||||
|
||||
#define LOSHADER_HUD_TEXT_UNIFORM_ALPHA 1
|
||||
|
||||
#define LOSHADER_HUD_TEXT_UNIBLOCK_INDEX 0
|
||||
|
||||
void loshader_hud_text_program_initialize(loshader_hud_text_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_hud_text_vshader_, sizeof(loshader_hud_text_vshader_),
|
||||
loshader_hud_text_fshader_, sizeof(loshader_hud_text_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_HUD_TEXT_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_hud_text_program_deinitialize(loshader_hud_text_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
void loshader_hud_text_drawer_initialize(
|
||||
loshader_hud_text_drawer_t* drawer,
|
||||
const loshader_hud_text_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
gleasy_texture_2d_t tex) {
|
||||
assert(drawer != NULL);
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
assert(tex != 0);
|
||||
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
.tex = tex,
|
||||
|
||||
.glyphas = glyphas_drawer_new(),
|
||||
|
||||
.alpha = 1,
|
||||
};
|
||||
}
|
||||
|
||||
void loshader_hud_text_drawer_deinitialize(
|
||||
loshader_hud_text_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glyphas_drawer_delete(drawer->glyphas);
|
||||
}
|
||||
|
||||
void loshader_hud_text_drawer_clear(
|
||||
loshader_hud_text_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
glyphas_drawer_clear(drawer->glyphas, drawer->tex, reserve);
|
||||
}
|
||||
|
||||
void loshader_hud_text_drawer_add_block(
|
||||
loshader_hud_text_drawer_t* drawer, const glyphas_block_t* block) {
|
||||
assert(drawer != NULL);
|
||||
assert(block != NULL);
|
||||
|
||||
glyphas_drawer_add_block(drawer->glyphas, block);
|
||||
}
|
||||
|
||||
void loshader_hud_text_drawer_draw(const loshader_hud_text_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_HUD_TEXT_UNIBLOCK_INDEX);
|
||||
|
||||
glUniform1f(LOSHADER_HUD_TEXT_UNIFORM_ALPHA, drawer->alpha);
|
||||
|
||||
glyphas_drawer_draw(drawer->glyphas);
|
||||
}
|
28
core/loshader/hud_text.fshader
Normal file
28
core/loshader/hud_text.fshader
Normal file
@@ -0,0 +1,28 @@
|
||||
layout (location = 0) uniform sampler2D u_tex;
|
||||
layout (location = 1) uniform float u_alpha;
|
||||
|
||||
in vec2 v_pos;
|
||||
in vec2 v_size;
|
||||
in vec2 v_uv_pos;
|
||||
in vec2 v_uv_size;
|
||||
in vec2 v_dp;
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
vec2 dp = v_dp;
|
||||
dp *= pow(length(dp), .1);
|
||||
|
||||
vec2 uvp = (dp - v_pos) / v_size;
|
||||
vec2 uv = uvp*v_uv_size + v_uv_pos;
|
||||
uvp = abs(uvp);
|
||||
|
||||
float a =
|
||||
texture(u_tex, uv).r *
|
||||
step(abs(uvp.x-.5), .5) *
|
||||
step(abs(uvp.y-.5), .5);
|
||||
|
||||
o_color = v_color;
|
||||
o_color.a *= a*u_alpha;
|
||||
}
|
66
core/loshader/hud_text.h
Normal file
66
core/loshader/hud_text.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/glyphas/block.h"
|
||||
#include "util/glyphas/drawer.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_hud_text_program_t;
|
||||
|
||||
typedef struct {
|
||||
/* injected deps */
|
||||
const loshader_hud_text_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
gleasy_texture_2d_t tex;
|
||||
|
||||
/* owned objects */
|
||||
glyphas_drawer_t* glyphas;
|
||||
|
||||
/* public params */
|
||||
float alpha;
|
||||
} loshader_hud_text_drawer_t;
|
||||
|
||||
void
|
||||
loshader_hud_text_program_initialize(
|
||||
loshader_hud_text_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_text_program_deinitialize(
|
||||
loshader_hud_text_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_text_drawer_initialize(
|
||||
loshader_hud_text_drawer_t* drawer,
|
||||
const loshader_hud_text_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
gleasy_texture_2d_t tex
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_text_drawer_deinitialize(
|
||||
loshader_hud_text_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_text_drawer_clear(
|
||||
loshader_hud_text_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_text_drawer_add_block(
|
||||
loshader_hud_text_drawer_t* drawer,
|
||||
const glyphas_block_t* block
|
||||
);
|
||||
|
||||
void
|
||||
loshader_hud_text_drawer_draw(
|
||||
const loshader_hud_text_drawer_t* drawer
|
||||
);
|
33
core/loshader/hud_text.vshader
Normal file
33
core/loshader/hud_text.vshader
Normal file
@@ -0,0 +1,33 @@
|
||||
layout (location = 0) in vec2 i_pos;
|
||||
layout (location = 1) in vec2 i_size;
|
||||
layout (location = 2) in vec2 i_uv_pos;
|
||||
layout (location = 3) in vec2 i_uv_size;
|
||||
layout (location = 4) in vec4 i_color;
|
||||
|
||||
out vec2 v_pos;
|
||||
out vec2 v_size;
|
||||
out vec2 v_uv_pos;
|
||||
out vec2 v_uv_size;
|
||||
out vec2 v_dp;
|
||||
out vec4 v_color;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0., 0.), vec2( 0., -1.), vec2( 1., -1.),
|
||||
vec2( 0., 0.), vec2( 1., -1.), vec2( 1., 0.)
|
||||
);
|
||||
|
||||
float scale = (uni.cam * vec4(1., 0., 0., 0.)).x;
|
||||
scale = pow(1.2, scale-1.);
|
||||
|
||||
v_pos = i_pos * scale;
|
||||
v_size = i_size * scale;
|
||||
v_uv_pos = i_uv_pos;
|
||||
v_uv_size = i_uv_size;
|
||||
v_color = i_color;
|
||||
|
||||
v_dp = verts[gl_VertexID]*v_size*1.5 + v_pos;
|
||||
v_dp /= pow(length(v_dp), .1);
|
||||
|
||||
gl_Position = vec4(v_dp, 0., 1.);
|
||||
}
|
97
core/loshader/menu_background.c
Normal file
97
core/loshader/menu_background.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "./menu_background.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/menu_background.vshader.h"
|
||||
#include "anysrc/menu_background.fshader.h"
|
||||
|
||||
#define LOSHADER_MENU_BACKGROUND_UNIFORM_ALPHA 0
|
||||
|
||||
struct loshader_menu_background_drawer_t {
|
||||
const loshader_menu_background_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
float alpha;
|
||||
};
|
||||
|
||||
#define LOSHADER_MENU_BACKGROUND_UNIBLOCK_INDEX 0
|
||||
|
||||
void loshader_menu_background_program_initialize(
|
||||
loshader_menu_background_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_,
|
||||
sizeof(loshader_header_shader_),
|
||||
loshader_menu_background_vshader_,
|
||||
sizeof(loshader_menu_background_vshader_),
|
||||
loshader_menu_background_fshader_,
|
||||
sizeof(loshader_menu_background_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(
|
||||
*prog, uniblock, LOSHADER_MENU_BACKGROUND_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_menu_background_program_deinitialize(
|
||||
loshader_menu_background_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_menu_background_drawer_t* loshader_menu_background_drawer_new(
|
||||
const loshader_menu_background_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_menu_background_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_menu_background_drawer_delete(
|
||||
loshader_menu_background_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_menu_background_drawer_set_alpha(
|
||||
loshader_menu_background_drawer_t* drawer, float alpha) {
|
||||
assert(drawer != NULL);
|
||||
assert(MATH_FLOAT_VALID(alpha));
|
||||
|
||||
drawer->alpha = alpha;
|
||||
}
|
||||
|
||||
void loshader_menu_background_drawer_draw(
|
||||
const loshader_menu_background_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->alpha == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(
|
||||
drawer->uniblock, LOSHADER_MENU_BACKGROUND_UNIBLOCK_INDEX);
|
||||
|
||||
glUniform1f(LOSHADER_MENU_BACKGROUND_UNIFORM_ALPHA, drawer->alpha);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
35
core/loshader/menu_background.fshader
Normal file
35
core/loshader/menu_background.fshader
Normal file
@@ -0,0 +1,35 @@
|
||||
layout (location = 0) uniform float u_alpha;
|
||||
|
||||
in vec2 v_uv;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
float atan2(in vec2 p){
|
||||
return p.x == 0. ? sign(p.y)*PI/2. : atan(p.y, p.x);
|
||||
}
|
||||
|
||||
float map(in vec2 p, in float t) {
|
||||
if (p.x >= 2.) return 0.;
|
||||
|
||||
vec2 v = vec2(.3, .4 + t*.3);
|
||||
for (float i = 0.; i < 10.; ++i) {
|
||||
p = abs(p) - v;
|
||||
v /= dot(p, p);
|
||||
}
|
||||
return abs(p.x);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec2 uv = v_uv * uni.resolution.xy / (4.*uni.dpi);
|
||||
|
||||
vec2 polar = vec2(length(uv), atan2(uv));
|
||||
polar.y = abs(mod(polar.y, PI/3.) - PI/6.);
|
||||
|
||||
vec2 p = vec2(cos(polar.y), sin(polar.y))*polar.x;
|
||||
|
||||
o_color = vec4(0, 0, 0, .7*u_alpha);
|
||||
|
||||
float t = 1.-pow(1.-u_alpha, 8.);
|
||||
float fractal = step(100.-t*100.+3., map(p*1.8, t)) * polar.x;
|
||||
o_color = mix(o_color, vec4(.4, .2, .2, .1), fractal);
|
||||
}
|
44
core/loshader/menu_background.h
Normal file
44
core/loshader/menu_background.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_menu_background_program_t;
|
||||
|
||||
struct loshader_menu_background_drawer_t;
|
||||
typedef
|
||||
struct loshader_menu_background_drawer_t
|
||||
loshader_menu_background_drawer_t;
|
||||
|
||||
void
|
||||
loshader_menu_background_program_initialize(
|
||||
loshader_menu_background_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_background_program_deinitialize(
|
||||
loshader_menu_background_program_t* prog
|
||||
);
|
||||
|
||||
loshader_menu_background_drawer_t*
|
||||
loshader_menu_background_drawer_new(
|
||||
const loshader_menu_background_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_background_drawer_delete(
|
||||
loshader_menu_background_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_background_drawer_set_alpha(
|
||||
loshader_menu_background_drawer_t* drawer,
|
||||
float alpha
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_background_drawer_draw(
|
||||
const loshader_menu_background_drawer_t* drawer
|
||||
);
|
11
core/loshader/menu_background.vshader
Normal file
11
core/loshader/menu_background.vshader
Normal file
@@ -0,0 +1,11 @@
|
||||
out vec2 v_uv;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., -1.),
|
||||
vec2(-1., 1.), vec2( 1., -1.), vec2( 1., 1.)
|
||||
);
|
||||
|
||||
v_uv = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
gl_Position = vec4(v_uv, 0., 1.);
|
||||
}
|
185
core/loshader/menu_stance.c
Normal file
185
core/loshader/menu_stance.c
Normal file
@@ -0,0 +1,185 @@
|
||||
#include "./menu_stance.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/menu_stance.vshader.h"
|
||||
#include "anysrc/menu_stance.fshader.h"
|
||||
|
||||
#define LOSHADER_MENU_STANCE_VSHADER_IN_ID 0
|
||||
#define LOSHADER_MENU_STANCE_VSHADER_IN_POS 1
|
||||
#define LOSHADER_MENU_STANCE_VSHADER_IN_SIZE 2
|
||||
#define LOSHADER_MENU_STANCE_VSHADER_IN_ALPHA 3
|
||||
#define LOSHADER_MENU_STANCE_VSHADER_IN_HIGHLIGHT 4
|
||||
|
||||
struct loshader_menu_stance_drawer_t {
|
||||
const loshader_menu_stance_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
GLuint vao;
|
||||
|
||||
gleasy_buffer_array_t instances;
|
||||
size_t instances_length;
|
||||
size_t instances_reserved;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint8_t id;
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
float alpha;
|
||||
float highlight;
|
||||
} loshader_menu_stance_drawer_internal_instance_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_MENU_STANCE_UNIBLOCK_INDEX 0
|
||||
#define LOSHADER_MENU_STANCE_PRIMITIVE_COUNT 60
|
||||
|
||||
static void loshader_menu_stance_program_setup_vao_(
|
||||
gleasy_buffer_array_t instances) {
|
||||
assert(instances != 0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, instances);
|
||||
|
||||
# define enable_attrib_(NAME, name, dim, type) do { \
|
||||
glEnableVertexAttribArray(LOSHADER_MENU_STANCE_VSHADER_IN_##NAME); \
|
||||
glVertexAttribPointer( \
|
||||
LOSHADER_MENU_STANCE_VSHADER_IN_##NAME, dim, type, GL_FALSE, \
|
||||
sizeof(loshader_menu_stance_drawer_internal_instance_t), \
|
||||
NULL + offsetof(loshader_menu_stance_drawer_internal_instance_t, name)); \
|
||||
glVertexAttribDivisor(LOSHADER_MENU_STANCE_VSHADER_IN_##NAME, 1); \
|
||||
} while (0)
|
||||
|
||||
enable_attrib_(ID, id, 1, GL_UNSIGNED_BYTE);
|
||||
enable_attrib_(POS, pos, 2, GL_FLOAT);
|
||||
enable_attrib_(SIZE, size, 2, GL_FLOAT);
|
||||
enable_attrib_(ALPHA, alpha, 1, GL_FLOAT);
|
||||
enable_attrib_(HIGHLIGHT, highlight, 1, GL_FLOAT);
|
||||
|
||||
# undef enable_attrib_
|
||||
}
|
||||
|
||||
void loshader_menu_stance_program_initialize(
|
||||
loshader_menu_stance_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_menu_stance_vshader_, sizeof(loshader_menu_stance_vshader_),
|
||||
loshader_menu_stance_fshader_, sizeof(loshader_menu_stance_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_MENU_STANCE_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_menu_stance_program_deinitialize(
|
||||
loshader_menu_stance_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_menu_stance_drawer_t* loshader_menu_stance_drawer_new(
|
||||
const loshader_menu_stance_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
|
||||
loshader_menu_stance_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
};
|
||||
|
||||
glCreateVertexArrays(1, &drawer->vao);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
glGenBuffers(1, &drawer->instances);
|
||||
loshader_menu_stance_program_setup_vao_(drawer->instances);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_menu_stance_drawer_delete(
|
||||
loshader_menu_stance_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glDeleteBuffers(1, &drawer->instances);
|
||||
|
||||
glDeleteVertexArrays(1, &drawer->vao);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_menu_stance_drawer_clear(
|
||||
loshader_menu_stance_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
drawer->instances_length = 0;
|
||||
|
||||
if (drawer->instances_reserved < reserve) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferData(GL_ARRAY_BUFFER,
|
||||
reserve * sizeof(loshader_menu_stance_drawer_internal_instance_t),
|
||||
NULL, GL_DYNAMIC_DRAW);
|
||||
drawer->instances_reserved = reserve;
|
||||
}
|
||||
}
|
||||
|
||||
void loshader_menu_stance_drawer_add_instance(
|
||||
loshader_menu_stance_drawer_t* drawer,
|
||||
const loshader_menu_stance_drawer_instance_t* instance) {
|
||||
assert(drawer != NULL);
|
||||
assert(instance != NULL);
|
||||
|
||||
if (drawer->instances_length >= drawer->instances_reserved) {
|
||||
fprintf(stderr, "menu stance drawer instance overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
const loshader_menu_stance_drawer_internal_instance_t insta = {
|
||||
.id = instance->id,
|
||||
.pos = instance->pos,
|
||||
.size = instance->size,
|
||||
.alpha = instance->alpha,
|
||||
.highlight = instance->highlight,
|
||||
};
|
||||
|
||||
const size_t offset = drawer->instances_length * sizeof(insta);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, drawer->instances);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(insta), &insta);
|
||||
|
||||
++drawer->instances_length;
|
||||
}
|
||||
|
||||
void loshader_menu_stance_drawer_draw(
|
||||
const loshader_menu_stance_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
if (drawer->instances_length == 0) return;
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
glBindVertexArray(drawer->vao);
|
||||
|
||||
loshader_uniblock_bind(
|
||||
drawer->uniblock, LOSHADER_MENU_STANCE_UNIBLOCK_INDEX);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLES,
|
||||
0, LOSHADER_MENU_STANCE_PRIMITIVE_COUNT, drawer->instances_length);
|
||||
}
|
9
core/loshader/menu_stance.fshader
Normal file
9
core/loshader/menu_stance.fshader
Normal file
@@ -0,0 +1,9 @@
|
||||
in float v_id;
|
||||
in vec2 v_uv;
|
||||
in float v_alpha;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
o_color = vec4(1., 1., 1., v_alpha*.8);
|
||||
}
|
68
core/loshader/menu_stance.h
Normal file
68
core/loshader/menu_stance.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_menu_stance_program_t;
|
||||
|
||||
struct loshader_menu_stance_drawer_t;
|
||||
typedef struct loshader_menu_stance_drawer_t loshader_menu_stance_drawer_t;
|
||||
|
||||
typedef enum {
|
||||
LOSHADER_MENU_STANCE_ID_EMPTY = 0,
|
||||
LOSHADER_MENU_STANCE_ID_MISSIONARY = 1,
|
||||
LOSHADER_MENU_STANCE_ID_REVOLUTIONER = 2,
|
||||
LOSHADER_MENU_STANCE_ID_UNFINISHER = 3,
|
||||
LOSHADER_MENU_STANCE_ID_PHILOSOPHER = 4,
|
||||
} loshader_menu_stance_id_t;
|
||||
|
||||
typedef struct {
|
||||
loshader_menu_stance_id_t id;
|
||||
|
||||
vec2_t pos;
|
||||
vec2_t size;
|
||||
float alpha;
|
||||
float highlight;
|
||||
} loshader_menu_stance_drawer_instance_t;
|
||||
|
||||
void
|
||||
loshader_menu_stance_program_initialize(
|
||||
loshader_menu_stance_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_stance_program_deinitialize(
|
||||
loshader_menu_stance_program_t* prog
|
||||
);
|
||||
|
||||
loshader_menu_stance_drawer_t*
|
||||
loshader_menu_stance_drawer_new(
|
||||
const loshader_menu_stance_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_stance_drawer_delete(
|
||||
loshader_menu_stance_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_stance_drawer_clear(
|
||||
loshader_menu_stance_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_stance_drawer_add_instance(
|
||||
loshader_menu_stance_drawer_t* drawer,
|
||||
const loshader_menu_stance_drawer_instance_t* instance
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_stance_drawer_draw(
|
||||
const loshader_menu_stance_drawer_t* drawer
|
||||
);
|
93
core/loshader/menu_stance.vshader
Normal file
93
core/loshader/menu_stance.vshader
Normal file
@@ -0,0 +1,93 @@
|
||||
layout (location = 0) in float i_id;
|
||||
layout (location = 1) in vec2 i_pos;
|
||||
layout (location = 2) in vec2 i_size;
|
||||
layout (location = 3) in float i_alpha;
|
||||
layout (location = 4) in float i_highlight;
|
||||
|
||||
out float v_id;
|
||||
out vec2 v_uv;
|
||||
out float v_alpha;
|
||||
|
||||
const vec2[] frame_ = vec2[](
|
||||
vec2( 0.0, 1.0), vec2(-1.0, 0.0), vec2( 0.0, 0.9),
|
||||
vec2( 0.0, 0.9), vec2(-1.0, 0.0), vec2(-0.9, 0.0),
|
||||
vec2(-1.0, 0.0), vec2( 0.0, -1.0), vec2(-0.9, 0.0),
|
||||
vec2(-0.9, 0.0), vec2( 0.0, -1.0), vec2( 0.0, -0.9),
|
||||
vec2( 0.9, 0.0), vec2( 0.0, -0.9), vec2( 0.0, -1.0),
|
||||
vec2( 1.0, 0.0), vec2( 0.9, 0.0), vec2( 0.0, -1.0),
|
||||
vec2( 0.0, 1.0), vec2( 0.9, 0.0), vec2( 1.0, 0.0),
|
||||
vec2( 0.0, 1.0), vec2( 0.0, 0.9), vec2( 0.9, 0.0)
|
||||
);
|
||||
|
||||
vec2 empty(in int id) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0., 1.), vec2(-1., 0.), vec2( 0., -1.),
|
||||
vec2( 0., 1.), vec2( 1., 0.), vec2( 0., -1.)
|
||||
);
|
||||
return id < verts.length()? verts[id]: vec2(0.);
|
||||
}
|
||||
|
||||
vec2 missionary(in int id) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.12, 0.52), vec2(-0.52, 0.24), vec2( 0.04, 0.40),
|
||||
vec2(-0.52, 0.24), vec2( 0.00, 0.00), vec2( 0.00, 0.12),
|
||||
vec2(-0.60, 0.08), vec2(-0.68, 0.00), vec2(-0.04, -0.36),
|
||||
vec2(-0.72, 0.00), vec2(-0.08, -0.52), vec2( 0.00, -0.40),
|
||||
vec2(-0.76, -0.04), vec2(-0.60, -0.36), vec2(-0.12, -0.56),
|
||||
vec2(-0.60, -0.40), vec2(-0.04, -0.96), vec2(-0.12, -0.60)
|
||||
);
|
||||
return
|
||||
id < verts.length() ? verts[id]:
|
||||
id < verts.length()*2? verts[id-verts.length()]*vec2(-1., 1.):
|
||||
vec2(0.);
|
||||
}
|
||||
vec2 revolutioner(in int id) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-0.52, 0.24), vec2(-0.60, 0.20), vec2( 0.00, -0.80),
|
||||
vec2( 0.00, 0.36), vec2(-0.48, 0.08), vec2(-0.24, -0.16),
|
||||
vec2( 0.08, 0.64), vec2(-0.16, 0.40), vec2( 0.44, 0.36),
|
||||
vec2( 0.04, 0.24), vec2(-0.16, -0.12), vec2( 0.56, 0.28)
|
||||
);
|
||||
return id < verts.length()? verts[id]: vec2(0.);
|
||||
}
|
||||
vec2 unfinisher(in int id) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.00, 1.00), vec2(-0.08, 0.20), vec2( 0.08, 0.20),
|
||||
vec2(-0.08, 0.20), vec2(-0.40, 0.00), vec2(-0.40, -0.40),
|
||||
vec2(-0.40, -0.40), vec2( 0.00, -0.60), vec2( 0.40, -0.40),
|
||||
vec2( 0.08, 0.20), vec2( 0.40, 0.00), vec2( 0.40, -0.40)
|
||||
);
|
||||
return id < verts.length()? verts[id]: vec2(0.);
|
||||
}
|
||||
vec2 philosopher(in int id) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0.117, -0.367), vec2( 0.000, -0.750), vec2( 0.300, -0.533),
|
||||
vec2( 0.117, 0.050), vec2(-0.083, -0.117), vec2( 0.367, -0.517),
|
||||
vec2(-0.050, 0.283), vec2(-0.133, -0.117), vec2( 0.117, 0.083),
|
||||
vec2( 0.500, 0.500), vec2(-0.050, 0.333), vec2( 0.150, 0.133),
|
||||
vec2( 0.250, 0.917), vec2(-0.233, 0.317), vec2( 0.500, 0.533),
|
||||
vec2( 0.217, 0.917), vec2(-0.300, 0.817), vec2(-0.283, 0.333),
|
||||
vec2(-0.333, 0.783), vec2(-0.500, 0.567), vec2(-0.333, 0.333)
|
||||
);
|
||||
return id < verts.length()? verts[id]*vec2(1.1, .9)+vec2(0, -.1): vec2(0.);
|
||||
}
|
||||
|
||||
vec2 get_vertex(in int id) {
|
||||
return
|
||||
i_id == 1.? missionary(id):
|
||||
i_id == 2.? revolutioner(id):
|
||||
i_id == 3.? unfinisher(id):
|
||||
i_id == 4.? philosopher(id):
|
||||
empty(id);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
v_uv = gl_VertexID < frame_.length()?
|
||||
frame_[gl_VertexID]: get_vertex(gl_VertexID - frame_.length())*.8;
|
||||
|
||||
v_id = i_id;
|
||||
v_alpha = i_alpha;
|
||||
|
||||
float s = i_highlight*.2 + 1.;
|
||||
gl_Position = vec4(v_uv*i_size*s + i_pos, 0., 1.);
|
||||
}
|
97
core/loshader/menu_text.c
Normal file
97
core/loshader/menu_text.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "./menu_text.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/glyphas/block.h"
|
||||
#include "util/glyphas/drawer.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/menu_text.vshader.h"
|
||||
#include "anysrc/menu_text.fshader.h"
|
||||
|
||||
#define LOSHADER_MENU_TEXT_UNIFORM_ALPHA 1
|
||||
|
||||
#define LOSHADER_MENU_TEXT_UNIBLOCK_INDEX 0
|
||||
|
||||
void loshader_menu_text_program_initialize(
|
||||
loshader_menu_text_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_menu_text_vshader_, sizeof(loshader_menu_text_vshader_),
|
||||
loshader_menu_text_fshader_, sizeof(loshader_menu_text_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_MENU_TEXT_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_menu_text_program_deinitialize(
|
||||
loshader_menu_text_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
void loshader_menu_text_drawer_initialize(
|
||||
loshader_menu_text_drawer_t* drawer,
|
||||
const loshader_menu_text_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
gleasy_texture_2d_t tex) {
|
||||
assert(drawer != NULL);
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
assert(tex != 0);
|
||||
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
.tex = tex,
|
||||
|
||||
.glyphas = glyphas_drawer_new(),
|
||||
|
||||
.alpha = 1,
|
||||
};
|
||||
}
|
||||
|
||||
void loshader_menu_text_drawer_deinitialize(
|
||||
loshader_menu_text_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glyphas_drawer_delete(drawer->glyphas);
|
||||
}
|
||||
|
||||
void loshader_menu_text_drawer_clear(
|
||||
loshader_menu_text_drawer_t* drawer, size_t reserve) {
|
||||
assert(drawer != NULL);
|
||||
assert(reserve > 0);
|
||||
|
||||
glyphas_drawer_clear(drawer->glyphas, drawer->tex, reserve);
|
||||
}
|
||||
|
||||
void loshader_menu_text_drawer_add_block(
|
||||
loshader_menu_text_drawer_t* drawer, const glyphas_block_t* block) {
|
||||
assert(drawer != NULL);
|
||||
assert(block != NULL);
|
||||
|
||||
glyphas_drawer_add_block(drawer->glyphas, block);
|
||||
}
|
||||
|
||||
void loshader_menu_text_drawer_draw(const loshader_menu_text_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_MENU_TEXT_UNIBLOCK_INDEX);
|
||||
|
||||
glUniform1f(LOSHADER_MENU_TEXT_UNIFORM_ALPHA, drawer->alpha);
|
||||
|
||||
glyphas_drawer_draw(drawer->glyphas);
|
||||
}
|
12
core/loshader/menu_text.fshader
Normal file
12
core/loshader/menu_text.fshader
Normal file
@@ -0,0 +1,12 @@
|
||||
layout (location = 0) uniform sampler2D u_tex;
|
||||
layout (location = 1) uniform float u_alpha;
|
||||
|
||||
in vec2 v_uv;
|
||||
in vec4 v_color;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
void main(void) {
|
||||
float a = texture(u_tex, v_uv).r;
|
||||
o_color = vec4(v_color.rgb, v_color.a*a*u_alpha);
|
||||
}
|
66
core/loshader/menu_text.h
Normal file
66
core/loshader/menu_text.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/gleasy/texture.h"
|
||||
#include "util/glyphas/block.h"
|
||||
#include "util/glyphas/drawer.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_menu_text_program_t;
|
||||
|
||||
typedef struct {
|
||||
/* injected deps */
|
||||
const loshader_menu_text_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
gleasy_texture_2d_t tex;
|
||||
|
||||
/* owned objects */
|
||||
glyphas_drawer_t* glyphas;
|
||||
|
||||
/* public params */
|
||||
float alpha;
|
||||
} loshader_menu_text_drawer_t;
|
||||
|
||||
void
|
||||
loshader_menu_text_program_initialize(
|
||||
loshader_menu_text_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_text_program_deinitialize(
|
||||
loshader_menu_text_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_text_drawer_initialize(
|
||||
loshader_menu_text_drawer_t* drawer,
|
||||
const loshader_menu_text_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
gleasy_texture_2d_t tex
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_text_drawer_deinitialize(
|
||||
loshader_menu_text_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_text_drawer_clear(
|
||||
loshader_menu_text_drawer_t* drawer,
|
||||
size_t reserve
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_text_drawer_add_block(
|
||||
loshader_menu_text_drawer_t* drawer,
|
||||
const glyphas_block_t* block
|
||||
);
|
||||
|
||||
void
|
||||
loshader_menu_text_drawer_draw(
|
||||
const loshader_menu_text_drawer_t* drawer
|
||||
);
|
24
core/loshader/menu_text.vshader
Normal file
24
core/loshader/menu_text.vshader
Normal file
@@ -0,0 +1,24 @@
|
||||
layout (location = 0) in vec2 i_pos;
|
||||
layout (location = 1) in vec2 i_size;
|
||||
layout (location = 2) in vec2 i_uv_pos;
|
||||
layout (location = 3) in vec2 i_uv_size;
|
||||
layout (location = 4) in vec4 i_color;
|
||||
|
||||
out vec2 v_uv;
|
||||
out vec4 v_color;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2( 0., 0.), vec2( 0., -1.), vec2( 1., -1.),
|
||||
vec2( 0., 0.), vec2( 1., -1.), vec2( 1., 0.)
|
||||
|
||||
);
|
||||
|
||||
vec2 p = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
vec2 dp = p*i_size + i_pos;
|
||||
|
||||
gl_Position = vec4(dp, 0, 1);
|
||||
v_uv = p*i_uv_size + i_uv_pos;
|
||||
v_color = i_color;
|
||||
}
|
||||
|
109
core/loshader/pixsort.c
Normal file
109
core/loshader/pixsort.c
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "./pixsort.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/framebuffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/pixsort.vshader.h"
|
||||
#include "anysrc/pixsort.fshader.h"
|
||||
|
||||
#define LOSHADER_PIXSORT_UNIFORM_SRC 0
|
||||
#define LOSHADER_PIXSORT_UNIFORM_INTENSITY 1
|
||||
|
||||
#define LOSHADER_PIXSORT_UNIBLOCK_INDEX 0
|
||||
|
||||
struct loshader_pixsort_drawer_t {
|
||||
const loshader_pixsort_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
const gleasy_framebuffer_t* fb;
|
||||
|
||||
float intensity;
|
||||
};
|
||||
|
||||
void loshader_pixsort_program_initialize(
|
||||
loshader_pixsort_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_pixsort_vshader_, sizeof(loshader_pixsort_vshader_),
|
||||
loshader_pixsort_fshader_, sizeof(loshader_pixsort_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_PIXSORT_UNIBLOCK_INDEX);
|
||||
}
|
||||
|
||||
void loshader_pixsort_program_deinitialize(
|
||||
loshader_pixsort_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_pixsort_drawer_t* loshader_pixsort_drawer_new(
|
||||
const loshader_pixsort_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
const gleasy_framebuffer_t* fb) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
assert(fb != NULL);
|
||||
|
||||
loshader_pixsort_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
.fb = fb,
|
||||
};
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_pixsort_drawer_delete(loshader_pixsort_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_pixsort_drawer_set_intensity(
|
||||
loshader_pixsort_drawer_t* drawer,
|
||||
float intensity) {
|
||||
assert(drawer != NULL);
|
||||
assert(MATH_FLOAT_VALID(intensity));
|
||||
|
||||
drawer->intensity = intensity;
|
||||
}
|
||||
|
||||
void loshader_pixsort_drawer_draw(
|
||||
const loshader_pixsort_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, drawer->fb->colorbuf);
|
||||
glUniform1i(LOSHADER_PIXSORT_UNIFORM_SRC, 0);
|
||||
|
||||
glUniform1f(LOSHADER_PIXSORT_UNIFORM_INTENSITY, drawer->intensity);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
bool loshader_pixsort_drawer_is_skippable(
|
||||
const loshader_pixsort_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
return drawer->intensity == 0;
|
||||
}
|
71
core/loshader/pixsort.fshader
Normal file
71
core/loshader/pixsort.fshader
Normal file
@@ -0,0 +1,71 @@
|
||||
layout (location = 0) uniform sampler2D u_src;
|
||||
layout (location = 1) uniform float u_intensity;
|
||||
|
||||
in vec2 v_uv;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
const int N = 2;
|
||||
const int S = 20;
|
||||
|
||||
float luminance(in vec4 col) {
|
||||
return col.r*.3+col.g*.6+col.b*.1;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec2 uv = (v_uv + 1.)/2.;
|
||||
vec2 uvi = uv * uni.resolution.y;
|
||||
float unit = 1.0/uni.resolution.y;
|
||||
|
||||
o_color = texture(u_src, uv);
|
||||
|
||||
int darkest_y = 0;
|
||||
float darkest_lum = 1.;
|
||||
int brightest_y = 0;
|
||||
float brightest_lum = 0.;
|
||||
|
||||
int stride = int(uni.resolution.y/float(S));
|
||||
for (int i = 0; i < int(uni.resolution.y); i+=stride) {
|
||||
vec4 col = texture(u_src, vec2(uv.x, unit*float(i)));
|
||||
|
||||
float lum = luminance(col);
|
||||
if (brightest_lum < lum) {
|
||||
brightest_y = i;
|
||||
brightest_lum = lum;
|
||||
}
|
||||
if (darkest_lum > lum) {
|
||||
darkest_y = i;
|
||||
darkest_lum = lum;
|
||||
}
|
||||
}
|
||||
int st = min(darkest_y, brightest_y);
|
||||
int ed = max(darkest_y, brightest_y);
|
||||
st = ed-int(float(ed-st)*u_intensity);
|
||||
|
||||
if (int(uvi.y) <= st || int(uvi.y) >= ed) {
|
||||
return;
|
||||
}
|
||||
|
||||
float lum_unit = (brightest_lum-darkest_lum) / float(N);
|
||||
stride /= 5;
|
||||
|
||||
int count = st;
|
||||
for (int n = 0; n < N; ++n) {
|
||||
float n2 = float(darkest_y < brightest_y? n: N-n-1);
|
||||
float low = lum_unit * n2 + darkest_lum;
|
||||
float high = low + lum_unit;
|
||||
|
||||
for (int i = st; i < ed; i+=stride) {
|
||||
vec4 col = texture(u_src, vec2(uv.x, unit*float(i)));
|
||||
|
||||
float lum = luminance(col);
|
||||
if (low <= lum && lum <= high) {
|
||||
count += stride;
|
||||
if (count >= int(uvi.y)) {
|
||||
o_color = col;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
51
core/loshader/pixsort.h
Normal file
51
core/loshader/pixsort.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/framebuffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_pixsort_program_t;
|
||||
|
||||
struct loshader_pixsort_drawer_t;
|
||||
typedef struct loshader_pixsort_drawer_t loshader_pixsort_drawer_t;
|
||||
|
||||
void
|
||||
loshader_pixsort_program_initialize(
|
||||
loshader_pixsort_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_pixsort_program_deinitialize(
|
||||
loshader_pixsort_program_t* prog
|
||||
);
|
||||
|
||||
loshader_pixsort_drawer_t* /* OWNERSHIP */
|
||||
loshader_pixsort_drawer_new(
|
||||
const loshader_pixsort_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
const gleasy_framebuffer_t* fb
|
||||
);
|
||||
|
||||
void
|
||||
loshader_pixsort_drawer_delete(
|
||||
loshader_pixsort_drawer_t* drawer /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loshader_pixsort_drawer_set_intensity(
|
||||
loshader_pixsort_drawer_t* drawer,
|
||||
float intensity
|
||||
);
|
||||
|
||||
void
|
||||
loshader_pixsort_drawer_draw(
|
||||
const loshader_pixsort_drawer_t* drawer
|
||||
);
|
||||
|
||||
bool
|
||||
loshader_pixsort_drawer_is_skippable(
|
||||
const loshader_pixsort_drawer_t* drawer
|
||||
);
|
12
core/loshader/pixsort.vshader
Normal file
12
core/loshader/pixsort.vshader
Normal file
@@ -0,0 +1,12 @@
|
||||
out vec2 v_uv;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., -1.),
|
||||
vec2(-1., 1.), vec2( 1., -1.), vec2( 1., 1.)
|
||||
);
|
||||
|
||||
v_uv = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
|
||||
gl_Position = vec4(v_uv, 0., 1.);
|
||||
}
|
144
core/loshader/posteffect.c
Normal file
144
core/loshader/posteffect.c
Normal file
@@ -0,0 +1,144 @@
|
||||
#include "./posteffect.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/gleasy/framebuffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
/* resources */
|
||||
#include "anysrc/header.shader.h"
|
||||
#include "anysrc/posteffect.vshader.h"
|
||||
#include "anysrc/posteffect.fshader.h"
|
||||
|
||||
#define LOSHADER_POSTEFFECT_UNIFORM_SRC 0
|
||||
|
||||
struct loshader_posteffect_drawer_t {
|
||||
const loshader_posteffect_program_t* prog;
|
||||
const loshader_uniblock_t* uniblock;
|
||||
|
||||
const gleasy_framebuffer_t* fb;
|
||||
|
||||
gleasy_buffer_uniform_t param;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
float whole_blur;
|
||||
float raster;
|
||||
|
||||
float radial_displacement;
|
||||
float amnesia_displacement;
|
||||
float radial_fade;
|
||||
|
||||
float brightness;
|
||||
} loshader_posteffect_drawer_param_internal_t;
|
||||
_Static_assert(
|
||||
sizeof(float)*6 ==
|
||||
sizeof(loshader_posteffect_drawer_param_internal_t));
|
||||
#pragma pack(pop)
|
||||
|
||||
#define LOSHADER_POSTEFFECT_UNIBLOCK_INDEX 0
|
||||
#define LOSHADER_POSTEFFECT_PARAM_INDEX 1
|
||||
|
||||
void loshader_posteffect_program_initialize(
|
||||
loshader_posteffect_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
*prog = gleasy_program_new(
|
||||
loshader_header_shader_, sizeof(loshader_header_shader_),
|
||||
loshader_posteffect_vshader_, sizeof(loshader_posteffect_vshader_),
|
||||
loshader_posteffect_fshader_, sizeof(loshader_posteffect_fshader_));
|
||||
|
||||
const GLuint uniblock = glGetUniformBlockIndex(*prog, "uniblock");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, uniblock, LOSHADER_POSTEFFECT_UNIBLOCK_INDEX);
|
||||
|
||||
const GLuint param = glGetUniformBlockIndex(*prog, "param");
|
||||
assert(glGetError() == GL_NO_ERROR);
|
||||
glUniformBlockBinding(*prog, param, LOSHADER_POSTEFFECT_PARAM_INDEX);
|
||||
}
|
||||
|
||||
void loshader_posteffect_program_deinitialize(
|
||||
loshader_posteffect_program_t* prog) {
|
||||
assert(prog != NULL);
|
||||
|
||||
glDeleteProgram(*prog);
|
||||
}
|
||||
|
||||
loshader_posteffect_drawer_t* loshader_posteffect_drawer_new(
|
||||
const loshader_posteffect_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
const gleasy_framebuffer_t* fb) {
|
||||
assert(prog != NULL);
|
||||
assert(uniblock != NULL);
|
||||
assert(fb != NULL);
|
||||
|
||||
loshader_posteffect_drawer_t* drawer = memory_new(sizeof(*drawer));
|
||||
*drawer = (typeof(*drawer)) {
|
||||
.prog = prog,
|
||||
.uniblock = uniblock,
|
||||
.fb = fb,
|
||||
};
|
||||
|
||||
glGenBuffers(1, &drawer->param);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(loshader_posteffect_drawer_param_internal_t),
|
||||
NULL,
|
||||
GL_DYNAMIC_DRAW);
|
||||
|
||||
return drawer;
|
||||
}
|
||||
|
||||
void loshader_posteffect_drawer_delete(loshader_posteffect_drawer_t* drawer) {
|
||||
if (drawer == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &drawer->param);
|
||||
|
||||
memory_delete(drawer);
|
||||
}
|
||||
|
||||
void loshader_posteffect_drawer_set_param(
|
||||
loshader_posteffect_drawer_t* drawer,
|
||||
const loshader_posteffect_drawer_param_t* param) {
|
||||
assert(drawer != NULL);
|
||||
assert(param != NULL);
|
||||
|
||||
const loshader_posteffect_drawer_param_internal_t p = {
|
||||
.whole_blur = param->whole_blur,
|
||||
.raster = param->raster,
|
||||
.radial_displacement = param->radial_displacement,
|
||||
.amnesia_displacement = param->amnesia_displacement,
|
||||
.radial_fade = param->radial_fade,
|
||||
.brightness = param->brightness,
|
||||
};
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, drawer->param);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(p), &p);
|
||||
}
|
||||
|
||||
void loshader_posteffect_drawer_draw(
|
||||
const loshader_posteffect_drawer_t* drawer) {
|
||||
assert(drawer != NULL);
|
||||
|
||||
glUseProgram(*drawer->prog);
|
||||
|
||||
loshader_uniblock_bind(drawer->uniblock, LOSHADER_POSTEFFECT_UNIBLOCK_INDEX);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,
|
||||
LOSHADER_POSTEFFECT_PARAM_INDEX, drawer->param);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, drawer->fb->colorbuf);
|
||||
glUniform1i(LOSHADER_POSTEFFECT_UNIFORM_SRC, 0);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
139
core/loshader/posteffect.fshader
Normal file
139
core/loshader/posteffect.fshader
Normal file
@@ -0,0 +1,139 @@
|
||||
layout (location = 0) uniform sampler2D u_src;
|
||||
|
||||
layout(std140) uniform param {
|
||||
float whole_blur;
|
||||
float raster;
|
||||
|
||||
float radial_displacement;
|
||||
float amnesia_displacement;
|
||||
|
||||
float radial_fade;
|
||||
|
||||
float brightness;
|
||||
} p;
|
||||
|
||||
in vec2 v_uv;
|
||||
|
||||
out vec4 o_color;
|
||||
|
||||
float atan2(in vec2 p){
|
||||
return p.x == 0. ? sign(p.y)*PI/2. : atan(p.y, p.x);
|
||||
}
|
||||
vec2 to_polar(in vec2 p) {
|
||||
return vec2(length(p), atan2(p));
|
||||
}
|
||||
vec2 to_rectangular(in vec2 p) {
|
||||
return vec2(cos(p.y)*p.x, sin(p.y)*p.x);
|
||||
}
|
||||
float rand(in vec2 p) {
|
||||
/* https://thebookofshaders.com/13/?lan=jp */
|
||||
return fract(sin(dot(p.xy, vec2(12.9898, 78.233)))*43758.5453123);
|
||||
}
|
||||
float noise (in vec2 _st) {
|
||||
/* https://thebookofshaders.com/13/?lan=jp*/
|
||||
vec2 i = floor(_st);
|
||||
vec2 f = fract(_st);
|
||||
|
||||
float a = rand(i);
|
||||
float b = rand(i + vec2(1.0, 0.0));
|
||||
float c = rand(i + vec2(0.0, 1.0));
|
||||
float d = rand(i + vec2(1.0, 1.0));
|
||||
|
||||
vec2 u = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
return
|
||||
mix(a, b, u.x) +
|
||||
(c - a)* u.y * (1.0 - u.x) +
|
||||
(d - b) * u.x * u.y;
|
||||
}
|
||||
float fbm (in vec2 _st) {
|
||||
/* https://thebookofshaders.com/13/?lan=jp*/
|
||||
const float octaves = 5;
|
||||
|
||||
float v = 0.0;
|
||||
float a = 0.5;
|
||||
vec2 shift = vec2(100.0);
|
||||
mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50));
|
||||
|
||||
for (int i = 0; i < octaves; ++i) {
|
||||
v += a * noise(_st);
|
||||
_st = rot * _st * 2.0 + shift;
|
||||
a *= 0.5;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
vec2 radial_displacement(in vec2 polar) {
|
||||
float intensity = p.radial_displacement + 1.;
|
||||
float r = polar.x;
|
||||
|
||||
const float sqrt2 = sqrt(2.);
|
||||
r = (1. - pow(abs(1. - r/sqrt2), intensity))*sqrt2 / intensity;
|
||||
|
||||
return vec2(r, polar.y);
|
||||
}
|
||||
vec2 amnesia_displacement(in vec2 uv) {
|
||||
vec2 auv = abs(uv);
|
||||
float intensity = p.amnesia_displacement*(1.-pow(max(auv.x, auv.y), 2.));
|
||||
return uv + fbm(uv)*intensity - intensity/2.;
|
||||
}
|
||||
|
||||
float radial_fade(in float len) {
|
||||
float intensity = p.radial_fade;
|
||||
return clamp(1. - intensity * max(len - (1.-intensity), 0.), 0., 1.);
|
||||
}
|
||||
|
||||
vec4 chromatic_aberration(in vec2 uv) {
|
||||
float a = length(v_uv)/sqrt(2.);
|
||||
vec2 e = 1./uni.resolution*a;
|
||||
|
||||
return vec4(
|
||||
texture(u_src, uv+e).r,
|
||||
texture(u_src, uv).g,
|
||||
texture(u_src, uv-e).b,
|
||||
1.);
|
||||
}
|
||||
|
||||
vec4 blur(in vec2 uv) {
|
||||
vec2 e1 = vec2(1./uni.resolution.x, 0.);
|
||||
vec2 e2 = vec2(0., 1./uni.resolution.y);
|
||||
|
||||
vec4 color =
|
||||
texture(u_src, uv+e1+.0) +
|
||||
texture(u_src, uv+e1+e2) +
|
||||
texture(u_src, uv+.0+e2) +
|
||||
texture(u_src, uv-e1+e2) +
|
||||
texture(u_src, uv-e1+.0) +
|
||||
texture(u_src, uv-e1-e2) +
|
||||
texture(u_src, uv+.0-e2) +
|
||||
texture(u_src, uv+e1-e2);
|
||||
return color/8.;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec2 uv = v_uv;
|
||||
|
||||
/* transformation */
|
||||
vec2 polar = to_polar(uv);
|
||||
polar = radial_displacement(polar);
|
||||
|
||||
uv = to_rectangular(polar);
|
||||
uv = amnesia_displacement(uv);
|
||||
|
||||
uv.x += sin(v_uv.y*PI*2./uni.aa*5.)*.05*p.raster;
|
||||
|
||||
/* pixel manipulation */
|
||||
uv = (uv+1.)/2.;
|
||||
vec4 color = chromatic_aberration(uv);
|
||||
|
||||
if (p.whole_blur > 0.) color = mix(color, blur(uv), p.whole_blur);
|
||||
|
||||
/* blending */
|
||||
float a = radial_fade(polar.x);
|
||||
o_color = mix(vec4(0., 0., 0., 1), color, a);
|
||||
|
||||
/* color manip */
|
||||
o_color = pow(o_color, vec4(1.4));
|
||||
o_color = min(o_color, vec4(max(o_color.r, max(o_color.g, o_color.b)))*.95);
|
||||
o_color *= p.brightness;
|
||||
}
|
57
core/loshader/posteffect.h
Normal file
57
core/loshader/posteffect.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "util/gleasy/framebuffer.h"
|
||||
#include "util/gleasy/program.h"
|
||||
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef gleasy_program_t loshader_posteffect_program_t;
|
||||
|
||||
struct loshader_posteffect_drawer_t;
|
||||
typedef struct loshader_posteffect_drawer_t loshader_posteffect_drawer_t;
|
||||
|
||||
typedef struct {
|
||||
float whole_blur;
|
||||
float raster;
|
||||
|
||||
float radial_displacement;
|
||||
float amnesia_displacement;
|
||||
float radial_fade;
|
||||
|
||||
float brightness;
|
||||
} loshader_posteffect_drawer_param_t;
|
||||
|
||||
void
|
||||
loshader_posteffect_program_initialize(
|
||||
loshader_posteffect_program_t* prog
|
||||
);
|
||||
|
||||
void
|
||||
loshader_posteffect_program_deinitialize(
|
||||
loshader_posteffect_program_t* prog
|
||||
);
|
||||
|
||||
loshader_posteffect_drawer_t* /* OWNERSHIP */
|
||||
loshader_posteffect_drawer_new(
|
||||
const loshader_posteffect_program_t* prog,
|
||||
const loshader_uniblock_t* uniblock,
|
||||
const gleasy_framebuffer_t* fb
|
||||
);
|
||||
|
||||
void
|
||||
loshader_posteffect_drawer_delete(
|
||||
loshader_posteffect_drawer_t* drawer /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loshader_posteffect_drawer_set_param(
|
||||
loshader_posteffect_drawer_t* drawer,
|
||||
const loshader_posteffect_drawer_param_t* param
|
||||
);
|
||||
|
||||
void
|
||||
loshader_posteffect_drawer_draw(
|
||||
const loshader_posteffect_drawer_t* drawer
|
||||
);
|
11
core/loshader/posteffect.vshader
Normal file
11
core/loshader/posteffect.vshader
Normal file
@@ -0,0 +1,11 @@
|
||||
out vec2 v_uv;
|
||||
|
||||
void main(void) {
|
||||
const vec2[] verts = vec2[](
|
||||
vec2(-1., 1.), vec2(-1., -1.), vec2( 1., -1.),
|
||||
vec2(-1., 1.), vec2( 1., -1.), vec2( 1., 1.)
|
||||
);
|
||||
v_uv = gl_VertexID < verts.length()? verts[gl_VertexID]: vec2(0.);
|
||||
|
||||
gl_Position = vec4(v_uv, 0., 1.);
|
||||
}
|
250
core/loshader/set.c
Normal file
250
core/loshader/set.c
Normal file
@@ -0,0 +1,250 @@
|
||||
#include "./set.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/atlas.h"
|
||||
#include "util/gleasy/framebuffer.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./backwall.h"
|
||||
#include "./bullet.h"
|
||||
#include "./character.h"
|
||||
#include "./cinescope.h"
|
||||
#include "./combat_ring.h"
|
||||
#include "./event_line.h"
|
||||
#include "./fog.h"
|
||||
#include "./ground.h"
|
||||
#include "./hud_bar.h"
|
||||
#include "./hud_text.h"
|
||||
#include "./menu_background.h"
|
||||
#include "./menu_stance.h"
|
||||
#include "./menu_text.h"
|
||||
#include "./posteffect.h"
|
||||
#include "./uniblock.h"
|
||||
|
||||
void loshader_set_initialize(
|
||||
loshader_set_t* set,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
const vec2_t* dpi,
|
||||
int32_t max_msaa) {
|
||||
assert(set != NULL);
|
||||
assert(width > 0);
|
||||
assert(height > 0);
|
||||
assert(vec2_valid(dpi));
|
||||
assert(max_msaa > 0);
|
||||
|
||||
*set = (typeof(*set)) {
|
||||
.resolution = vec2(width, height),
|
||||
.dpi = *dpi,
|
||||
};
|
||||
|
||||
set->uniblock = loshader_uniblock_new();
|
||||
loshader_uniblock_update_display_param(set->uniblock, &set->resolution, dpi);
|
||||
|
||||
int max_samples;
|
||||
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_samples);
|
||||
gleasy_framebuffer_initialize(
|
||||
&set->framebuffer, width, height, MATH_MIN(max_samples, max_msaa));
|
||||
|
||||
/* TODO(catfoot): atlas size should depend on DPI. */
|
||||
set->tex = (typeof(set->tex)) {
|
||||
.hud_text = gleasy_atlas_new(GL_RED, 1024, 1024, true),
|
||||
.menu_text = gleasy_atlas_new(GL_RED, 1024, 1024, true),
|
||||
.event_line = gleasy_atlas_new(GL_RED, 1024, 1024, true),
|
||||
};
|
||||
|
||||
loshader_backwall_program_initialize(&set->program.backwall);
|
||||
loshader_ground_program_initialize(&set->program.ground);
|
||||
loshader_character_program_initialize(&set->program.character);
|
||||
loshader_bullet_program_initialize(&set->program.bullet);
|
||||
loshader_fog_program_initialize(&set->program.fog);
|
||||
loshader_pixsort_program_initialize(&set->program.pixsort);
|
||||
loshader_posteffect_program_initialize(&set->program.posteffect);
|
||||
loshader_hud_bar_program_initialize(&set->program.hud_bar);
|
||||
loshader_hud_text_program_initialize(&set->program.hud_text);
|
||||
loshader_menu_background_program_initialize(&set->program.menu_background);
|
||||
loshader_menu_text_program_initialize(&set->program.menu_text);
|
||||
loshader_menu_stance_program_initialize(&set->program.menu_stance);
|
||||
loshader_combat_ring_program_initialize(&set->program.combat_ring);
|
||||
loshader_cinescope_program_initialize(&set->program.cinescope);
|
||||
loshader_event_line_program_initialize(&set->program.event_line);
|
||||
|
||||
set->drawer = (typeof(set->drawer)) {
|
||||
.backwall = loshader_backwall_drawer_new(
|
||||
&set->program.backwall, set->uniblock),
|
||||
|
||||
.ground = loshader_ground_drawer_new(
|
||||
&set->program.ground, set->uniblock),
|
||||
|
||||
.character = loshader_character_drawer_new(
|
||||
&set->program.character, set->uniblock),
|
||||
|
||||
.bullet = loshader_bullet_drawer_new(
|
||||
&set->program.bullet, set->uniblock),
|
||||
|
||||
.fog = loshader_fog_drawer_new(
|
||||
&set->program.fog, set->uniblock),
|
||||
|
||||
.pixsort = loshader_pixsort_drawer_new(
|
||||
&set->program.pixsort, set->uniblock, &set->framebuffer),
|
||||
|
||||
.posteffect = loshader_posteffect_drawer_new(
|
||||
&set->program.posteffect, set->uniblock, &set->framebuffer),
|
||||
|
||||
.hud_bar = loshader_hud_bar_drawer_new(
|
||||
&set->program.hud_bar, set->uniblock),
|
||||
|
||||
.menu_background = loshader_menu_background_drawer_new(
|
||||
&set->program.menu_background, set->uniblock),
|
||||
|
||||
.menu_stance = loshader_menu_stance_drawer_new(
|
||||
&set->program.menu_stance, set->uniblock),
|
||||
|
||||
.combat_ring = loshader_combat_ring_drawer_new(
|
||||
&set->program.combat_ring, set->uniblock),
|
||||
|
||||
.cinescope = loshader_cinescope_drawer_new(
|
||||
&set->program.cinescope, set->uniblock),
|
||||
};
|
||||
|
||||
loshader_hud_text_drawer_initialize(
|
||||
&set->drawer.hud_text,
|
||||
&set->program.hud_text,
|
||||
set->uniblock,
|
||||
gleasy_atlas_get_texture(set->tex.hud_text));
|
||||
|
||||
loshader_menu_text_drawer_initialize(
|
||||
&set->drawer.menu_text,
|
||||
&set->program.menu_text,
|
||||
set->uniblock,
|
||||
gleasy_atlas_get_texture(set->tex.menu_text));
|
||||
|
||||
loshader_event_line_drawer_initialize(
|
||||
&set->drawer.event_line,
|
||||
&set->program.event_line,
|
||||
set->uniblock,
|
||||
gleasy_atlas_get_texture(set->tex.event_line));
|
||||
}
|
||||
|
||||
void loshader_set_deinitialize(loshader_set_t* set) {
|
||||
assert(set != NULL);
|
||||
|
||||
loshader_backwall_drawer_delete(set->drawer.backwall);
|
||||
loshader_ground_drawer_delete(set->drawer.ground);
|
||||
loshader_character_drawer_delete(set->drawer.character);
|
||||
loshader_bullet_drawer_delete(set->drawer.bullet);
|
||||
loshader_fog_drawer_delete(set->drawer.fog);
|
||||
loshader_pixsort_drawer_delete(set->drawer.pixsort);
|
||||
loshader_posteffect_drawer_delete(set->drawer.posteffect);
|
||||
loshader_hud_bar_drawer_delete(set->drawer.hud_bar);
|
||||
loshader_hud_text_drawer_deinitialize(&set->drawer.hud_text);
|
||||
loshader_menu_background_drawer_delete(set->drawer.menu_background);
|
||||
loshader_menu_text_drawer_deinitialize(&set->drawer.menu_text);
|
||||
loshader_menu_stance_drawer_delete(set->drawer.menu_stance);
|
||||
loshader_combat_ring_drawer_delete(set->drawer.combat_ring);
|
||||
loshader_cinescope_drawer_delete(set->drawer.cinescope);
|
||||
loshader_event_line_drawer_deinitialize(&set->drawer.event_line);
|
||||
|
||||
loshader_backwall_program_deinitialize(&set->program.backwall);
|
||||
loshader_ground_program_deinitialize(&set->program.ground);
|
||||
loshader_character_program_deinitialize(&set->program.character);
|
||||
loshader_bullet_program_deinitialize(&set->program.bullet);
|
||||
loshader_fog_program_deinitialize(&set->program.fog);
|
||||
loshader_pixsort_program_deinitialize(&set->program.pixsort);
|
||||
loshader_posteffect_program_deinitialize(&set->program.posteffect);
|
||||
loshader_hud_bar_program_deinitialize(&set->program.hud_bar);
|
||||
loshader_hud_text_program_deinitialize(&set->program.hud_text);
|
||||
loshader_menu_background_program_deinitialize(&set->program.menu_background);
|
||||
loshader_menu_text_program_deinitialize(&set->program.menu_text);
|
||||
loshader_menu_stance_program_deinitialize(&set->program.menu_stance);
|
||||
loshader_combat_ring_program_deinitialize(&set->program.combat_ring);
|
||||
loshader_cinescope_program_deinitialize(&set->program.cinescope);
|
||||
loshader_event_line_program_deinitialize(&set->program.event_line);
|
||||
|
||||
gleasy_atlas_delete(set->tex.hud_text);
|
||||
gleasy_atlas_delete(set->tex.menu_text);
|
||||
gleasy_atlas_delete(set->tex.event_line);
|
||||
|
||||
loshader_uniblock_delete(set->uniblock);
|
||||
gleasy_framebuffer_deinitialize(&set->framebuffer);
|
||||
}
|
||||
|
||||
void loshader_set_clear_all(loshader_set_t* set) {
|
||||
assert(set != NULL);
|
||||
|
||||
loshader_ground_drawer_clear(set->drawer.ground, 256);
|
||||
loshader_character_drawer_clear(set->drawer.character, 256);
|
||||
loshader_bullet_drawer_clear(set->drawer.bullet, 256);
|
||||
|
||||
loshader_hud_bar_drawer_clear(set->drawer.hud_bar, 16);
|
||||
loshader_hud_text_drawer_clear(&set->drawer.hud_text, 256);
|
||||
loshader_menu_background_drawer_set_alpha(set->drawer.menu_background, 0);
|
||||
loshader_menu_text_drawer_clear(&set->drawer.menu_text, 512);
|
||||
loshader_menu_stance_drawer_clear(set->drawer.menu_stance, 16);
|
||||
loshader_combat_ring_drawer_clear(set->drawer.combat_ring, 8);
|
||||
loshader_event_line_drawer_clear(&set->drawer.event_line, 256);
|
||||
}
|
||||
|
||||
void loshader_set_draw_all(const loshader_set_t* set) {
|
||||
assert(set != NULL);
|
||||
|
||||
/* ---- path 1: game ---- */
|
||||
gleasy_framebuffer_bind(&set->framebuffer);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
loshader_backwall_drawer_draw(set->drawer.backwall);
|
||||
loshader_ground_drawer_draw(set->drawer.ground);
|
||||
loshader_character_drawer_draw(set->drawer.character);
|
||||
loshader_bullet_drawer_draw(set->drawer.bullet);
|
||||
loshader_fog_drawer_draw(set->drawer.fog);
|
||||
|
||||
gleasy_framebuffer_flush(&set->framebuffer);
|
||||
|
||||
/* ---- path 2: pixsort ---- */
|
||||
if (!loshader_pixsort_drawer_is_skippable(set->drawer.pixsort)) {
|
||||
gleasy_framebuffer_bind(&set->framebuffer);
|
||||
loshader_pixsort_drawer_draw(set->drawer.pixsort);
|
||||
gleasy_framebuffer_flush(&set->framebuffer);
|
||||
}
|
||||
|
||||
/* ---- path 2: HUD ---- */
|
||||
gleasy_framebuffer_bind(&set->framebuffer);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
|
||||
loshader_posteffect_drawer_draw(set->drawer.posteffect);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
loshader_hud_bar_drawer_draw(set->drawer.hud_bar);
|
||||
loshader_hud_text_drawer_draw(&set->drawer.hud_text);
|
||||
loshader_menu_background_drawer_draw(set->drawer.menu_background);
|
||||
loshader_menu_text_drawer_draw(&set->drawer.menu_text);
|
||||
loshader_menu_stance_drawer_draw(set->drawer.menu_stance);
|
||||
loshader_combat_ring_drawer_draw(set->drawer.combat_ring);
|
||||
loshader_cinescope_drawer_draw(set->drawer.cinescope);
|
||||
loshader_event_line_drawer_draw(&set->drawer.event_line);
|
||||
|
||||
gleasy_framebuffer_flush_to_other(&set->framebuffer, 0);
|
||||
}
|
||||
|
||||
void loshader_set_drop_cache(loshader_set_t* set) {
|
||||
assert(set != NULL);
|
||||
|
||||
gleasy_atlas_clear(set->tex.hud_text);
|
||||
gleasy_atlas_clear(set->tex.menu_text);
|
||||
gleasy_atlas_clear(set->tex.event_line);
|
||||
}
|
103
core/loshader/set.h
Normal file
103
core/loshader/set.h
Normal file
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/gleasy/atlas.h"
|
||||
#include "util/gleasy/framebuffer.h"
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "./backwall.h"
|
||||
#include "./bullet.h"
|
||||
#include "./character.h"
|
||||
#include "./cinescope.h"
|
||||
#include "./combat_ring.h"
|
||||
#include "./event_line.h"
|
||||
#include "./fog.h"
|
||||
#include "./ground.h"
|
||||
#include "./hud_bar.h"
|
||||
#include "./hud_text.h"
|
||||
#include "./menu_background.h"
|
||||
#include "./menu_stance.h"
|
||||
#include "./menu_text.h"
|
||||
#include "./pixsort.h"
|
||||
#include "./posteffect.h"
|
||||
#include "./uniblock.h"
|
||||
|
||||
typedef struct {
|
||||
gleasy_framebuffer_t framebuffer;
|
||||
loshader_uniblock_t* uniblock;
|
||||
|
||||
struct {
|
||||
gleasy_atlas_t* hud_text;
|
||||
gleasy_atlas_t* menu_text;
|
||||
gleasy_atlas_t* event_line;
|
||||
} tex;
|
||||
|
||||
struct {
|
||||
loshader_backwall_program_t backwall;
|
||||
loshader_ground_program_t ground;
|
||||
loshader_character_program_t character;
|
||||
loshader_bullet_program_t bullet;
|
||||
loshader_fog_program_t fog;
|
||||
loshader_pixsort_program_t pixsort;
|
||||
loshader_posteffect_program_t posteffect;
|
||||
loshader_hud_bar_program_t hud_bar;
|
||||
loshader_hud_text_program_t hud_text;
|
||||
loshader_menu_background_program_t menu_background;
|
||||
loshader_menu_text_program_t menu_text;
|
||||
loshader_menu_stance_program_t menu_stance;
|
||||
loshader_combat_ring_program_t combat_ring;
|
||||
loshader_cinescope_program_t cinescope;
|
||||
loshader_event_line_program_t event_line;
|
||||
} program;
|
||||
|
||||
struct {
|
||||
loshader_backwall_drawer_t* backwall;
|
||||
loshader_ground_drawer_t* ground;
|
||||
loshader_character_drawer_t* character;
|
||||
loshader_bullet_drawer_t* bullet;
|
||||
loshader_fog_drawer_t* fog;
|
||||
loshader_pixsort_drawer_t* pixsort;
|
||||
loshader_posteffect_drawer_t* posteffect;
|
||||
loshader_hud_bar_drawer_t* hud_bar;
|
||||
loshader_hud_text_drawer_t hud_text;
|
||||
loshader_menu_background_drawer_t* menu_background;
|
||||
loshader_menu_text_drawer_t menu_text;
|
||||
loshader_menu_stance_drawer_t* menu_stance;
|
||||
loshader_combat_ring_drawer_t* combat_ring;
|
||||
loshader_cinescope_drawer_t* cinescope;
|
||||
loshader_event_line_drawer_t event_line;
|
||||
} drawer;
|
||||
|
||||
vec2_t resolution;
|
||||
vec2_t dpi;
|
||||
} loshader_set_t;
|
||||
|
||||
void
|
||||
loshader_set_initialize(
|
||||
loshader_set_t* set,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
const vec2_t* dpi,
|
||||
int32_t max_msaa
|
||||
);
|
||||
|
||||
void
|
||||
loshader_set_deinitialize(
|
||||
loshader_set_t* set
|
||||
);
|
||||
|
||||
void
|
||||
loshader_set_clear_all(
|
||||
loshader_set_t* set
|
||||
);
|
||||
|
||||
void
|
||||
loshader_set_draw_all(
|
||||
const loshader_set_t* set
|
||||
);
|
||||
|
||||
void
|
||||
loshader_set_drop_cache(
|
||||
loshader_set_t* set
|
||||
);
|
117
core/loshader/uniblock.c
Normal file
117
core/loshader/uniblock.c
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "./uniblock.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/gleasy/buffer.h"
|
||||
#include "util/math/algorithm.h"
|
||||
#include "util/math/vector.h"
|
||||
#include "util/math/matrix.h"
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
struct loshader_uniblock_t {
|
||||
gleasy_buffer_uniform_t buf;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
vec2_t resolution;
|
||||
vec2_t dpi;
|
||||
float aa;
|
||||
|
||||
int8_t padding[12];
|
||||
|
||||
mat4_t proj;
|
||||
mat4_t camera;
|
||||
vec4_t pos;
|
||||
float time;
|
||||
} loshader_uniblock_internal_t;
|
||||
_Static_assert(
|
||||
sizeof(float)*5 + 12 + sizeof(float)*37 ==
|
||||
sizeof(loshader_uniblock_internal_t));
|
||||
#pragma pack(pop)
|
||||
|
||||
bool loshader_uniblock_param_valid(const loshader_uniblock_param_t* param) {
|
||||
return
|
||||
param != NULL &&
|
||||
mat4_valid(¶m->proj) &&
|
||||
mat4_valid(¶m->cam) &&
|
||||
locommon_position_valid(¶m->pos) &&
|
||||
MATH_FLOAT_VALID(param->time);
|
||||
}
|
||||
|
||||
loshader_uniblock_t* loshader_uniblock_new(void) {
|
||||
loshader_uniblock_t* uni = memory_new(sizeof(*uni));
|
||||
*uni = (typeof(*uni)) {0};
|
||||
|
||||
glGenBuffers(1, &uni->buf);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, uni->buf);
|
||||
glBufferData(GL_UNIFORM_BUFFER,
|
||||
sizeof(loshader_uniblock_internal_t), NULL, GL_DYNAMIC_DRAW);
|
||||
|
||||
return uni;
|
||||
}
|
||||
|
||||
void loshader_uniblock_delete(loshader_uniblock_t* uni) {
|
||||
if (uni == NULL) return;
|
||||
|
||||
glDeleteBuffers(1, &uni->buf);
|
||||
memory_delete(uni);
|
||||
}
|
||||
|
||||
void loshader_uniblock_update_display_param(
|
||||
loshader_uniblock_t* uni, const vec2_t* resolution, const vec2_t* dpi) {
|
||||
assert(uni != NULL);
|
||||
assert(vec2_valid(resolution));
|
||||
assert(vec2_valid(dpi));
|
||||
|
||||
const loshader_uniblock_internal_t internal = {
|
||||
.resolution = *resolution,
|
||||
.dpi = *dpi,
|
||||
.aa = MATH_MAX(dpi->x, dpi->y) / 100000,
|
||||
};
|
||||
|
||||
static const size_t size =
|
||||
offsetof(loshader_uniblock_internal_t, aa) + sizeof(internal.aa);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, uni->buf);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, size, &internal);
|
||||
}
|
||||
|
||||
void loshader_uniblock_update_param(
|
||||
loshader_uniblock_t* uni,
|
||||
const loshader_uniblock_param_t* param) {
|
||||
assert(uni != NULL);
|
||||
assert(loshader_uniblock_param_valid(param));
|
||||
|
||||
const vec4_t pos = vec4(
|
||||
param->pos.chunk.x,
|
||||
param->pos.chunk.y,
|
||||
param->pos.fract.x,
|
||||
param->pos.fract.y);
|
||||
|
||||
const loshader_uniblock_internal_t internal = {
|
||||
.proj = param->proj,
|
||||
.camera = param->cam,
|
||||
.pos = pos,
|
||||
.time = param->time,
|
||||
};
|
||||
|
||||
static const size_t offset = offsetof(loshader_uniblock_internal_t, proj);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, uni->buf);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER,
|
||||
offset, sizeof(internal)-offset, &internal.proj);
|
||||
}
|
||||
|
||||
void loshader_uniblock_bind(const loshader_uniblock_t* uni, GLuint index) {
|
||||
assert(uni != NULL);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, index, uni->buf);
|
||||
}
|
56
core/loshader/uniblock.h
Normal file
56
core/loshader/uniblock.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
#include "util/math/matrix.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
struct loshader_uniblock_t;
|
||||
typedef struct loshader_uniblock_t loshader_uniblock_t;
|
||||
|
||||
typedef struct {
|
||||
mat4_t proj;
|
||||
mat4_t cam;
|
||||
|
||||
locommon_position_t pos;
|
||||
|
||||
float time;
|
||||
} loshader_uniblock_param_t;
|
||||
|
||||
bool
|
||||
loshader_uniblock_param_valid(
|
||||
const loshader_uniblock_param_t* param
|
||||
);
|
||||
|
||||
loshader_uniblock_t* /* OWNERSHIP */
|
||||
loshader_uniblock_new(
|
||||
void
|
||||
);
|
||||
|
||||
void
|
||||
loshader_uniblock_delete(
|
||||
loshader_uniblock_t* uni /* OWNERSHIP */
|
||||
);
|
||||
|
||||
void
|
||||
loshader_uniblock_update_display_param(
|
||||
loshader_uniblock_t* uni,
|
||||
const vec2_t* resolution,
|
||||
const vec2_t* dpi
|
||||
);
|
||||
|
||||
void
|
||||
loshader_uniblock_update_param(
|
||||
loshader_uniblock_t* uni,
|
||||
const loshader_uniblock_param_t* param
|
||||
);
|
||||
|
||||
void
|
||||
loshader_uniblock_bind(
|
||||
const loshader_uniblock_t* uni,
|
||||
GLuint index
|
||||
);
|
Reference in New Issue
Block a user