Compare commits

..

No commits in common. "4d74b5e3e9a597a63d6a3e38143e2ec8382e8ac7" and "a06aacd405e06f36a0eb7a878a3104b679c9bd6f" have entirely different histories.

13 changed files with 386 additions and 3219 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +0,0 @@
// File: bc7enc.h - Richard Geldreich, Jr. - MIT license or public domain (see end of bc7enc.c)
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BC7ENC_BLOCK_SIZE (16)
#define BC7ENC_MAX_PARTITIONS1 (64)
#define BC7ENC_MAX_UBER_LEVEL (4)
typedef uint8_t bc7enc_bool;
#define BC7ENC_TRUE (1)
#define BC7ENC_FALSE (0)
typedef struct
{
// m_max_partitions_mode may range from 0 (disables mode 1) to BC7ENC_MAX_PARTITIONS1. The higher this value, the slower the compressor, but the higher the quality.
uint32_t m_max_partitions_mode;
// Relative RGBA or YCbCrA weights.
uint32_t m_weights[4];
// m_uber_level may range from 0 to BC7ENC_MAX_UBER_LEVEL. The higher this value, the slower the compressor, but the higher the quality.
uint32_t m_uber_level;
// If m_perceptual is true, colorspace error is computed in YCbCr space, otherwise RGB.
bc7enc_bool m_perceptual;
// Set m_try_least_squares to false for slightly faster/lower quality compression.
bc7enc_bool m_try_least_squares;
// When m_mode_partition_estimation_filterbank, the mode1 partition estimator skips lesser used partition patterns unless they are strongly predicted to be potentially useful.
// There's a slight loss in quality with this enabled (around .08 dB RGB PSNR or .05 dB Y PSNR), but up to a 11% gain in speed depending on the other settings.
bc7enc_bool m_mode_partition_estimation_filterbank;
bc7enc_bool m_use_mode5_for_alpha;
bc7enc_bool m_use_mode7_for_alpha;
} bc7enc_compress_block_params;
inline static void bc7enc_compress_block_params_init_linear_weights(bc7enc_compress_block_params *p)
{
p->m_perceptual = BC7ENC_FALSE;
p->m_weights[0] = 1;
p->m_weights[1] = 1;
p->m_weights[2] = 1;
p->m_weights[3] = 1;
}
inline static void bc7enc_compress_block_params_init_perceptual_weights(bc7enc_compress_block_params *p)
{
p->m_perceptual = BC7ENC_TRUE;
p->m_weights[0] = 128;
p->m_weights[1] = 64;
p->m_weights[2] = 16;
p->m_weights[3] = 32;
}
inline static void bc7enc_compress_block_params_init(bc7enc_compress_block_params *p)
{
p->m_max_partitions_mode = BC7ENC_MAX_PARTITIONS1;
p->m_try_least_squares = BC7ENC_TRUE;
p->m_mode_partition_estimation_filterbank = BC7ENC_TRUE;
p->m_uber_level = 0;
p->m_use_mode5_for_alpha = BC7ENC_TRUE;
p->m_use_mode7_for_alpha = BC7ENC_TRUE;
bc7enc_compress_block_params_init_perceptual_weights(p);
}
// bc7enc_compress_block_init() MUST be called before calling bc7enc_compress_block() (or you'll get artifacts).
void bc7enc_compress_block_init();
// Packs a single block of 16x16 RGBA pixels (R first in memory) to 128-bit BC7 block pBlock, using either mode 1 and/or 6.
// Alpha blocks will always use mode 6, and by default opaque blocks will use either modes 1 or 6.
// Returns BC7ENC_TRUE if the block had any pixels with alpha < 255, otherwise it return BC7ENC_FALSE. (This is not an error code - a block is always encoded.)
bc7enc_bool bc7enc_compress_block(void *pBlock, const void *pPixelsRGBA, const bc7enc_compress_block_params *pComp_params);
#ifdef __cplusplus
}
#endif

682
src/k3.c

File diff suppressed because it is too large Load Diff

View File

