Compare commits
No commits in common. "4d74b5e3e9a597a63d6a3e38143e2ec8382e8ac7" and "a06aacd405e06f36a0eb7a878a3104b679c9bd6f" have entirely different histories.
4d74b5e3e9
...
a06aacd405
2215
src/compr/bc7enc.c
2215
src/compr/bc7enc.c
File diff suppressed because it is too large
Load Diff
@ -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
|
13
src/k3.h
13
src/k3.h
@ -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*);
|
||||
|
@ -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;
|
||||
};
|
145
src/k3batch.c
145
src/k3batch.c
@ -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);
|
||||
|
@ -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();
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
95
src/k3menu.c
95
src/k3menu.c
@ -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;
|
||||
|
||||
|
20
src/k3menu.h
20
src/k3menu.h
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
Loading…
Reference in New Issue
Block a user