update
This commit is contained in:
2
build
2
build
@@ -5,7 +5,7 @@ COMMON_FLAGS="-DOS_LINUX=1 -DCOMPOSITOR_WAYLAND=1 -xc -std=c99 -Wno-initializer-
|
|||||||
|
|
||||||
echo [Building target]
|
echo [Building target]
|
||||||
if [ $DEBUG ]; then
|
if [ $DEBUG ]; then
|
||||||
time clang -O0 -g -g2 $COMMON_FLAGS -DDJSTDLIB_DEBUG=1 ./src/main.c -o ./target/somaesque $LIB_INCLUDE
|
time clang -O1 -g -g2 $COMMON_FLAGS -O1 -fsanitize=address,undefined -DDJSTDLIB_DEBUG=1 ./src/main.c -o ./target/somaesque $LIB_INCLUDE
|
||||||
else
|
else
|
||||||
time clang -O2 $COMMON_FLAGS ./src/main.c -o ./target/somaesque $LIB_INCLUDE
|
time clang -O2 $COMMON_FLAGS ./src/main.c -o ./target/somaesque $LIB_INCLUDE
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
#include <asm-generic/errno-base.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
Texture createTexture(const char* bitmap, int32 width, int32 height) {
|
Texture createTexture(const char* bitmap, int32 width, int32 height) {
|
||||||
Texture result = {0};
|
Texture result = {0};
|
||||||
@@ -20,16 +22,44 @@ Texture createTexture(const char* bitmap, int32 width, int32 height) {
|
|||||||
|
|
||||||
DefineList(stbtt_bakedchar, STBBakedChar);
|
DefineList(stbtt_bakedchar, STBBakedChar);
|
||||||
|
|
||||||
|
static void saveGrayscaleTarga(string location, const char *bytes, int width, int height) {
|
||||||
|
char tgaHeader[18] = {
|
||||||
|
// Image ID length
|
||||||
|
0x0,
|
||||||
|
// Color map type
|
||||||
|
0x0,
|
||||||
|
// Image type
|
||||||
|
0x3,
|
||||||
|
// Color map info (unused)
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
// Image spec
|
||||||
|
0x0, 0x0, // x origin
|
||||||
|
0x0, 0x0, // y origin
|
||||||
|
width & 0xFF, (width >> 8) & 0xFF, // width
|
||||||
|
height & 0xFF, (height >> 8) & 0xFF, // width
|
||||||
|
0x8, // bits per px (depth)
|
||||||
|
0b00001000, // image descriptor
|
||||||
|
};
|
||||||
|
os_writeEntireFile(location, tgaHeader, ArrayCount(tgaHeader));
|
||||||
|
os_fileAppend(location, bytes, width * height);
|
||||||
|
}
|
||||||
|
|
||||||
Font createFont(Arena *arena, string ttfLocation, real32 lineHeight) {
|
Font createFont(Arena *arena, string ttfLocation, real32 lineHeight) {
|
||||||
const int CODEPOINT_START = 32;
|
const int CODEPOINT_START = 32;
|
||||||
const int CODEPOINT_END = 126;
|
const int CODEPOINT_END = 126;
|
||||||
|
|
||||||
int32 atlasWidth = 16 * lineHeight;
|
int32 atlasWidth = 512;//16 * lineHeight;
|
||||||
int32 atlasHeight = 6 * lineHeight;
|
int32 atlasHeight = 512;// * lineHeight;
|
||||||
|
|
||||||
STBBakedCharList bakedCharlist = PushFullListZero(arena, STBBakedCharList, CODEPOINT_END - CODEPOINT_START);
|
STBBakedCharList bakedCharlist = PushFullListZero(arena, STBBakedCharList, CODEPOINT_END - CODEPOINT_START);
|
||||||
string fontFile = os_readEntireFile(arena, ttfLocation);
|
string fontFile = os_readEntireFile(arena, ttfLocation);
|
||||||
|
|
||||||
|
stbtt_fontinfo info;
|
||||||
|
stbtt_InitFont(&info, (unsigned char *)fontFile.str, stbtt_GetFontOffsetForIndex((unsigned char *)fontFile.str, 0));
|
||||||
|
int ascent, descent, lineGap;
|
||||||
|
stbtt_GetFontVMetrics(&info, &ascent, &descent, &lineGap);
|
||||||
|
real32 scale = stbtt_ScaleForPixelHeight(&info, 96);
|
||||||
|
|
||||||
char *bakedFontBitmap = PushArrayZero(arena, char, atlasWidth*atlasHeight);
|
char *bakedFontBitmap = PushArrayZero(arena, char, atlasWidth*atlasHeight);
|
||||||
int32 bake_result = stbtt_BakeFontBitmap(
|
int32 bake_result = stbtt_BakeFontBitmap(
|
||||||
(unsigned char *)fontFile.str, 0,
|
(unsigned char *)fontFile.str, 0,
|
||||||
@@ -38,6 +68,8 @@ Font createFont(Arena *arena, string ttfLocation, real32 lineHeight) {
|
|||||||
CODEPOINT_START, CODEPOINT_END - CODEPOINT_START,
|
CODEPOINT_START, CODEPOINT_END - CODEPOINT_START,
|
||||||
bakedCharlist.data);
|
bakedCharlist.data);
|
||||||
|
|
||||||
|
saveGrayscaleTarga(s("bakedfont.tga"), bakedFontBitmap, atlasWidth, atlasHeight);
|
||||||
|
|
||||||
GlyphMetaList glyphMeta = PushFullListZero(arena, GlyphMetaList, bakedCharlist.length);
|
GlyphMetaList glyphMeta = PushFullListZero(arena, GlyphMetaList, bakedCharlist.length);
|
||||||
real32 x, y;
|
real32 x, y;
|
||||||
real32 lastX, lastY;
|
real32 lastX, lastY;
|
||||||
@@ -48,7 +80,7 @@ Font createFont(Arena *arena, string ttfLocation, real32 lineHeight) {
|
|||||||
.uv0=(RLVector2){q.s0, q.t1},
|
.uv0=(RLVector2){q.s0, q.t1},
|
||||||
.uv1=(RLVector2){q.s1, q.t0},
|
.uv1=(RLVector2){q.s1, q.t0},
|
||||||
.xOffset=q.x0 - lastX,
|
.xOffset=q.x0 - lastX,
|
||||||
.yOffset=q.y0 + lineHeight,
|
.yOffset=q.y0 + lineHeight + scale * descent,
|
||||||
.width=q.x1-q.x0,
|
.width=q.x1-q.x0,
|
||||||
.height=q.y1-q.y0,
|
.height=q.y1-q.y0,
|
||||||
};
|
};
|
||||||
@@ -63,7 +95,6 @@ Font createFont(Arena *arena, string ttfLocation, real32 lineHeight) {
|
|||||||
|
|
||||||
glGenTextures(1, &result.texId);
|
glGenTextures(1, &result.texId);
|
||||||
glBindTexture(GL_TEXTURE_2D, result.texId);
|
glBindTexture(GL_TEXTURE_2D, result.texId);
|
||||||
//glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, atlasWidth, atlasHeight, 0, GL_RED, GL_UNSIGNED_BYTE, bakedFontBitmap);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, atlasWidth, atlasHeight, 0, GL_RED, GL_UNSIGNED_BYTE, bakedFontBitmap);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|||||||
74
src/main.c
74
src/main.c
@@ -140,16 +140,15 @@ void framebufferSizeCallback(GLFWwindow *window, int width, int height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLFWwindow *initWindowAndGL(uint32 windowWidth, uint32 windowHeight) {
|
GLFWwindow *initWindowAndGL(uint32 windowWidth, uint32 windowHeight) {
|
||||||
#ifdef OS_LINUX
|
if (!glfwInit()) {
|
||||||
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_X11);
|
return NULL;
|
||||||
#endif
|
}
|
||||||
|
glfwWindowHintString(GLFW_WAYLAND_APP_ID, "Somaesque");
|
||||||
glfwInit();
|
|
||||||
//glfwWindowHintString(GLFW_WAYLAND_APP_ID, "Somaesque");
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
glfwWindowHint(GLFW_SAMPLES, 4);
|
||||||
GLFWwindow *window = glfwCreateWindow(
|
GLFWwindow *window = glfwCreateWindow(
|
||||||
windowWidth,
|
windowWidth,
|
||||||
windowHeight,
|
windowHeight,
|
||||||
@@ -174,11 +173,11 @@ GLFWwindow *initWindowAndGL(uint32 windowWidth, uint32 windowHeight) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, windowWidth, windowHeight);
|
glViewport(0, 0, windowWidth, windowHeight);
|
||||||
glfwSwapInterval(0);
|
glfwSwapInterval(1);
|
||||||
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
|
|
||||||
glfwSetInputMode(window, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL);
|
glfwSetInputMode(window, GLFW_CURSOR | GLFW_RAW_MOUSE_MOTION, GLFW_CURSOR_NORMAL);
|
||||||
glfwSetWindowSize(window, windowWidth, windowHeight);
|
glfwSetWindowSize(window, windowWidth, windowHeight);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
@@ -365,7 +364,7 @@ static void ui_Interaction(UI_Context *ui, Soma *soma) {
|
|||||||
for (int y = 0; y < currentPolycube->repr.dim_y; y++) UI(.childGap=childGap) {
|
for (int y = 0; y < currentPolycube->repr.dim_y; y++) UI(.childGap=childGap) {
|
||||||
for (int z = 0; z < currentPolycube->repr.dim_z; z++) {
|
for (int z = 0; z < currentPolycube->repr.dim_z; z++) {
|
||||||
bool cellActive = filledAt(¤tPolycube->repr, x, y, z);
|
bool cellActive = filledAt(¤tPolycube->repr, x, y, z);
|
||||||
if (ui_CheckboxRect(ui, &cellActive, UI_CreateRect(
|
if (ui_CheckboxRect(ui, &cellActive, UI_RectAttr(
|
||||||
.width = boxSize,
|
.width = boxSize,
|
||||||
.height = boxSize,
|
.height = boxSize,
|
||||||
.borderRadius = 2,
|
.borderRadius = 2,
|
||||||
@@ -385,39 +384,35 @@ static void ui_Interaction(UI_Context *ui, Soma *soma) {
|
|||||||
static void DJUI_Soma(UI_Context *ui, Soma *soma) {
|
static void DJUI_Soma(UI_Context *ui, Soma *soma) {
|
||||||
RLVector4 darkgrey = {0.2, 0.2, 0.2, 1};
|
RLVector4 darkgrey = {0.2, 0.2, 0.2, 1};
|
||||||
RLVector4 grey = {0.4, 0.4, 0.4, 1};
|
RLVector4 grey = {0.4, 0.4, 0.4, 1};
|
||||||
|
UI_Padding btnPad = {.left=10, .right=10, .top=5, .bottom=5};
|
||||||
|
|
||||||
UI(.flags=UI_Flag_HeightGrow | UI_Flag_WidthGrow) {
|
UI(.flags=UI_Flag_HeightGrow | UI_Flag_WidthGrow) {
|
||||||
UI(.padding={.left=20, .right=20, .top=5}, .color=darkgrey, .flags=UI_Flag_HeightGrow | UI_Flag_Vertical) {
|
UI(.padding={.left=20, .right=20}, .color=darkgrey, .flags=UI_Flag_HeightGrow | UI_Flag_Vertical) {
|
||||||
UI() UI_Text(s("Somaesque"), .lineHeight=26);
|
UI(.padding=UI_PadUniform(10)) UI_Txt(s("Somaesque"), .lineHeight=26);
|
||||||
ui_Interaction(ui, soma);
|
ui_Interaction(ui, soma);
|
||||||
}
|
}
|
||||||
UI(.flags=UI_Flag_Vertical | UI_Flag_HeightGrow | UI_Flag_WidthGrow) {
|
UI(.flags=UI_Flag_Vertical | UI_Flag_HeightGrow | UI_Flag_WidthGrow) {
|
||||||
UI(.padding=UI_PadUniform(10), .color=darkgrey, .flags=UI_Flag_WidthGrow) {
|
UI(.padding=UI_PadUniform(10), .color=darkgrey, .flags=UI_Flag_WidthGrow) {
|
||||||
UI(.flags=UI_Flag_WidthGrow) {
|
|
||||||
UI(.childGap=10) {
|
UI(.childGap=10) {
|
||||||
if (ui_Button(ui, UI_CreateRect(.height=30, .padding={.left=10, .right=10}, .color=grey), UI_CreateText(s("Previous"), .lineHeight=20))) {
|
if (ui_Button(ui, UI_RectAttr(.padding=btnPad, .color=grey), UI_TxtAttr(s("Previous"), .lineHeight=20))) {
|
||||||
advanceDisplayReverse(soma);
|
advanceDisplayReverse(soma);
|
||||||
}
|
}
|
||||||
if (ui_Button(ui, UI_CreateRect(.height=30, .padding={.left=10, .right=10}, .color=grey), UI_CreateText(s("Next"), .lineHeight=20))) {
|
if (ui_Button(ui, UI_RectAttr(.padding=btnPad, .color=grey), UI_TxtAttr(s("Next"), .lineHeight=20))) {
|
||||||
advanceDisplay(soma);
|
advanceDisplay(soma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
UI(.flags=UI_Flag_WidthGrow);
|
||||||
UI(.childGap=10) {
|
UI(.childGap=10) {
|
||||||
if (ui_Button(ui, UI_CreateRect(
|
if (ui_Button(ui, UI_RectAttr(
|
||||||
.width=30,
|
.padding=btnPad,
|
||||||
.height=30,
|
|
||||||
.padding={.left=10, .right=10},
|
|
||||||
.color=soma->state.displayingSolutions ? grey : (RLVector4){0.2, 0.2, 0.7, 1},
|
.color=soma->state.displayingSolutions ? grey : (RLVector4){0.2, 0.2, 0.7, 1},
|
||||||
), UI_CreateText(s("Design"), .lineHeight=20))) {
|
), UI_TxtAttr(s("Design"), .lineHeight=20))) {
|
||||||
soma->state.displayingSolutions = false;
|
soma->state.displayingSolutions = false;
|
||||||
}
|
}
|
||||||
if (ui_Button(ui, UI_CreateRect(
|
if (ui_Button(ui, UI_RectAttr(
|
||||||
.width=30,
|
.padding=btnPad,
|
||||||
.height=30,
|
|
||||||
.padding={.left=10, .right=10},
|
|
||||||
.color=soma->state.displayingSolutions ? (RLVector4){0.2, 0.2, 0.7, 1} : grey,
|
.color=soma->state.displayingSolutions ? (RLVector4){0.2, 0.2, 0.7, 1} : grey,
|
||||||
), UI_CreateText(s("Solve"), .lineHeight=20))) {
|
), UI_TxtAttr(s("Solve"), .lineHeight=20))) {
|
||||||
if (!soma->state.displayingSolutions) {
|
if (!soma->state.displayingSolutions) {
|
||||||
tryScheduleSolve(soma);
|
tryScheduleSolve(soma);
|
||||||
} else {
|
} else {
|
||||||
@@ -426,7 +421,22 @@ static void DJUI_Soma(UI_Context *ui, Soma *soma) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UI(.flags=UI_Flag_WidthGrow | UI_Flag_HeightGrow | UI_Flag_3DScene);
|
UI(.flags=UI_Flag_Vertical | UI_Flag_WidthGrow | UI_Flag_HeightGrow | UI_Flag_3DScene) {
|
||||||
|
UI(.flags=UI_Flag_HeightGrow);
|
||||||
|
UI(.flags=UI_Flag_WidthGrow, .padding=UI_PadUniform(10)) {
|
||||||
|
if (soma->solveTaskCtx.taskStatus == SolveTaskStatus_Solving) {
|
||||||
|
UI_Txt(s("Solving..."), .lineHeight=26);
|
||||||
|
} else {
|
||||||
|
bool soln = soma->state.displayingSolutions;
|
||||||
|
UI_TxtSeg(soln ? s("Solution") : s("Polycube"), .lineHeight=26);
|
||||||
|
UI_TxtSeg(
|
||||||
|
strPrintf(ui->arena, " #%d (%d total)",
|
||||||
|
(soln ? soma->state.displayedSolution : soma->state.displayedPolycube) + 1,
|
||||||
|
soln ? soma->solutions.length : soma->polycubeInput.length),
|
||||||
|
.lineHeight=26);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -499,6 +509,13 @@ static void updateWindow(Soma *soma) {
|
|||||||
const int32 MAX_POLYCUBE_INPUT = 64;
|
const int32 MAX_POLYCUBE_INPUT = 64;
|
||||||
const int32 TARGET_FPS = 144;
|
const int32 TARGET_FPS = 144;
|
||||||
|
|
||||||
|
void APIENTRY glDebugCallback(GLenum source, GLenum type, GLuint id,
|
||||||
|
GLenum severity, GLsizei length,
|
||||||
|
const GLchar* message, const void* userParam)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "GL: %s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
int mainGfx() {
|
int mainGfx() {
|
||||||
Arena *arena = arenaAlloc(Megabytes(128));
|
Arena *arena = arenaAlloc(Megabytes(128));
|
||||||
Arena *solutionsArena = arenaAlloc(Megabytes(128));
|
Arena *solutionsArena = arenaAlloc(Megabytes(128));
|
||||||
@@ -510,6 +527,10 @@ int mainGfx() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
|
glDebugMessageCallback(glDebugCallback, NULL);
|
||||||
|
|
||||||
Scene mainScene = createScene(arena);
|
Scene mainScene = createScene(arena);
|
||||||
Camera cam = createCamera(winWidth, winHeight);
|
Camera cam = createCamera(winWidth, winHeight);
|
||||||
Renderer renderer = createRenderer(arena, &mainScene, &cam, createSceneGraphNode(&mainScene));
|
Renderer renderer = createRenderer(arena, &mainScene, &cam, createSceneGraphNode(&mainScene));
|
||||||
@@ -564,6 +585,7 @@ int mainGfx() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
glfwSetWindowUserPointer(windowHandle, &soma);
|
glfwSetWindowUserPointer(windowHandle, &soma);
|
||||||
|
glfwSetFramebufferSizeCallback(windowHandle, framebufferSizeCallback);
|
||||||
glfwSetScrollCallback(windowHandle, onMouseScroll);
|
glfwSetScrollCallback(windowHandle, onMouseScroll);
|
||||||
|
|
||||||
VoxelSpaceReprList stdSoma = AsList(VoxelSpaceReprList, STD_SOMA);
|
VoxelSpaceReprList stdSoma = AsList(VoxelSpaceReprList, STD_SOMA);
|
||||||
|
|||||||
22
src/render.c
22
src/render.c
@@ -130,7 +130,6 @@ static void updateCharObjectBuffers(Renderer *r) {
|
|||||||
GL_UpdateBuffer(r->chars.color);
|
GL_UpdateBuffer(r->chars.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void updateRectangleObjectBuffers(Renderer *r) {
|
static void updateRectangleObjectBuffers(Renderer *r) {
|
||||||
glBindVertexArray(r->rects.vao);
|
glBindVertexArray(r->rects.vao);
|
||||||
GL_UpdateBuffer(r->rects.p0);
|
GL_UpdateBuffer(r->rects.p0);
|
||||||
@@ -170,6 +169,8 @@ void renderBegin(Renderer *r) {
|
|||||||
r->sceneY = 0;
|
r->sceneY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CHECK() do{ GLenum e=glGetError(); if(e) printf("GL err 0x%x at %s:%d\n",e,__FILE__,__LINE__); }while(0)
|
||||||
|
|
||||||
void renderEnd(Renderer *r) {
|
void renderEnd(Renderer *r) {
|
||||||
// 3D Scene
|
// 3D Scene
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
@@ -222,22 +223,25 @@ void renderEnd(Renderer *r) {
|
|||||||
updateCharObjectBuffers(r);
|
updateCharObjectBuffers(r);
|
||||||
glUseProgram(r->textShader->progId);
|
glUseProgram(r->textShader->progId);
|
||||||
setUniformMat4fv(r->textShader, "projection", &ortho);
|
setUniformMat4fv(r->textShader, "projection", &ortho);
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0); CHECK();
|
||||||
glBindTexture(GL_TEXTURE_2D, r->activeFont->texId);
|
glBindTexture(GL_TEXTURE_2D, r->activeFont->texId); CHECK();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1); CHECK();
|
||||||
glBindTexture(GL_TEXTURE_BUFFER, r->activeFont->glyphTableTexId);
|
glBindTexture(GL_TEXTURE_BUFFER, r->activeFont->glyphTableTexId); CHECK();
|
||||||
setUniform1i(r->textShader, "glyph_table", 1);
|
setUniform1i(r->textShader, "glyph_table", 1); CHECK();
|
||||||
|
|
||||||
glBindVertexArray(r->chars.vao);
|
glBindVertexArray(r->chars.vao); CHECK();
|
||||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, r->chars.begin.buf.length);
|
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, r->chars.begin.buf.length); CHECK();
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rendererPlaceRectangle(Renderer *r, real32 x, real32 y, real32 width, real32 height, RLVector4 color, real32 borderRadius, real32 borderThickness) {
|
void rendererPlaceRectangle(Renderer *r, real32 x, real32 y, real32 width, real32 height, RLVector4 color, real32 borderRadius, real32 borderThickness) {
|
||||||
|
x = roundf(x);
|
||||||
|
y = roundf(y);
|
||||||
|
width = roundf(width);
|
||||||
|
height = roundf(height);
|
||||||
ListAppend(r->rects.p0.buf, ((RLVector2){ x, y }));
|
ListAppend(r->rects.p0.buf, ((RLVector2){ x, y }));
|
||||||
ListAppend(r->rects.p1.buf, ((RLVector2){ x + width, y + height }));
|
ListAppend(r->rects.p1.buf, ((RLVector2){ x + width, y + height }));
|
||||||
ListAppend(r->rects.color.buf, color);
|
ListAppend(r->rects.color.buf, color);
|
||||||
|
|||||||
24
src/ui.c
24
src/ui.c
@@ -1,8 +1,6 @@
|
|||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
#include "lib/djstdlib/core.h"
|
#include "lib/djstdlib/core.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
UI_Context *__UI_current_ctx__ = NULL;
|
UI_Context *__UI_current_ctx__ = NULL;
|
||||||
|
|
||||||
@@ -186,14 +184,15 @@ void ui_begin(UI_Context *ui) {
|
|||||||
void ui_end(UI_Context *ui) {
|
void ui_end(UI_Context *ui) {
|
||||||
ui_closeElement(ui);
|
ui_closeElement(ui);
|
||||||
|
|
||||||
// 1. Calculate layout
|
// 1) a. Calculate layout
|
||||||
ui_sizingPass(ui, true, ui->rootRect);
|
ui_sizingPass(ui, true, ui->rootRect); // x
|
||||||
ui_sizingPass(ui, false, ui->rootRect);
|
ui_sizingPass(ui, false, ui->rootRect); // y
|
||||||
|
|
||||||
ui_calcLayout(ui, true, ui->rootRect);
|
// 1) b.
|
||||||
ui_calcLayout(ui, false, ui->rootRect);
|
ui_calcLayout(ui, true, ui->rootRect); // x
|
||||||
|
ui_calcLayout(ui, false, ui->rootRect); // y
|
||||||
|
|
||||||
// 2. Create render commands:
|
// 2) Create render commands:
|
||||||
|
|
||||||
for (EachEl(ui->rects, UI_Rect, rect)) {
|
for (EachEl(ui->rects, UI_Rect, rect)) {
|
||||||
rendererPlaceRectangle(
|
rendererPlaceRectangle(
|
||||||
@@ -211,8 +210,8 @@ void ui_end(UI_Context *ui) {
|
|||||||
rendererPlaceString(
|
rendererPlaceString(
|
||||||
ui->renderer,
|
ui->renderer,
|
||||||
str->s,
|
str->s,
|
||||||
rect->x + str->xOffset,
|
rect->x + str->xOffset + rect->padding.left,
|
||||||
rect->y + str->yOffset,
|
rect->y + str->yOffset + rect->padding.top,
|
||||||
str->color,
|
str->color,
|
||||||
str->lineHeight
|
str->lineHeight
|
||||||
);
|
);
|
||||||
@@ -266,8 +265,7 @@ void ui_closeElement(UI_Context *ui) {
|
|||||||
|
|
||||||
if (currRect->width != -1) {
|
if (currRect->width != -1) {
|
||||||
currRect->resolvedWidth = currRect->width;
|
currRect->resolvedWidth = currRect->width;
|
||||||
}
|
} else if (currRect->minWidth == -1) {
|
||||||
if (currRect->minWidth == -1) {
|
|
||||||
if (currRect->stringData) {
|
if (currRect->stringData) {
|
||||||
real32 charWidth = currRect->stringData->lineHeight / ui->renderer->activeFont->lineHeight * ui->renderer->activeFont->charWidth;
|
real32 charWidth = currRect->stringData->lineHeight / ui->renderer->activeFont->lineHeight * ui->renderer->activeFont->charWidth;
|
||||||
currRect->minWidth = charWidth*currRect->stringData->s.length;
|
currRect->minWidth = charWidth*currRect->stringData->s.length;
|
||||||
@@ -278,7 +276,7 @@ void ui_closeElement(UI_Context *ui) {
|
|||||||
currRect->resolvedWidth = currRect->padding.left + currRect->padding.right + (currRect->resolvedWidth < currRect->minWidth ? currRect->minWidth : currRect->resolvedWidth);
|
currRect->resolvedWidth = currRect->padding.left + currRect->padding.right + (currRect->resolvedWidth < currRect->minWidth ? currRect->minWidth : currRect->resolvedWidth);
|
||||||
|
|
||||||
if (currRect->height != -1) {
|
if (currRect->height != -1) {
|
||||||
currRect->resolvedHeight = currRect->height;
|
currRect->resolvedHeight = currRect->height - currRect->padding.top - currRect->padding.bottom;
|
||||||
} else if (currRect->minHeight == -1) {
|
} else if (currRect->minHeight == -1) {
|
||||||
if (currRect->stringData) {
|
if (currRect->stringData) {
|
||||||
currRect->minHeight = currRect->stringData->lineHeight;
|
currRect->minHeight = currRect->stringData->lineHeight;
|
||||||
|
|||||||
22
src/ui.h
22
src/ui.h
@@ -38,10 +38,12 @@ struct Input {
|
|||||||
|
|
||||||
enum UI_Flag {
|
enum UI_Flag {
|
||||||
UI_Flag_WidthGrow=1<<0, // Default is fixed
|
UI_Flag_WidthGrow=1<<0, // Default is fixed
|
||||||
UI_Flag_HeightGrow=1<<1,
|
UI_Flag_HeightGrow=1<<1, // Default is fixed
|
||||||
UI_Flag_Vertical=1<<2, // Default is horizontal
|
UI_Flag_Vertical=1<<2, // Default is horizontal
|
||||||
UI_Flag_3DScene=1<<3,
|
UI_Flag_3DScene=1<<3,
|
||||||
UI_Flag_Center=1<<4,
|
UI_Flag_Center=1<<4,
|
||||||
|
UI_Flag_Textalign_Right=1<<5, // Default is left
|
||||||
|
UI_Flag_Textalign_Center=1<<6,
|
||||||
// ..
|
// ..
|
||||||
UI_Flag_COUNT,
|
UI_Flag_COUNT,
|
||||||
};
|
};
|
||||||
@@ -61,12 +63,13 @@ struct UI_RectStr {
|
|||||||
real32 yOffset;
|
real32 yOffset;
|
||||||
real32 lineHeight;
|
real32 lineHeight;
|
||||||
RLVector4 color;
|
RLVector4 color;
|
||||||
|
int8 alignment;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct UI_Rect UI_Rect;
|
typedef struct UI_Rect UI_Rect;
|
||||||
struct UI_Rect {
|
struct UI_Rect {
|
||||||
/** UI_Rect_LayoutFlag */
|
/** UI_Rect_LayoutFlag */
|
||||||
uint64 flags;
|
enum UI_Flag flags;
|
||||||
|
|
||||||
int32 parent;
|
int32 parent;
|
||||||
int32 firstChild;
|
int32 firstChild;
|
||||||
@@ -135,13 +138,20 @@ bool ui_CheckboxRect(UI_Context *ui, bool *value, UI_Rect rect);
|
|||||||
|
|
||||||
extern UI_Context *__UI_current_ctx__;
|
extern UI_Context *__UI_current_ctx__;
|
||||||
|
|
||||||
#define UI(...) DeferLoop(ui_openElement((__UI_current_ctx__), UI_CreateRect(__VA_ARGS__)), ui_closeElement((__UI_current_ctx__)))
|
#if 0
|
||||||
#define UI_CreateRect(...) ((UI_Rect){.minHeight=-1, .minWidth=-1, .width=-1, .height=-1, __VA_ARGS__})
|
#define UI_WIREFRAME .color=COLOR_RED, .borderThickness=1,
|
||||||
|
#else
|
||||||
|
#define UI_WIREFRAME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UI(...) DeferLoop(ui_openElement((__UI_current_ctx__), UI_RectAttr(__VA_ARGS__)), ui_closeElement((__UI_current_ctx__)))
|
||||||
|
#define UI_RectAttr(...) ((UI_Rect){UI_WIREFRAME .minHeight=-1, .minWidth=-1, .width=-1, .height=-1, __VA_ARGS__})
|
||||||
#define UI_FromRect(rect) DeferLoop(ui_openElement((__UI_current_ctx__), (rect)), ui_closeElement((__UI_current_ctx__)))
|
#define UI_FromRect(rect) DeferLoop(ui_openElement((__UI_current_ctx__), (rect)), ui_closeElement((__UI_current_ctx__)))
|
||||||
#define UI_Pass(ui) DeferLoop(ui_begin((ui)), ui_end((ui)))
|
#define UI_Pass(ui) DeferLoop(ui_begin((ui)), ui_end((ui)))
|
||||||
#define UI_PadUniform(padding) ((UI_Padding){ (padding), (padding), (padding), (padding) })
|
#define UI_PadUniform(padding) ((UI_Padding){ (padding), (padding), (padding), (padding) })
|
||||||
#define UI_NextID() ((__UI_current_ctx__)->rects.length)
|
#define UI_NextID() ((__UI_current_ctx__)->rects.length)
|
||||||
#define UI_Text(str, ...) (ui_placeText((__UI_current_ctx__), ((UI_RectStr){ .xOffset=0, .yOffset=0, .lineHeight=-1, .s=(str), __VA_ARGS__ })))
|
#define UI_Txt(str, ...) (ui_placeText((__UI_current_ctx__), ((UI_RectStr){ .xOffset=0, .yOffset=0, .lineHeight=-1, .s=(str), __VA_ARGS__ })))
|
||||||
#define UI_CreateText(str, ...) ((UI_RectStr){ .xOffset=0, .yOffset=0, .lineHeight=-1, .s=(str), __VA_ARGS__ })
|
#define UI_TxtSeg(str, ...) UI() (UI_Txt((str), __VA_ARGS__))
|
||||||
|
#define UI_TxtAttr(str, ...) ((UI_RectStr){ .xOffset=0, .yOffset=0, .lineHeight=-1, .s=(str), __VA_ARGS__ })
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user