@ -6,13 +6,8 @@
#include<cglm/mat4.h>
#include<cglm/quat.h>
#ifdef k3_MULTITHREAD
#include<pthread.h>
#endif
void k3Init();
void k3Resize(uint16_t width, uint16_t height);
void k3Update();
enum k3TexType {
k3_DIFFUSE, k3_NORMAL, k3_DISPLACEMENT, k3_EMISSION, k3_ROUGHNESS, k3_ALPHA,
@ -48,8 +43,7 @@ struct k3ARBFP;
struct k3ARBFP *k3ProgramARBFP(const char *src);
extern uint8_t k3GraphicalReduction;
extern bool k3IsCore;
extern bool k3IsSoftSkinning;
extern int k3IsCore;
struct k3Mat {
struct {
@ -97,7 +91,6 @@ struct k3Mat {
char transparent;
char nocull;
char alphatest;
char depthwrite;
} passes[1];
};
@ -141,7 +134,6 @@ struct k3Light {
_Alignas(16) union {
struct {
vec4 direction;
uint8_t cascadeCount;
} dir;
struct {
vec4 position;
@ -163,8 +155,6 @@ struct k3Storage;
void k3StorageRef(struct k3Storage*);
void k3StorageUnref(struct k3Storage*);
#define k3_ATTRIB_NONE (NULL)
#define k3_ATTRIB_EMPTY ((void*) 1)
struct k3Mdl;
struct k3Mdl *k3MdlCreate(size_t verts, size_t indices, size_t boneCount, vec3 *pos, uint8_t *nrm, float *uvs, uint8_t *cols, uint8_t *boneids, uint16_t *boneweights, uint16_t *inds, mat4 *invBind, uint8_t *boneParents);
void k3MdlUpdatePos(struct k3Mdl *mdl, vec3 *pos);
@ -195,7 +185,6 @@ void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull);
void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr);
struct k3Offscreen;
struct k3Offscreen *k3OffscreenCreateMultisampled(struct k3Tex *diffuse, struct k3Tex *depth, uint8_t samples);
struct k3Offscreen *k3OffscreenCreate(struct k3Tex *diffuse, struct k3Tex *depth);
void k3BeginOffscreen(struct k3Offscreen*);
void k3EndOffscreen(struct k3Offscreen*);

View File

@ -1,83 +0,0 @@
#pragma once
#include"k3.h"
#include"gl.h"
#include<cglm/vec2.h>
#include<cglm/frustum.h>
#include<cglm/cam.h>
#define GL_FROM_K3TEX(k3t) ((k3t) ? (k3t)->tex : 0)
#define GL_FROM_K3MARCHER(k3m) ((GLuint) (uintptr_t) (k3m))
#define GL_FROM_K3ARBVP(k3m) ((GLuint) (uintptr_t) (k3m))
#define GL_FROM_K3ARBFP(k3m) ((GLuint) (uintptr_t) (k3m))
#define GL_FROM_K3GLSL(k3m) ((GLuint) (uintptr_t) (k3m))
struct k3Tex {
GLuint tex;
int cubemap;
uint32_t szX;
uint32_t szY;
uint32_t szZ;
GLuint glInternalFormat;
GLuint glExternalFormat;
GLuint glInType;
bool mipmap;
// Asynchronous decoding
uint8_t deferredRemaining;
uint8_t *deferredData[6];
struct k3Tex *deferredNext;
};
struct k3Storage {
int16_t ref;
void(*free)(struct k3Storage*);
};
struct k3StorageBasic {
struct k3Storage;
GLuint gl;
};
struct k3Offscreen {
GLuint fbo;
struct k3Tex *diffuse;
struct k3Tex *depth;
struct {
uint8_t samples;
GLuint fbo;
GLuint rboDiffuse;
GLuint rboDepth;
} multisampling;
};
struct k3Mdl {
struct {
vec3 *pos;
uint8_t *boneids;
uint16_t *boneweights;
} cpuSkinning;
size_t verts;
struct k3StorageBasic *vstore;
struct k3StorageBasic *estore;
uint16_t meshCount;
struct k3Mesh *meshes;
size_t boneCount;
mat4 *invBind;
uint8_t *boneParents;
uint16_t animCount;
struct k3Animation **anims;
vec3 aabb[2];
int offV, offN, offC, offU, offB, offT;
const char *debugname;
};

View File

@ -12,8 +12,6 @@ struct S {
};
static struct k3Tex *activeTex;
static float activeBorderRadius;
static size_t SCount, SCapacity;
static struct S *S;
@ -27,33 +25,21 @@ void k3BatchInit() {
"in vec2 a_pos;\n"
"in vec2 a_uv;\n"
"in vec4 a_color;\n"
"in vec2 a_size;\n"
"out vec2 v_uv;\n"
"out vec4 v_color;\n"
"out vec2 v_size;\n"
"void main() {\n"
" v_uv = a_uv;\n"
" v_color = a_color;\n"
" v_size = a_size;\n"
" gl_Position = vec4(vec2(a_pos.x / 3600.0, a_pos.y / 2025.0) * 2.0 - 1.0, 0.0, 1.0);\n"
"}\n"
, NULL), k3ShaderGLSLF(
"#version 330\n"
"uniform sampler2D u_tex;\n"
"uniform float u_texuse;\n"
"uniform float u_borderradius;\n"
"in vec2 v_uv;\n"
"in vec4 v_color;\n"
"in vec2 v_size;\n"
"out vec4 fragcolor;\n"
"void main() {\n"
" vec2 sz = v_size / 2.0;\n"
" vec2 c = abs(v_uv * 2.0 - 1.0);\n"
" c = c * (sz + u_borderradius);\n"
" c = max(c - sz, 0.0);\n"
" if(length(c) > u_borderradius) {\n"
" discard;\n"
" }\n"
" fragcolor = mix(vec4(1, 1, 1, 1), texture2D(u_tex, v_uv), u_texuse) * v_color;\n"
"}\n"
, NULL), NULL);
@ -62,11 +48,10 @@ void k3BatchInit() {
}
}
void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color, float borderRadius) {
if(activeTex != tex || borderRadius != activeBorderRadius) {
void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color) {
if(activeTex != tex) {
k3BatchFlush();
activeTex = tex;
activeBorderRadius = borderRadius;
}
if(SCount == SCapacity) {
@ -88,8 +73,6 @@ void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float
}
void k3BatchFlush() {
if(!S) return;
if(!k3IsCore) {
glDisable(GL_NORMALIZE);
@ -125,107 +108,89 @@ void k3BatchFlush() {
if(k3IsCore) {
glUseProgram((GLuint) coreProg);
float *farr = alloca(SCount * 60 * sizeof(*farr));
float *farr = alloca(SCount * 48 * sizeof(*farr));
struct S *s = S;
for(size_t i = 0; i < SCount; i++) {
farr[i * 60 + 0] = s->dst.x;
farr[i * 60 + 1] = s->dst.y;
farr[i * 60 + 2] = s->src.x;
farr[i * 60 + 3] = s->src.y + s->src.h;
farr[i * 60 + 4] = s->color[0];
farr[i * 60 + 5] = s->color[1];
farr[i * 60 + 6] = s->color[2];
farr[i * 60 + 7] = s->color[3];
farr[i * 60 + 8] = s->dst.w;
farr[i * 60 + 9] = s->dst.h;
farr[i * 48 + 0] = s->dst.x;
farr[i * 48 + 1] = s->dst.y;
farr[i * 48 + 2] = s->src.x;
farr[i * 48 + 3] = s->src.y + s->src.h;
farr[i * 48 + 4] = s->color[0];
farr[i * 48 + 5] = s->color[1];
farr[i * 48 + 6] = s->color[2];
farr[i * 48 + 7] = s->color[3];
farr[i * 60 + 10] = s->dst.x + s->dst.w;
farr[i * 60 + 11] = s->dst.y;
farr[i * 60 + 12] = s->src.x + s->src.w;
farr[i * 60 + 13] = s->src.y + s->src.h;
farr[i * 60 + 14] = s->color[0];
farr[i * 60 + 15] = s->color[1];
farr[i * 60 + 16] = s->color[2];
farr[i * 60 + 17] = s->color[3];
farr[i * 60 + 18] = s->dst.w;
farr[i * 60 + 19] = s->dst.h;
farr[i * 48 + 8] = s->dst.x + s->dst.w;
farr[i * 48 + 9] = s->dst.y;
farr[i * 48 + 10] = s->src.x + s->src.w;
farr[i * 48 + 11] = s->src.y + s->src.h;
farr[i * 48 + 12] = s->color[0];
farr[i * 48 + 13] = s->color[1];
farr[i * 48 + 14] = s->color[2];
farr[i * 48 + 15] = s->color[3];
farr[i * 60 + 20] = s->dst.x + s->dst.w;
farr[i * 60 + 21] = s->dst.y + s->dst.h;
farr[i * 60 + 22] = s->src.x + s->src.w;
farr[i * 60 + 23] = s->src.y;
farr[i * 60 + 24] = s->color[0];
farr[i * 60 + 25] = s->color[1];
farr[i * 60 + 26] = s->color[2];
farr[i * 60 + 27] = s->color[3];
farr[i * 60 + 28] = s->dst.w;
farr[i * 60 + 29] = s->dst.h;
farr[i * 48 + 16] = s->dst.x + s->dst.w;
farr[i * 48 + 17] = s->dst.y + s->dst.h;
farr[i * 48 + 18] = s->src.x + s->src.w;
farr[i * 48 + 19] = s->src.y;
farr[i * 48 + 20] = s->color[0];
farr[i * 48 + 21] = s->color[1];
farr[i * 48 + 22] = s->color[2];
farr[i * 48 + 23] = s->color[3];
farr[i * 60 + 30] = s->dst.x;
farr[i * 60 + 31] = s->dst.y;
farr[i * 60 + 32] = s->src.x;
farr[i * 60 + 33] = s->src.y + s->src.h;
farr[i * 60 + 34] = s->color[0];
farr[i * 60 + 35] = s->color[1];
farr[i * 60 + 36] = s->color[2];
farr[i * 60 + 37] = s->color[3];
farr[i * 60 + 38] = s->dst.w;
farr[i * 60 + 39] = s->dst.h;
farr[i * 48 + 24] = s->dst.x;
farr[i * 48 + 25] = s->dst.y;
farr[i * 48 + 26] = s->src.x;
farr[i * 48 + 27] = s->src.y + s->src.h;
farr[i * 48 + 28] = s->color[0];
farr[i * 48 + 29] = s->color[1];
farr[i * 48 + 30] = s->color[2];
farr[i * 48 + 31] = s->color[3];
farr[i * 60 + 40] = s->dst.x + s->dst.w;
farr[i * 60 + 41] = s->dst.y + s->dst.h;
farr[i * 60 + 42] = s->src.x + s->src.w;
farr[i * 60 + 43] = s->src.y;
farr[i * 60 + 44] = s->color[0];
farr[i * 60 + 45] = s->color[1];
farr[i * 60 + 46] = s->color[2];
farr[i * 60 + 47] = s->color[3];
farr[i * 60 + 48] = s->dst.w;
farr[i * 60 + 49] = s->dst.h;
farr[i * 48 + 32] = s->dst.x + s->dst.w;
farr[i * 48 + 33] = s->dst.y + s->dst.h;
farr[i * 48 + 34] = s->src.x + s->src.w;
farr[i * 48 + 35] = s->src.y;
farr[i * 48 + 36] = s->color[0];
farr[i * 48 + 37] = s->color[1];
farr[i * 48 + 38] = s->color[2];
farr[i * 48 + 39] = s->color[3];
farr[i * 60 + 50] = s->dst.x;
farr[i * 60 + 51] = s->dst.y + s->dst.h;
farr[i * 60 + 52] = s->src.x;
farr[i * 60 + 53] = s->src.y;
farr[i * 60 + 54] = s->color[0];
farr[i * 60 + 55] = s->color[1];
farr[i * 60 + 56] = s->color[2];
farr[i * 60 + 57] = s->color[3];
farr[i * 60 + 58] = s->dst.w;
farr[i * 60 + 59] = s->dst.h;
farr[i * 48 + 40] = s->dst.x;
farr[i * 48 + 41] = s->dst.y + s->dst.h;
farr[i * 48 + 42] = s->src.x;
farr[i * 48 + 43] = s->src.y;
farr[i * 48 + 44] = s->color[0];
farr[i * 48 + 45] = s->color[1];
farr[i * 48 + 46] = s->color[2];
farr[i * 48 + 47] = s->color[3];
s++;
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB, coreVBO);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, SCount * 60 * sizeof(*farr), farr, GL_DYNAMIC_DRAW);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, SCount * 48 * sizeof(*farr), farr, GL_DYNAMIC_DRAW);
glUniform1f(glGetUniformLocation((GLuint) coreProg, "u_texuse"), !!activeTex);
glUniform1f(glGetUniformLocation((GLuint) coreProg, "u_borderradius"), activeBorderRadius);
GLint aPos = glGetAttribLocation((GLuint) coreProg, "a_pos");
GLint aUv = glGetAttribLocation((GLuint) coreProg, "a_uv");
GLint aColor = glGetAttribLocation((GLuint) coreProg, "a_color");
GLint aSize = glGetAttribLocation((GLuint) coreProg, "a_size");
glEnableVertexAttribArray(aPos);
glEnableVertexAttribArray(aUv);
glEnableVertexAttribArray(aColor);
glEnableVertexAttribArray(aSize);
glVertexAttribPointer(aPos, 2, GL_FLOAT, GL_FALSE, 40, (void*) 0);
glVertexAttribPointer(aUv, 2, GL_FLOAT, GL_FALSE, 40, (void*) 8);
glVertexAttribPointer(aColor, 4, GL_FLOAT, GL_FALSE, 40, (void*) 16);
glVertexAttribPointer(aSize, 2, GL_FLOAT, GL_FALSE, 40, (void*) 32);
glVertexAttribPointer(aPos, 2, GL_FLOAT, GL_FALSE, 32, (void*) 0);
glVertexAttribPointer(aUv, 2, GL_FLOAT, GL_FALSE, 32, (void*) 8);
glVertexAttribPointer(aColor, 4, GL_FLOAT, GL_FALSE, 32, (void*) 16);
glDrawArrays(GL_TRIANGLES, 0, SCount * 6);
glDisableVertexAttribArray(aPos);
glDisableVertexAttribArray(aUv);
glDisableVertexAttribArray(aColor);
glDisableVertexAttribArray(aSize);
} else {
if(GLAD_GL_ARB_shading_language_100) {
glUseProgramObjectARB(0);

View File

@ -10,5 +10,5 @@ struct k3RectF {
float h;
};
void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color, float borderRadius);
void k3BatchFlush();
void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color);
void k3BatchFlush();

View File

@ -32,8 +32,8 @@ int make_mb1() {
if(!v) return 0;
struct k3GLSLF *f = !k3IsCore ? k3ShaderGLSLF(
"#define THRESHOLD 0.6" "\n"
"#define FACTOR 0.07" "\n"
"#define THRESHOLD 0.7" "\n"
"#define FACTOR 0.08" "\n"
"uniform sampler2D u_tex;" "\n"
"varying vec2 v_uv;" "\n"
"vec3 get_col(vec2 uv) {" "\n"
@ -57,8 +57,8 @@ int make_mb1() {
"}" "\n"
, NULL) : k3ShaderGLSLF(
"#version 330\n"
"#define THRESHOLD 0.6" "\n"
"#define FACTOR 0.07" "\n"
"#define THRESHOLD 0.7" "\n"
"#define FACTOR 0.08" "\n"
"uniform sampler2D u_tex;" "\n"
"in vec2 v_uv;" "\n"
"out vec4 fragcolor;" "\n"
@ -122,15 +122,15 @@ int make_mb2() {
"}" "\n"
"void main() {" "\n"
" vec3 c = vec3(0);" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, -4.0 / 256.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, -3.0 / 256.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, -2.0 / 256.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, -1.0 / 256.0));" "\n"
" c += 0.3829 * get_col(v_uv + vec2(0, +0.0 / 256.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, +1.0 / 256.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, +2.0 / 256.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, +3.0 / 256.0));" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, +4.0 / 256.0));" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, -4.0 / 512.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, -3.0 / 512.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, -2.0 / 512.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, -1.0 / 512.0));" "\n"
" c += 0.3829 * get_col(v_uv + vec2(0, +0.0 / 512.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, +1.0 / 512.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, +2.0 / 512.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, +3.0 / 512.0));" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, +4.0 / 512.0));" "\n"
" gl_FragColor = vec4(c, 1);" "\n"
"}" "\n"
, NULL) : k3ShaderGLSLF(
@ -144,15 +144,15 @@ int make_mb2() {
"}" "\n"
"void main() {" "\n"
" vec3 c = vec3(0);" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, -4.0 / 256.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, -3.0 / 256.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, -2.0 / 256.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, -1.0 / 256.0));" "\n"
" c += 0.3829 * get_col(v_uv + vec2(0, +0.0 / 256.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, +1.0 / 256.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, +2.0 / 256.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, +3.0 / 256.0));" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, +4.0 / 256.0));" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, -4.0 / 512.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, -3.0 / 512.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, -2.0 / 512.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, -1.0 / 512.0));" "\n"
" c += 0.3829 * get_col(v_uv + vec2(0, +0.0 / 512.0));" "\n"
" c += 0.2417 * get_col(v_uv + vec2(0, +1.0 / 512.0));" "\n"
" c += 0.0606 * get_col(v_uv + vec2(0, +2.0 / 512.0));" "\n"
" c += 0.0060 * get_col(v_uv + vec2(0, +3.0 / 512.0));" "\n"
" c += 0.0020 * get_col(v_uv + vec2(0, +4.0 / 512.0));" "\n"
" fragcolor = vec4(c, 1);" "\n"
"}" "\n"
, NULL);
@ -237,7 +237,7 @@ int make_tonemapper() {
"}" "\n"
"vec3 get_col(vec2 uv) {" "\n"
" vec3 col = texture2D(u_tex, uv).rgb;" "\n"
" col = toner(col, 0.80, 1.0);" "\n"
" col = toner(col, 0.80, 1.5);" "\n"
" return col;" "\n"
"}" "\n"
"void main() {" "\n"

View File

@ -131,7 +131,6 @@ void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const
struct k3Tex *tex = this->pages[g->page];
size_t texW = this->texW;
size_t texH = this->texH;
k3BatchAdd(tex,
(struct k3RectF) {(float) g->x / texW, (float) g->y / texH, (float) g->width / texW, (float) g->height / texH},
(struct k3RectF) {
@ -139,7 +138,7 @@ void k3FontDraw(struct k3Font *this, float xStart, float yStart, float sz, const
y + ((-g->height - g->yoffset) * this->lineScale + 1) * sz,
g->width * this->lineScale * sz,
g->height * this->lineScale * sz
}, 0, color, 0);
}, 0, color);
x += g->xadvance * this->lineScale * sz;
}

