adding gfx and ui stuff
This commit is contained in:
137
gfx/Texture.c
Normal file
137
gfx/Texture.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#include "Texture.h"
|
||||
#include "../os.h"
|
||||
#include <math.h>
|
||||
|
||||
Texture createTexture(const char* bitmap, int32 width, int32 height) {
|
||||
Texture result = {0};
|
||||
result.width = width;
|
||||
result.height = height;
|
||||
glGenTextures(1, &result.tex_id);
|
||||
glBindTexture(GL_TEXTURE_2D, result.tex_id);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, result.width, result.height, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmap);
|
||||
|
||||
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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DefineList(stbtt_bakedchar, STBBakedChar);
|
||||
|
||||
static void saveGrayscaleTarga(string location, const char *bytes, int width, int height) {
|
||||
char tgaHeader[18] = {
|
||||
// Image ID length
|
||||
0x00,
|
||||
// Color map type
|
||||
0x00,
|
||||
// Image type
|
||||
0x03,
|
||||
// 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)
|
||||
0b00000000, // image descriptor
|
||||
};
|
||||
os_writeEntireFile(location, tgaHeader, ArrayCount(tgaHeader));
|
||||
os_fileAppend(location, bytes, width * height);
|
||||
}
|
||||
|
||||
Font createFont(Arena *arena, string ttfLocation, real32 lineHeight) {
|
||||
const int CODEPOINT_START = 32;
|
||||
const int CODEPOINT_END = 126;
|
||||
|
||||
int32 atlasWidth = ((int32)lineHeight)*(int32)sqrt(CODEPOINT_END - CODEPOINT_START);
|
||||
int32 atlasHeight = ((int32)lineHeight)*(int32)sqrt(CODEPOINT_END - CODEPOINT_START);
|
||||
|
||||
STBBakedCharList bakedCharlist = PushFullListZero(arena, STBBakedCharList, CODEPOINT_END - CODEPOINT_START);
|
||||
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, lineHeight);
|
||||
|
||||
char *bakedFontBitmap = PushArrayZero(arena, char, atlasWidth*atlasHeight);
|
||||
int32 bake_result = stbtt_BakeFontBitmap(
|
||||
(unsigned char *)fontFile.str, 0,
|
||||
lineHeight,
|
||||
(unsigned char *)bakedFontBitmap, atlasWidth, atlasHeight,
|
||||
CODEPOINT_START, CODEPOINT_END - CODEPOINT_START,
|
||||
bakedCharlist.data);
|
||||
|
||||
GlyphMetaList glyphMeta = PushFullListZero(arena, GlyphMetaList, bakedCharlist.length);
|
||||
real32 x, y;
|
||||
real32 lastX, lastY;
|
||||
for (EachIn(bakedCharlist, i)) {
|
||||
stbtt_aligned_quad q;
|
||||
stbtt_GetBakedQuad(bakedCharlist.data, atlasWidth, atlasHeight, i, &x, &y, &q, 1);
|
||||
glyphMeta.data[i] = (GlyphMeta){
|
||||
.uv0=(Vec2){q.s0, q.t1},
|
||||
.uv1=(Vec2){q.s1, q.t0},
|
||||
.xOffset=q.x0 - lastX,
|
||||
.yOffset=q.y0 + lineHeight + scale * descent,
|
||||
.width=q.x1-q.x0,
|
||||
.height=q.y1-q.y0,
|
||||
};
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
}
|
||||
|
||||
Font result = {0};
|
||||
result.glyphMeta = glyphMeta;
|
||||
result.lineHeight = lineHeight;
|
||||
result.charWidth = bakedCharlist.data[0].xadvance;
|
||||
|
||||
//saveGrayscaleTarga(s("atlas.tga"), bakedFontBitmap, atlasWidth, atlasHeight);
|
||||
|
||||
glGenTextures(1, &result.texId);
|
||||
glBindTexture(GL_TEXTURE_2D, result.texId);
|
||||
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_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glGenBuffers(1, &result.glyphTableBufId);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, result.glyphTableBufId);
|
||||
glBufferData(GL_TEXTURE_BUFFER, sizeof(result.glyphMeta.data[0])*result.glyphMeta.length, result.glyphMeta.data, GL_STATIC_DRAW);
|
||||
|
||||
glGenTextures(1, &result.glyphTableTexId);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, result.glyphTableTexId);
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, result.glyphTableBufId);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Texture createTextureFromFile(const char* source_path) {
|
||||
Texture result = {0};
|
||||
glGenTextures(1, &result.tex_id);
|
||||
glBindTexture(GL_TEXTURE_2D, result.tex_id);
|
||||
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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
int nr_channels;
|
||||
stbi_uc *data = stbi_load(source_path, &result.width, &result.height, &nr_channels, 0);
|
||||
if (data) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, result.width, result.height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
} else {
|
||||
print("Failed to load texture.");
|
||||
}
|
||||
stbi_image_free(data);
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user