Compare commits
4 Commits
a571d2d999
...
9160c8ce35
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9160c8ce35 | ||
|
|
2175d32da4 | ||
|
|
c44e58c4ac | ||
|
|
63d641cc82 |
164
src/k3.c
164
src/k3.c
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include"ssort.h"
|
#include"ssort.h"
|
||||||
|
|
||||||
|
#include<stb_image_resize.h>
|
||||||
|
|
||||||
#define RAST_DIFF 0
|
#define RAST_DIFF 0
|
||||||
#define RAST_NORM 1
|
#define RAST_NORM 1
|
||||||
#define RAST_DISP 2
|
#define RAST_DISP 2
|
||||||
@ -495,6 +497,20 @@ struct k3Tex *k3TexCreate(enum k3TexType type) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int k3TexSetParameter(struct k3Tex *tex, enum k3TexParam param, void *value) {
|
||||||
|
switch(param) {
|
||||||
|
case k3_TEX_SET_MIPMAPPING_DISABLED:
|
||||||
|
tex->mipmapForceDisabled = *(bool*) value;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case k3_TEX_SET_MIPMAP_ALPHA:
|
||||||
|
tex->mipmapAlphaMode = *(int*) value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t width, uint16_t height, void *data) {
|
void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t width, uint16_t height, void *data) {
|
||||||
GLenum target = tex->cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
GLenum target = tex->cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||||
|
|
||||||
@ -518,22 +534,28 @@ void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t wid
|
|||||||
GLint internalFmt, externalFmt, intype;
|
GLint internalFmt, externalFmt, intype;
|
||||||
int linearFilter, mipmap;
|
int linearFilter, mipmap;
|
||||||
int compressed = 0;
|
int compressed = 0;
|
||||||
|
int channels;
|
||||||
|
bool gamma;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case k3_RAWCOLOR:
|
case k3_RAWCOLOR:
|
||||||
internalFmt = GLAD_GL_ARB_texture_float ? GL_RGBA32F_ARB : GL_RGB10_A2;
|
internalFmt = GLAD_GL_ARB_texture_float ? GL_RGBA32F_ARB : GL_RGB10_A2;
|
||||||
externalFmt = GL_RGBA;
|
externalFmt = GL_RGBA;
|
||||||
|
channels = 4;
|
||||||
intype = GL_UNSIGNED_BYTE;
|
intype = GL_UNSIGNED_BYTE;
|
||||||
linearFilter = 1;
|
linearFilter = 1;
|
||||||
mipmap = 1;
|
mipmap = 0;
|
||||||
|
gamma = false;
|
||||||
break;
|
break;
|
||||||
case k3_NORMAL:
|
case k3_NORMAL:
|
||||||
compressed = TextureCompressionEnabled;
|
compressed = TextureCompressionEnabled;
|
||||||
internalFmt = compressed ? TextureCompressionRGBA : GL_RGBA;
|
internalFmt = compressed ? TextureCompressionRGBA : GL_RGBA;
|
||||||
externalFmt = GL_RGBA;
|
externalFmt = GL_RGBA;
|
||||||
|
channels = 4;
|
||||||
intype = GL_UNSIGNED_BYTE;
|
intype = GL_UNSIGNED_BYTE;
|
||||||
linearFilter = 1;
|
linearFilter = 1;
|
||||||
mipmap = 1;
|
mipmap = 1;
|
||||||
|
gamma = false;
|
||||||
break;
|
break;
|
||||||
case k3_DIFFUSE:
|
case k3_DIFFUSE:
|
||||||
case k3_EMISSION:
|
case k3_EMISSION:
|
||||||
@ -542,39 +564,47 @@ void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t wid
|
|||||||
? (GLAD_GL_EXT_texture_sRGB ? TextureCompressionSRGBA : TextureCompressionRGBA)
|
? (GLAD_GL_EXT_texture_sRGB ? TextureCompressionSRGBA : TextureCompressionRGBA)
|
||||||
: (GLAD_GL_EXT_texture_sRGB ? GL_SRGB8_ALPHA8_EXT : GL_RGBA8);
|
: (GLAD_GL_EXT_texture_sRGB ? GL_SRGB8_ALPHA8_EXT : GL_RGBA8);
|
||||||
externalFmt = GL_RGBA;
|
externalFmt = GL_RGBA;
|
||||||
|
channels = 4;
|
||||||
intype = GL_UNSIGNED_BYTE;
|
intype = GL_UNSIGNED_BYTE;
|
||||||
linearFilter = 1;
|
linearFilter = 1;
|
||||||
mipmap = 1;
|
mipmap = 1;
|
||||||
|
gamma = true;
|
||||||
break;
|
break;
|
||||||
case k3_DISPLACEMENT:
|
case k3_DISPLACEMENT:
|
||||||
case k3_ROUGHNESS:
|
case k3_ROUGHNESS:
|
||||||
internalFmt = !k3IsCore ? GL_LUMINANCE8 : GL_RED;
|
internalFmt = !k3IsCore ? GL_LUMINANCE8 : GL_RED;
|
||||||
externalFmt = GL_RED;
|
externalFmt = GL_RED;
|
||||||
|
channels = 1;
|
||||||
intype = GL_UNSIGNED_BYTE;
|
intype = GL_UNSIGNED_BYTE;
|
||||||
linearFilter = 1;
|
linearFilter = 1;
|
||||||
mipmap = 1;
|
mipmap = 1;
|
||||||
|
gamma = false;
|
||||||
break;
|
break;
|
||||||
case k3_ALPHA:
|
case k3_ALPHA:
|
||||||
internalFmt = !k3IsCore ? GL_ALPHA8 : GL_RED;
|
internalFmt = !k3IsCore ? GL_ALPHA8 : GL_RED;
|
||||||
externalFmt = !k3IsCore ? GL_ALPHA : GL_RED;
|
externalFmt = !k3IsCore ? GL_ALPHA : GL_RED;
|
||||||
|
channels = 1;
|
||||||
intype = GL_UNSIGNED_BYTE;
|
intype = GL_UNSIGNED_BYTE;
|
||||||
linearFilter = 1;
|
linearFilter = 1;
|
||||||
mipmap = 1;
|
mipmap = 1;
|
||||||
|
gamma = false;
|
||||||
break;
|
break;
|
||||||
case k3_DEPTH:
|
case k3_DEPTH:
|
||||||
internalFmt = GL_DEPTH_COMPONENT32F;
|
internalFmt = GL_DEPTH_COMPONENT24;
|
||||||
externalFmt = GL_DEPTH_COMPONENT;
|
externalFmt = GL_DEPTH_COMPONENT;
|
||||||
intype = GL_UNSIGNED_INT;
|
intype = GL_UNSIGNED_INT;
|
||||||
|
channels = 4;
|
||||||
if(!k3IsCore) glTexParameteri(target, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
if(!k3IsCore) glTexParameteri(target, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
|
||||||
linearFilter = 1;
|
linearFilter = 1;
|
||||||
mipmap = 0;
|
mipmap = 0;
|
||||||
|
gamma = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!MipmappingEnabled) {
|
if(!MipmappingEnabled || tex->mipmapForceDisabled) {
|
||||||
mipmap = 0;
|
mipmap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,10 +617,6 @@ void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t wid
|
|||||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
} else {
|
|
||||||
if(!k3IsCore && mipmap) {
|
|
||||||
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == k3_DEPTH) {
|
if(type == k3_DEPTH) {
|
||||||
@ -623,23 +649,6 @@ void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t wid
|
|||||||
k3Log(k3_WARN, "Non-zero index passed for non-cubemap texture");
|
k3Log(k3_WARN, "Non-zero index passed for non-cubemap texture");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(compressed && TextureOfflineCompressor) {
|
|
||||||
k3Log(k3_DEBUG, "Compressing texture...");
|
|
||||||
|
|
||||||
size_t len;
|
|
||||||
data = TextureOfflineCompressor(data, width, height, externalFmt, intype, &len);
|
|
||||||
|
|
||||||
glCompressedTexImage2D(target, 0, internalFmt, width, height, 0, len, data);
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
} else {
|
|
||||||
glTexImage2D(target, 0, internalFmt, width, height, 0, externalFmt, intype, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!tex->cubemap && k3IsCore && mipmap) {
|
|
||||||
glGenerateMipmap(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
tex->szX = width;
|
tex->szX = width;
|
||||||
tex->szY = height;
|
tex->szY = height;
|
||||||
tex->szZ = 0;
|
tex->szZ = 0;
|
||||||
@ -647,6 +656,65 @@ void k3TexUpdate(struct k3Tex *tex, enum k3TexType type, int index, uint16_t wid
|
|||||||
tex->glInternalFormat = internalFmt;
|
tex->glInternalFormat = internalFmt;
|
||||||
tex->glExternalFormat = externalFmt;
|
tex->glExternalFormat = externalFmt;
|
||||||
tex->glInType = intype;
|
tex->glInType = intype;
|
||||||
|
|
||||||
|
if(data) {
|
||||||
|
char *resized = malloc(width * height * channels);
|
||||||
|
memcpy(resized, data, width * height * channels);
|
||||||
|
|
||||||
|
size_t level;
|
||||||
|
for(level = 0;; level++) {
|
||||||
|
if(compressed && TextureOfflineCompressor) {
|
||||||
|
k3Log(k3_DEBUG, "Compressing level %i...", level);
|
||||||
|
|
||||||
|
size_t len;
|
||||||
|
void *compressedData = TextureOfflineCompressor(data, width, height, externalFmt, intype, &len);
|
||||||
|
|
||||||
|
glCompressedTexImage2D(target, level, internalFmt, width, height, 0, len, compressedData);
|
||||||
|
|
||||||
|
free(compressedData);
|
||||||
|
} else {
|
||||||
|
glTexImage2D(target, level, internalFmt, width, height, 0, externalFmt, intype, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mipmap || tex->cubemap || (width <= 1 && height <= 1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t resizedWidth = width >> 1;
|
||||||
|
if(resizedWidth == 0) {
|
||||||
|
resizedWidth = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t resizedHeight = height >> 1;
|
||||||
|
if(resizedHeight == 0) {
|
||||||
|
resizedHeight = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
stbir_resize_uint8_generic(data, width, height, 0, resized, resizedWidth, resizedHeight, 0, channels, channels == 4 ? 3 : STBIR_ALPHA_CHANNEL_NONE, 0, STBIR_EDGE_CLAMP, STBIR_FILTER_BOX, gamma ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, NULL);
|
||||||
|
|
||||||
|
data = resized;
|
||||||
|
width = resizedWidth;
|
||||||
|
height = resizedHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
|
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, level);
|
||||||
|
|
||||||
|
free(resized);
|
||||||
|
} else {
|
||||||
|
glTexImage2D(target, 0, internalFmt, width, height, 0, externalFmt, intype, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void k3TexUpdateSub(struct k3Tex *this, int index, uint16_t x, uint16_t y, uint16_t width, uint16_t height, void *data) {
|
||||||
|
GLenum target = GL_TEXTURE_2D;
|
||||||
|
if(this->cubemap) {
|
||||||
|
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + index;
|
||||||
|
} else if(index) {
|
||||||
|
k3Log(k3_WARN, "Non-zero index passed for non-cubemap texture");
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(target, this->tex);
|
||||||
|
glTexSubImage2D(target, index, x, y, width, height, this->glExternalFormat, this->glInType, data);
|
||||||
}
|
}
|
||||||
uint32_t k3TexSzX(struct k3Tex *this) {
|
uint32_t k3TexSzX(struct k3Tex *this) {
|
||||||
return this->szX;
|
return this->szX;
|
||||||
@ -1572,7 +1640,7 @@ static void forward_subpass(mat4 projection, mat4 view, int transparent, int lig
|
|||||||
if(!k3IsCore) {
|
if(!k3IsCore) {
|
||||||
if(mat->passes[0].alphatest) {
|
if(mat->passes[0].alphatest) {
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_GREATER, 0.9f);
|
glAlphaFunc(GL_GREATER, mat->passes[0].alphatest);
|
||||||
} else {
|
} else {
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
}
|
}
|
||||||
@ -1637,7 +1705,7 @@ void k3PassForward(mat4 projection, mat4 cam) {
|
|||||||
if(GLAD_GL_EXT_framebuffer_sRGB) {
|
if(GLAD_GL_EXT_framebuffer_sRGB) {
|
||||||
glEnable(GL_FRAMEBUFFER_SRGB_EXT);
|
glEnable(GL_FRAMEBUFFER_SRGB_EXT);
|
||||||
}
|
}
|
||||||
glEnable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_MULTISAMPLE);
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
@ -1659,6 +1727,7 @@ void k3PassForward(mat4 projection, mat4 cam) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
// Horribly inefficient.
|
// Horribly inefficient.
|
||||||
for(size_t rble = 0; rble < renderQueueSize; rble++) {
|
for(size_t rble = 0; rble < renderQueueSize; rble++) {
|
||||||
@ -1712,12 +1781,8 @@ void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull) {
|
|||||||
if(GLAD_GL_ARB_vertex_program)
|
if(GLAD_GL_ARB_vertex_program)
|
||||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||||
|
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
if(cull) {
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
} else {
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint lastVP = 0;
|
GLuint lastVP = 0;
|
||||||
struct k3GLSLP *lastGLSLP = NULL;
|
struct k3GLSLP *lastGLSLP = NULL;
|
||||||
@ -1792,7 +1857,7 @@ void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull) {
|
|||||||
if(!k3IsCore) {
|
if(!k3IsCore) {
|
||||||
if(mat->passes[0].alphatest) {
|
if(mat->passes[0].alphatest) {
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_GREATER, 0.9f);
|
glAlphaFunc(GL_GREATER, mat->passes[0].alphatest);
|
||||||
} else {
|
} else {
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
}
|
}
|
||||||
@ -1880,7 +1945,11 @@ static size_t compute_light_views(struct LightView lv[]) {
|
|||||||
glm_frustum_center(corners, viewcenter);
|
glm_frustum_center(corners, viewcenter);
|
||||||
|
|
||||||
mat4 lightview;
|
mat4 lightview;
|
||||||
glm_look_anyup(viewcenter, l->dir.direction, lightview);
|
if(glm_vec3_dot(l->dir.direction, (vec3) {0, 1, 0}) >= 0.99) {
|
||||||
|
glm_look(viewcenter, l->dir.direction, (vec3) {1, 0, 0}, lightview);
|
||||||
|
} else {
|
||||||
|
glm_look(viewcenter, l->dir.direction, (vec3) {0, 1, 0}, lightview);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 minaabb = {+HUGE_VALF, +HUGE_VALF, +HUGE_VALF};
|
vec4 minaabb = {+HUGE_VALF, +HUGE_VALF, +HUGE_VALF};
|
||||||
vec4 maxaabb = {-HUGE_VALF, -HUGE_VALF, -HUGE_VALF};
|
vec4 maxaabb = {-HUGE_VALF, -HUGE_VALF, -HUGE_VALF};
|
||||||
@ -1893,7 +1962,10 @@ static size_t compute_light_views(struct LightView lv[]) {
|
|||||||
glm_vec4_maxv(maxaabb, lightspaceCorner, maxaabb);
|
glm_vec4_maxv(maxaabb, lightspaceCorner, maxaabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm_ortho(minaabb[0], maxaabb[0], minaabb[1], maxaabb[1], minaabb[2] - 50, maxaabb[2], lv[i].p[cascade]);
|
// TODO: automate
|
||||||
|
float minz = 50;
|
||||||
|
|
||||||
|
glm_ortho(minaabb[0], maxaabb[0], minaabb[1], maxaabb[1], minaabb[2] - minz, maxaabb[2], lv[i].p[cascade]);
|
||||||
glm_mat4_inv_fast(lightview, lv[i].c[cascade]);
|
glm_mat4_inv_fast(lightview, lv[i].c[cascade]);
|
||||||
}
|
}
|
||||||
} else if(l->type == k3_SPOT || l->type == k3_HALF_OMNI) {
|
} else if(l->type == k3_SPOT || l->type == k3_HALF_OMNI) {
|
||||||
@ -2194,7 +2266,7 @@ void k3PassIrregular(struct k3Offscreen *mainview, mat4 mainproj, mat4 maincam)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Constructs shadowmap atlas, saves `offscr` for own use
|
// Constructs shadowmap atlas, saves `offscr` for own use
|
||||||
void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr, float cellSizeLimit) {
|
void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr, int minimumSubdivision) {
|
||||||
struct k3Timer timer = k3StartTimer("k3PassShadowmap");
|
struct k3Timer timer = k3StartTimer("k3PassShadowmap");
|
||||||
|
|
||||||
glm_mat4_copy(projection, ProjMat);
|
glm_mat4_copy(projection, ProjMat);
|
||||||
@ -2237,12 +2309,17 @@ void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr, floa
|
|||||||
cellsPerDimension = cellsTotalSqrt;
|
cellsPerDimension = cellsTotalSqrt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cellsPerDimension < minimumSubdivision) {
|
||||||
|
cellsPerDimension = minimumSubdivision;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t sz = k3TexSzX(offscr->depth);
|
uint16_t sz = k3TexSzX(offscr->depth);
|
||||||
float cellSz = (float) sz / cellsPerDimension;
|
float cellSz = (float) sz / cellsPerDimension;
|
||||||
|
|
||||||
if(cellSizeLimit > 0) {
|
#ifdef SHADOWSKIP
|
||||||
cellSz = fminf(cellSizeLimit, cellSz);
|
static size_t shadowskipI = 0;
|
||||||
}
|
shadowskipI++;
|
||||||
|
#endif
|
||||||
|
|
||||||
k3BeginOffscreen(offscr);
|
k3BeginOffscreen(offscr);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -2274,9 +2351,18 @@ void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr, floa
|
|||||||
glm_vec4_copy((vec4) {i, (float) cellSz / sz, 0, 0}, LightShadows[li].atlasSegment);
|
glm_vec4_copy((vec4) {i, (float) cellSz / sz, 0, 0}, LightShadows[li].atlasSegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SHADOWSKIP
|
||||||
|
// Skip every second light
|
||||||
|
if((li + shadowskipI) % 2) {
|
||||||
|
#endif
|
||||||
|
|
||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
k3PassDepthOnly(proj, lv->c[camIdx], i == 0, false);
|
k3PassDepthOnly(proj, lv->c[camIdx], i == 0, false);
|
||||||
|
|
||||||
|
#ifdef SHADOWSKIP
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/k3.h
16
src/k3.h
@ -22,9 +22,18 @@ enum k3TexType {
|
|||||||
k3_RAWCOLOR,
|
k3_RAWCOLOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum k3TexParam {
|
||||||
|
k3_TEX_SET_MIPMAP_ALPHA,
|
||||||
|
k3_TEX_SET_MIPMAPPING_DISABLED,
|
||||||
|
};
|
||||||
|
#define k3_PARAM_STANDARD 0
|
||||||
|
#define k3_PARAM_MAX_DOWNSAMPLE 1
|
||||||
|
|
||||||
struct k3Tex;
|
struct k3Tex;
|
||||||
struct k3Tex *k3TexCreate(enum k3TexType type);
|
struct k3Tex *k3TexCreate(enum k3TexType type);
|
||||||
|
int k3TexSetParameter(struct k3Tex*, enum k3TexParam, void*);
|
||||||
void k3TexUpdate(struct k3Tex*, enum k3TexType type, int index, uint16_t width, uint16_t height, void *data);
|
void k3TexUpdate(struct k3Tex*, enum k3TexType type, int index, uint16_t width, uint16_t height, void *data);
|
||||||
|
void k3TexUpdateSub(struct k3Tex*, int index, uint16_t x, uint16_t y, uint16_t width, uint16_t height, void *data);
|
||||||
uint32_t k3TexSzX(struct k3Tex*);
|
uint32_t k3TexSzX(struct k3Tex*);
|
||||||
uint32_t k3TexSzY(struct k3Tex*);
|
uint32_t k3TexSzY(struct k3Tex*);
|
||||||
uint32_t k3TexSzZ(struct k3Tex*);
|
uint32_t k3TexSzZ(struct k3Tex*);
|
||||||
@ -68,7 +77,7 @@ struct k3Mat {
|
|||||||
} arbfp;
|
} arbfp;
|
||||||
struct {
|
struct {
|
||||||
struct k3GLSLP *hp;
|
struct k3GLSLP *hp;
|
||||||
|
|
||||||
#ifdef k3_IRREGULAR_SHADOWS
|
#ifdef k3_IRREGULAR_SHADOWS
|
||||||
struct k3GLSLP *hpIrreg1;
|
struct k3GLSLP *hpIrreg1;
|
||||||
struct k3GLSLP *hpIrreg2;
|
struct k3GLSLP *hpIrreg2;
|
||||||
@ -97,7 +106,7 @@ struct k3Mat {
|
|||||||
char additive;
|
char additive;
|
||||||
char transparent;
|
char transparent;
|
||||||
char nocull;
|
char nocull;
|
||||||
char alphatest;
|
float alphatest;
|
||||||
char depthwrite;
|
char depthwrite;
|
||||||
} passes[1];
|
} passes[1];
|
||||||
};
|
};
|
||||||
@ -159,6 +168,7 @@ void k3StorageUnref(struct k3Storage*);
|
|||||||
struct k3Mdl;
|
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);
|
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);
|
void k3MdlUpdatePos(struct k3Mdl *mdl, vec3 *pos);
|
||||||
|
void k3MdlUpdateNrm(struct k3Mdl *mdl, uint8_t *nrm);
|
||||||
void k3MdlAddMesh(struct k3Mdl*, struct k3Mat*, uint32_t idxStart, uint32_t idxNumber);
|
void k3MdlAddMesh(struct k3Mdl*, struct k3Mat*, uint32_t idxStart, uint32_t idxNumber);
|
||||||
struct k3Mesh *k3MdlGetMeshes(struct k3Mdl*, size_t *count);
|
struct k3Mesh *k3MdlGetMeshes(struct k3Mdl*, size_t *count);
|
||||||
void k3MdlAddAnim(struct k3Mdl*, struct k3AnimationFountain*);
|
void k3MdlAddAnim(struct k3Mdl*, struct k3AnimationFountain*);
|
||||||
@ -185,7 +195,7 @@ void k3BatchClear();
|
|||||||
void k3PassForward(mat4 projection, mat4 cam);
|
void k3PassForward(mat4 projection, mat4 cam);
|
||||||
void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull);
|
void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull);
|
||||||
|
|
||||||
void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr, float cellSizeLimit);
|
void k3PassShadowmap(mat4 projection, mat4 cam, struct k3Offscreen *offscr, int minimumSubdivision);
|
||||||
|
|
||||||
struct k3Offscreen;
|
struct k3Offscreen;
|
||||||
struct k3Offscreen *k3OffscreenCreateMultisampled(struct k3Tex *diffuse, struct k3Tex *depth, uint8_t samples);
|
struct k3Offscreen *k3OffscreenCreateMultisampled(struct k3Tex *diffuse, struct k3Tex *depth, uint8_t samples);
|
||||||
|
|||||||
@ -28,10 +28,8 @@ struct k3Tex {
|
|||||||
GLuint glInType;
|
GLuint glInType;
|
||||||
bool mipmap;
|
bool mipmap;
|
||||||
|
|
||||||
// Asynchronous decoding
|
bool mipmapForceDisabled;
|
||||||
uint8_t deferredRemaining;
|
int mipmapAlphaMode;
|
||||||
uint8_t *deferredData[6];
|
|
||||||
struct k3Tex *deferredNext;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct k3Storage {
|
struct k3Storage {
|
||||||
@ -105,7 +103,7 @@ static inline struct k3Timer k3StartTimer(char *name) {
|
|||||||
struct k3Timer t = {};
|
struct k3Timer t = {};
|
||||||
|
|
||||||
if(!GLAD_GL_ARB_timer_query) {
|
if(!GLAD_GL_ARB_timer_query) {
|
||||||
return;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
glGenQueries(2, (GLuint*) &t);
|
glGenQueries(2, (GLuint*) &t);
|
||||||
|
|||||||
@ -10,6 +10,8 @@ struct k3RectF {
|
|||||||
float h;
|
float h;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void k3BatchInit();
|
||||||
|
|
||||||
void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color, float borderRadius, float minAlpha);
|
void k3BatchAdd(struct k3Tex *tex, struct k3RectF src, struct k3RectF dst, float rot, vec4 color, float borderRadius, float minAlpha);
|
||||||
void k3BatchFlush();
|
void k3BatchFlush();
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include<string.h>
|
#include<string.h>
|
||||||
#include"gl.h"
|
#include"gl.h"
|
||||||
#include<freetype/freetype.h>
|
#include<freetype/freetype.h>
|
||||||
|
#include<freetype/ftmodapi.h>
|
||||||
|
|
||||||
#define GLCA_IMPLEMENTATION
|
#define GLCA_IMPLEMENTATION
|
||||||
#include"glyphcache/glca.h"
|
#include"glyphcache/glca.h"
|
||||||
@ -48,6 +49,9 @@ int k3FontLoad(struct k3Font *this, const char *fn) {
|
|||||||
this->atlasSize = k3TexSzMax() / 4;
|
this->atlasSize = k3TexSzMax() / 4;
|
||||||
this->atlas = k3TexCreate(k3_ALPHA);
|
this->atlas = k3TexCreate(k3_ALPHA);
|
||||||
this->atlasCPU = malloc(this->atlasSize * this->atlasSize);
|
this->atlasCPU = malloc(this->atlasSize * this->atlasSize);
|
||||||
|
|
||||||
|
k3TexSetParameter(this->atlas, k3_TEX_SET_MIPMAPPING_DISABLED, &(bool) {true});
|
||||||
|
|
||||||
k3TexUpdate(this->atlas, k3_ALPHA, 0, this->atlasSize, this->atlasSize, NULL);
|
k3TexUpdate(this->atlas, k3_ALPHA, 0, this->atlasSize, this->atlasSize, NULL);
|
||||||
|
|
||||||
this->fontPixelSize = this->atlasSize / 16;
|
this->fontPixelSize = this->atlasSize / 16;
|
||||||
|
|||||||
4
src/k3menu_internal.h
Normal file
4
src/k3menu_internal.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct k3Tex;
|
||||||
|
typedef struct k3Tex *k3MImageData;
|
||||||
Loading…
Reference in New Issue
Block a user