View File

@ -70,30 +70,9 @@ bool k3MEventSend(struct k3MEvent *ev) {
return true;
}
static void obj_draw(struct k3MObj *this) {
struct k3MProperty *borderRadiusProp = k3MFindProperty(this, k3M_PROP_BORDER_RADIUS, false);
float borderRadius = borderRadiusProp ? borderRadiusProp->si[0] : 0;
struct k3MProperty *bgColorProp = k3MFindProperty(this, k3M_PROP_BG_COLOR, false);
vec4 bgColor = {0, 0, 0, 0};
if(bgColorProp) {
bgColor[0] = bgColorProp->si[0] / 255.0;
bgColor[1] = bgColorProp->si[1] / 255.0;
bgColor[2] = bgColorProp->si[2] / 255.0;
bgColor[3] = bgColorProp->si[3] / 255.0;
}
k3BatchAdd(NULL, (struct k3RectF) {0, 0, 1, 1}, (struct k3RectF) {
this->x, this->y,
this->w, this->h
}, 0, bgColor, borderRadius);
}
static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
struct k3MLabel *this = (void*) ev->target;
obj_draw((void*) this);
if(this->txt) {
k3FontDraw(this->font, this->x, this->y, this->sz, this->txt, (vec4) {1, 1, 1, 1});
}
@ -139,29 +118,51 @@ void k3MAddChild(struct k3MObj *parent, struct k3MObj *child) {
child->parent = parent;
}
void k3MOverrideProperty(struct k3MObj *obj, struct k3MProperty n) {
struct k3MProperty *o = k3MFindProperty(obj, n.type, true);
/*static struct k3Menu *k3ScreenFuncMouse(struct k3Menu *_, int16_t x, int16_t y, int ev) {
struct k3Screen *this = (void*) _;
if(!o) {
obj->properties = realloc(obj->properties, ++obj->propertyCount * sizeof(*obj->properties));
o = &obj->properties[obj->propertyCount - 1];
if(ev == k3_MENU_MOUSE_MOVE) {
struct k3Menu *newHovered = k3ContainerFuncMouse(_, x, y, k3_MENU_MOUSE_TEST);
if(this->hovered != newHovered) {
if(this->hovered && this->hovered->funcmouse) {
this->hovered->funcmouse(this->hovered, x, y, k3_MENU_MOUSE_OUT);
}
this->hovered = newHovered;
if(this->hovered && this->hovered->funcmouse) {
this->hovered->funcmouse(this->hovered, x, y, k3_MENU_MOUSE_IN);
}
} else {
if(this->hovered && this->hovered->funcmouse) {
return this->hovered->funcmouse(this->hovered, x, y, k3_MENU_MOUSE_MOVE);
}
}
} else if(this->hovered && this->hovered->funcmouse) {
struct k3Menu *ret = this->hovered->funcmouse(this->hovered, x, y, ev);
this->keyboardFocus = ret;
return ret;
}
memcpy(o, &n, sizeof(n));
return NULL;
}
struct k3MProperty *k3MFindProperty(struct k3MObj *obj, enum k3MPropertyType t, bool direct) {
for(size_t i = 0; i < obj->propertyCount; i++) {
if(obj->properties[i].type == t) {
return &obj->properties[i];
}
static void k3ScreenFuncKey(struct k3Menu *_, int key, int action, int modifiers) {
struct k3Screen *this = (void*) _;
if(this->keyboardFocus && this->keyboardFocus->funckey) {
this->keyboardFocus->funckey(this->keyboardFocus, key, action, modifiers);
}
if(direct || !obj->parent) {
return NULL;
}
return k3MFindProperty(obj->parent, t, direct);
}
static void k3ScreenFuncChar(struct k3Menu *_, uint32_t codepoint) {
struct k3Screen *this = (void*) _;
if(this->keyboardFocus && this->keyboardFocus->funcchar) {
this->keyboardFocus->funcchar(this->keyboardFocus, codepoint);
}
}*/
static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
struct k3MScreen *this = (void*) ev->target;
@ -193,12 +194,6 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
}
if(innermost != this->lastHover) {
this->lastHover->hovered = false;
innermost->hovered = true;
this->lastHover = innermost;
}
if(innermost != (void*) this) {
if(ev->code == k3M_EVENT_MOUSE_PRESS) {
@ -247,8 +242,6 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
struct k3MScreen *k3MScreen() {
struct k3MScreen *ret = calloc(1, sizeof(*ret));
ret->lastHover = (void*) ret;
k3MRegisterEventHandler(ret, k3M_EVENT_ALL, screen_ev, NULL, 0);
return ret;
@ -257,9 +250,12 @@ struct k3MScreen *k3MScreen() {
static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) {
struct k3MTextButton *this = (void*) ev->target;
obj_draw((void*) this);
if(this->txt) {
k3BatchAdd(NULL, (struct k3RectF) {}, (struct k3RectF) {
this->x, this->y,
this->w, this->h
}, 0, (vec4) {1, 1, 1, 0.2 + 0.1 * this->hovered});
struct k3RectF txtsz;
k3FontSz(this->font, this->sz, this->txt, &txtsz);
@ -284,9 +280,12 @@ struct k3MTextButton *k3MTextButton(struct k3Font *font, float sz, const char *t
static bool textinput_draw(struct k3MEvent *ev, uint8_t *ud) {
struct k3MTextInput *this = (void*) ev->target;
obj_draw((void*) this);
if(this->txt) {
k3BatchAdd(NULL, (struct k3RectF) {}, (struct k3RectF) {
this->x, this->y,
this->w, this->h
}, 0, (vec4) {1, 1, 1, 0.2});
int isPlaceholder = strlen(this->txt) == 0;
const char *txt = isPlaceholder ? this->placeholder : this->txt;

View File

@ -61,19 +61,6 @@ typedef struct k3MEventHandler {
uint16_t code;
} k3MEventHandler;
enum k3MPropertyType {
k3M_PROP_BG_COLOR,
k3M_PROP_BORDER_RADIUS,
};
struct k3MProperty {
enum k3MPropertyType type;
union {
intmax_t si[4];
void *ptr;
uint8_t buf[32];
};
};
struct k3MObj {
struct k3MObj *parent;
@ -89,9 +76,6 @@ struct k3MObj {
k3MEventHandler *handlers;
size_t handlerCount;
struct k3MProperty *properties;
size_t propertyCount;
};
#define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h))
@ -105,9 +89,6 @@ bool k3MEventSend(struct k3MEvent *ev);
int k3MRemoveChild(struct k3MObj *parent, struct k3MObj *child);
void k3MAddChild(struct k3MObj *parent, struct k3MObj *child);
void k3MOverrideProperty(struct k3MObj *obj, struct k3MProperty);
struct k3MProperty *k3MFindProperty(struct k3MObj *obj, enum k3MPropertyType, bool direct);
struct k3MLabel {
struct k3MObj;
@ -121,7 +102,6 @@ struct k3MScreen {
struct k3MObj;
struct k3MObj *keyboardFocus;
struct k3MObj *lastHover;
};
struct k3MScreen *k3MScreen();

View File

@ -1,185 +0,0 @@
#include"k3particles.h"
#include"k3_internal.h"
struct xorshift128_state {
uint32_t x[4];
};
uint32_t xorshift128(struct xorshift128_state *state) {
uint32_t t = state->x[3];
uint32_t s = state->x[0];
state->x[3] = state->x[2];
state->x[2] = state->x[1];
state->x[1] = s;
t ^= t << 11;
t ^= t >> 8;
return state->x[0] = t ^ s ^ (s >> 19);
}
struct xorshift128_state xs = {{1, 2, 3, 4}};
static uint32_t randint(uint32_t min, uint32_t max) {
uint32_t x;
do {
x = xorshift128(&xs);
} while(0x100000000UL - 0x100000000UL % ((uint64_t) max + 1) <= x);
return x / (0x100000000UL / ((uint64_t) max + 1));
}
static float randfloat() {
union { uint32_t u32; float f; } u = { .u32 = xorshift128(&xs) >> 9 | 0x3f800000 };
return u.f - 1.0;
}
void k3CPUQuadParticlesInit(struct k3CPUQuadParticles *this, struct k3Mat *mat) {
uint16_t *inds = calloc(sizeof(*inds), this->capacity * 6);
for(size_t i = 0; i < this->capacity; i++) {
inds[i * 6 + 0] = i * 4 + 0;
inds[i * 6 + 1] = i * 4 + 1;
inds[i * 6 + 2] = i * 4 + 2;
inds[i * 6 + 3] = i * 4 + 0;
inds[i * 6 + 4] = i * 4 + 2;
inds[i * 6 + 5] = i * 4 + 3;
}
this->mdl = k3MdlCreate(this->capacity * 4, this->capacity * 6, 0, k3_ATTRIB_EMPTY, k3_ATTRIB_EMPTY, k3_ATTRIB_EMPTY, k3_ATTRIB_EMPTY, NULL, NULL, inds, NULL, NULL);
k3MdlAddMesh(this->mdl, mat, 0, this->capacity * 6);
k3MdlSetDebugName(this->mdl, "k3CPUQuadParticles");
free(inds);
this->positions = calloc(sizeof(*this->positions), this->capacity);
this->velocities = calloc(sizeof(*this->velocities), this->capacity);
this->sizes = calloc(sizeof(*this->sizes), this->capacity);
this->lifetimes = calloc(sizeof(*this->lifetimes), this->capacity);
}
static void random_cone_vector(float coneAngle, vec3 output) {
float minZ = cosf(coneAngle);
float z = randfloat() * (1 - minZ) + minZ;
float phi = randfloat() * 6.2831853;
output[0] = sqrtf(1 - z * z) * cosf(phi);
output[1] = z;
output[2] = sqrtf(1 - z * z) * sinf(phi);
}
static void regenerate_model(struct k3CPUQuadParticles *this, vec3 cameraRight, vec3 cameraUp, vec3 cameraFront) {
vec3 *vpos = calloc(sizeof(*vpos), 4 * this->capacity);
uint8_t *vcols = calloc(4, 4 * this->capacity);
vec2 *vuvs = calloc(sizeof(*vuvs), 4 * this->capacity);
uint8_t *vnrms = calloc(3, 4 * this->capacity);
vec3 halfRight, halfUp;
glm_vec3_scale(cameraRight, 0.5, halfRight);
glm_vec3_scale(cameraUp, 0.5, halfUp);
#pragma omp parallel for
for(size_t i = 0; i < this->count; i++) {
glm_vec3_copy(this->positions[i], vpos[i * 4 + 0]);
glm_vec3_copy(this->positions[i], vpos[i * 4 + 1]);
glm_vec3_copy(this->positions[i], vpos[i * 4 + 2]);
glm_vec3_copy(this->positions[i], vpos[i * 4 + 3]);
glm_vec3_muladds(halfRight, -this->sizes[i], vpos[i * 4 + 0]);
glm_vec3_muladds(halfUp, -this->sizes[i], vpos[i * 4 + 0]);
glm_vec3_muladds(halfRight, this->sizes[i], vpos[i * 4 + 1]);
glm_vec3_muladds(halfUp, -this->sizes[i], vpos[i * 4 + 1]);
glm_vec3_muladds(halfRight, this->sizes[i], vpos[i * 4 + 2]);
glm_vec3_muladds(halfUp, this->sizes[i], vpos[i * 4 + 2]);
glm_vec3_muladds(halfRight, -this->sizes[i], vpos[i * 4 + 3]);
glm_vec3_muladds(halfUp, this->sizes[i], vpos[i * 4 + 3]);
vec4 color;
glm_vec4_lerp(this->colorEnd, this->colorStart, this->lifetimes[i] / this->particleLifetime, color);
for(size_t c = 0; c < 16; c += 4) {
vcols[i * 16 + c + 0] = color[0] * 255;
vcols[i * 16 + c + 1] = color[1] * 255;
vcols[i * 16 + c + 2] = color[2] * 255;
vcols[i * 16 + c + 3] = color[3] * 255;
}
glm_vec2_copy((vec2) {0, 0}, vuvs[i * 4 + 0]);
glm_vec2_copy((vec2) {1, 0}, vuvs[i * 4 + 1]);
glm_vec2_copy((vec2) {1, 1}, vuvs[i * 4 + 2]);
glm_vec2_copy((vec2) {0, 1}, vuvs[i * 4 + 3]);
for(size_t c = 0; c < 12; c += 3) {
vnrms[i * 12 + c + 0] = (uint8_t) (cameraFront[0] * 127);
vnrms[i * 12 + c + 1] = (uint8_t) (cameraFront[1] * 127);
vnrms[i * 12 + c + 2] = (uint8_t) (cameraFront[2] * 127);
}
}
// This update the AABB
k3MdlUpdatePos(this->mdl, vpos);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->mdl->vstore->gl);
//glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, this->mdl->offV, sizeof(*vpos) * this->capacity * 4, vpos);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, this->mdl->offC, sizeof(*vcols) * this->capacity * 4 * 4, vcols);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, this->mdl->offU, sizeof(*vuvs) * this->capacity * 4, vuvs);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, this->mdl->offN, sizeof(*vnrms) * this->capacity * 4 * 3, vnrms);
this->mdl->meshes[0].idxNumber = this->count * 6;
free(vpos);
free(vcols);
free(vuvs);
free(vnrms);
}
static void copy_particle(struct k3CPUQuadParticles *this, size_t from, size_t to) {
glm_vec3_copy(this->positions[from], this->positions[to]);
glm_vec3_copy(this->velocities[from], this->velocities[to]);
this->sizes[to] = this->sizes[from];
this->lifetimes[to] = this->lifetimes[from];
}
void k3CPUQuadParticlesUpdate(struct k3CPUQuadParticles *this, float dt, vec3 cameraRight, vec3 cameraUp, vec3 cameraFront) {
size_t numGenerated = dt * this->emissionRate;
if((this->emissionLifetime -= dt) <= 0) {
this->emissionEnabled = false;
}
if(!this->emissionEnabled) numGenerated = 0;
if(this->count + numGenerated > this->capacity) {
numGenerated = this->capacity - this->count;
}
for(size_t i = this->count, j = 0; j < numGenerated; i++, j++, this->count++) {
glm_vec3_copy(this->origin, this->positions[i]);
random_cone_vector(this->emissionConeAngle, this->velocities[i]);
glm_vec3_scale(this->velocities[i], 2, this->velocities[i]);
this->sizes[i] = 1;
this->lifetimes[i] = this->particleLifetime;
}
vec3 accdt;
glm_vec3_scale(this->gravity, dt, accdt);
for(size_t i = 0; i < this->count;) {
glm_vec3_add(this->velocities[i], accdt, this->velocities[i]);
vec3 veldt;
glm_vec3_scale(this->velocities[i], dt, veldt);
glm_vec3_add(this->positions[i], veldt, this->positions[i]);
this->lifetimes[i] -= dt;
if(this->lifetimes[i] <= 0) {
copy_particle(this, --this->count, i);
} else {
i++;
}
}
regenerate_model(this, cameraRight, cameraUp, cameraFront);
}

View File

@ -1,32 +0,0 @@
#pragma once
#include<cglm/vec3.h>
#include<stdbool.h>
#include"k3.h"
struct k3CPUQuadParticles {
size_t capacity;
size_t count;
vec3 *positions;
vec3 *velocities;
float *sizes;
float *lifetimes;
struct k3Mdl *mdl;
vec4 colorStart;
vec4 colorEnd;
vec3 origin;
vec3 gravity;
float emissionRate;
vec3 emissionConeDirection;
float emissionConeAngle;
float particleLifetime;
bool emissionEnabled;
float emissionLifetime;
};
void k3CPUQuadParticlesInit(struct k3CPUQuadParticles*, struct k3Mat*);
void k3CPUQuadParticlesUpdate(struct k3CPUQuadParticles*, float dt, vec3 cameraRight, vec3 cameraUp, vec3 cameraFront);