mirror of https://github.com/bjornbytes/lovr.git
Really terrible font rendering;
This commit is contained in:
parent
853e9d89d7
commit
ab2d0ee79a
|
@ -0,0 +1,121 @@
|
|||
#include "graphics/font.h"
|
||||
#include "graphics/graphics.h"
|
||||
#include "graphics/texture.h"
|
||||
#include "math/math.h"
|
||||
#include "loaders/font.h"
|
||||
#include "loaders/texture.h"
|
||||
#include "vendor/vec/vec.h"
|
||||
#include <string.h>
|
||||
|
||||
static vec_float_t scratch;
|
||||
|
||||
Font* lovrFontCreate(FontData* fontData) {
|
||||
Font* font = lovrAlloc(sizeof(Font), lovrFontDestroy);
|
||||
if (!font) return NULL;
|
||||
|
||||
font->fontData = fontData;
|
||||
font->padding = 1;
|
||||
font->tx = font->padding;
|
||||
font->ty = font->padding;
|
||||
font->tw = 256;
|
||||
font->th = 256;
|
||||
TextureData* textureData = lovrTextureDataGetBlank(font->tw, font->th, 0x00, FORMAT_RG);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
||||
font->texture = lovrTextureCreate(textureData);
|
||||
lovrTextureSetWrap(font->texture, WRAP_CLAMP, WRAP_CLAMP);
|
||||
int swizzle[] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
||||
map_init(&font->glyphs);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void lovrFontDestroy(const Ref* ref) {
|
||||
Font* font = containerof(ref, Font);
|
||||
lovrFontDataDestroy(font->fontData);
|
||||
free(font);
|
||||
}
|
||||
|
||||
void lovrFontDataDestroy(FontData* fontData) {
|
||||
// TODO
|
||||
free(fontData);
|
||||
}
|
||||
|
||||
void lovrFontPrint(Font* font, const char* str) {
|
||||
vec_reserve(&scratch, strlen(str) * 30);
|
||||
vec_clear(&scratch);
|
||||
|
||||
// Cursor
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
|
||||
for (unsigned int i = 0; i < strlen(str); i++) {
|
||||
Glyph* glyph = lovrFontGetGlyph(font, str[i]);
|
||||
float s = glyph->s;
|
||||
float t = glyph->t;
|
||||
float w = glyph->glyphData->w;
|
||||
float h = glyph->glyphData->h;
|
||||
|
||||
float xx = x + glyph->glyphData->x;
|
||||
float yy = y - glyph->glyphData->y;
|
||||
|
||||
float v[30] = {
|
||||
xx, yy, -5, s, t + h / font->th,
|
||||
xx, yy + h, -5, s, t,
|
||||
xx + w, yy, -5, s + w / font->tw, t + h / font->th,
|
||||
xx + w, yy, -5, s + w / font->tw, t + h / font->th,
|
||||
xx, yy + h, -5, s, t,
|
||||
xx + w, yy + h, -5, s + w / font->tw, t
|
||||
};
|
||||
|
||||
x += glyph->glyphData->advance;
|
||||
|
||||
vec_pusharr(&scratch, v, 30);
|
||||
}
|
||||
|
||||
lovrGraphicsSetShapeData(scratch.data, scratch.length);
|
||||
lovrGraphicsDrawPrimitive(GL_TRIANGLES, font->texture, 0, 1, 0);
|
||||
}
|
||||
|
||||
Glyph* lovrFontGetGlyph(Font* font, char character) {
|
||||
|
||||
// Return the glyph if it's already loaded
|
||||
char key[2] = { character, '\0' };
|
||||
Glyph** g = (Glyph**) map_get(&font->glyphs, key);
|
||||
if (g) return *g;
|
||||
|
||||
// Otherwise, load it (3 mallocs isn't great FIXME)
|
||||
Glyph* glyph = malloc(sizeof(Glyph));
|
||||
glyph->glyphData = lovrFontDataCreateGlyph(font->fontData, character);
|
||||
|
||||
// Put the glyph somewhere, expanding texture as necessary
|
||||
while (font->tx + glyph->glyphData->w > font->tw - 2 * font->padding) {
|
||||
while (font->ty + glyph->glyphData->h > font->th - 2 * font->padding) {
|
||||
// Expand texture
|
||||
}
|
||||
font->tx = font->padding;
|
||||
font->ty += font->rowHeight;
|
||||
font->rowHeight = 0;
|
||||
}
|
||||
|
||||
// Calculate texture coordinate
|
||||
glyph->s = font->tx / (float) font->tw;
|
||||
glyph->t = font->ty / (float) font->th;
|
||||
|
||||
// Upload glyph to texture
|
||||
lovrGraphicsBindTexture(font->texture);
|
||||
glTexSubImage2D(
|
||||
GL_TEXTURE_2D, 0,
|
||||
font->tx, font->ty, glyph->glyphData->w, glyph->glyphData->h,
|
||||
GL_RG, GL_UNSIGNED_BYTE, glyph->glyphData->data
|
||||
);
|
||||
|
||||
// Advance the texture cursor
|
||||
font->tx += glyph->glyphData->w;
|
||||
font->rowHeight = MAX(font->rowHeight, glyph->glyphData->h);
|
||||
|
||||
// Write glyph to cache
|
||||
map_set(&font->glyphs, key, glyph);
|
||||
|
||||
return glyph;
|
||||
}
|
|
@ -1,14 +1,45 @@
|
|||
#include "util.h"
|
||||
#include "graphics/texture.h"
|
||||
#include "vendor/map/map.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
int advance;
|
||||
uint8_t* data;
|
||||
} GlyphData;
|
||||
|
||||
typedef struct {
|
||||
void* rasterizer;
|
||||
} FontData;
|
||||
|
||||
// GlyphData along with the glyph's position in the texture atlas
|
||||
typedef struct {
|
||||
GlyphData* glyphData;
|
||||
float s;
|
||||
float t;
|
||||
} Glyph;
|
||||
|
||||
typedef struct {
|
||||
void* face;
|
||||
} FontData;
|
||||
|
||||
typedef struct {
|
||||
FontData fontData;
|
||||
Ref ref;
|
||||
FontData* fontData;
|
||||
Texture* texture;
|
||||
int tx;
|
||||
int ty;
|
||||
int tw;
|
||||
int th;
|
||||
int rowHeight;
|
||||
int padding;
|
||||
map_void_t glyphs;
|
||||
} Font;
|
||||
|
||||
Font* lovrFontCreate(FontData* fontData);
|
||||
void lovrFontDestroy(const Ref* ref);
|
||||
void lovrFontDataDestroy(FontData* fontData);
|
||||
void lovrFontPrint(Font* font, const char* str);
|
||||
Glyph* lovrFontGetGlyph(Font* font, char character);
|
||||
|
|
|
@ -21,7 +21,7 @@ void lovrGraphicsInit() {
|
|||
state.fullscreenShader = lovrShaderCreate(lovrNoopVertexShader, lovrDefaultFragmentShader);
|
||||
int uniformId = lovrShaderGetUniformId(state.skyboxShader, "cube");
|
||||
lovrShaderSendInt(state.skyboxShader, uniformId, 1);
|
||||
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetBlank(1, 1, 0xff));
|
||||
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA));
|
||||
glGenBuffers(1, &state.shapeBuffer);
|
||||
glGenBuffers(1, &state.shapeIndexBuffer);
|
||||
glGenVertexArrays(1, &state.shapeArray);
|
||||
|
@ -182,6 +182,14 @@ void lovrGraphicsSetShader(Shader* shader) {
|
|||
}
|
||||
}
|
||||
|
||||
Font* lovrGraphicsGetFont() {
|
||||
return state.activeFont;
|
||||
}
|
||||
|
||||
void lovrGraphicsSetFont(Font* font) {
|
||||
state.activeFont = font;
|
||||
}
|
||||
|
||||
void lovrGraphicsBindTexture(Texture* texture) {
|
||||
if (!texture) {
|
||||
texture = state.defaultTexture;
|
||||
|
@ -348,6 +356,16 @@ void lovrGraphicsMatrixTransform(mat4 transform) {
|
|||
|
||||
// Primitives
|
||||
|
||||
void lovrGraphicsSetShapeData(float* data, int length) {
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, data, length);
|
||||
}
|
||||
|
||||
void lovrGraphicsSetIndexData(unsigned int* data, int length) {
|
||||
vec_clear(&state.shapeIndices);
|
||||
vec_pusharr(&state.shapeIndices, data, length);
|
||||
}
|
||||
|
||||
void lovrGraphicsDrawPrimitive(GLenum mode, Texture* texture, int hasNormals, int hasTexCoords, int useIndices) {
|
||||
int stride = 3 + (hasNormals ? 3 : 0) + (hasTexCoords ? 2 : 0);
|
||||
int strideBytes = stride * sizeof(float);
|
||||
|
@ -387,21 +405,18 @@ void lovrGraphicsDrawPrimitive(GLenum mode, Texture* texture, int hasNormals, in
|
|||
}
|
||||
|
||||
void lovrGraphicsPoints(float* points, int count) {
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, points, count);
|
||||
lovrGraphicsSetShapeData(points, count);
|
||||
lovrGraphicsDrawPrimitive(GL_POINTS, NULL, 0, 0, 0);
|
||||
}
|
||||
|
||||
void lovrGraphicsLine(float* points, int count) {
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, points, count);
|
||||
lovrGraphicsSetShapeData(points, count);
|
||||
lovrGraphicsDrawPrimitive(GL_LINE_STRIP, NULL, 0, 0, 0);
|
||||
}
|
||||
|
||||
void lovrGraphicsTriangle(DrawMode mode, float* points) {
|
||||
if (mode == DRAW_MODE_LINE) {
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, points, 9);
|
||||
lovrGraphicsSetShapeData(points, 9);
|
||||
lovrGraphicsDrawPrimitive(GL_LINE_LOOP, NULL, 0, 0, 0);
|
||||
} else {
|
||||
float normal[3];
|
||||
|
@ -413,8 +428,7 @@ void lovrGraphicsTriangle(DrawMode mode, float* points) {
|
|||
points[6], points[7], points[8], normal[0], normal[1], normal[2]
|
||||
};
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, data, 18);
|
||||
lovrGraphicsSetShapeData(data, 18);
|
||||
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, NULL, 1, 0, 0);
|
||||
}
|
||||
}
|
||||
|
@ -452,8 +466,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float
|
|||
-.5, -.5, 0
|
||||
};
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, points, 12);
|
||||
lovrGraphicsSetShapeData(points, 12);
|
||||
lovrGraphicsDrawPrimitive(GL_LINE_LOOP, NULL, 0, 0, 0);
|
||||
} else if (mode == DRAW_MODE_FILL) {
|
||||
float data[] = {
|
||||
|
@ -463,8 +476,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float
|
|||
.5, -.5, 0, 0, 0, -1, 1, 1
|
||||
};
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, data, 32);
|
||||
lovrGraphicsSetShapeData(data, 32);
|
||||
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, texture, 1, 1, 0);
|
||||
}
|
||||
|
||||
|
@ -483,8 +495,7 @@ void lovrGraphicsPlaneFullscreen(Texture* texture) {
|
|||
lovrRetain(&lastShader->ref);
|
||||
lovrGraphicsSetShader(state.fullscreenShader);
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, data, 20);
|
||||
lovrGraphicsSetShapeData(data, 20);
|
||||
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, texture, 0, 1, 0);
|
||||
|
||||
lovrGraphicsSetShader(lastShader);
|
||||
|
@ -516,10 +527,8 @@ void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform) {
|
|||
0, 4, 1, 5, 2, 6, 3, 7 // Connections
|
||||
};
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, points, 24);
|
||||
vec_clear(&state.shapeIndices);
|
||||
vec_pusharr(&state.shapeIndices, indices, 24);
|
||||
lovrGraphicsSetShapeData(points, 24);
|
||||
lovrGraphicsSetIndexData(indices, 24);
|
||||
lovrGraphicsDrawPrimitive(GL_LINES, NULL, 0, 0, 1);
|
||||
} else {
|
||||
float data[] = {
|
||||
|
@ -564,8 +573,7 @@ void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform) {
|
|||
.5, .5, .5, 0, 1, 0, 1, 0
|
||||
};
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, data, 208);
|
||||
lovrGraphicsSetShapeData(data, 208);
|
||||
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, texture, 1, 1, 0);
|
||||
}
|
||||
|
||||
|
@ -624,8 +632,7 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
|
|||
1.f, 1.f, 1.f
|
||||
};
|
||||
|
||||
vec_clear(&state.shapeData);
|
||||
vec_pusharr(&state.shapeData, cube, 156);
|
||||
lovrGraphicsSetShapeData(cube, 156);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
|
@ -644,3 +651,7 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
|
|||
lovrRelease(&lastShader->ref);
|
||||
lovrGraphicsPop();
|
||||
}
|
||||
|
||||
void lovrGraphicsPrint(const char* str) {
|
||||
lovrFontPrint(state.activeFont, str);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "graphics/buffer.h"
|
||||
#include "graphics/font.h"
|
||||
#include "graphics/model.h"
|
||||
#include "graphics/shader.h"
|
||||
#include "graphics/skybox.h"
|
||||
|
@ -48,6 +49,7 @@ typedef struct {
|
|||
Shader* defaultShader;
|
||||
Shader* skyboxShader;
|
||||
Shader* fullscreenShader;
|
||||
Font* activeFont;
|
||||
Texture* defaultTexture;
|
||||
float transforms[MAX_TRANSFORMS][16];
|
||||
CanvasState* canvases[MAX_CANVASES];
|
||||
|
@ -91,6 +93,8 @@ void lovrGraphicsGetScissor(int* x, int* y, int* width, int* height);
|
|||
void lovrGraphicsSetScissor(int x, int y, int width, int height);
|
||||
Shader* lovrGraphicsGetShader();
|
||||
void lovrGraphicsSetShader(Shader* shader);
|
||||
Font* lovrGraphicsGetFont();
|
||||
void lovrGraphicsSetFont(Font* font);
|
||||
void lovrGraphicsBindTexture(Texture* texture);
|
||||
mat4 lovrGraphicsGetProjection();
|
||||
void lovrGraphicsSetProjection(float near, float far, float fov);
|
||||
|
@ -124,6 +128,8 @@ void lovrGraphicsScale(float x, float y, float z);
|
|||
void lovrGraphicsMatrixTransform(mat4 transform);
|
||||
|
||||
// Primitives
|
||||
void lovrGraphicsSetShapeData(float* data, int length);
|
||||
void lovrGraphicsSetIndexData(unsigned int* data, int length);
|
||||
void lovrGraphicsDrawPrimitive(GLenum mode, Texture* texture, int hasNormals, int hasTexCoords, int useIndices);
|
||||
void lovrGraphicsPoints(float* points, int count);
|
||||
void lovrGraphicsLine(float* points, int count);
|
||||
|
@ -132,3 +138,4 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, float x, float y, float
|
|||
void lovrGraphicsPlaneFullscreen(Texture* texture);
|
||||
void lovrGraphicsCube(DrawMode mode, Texture* texture, mat4 transform);
|
||||
void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float az);
|
||||
void lovrGraphicsPrint(const char* str);
|
||||
|
|
|
@ -4,17 +4,29 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static GLenum getGLFormat(TextureFormat format) {
|
||||
switch (format) {
|
||||
case FORMAT_RED: return GL_RED;
|
||||
case FORMAT_RG: return GL_RG;
|
||||
case FORMAT_RGB: return GL_RGB;
|
||||
case FORMAT_RGBA: return GL_RGBA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture* lovrTextureCreate(TextureData* textureData) {
|
||||
Texture* texture = lovrAlloc(sizeof(Texture), lovrTextureDestroy);
|
||||
if (!texture) return NULL;
|
||||
|
||||
int w = textureData->width;
|
||||
int h = textureData->height;
|
||||
GLenum format = getGLFormat(textureData->format);
|
||||
|
||||
texture->textureData = textureData;
|
||||
glGenTextures(1, &texture->id);
|
||||
lovrTextureBind(texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData->data);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, textureData->data);
|
||||
lovrTextureSetFilter(texture, FILTER_LINEAR, FILTER_LINEAR);
|
||||
lovrTextureSetWrap(texture, WRAP_REPEAT, WRAP_REPEAT);
|
||||
|
||||
|
|
|
@ -5,11 +5,19 @@ struct CanvasState;
|
|||
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
FORMAT_RED,
|
||||
FORMAT_RG,
|
||||
FORMAT_RGB,
|
||||
FORMAT_RGBA
|
||||
} TextureFormat;
|
||||
|
||||
typedef struct {
|
||||
void* data;
|
||||
int width;
|
||||
int height;
|
||||
int channels;
|
||||
TextureFormat format;
|
||||
} TextureData;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -12,23 +12,55 @@ FontData* lovrFontDataCreate(void* data, int size) {
|
|||
}
|
||||
|
||||
FontData* fontData = malloc(sizeof(FontData));
|
||||
FT_Face face = fontData->face;
|
||||
if (FT_New_Memory_Face(ft, data, size, 0, &face)) {
|
||||
if (FT_New_Memory_Face(ft, data, size, 0, (FT_Face*)&fontData->rasterizer)) {
|
||||
error("Error loading font");
|
||||
}
|
||||
|
||||
if (FT_Set_Pixel_Sizes(face, 16, 16)) {
|
||||
if (FT_Set_Pixel_Sizes(fontData->rasterizer, 0, 64)) {
|
||||
error("Problem setting font size");
|
||||
}
|
||||
|
||||
return fontData;
|
||||
}
|
||||
|
||||
void lovrFontDataGetGlyph(FontData* fontData, char c, Glyph* glyph) {
|
||||
FT_Glyph ftglyph;
|
||||
FT_Face face = fontData->face;
|
||||
FT_Load_Glyph(face, c, FT_LOAD_DEFAULT);
|
||||
FT_Get_Glyph(face->glyph, &ftglyph);
|
||||
GlyphData* lovrFontDataCreateGlyph(FontData* fontData, uint32_t character) {
|
||||
FT_Face face = fontData->rasterizer;
|
||||
FT_Error err = FT_Err_Ok;
|
||||
FT_Glyph ftGlyph;
|
||||
FT_Bitmap ftBitmap;
|
||||
FT_BitmapGlyph ftBitmapGlyph;
|
||||
|
||||
//
|
||||
err |= FT_Load_Glyph(face, FT_Get_Char_Index(face, character), FT_LOAD_DEFAULT);
|
||||
err |= FT_Get_Glyph(face->glyph, &ftGlyph);
|
||||
err |= FT_Glyph_To_Bitmap(&ftGlyph, FT_RENDER_MODE_NORMAL, 0, 1);
|
||||
|
||||
if (err) {
|
||||
error("Error loading glyph\n");
|
||||
}
|
||||
|
||||
ftBitmapGlyph = (FT_BitmapGlyph) ftGlyph;
|
||||
ftBitmap = ftBitmapGlyph->bitmap;
|
||||
|
||||
GlyphData* glyphData = malloc(sizeof(GlyphData));
|
||||
FT_Glyph_Metrics* metrics = &face->glyph->metrics;
|
||||
glyphData->x = metrics->horiBearingX >> 6;
|
||||
glyphData->y = metrics->horiBearingY >> 6;
|
||||
glyphData->w = metrics->width >> 6;
|
||||
glyphData->h = metrics->height >> 6;
|
||||
glyphData->advance = metrics->horiAdvance >> 6;
|
||||
glyphData->data = malloc(2 * glyphData->w * glyphData->h);
|
||||
|
||||
int i = 0;
|
||||
uint8_t* row = ftBitmap.buffer;
|
||||
for (int y = 0; y < glyphData->h; y++) {
|
||||
for (int x = 0; x < glyphData->w; x++) {
|
||||
glyphData->data[i++] = 0xff;
|
||||
glyphData->data[i++] = row[x];
|
||||
}
|
||||
|
||||
row += ftBitmap.pitch;
|
||||
}
|
||||
|
||||
FT_Done_Glyph(ftGlyph);
|
||||
return glyphData;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "graphics/font.h"
|
||||
#include <stdint.h>
|
||||
|
||||
FontData* lovrFontDataCreate(void* data, int size);
|
||||
void lovrFontDataGetGlyph(FontData* fontData, char c, Glyph* glyph);
|
||||
GlyphData* lovrFontDataCreateGlyph(FontData* fontData, uint32_t characer);
|
||||
|
|
|
@ -3,11 +3,18 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value) {
|
||||
TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value, TextureFormat format) {
|
||||
TextureData* textureData = malloc(sizeof(TextureData));
|
||||
if (!textureData) return NULL;
|
||||
|
||||
int channels = 4;
|
||||
int channels = 0;
|
||||
switch (format) {
|
||||
case FORMAT_RED: channels = 1; break;
|
||||
case FORMAT_RG: channels = 2; break;
|
||||
case FORMAT_RGB: channels = 3; break;
|
||||
case FORMAT_RGBA: channels = 4; break;
|
||||
}
|
||||
|
||||
int size = sizeof(uint8_t) * width * height * channels;
|
||||
uint8_t* data = malloc(size);
|
||||
memset(data, value, size);
|
||||
|
@ -16,6 +23,7 @@ TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value) {
|
|||
textureData->width = width;
|
||||
textureData->height = height;
|
||||
textureData->channels = channels;
|
||||
textureData->format = format;
|
||||
|
||||
return textureData;
|
||||
}
|
||||
|
@ -28,6 +36,7 @@ TextureData* lovrTextureDataGetEmpty(int width, int height) {
|
|||
textureData->width = width;
|
||||
textureData->height = height;
|
||||
textureData->channels = 4;
|
||||
textureData->format = FORMAT_RGBA;
|
||||
|
||||
return textureData;
|
||||
}
|
||||
|
@ -44,6 +53,7 @@ TextureData* lovrTextureDataFromFile(void* data, int size) {
|
|||
|
||||
if (image) {
|
||||
textureData->data = image;
|
||||
textureData->format = FORMAT_RGBA;
|
||||
return textureData;
|
||||
}
|
||||
|
||||
|
@ -59,5 +69,6 @@ TextureData* lovrTextureDataFromOpenVRModel(OpenVRModel* vrModel) {
|
|||
textureData->width = texture->unWidth;
|
||||
textureData->height = texture->unHeight;
|
||||
textureData->data = texture->rubTextureMapData;
|
||||
textureData->format = FORMAT_RGBA;
|
||||
return textureData;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "openvr.h"
|
||||
#include <stdint.h>
|
||||
|
||||
TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value);
|
||||
TextureData* lovrTextureDataGetBlank(int width, int height, uint8_t value, TextureFormat format);
|
||||
TextureData* lovrTextureDataGetEmpty(int width, int height);
|
||||
TextureData* lovrTextureDataFromFile(void* data, int size);
|
||||
TextureData* lovrTextureDataFromOpenVRModel(OpenVRModel* vrModel);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "lovr/types/texture.h"
|
||||
#include "lovr/types/transform.h"
|
||||
#include "graphics/graphics.h"
|
||||
#include "loaders/font.h"
|
||||
#include "loaders/model.h"
|
||||
#include "loaders/texture.h"
|
||||
#include "filesystem/filesystem.h"
|
||||
|
@ -68,6 +69,8 @@ const luaL_Reg lovrGraphics[] = {
|
|||
{ "setScissor", l_lovrGraphicsSetScissor },
|
||||
{ "getShader", l_lovrGraphicsGetShader },
|
||||
{ "setShader", l_lovrGraphicsSetShader },
|
||||
{ "getFont", l_lovrGraphicsGetFont },
|
||||
{ "setFont", l_lovrGraphicsSetFont },
|
||||
{ "setProjection", l_lovrGraphicsSetProjection },
|
||||
{ "getLineWidth", l_lovrGraphicsGetLineWidth },
|
||||
{ "setLineWidth", l_lovrGraphicsSetLineWidth },
|
||||
|
@ -93,11 +96,13 @@ const luaL_Reg lovrGraphics[] = {
|
|||
{ "triangle", l_lovrGraphicsTriangle },
|
||||
{ "plane", l_lovrGraphicsPlane },
|
||||
{ "cube", l_lovrGraphicsCube },
|
||||
{ "print", l_lovrGraphicsPrint },
|
||||
{ "getWidth", l_lovrGraphicsGetWidth },
|
||||
{ "getHeight", l_lovrGraphicsGetHeight },
|
||||
{ "getDimensions", l_lovrGraphicsGetDimensions },
|
||||
{ "newModel", l_lovrGraphicsNewModel },
|
||||
{ "newBuffer", l_lovrGraphicsNewBuffer },
|
||||
{ "newFont", l_lovrGraphicsNewFont },
|
||||
{ "newModel", l_lovrGraphicsNewModel },
|
||||
{ "newShader", l_lovrGraphicsNewShader },
|
||||
{ "newSkybox", l_lovrGraphicsNewSkybox },
|
||||
{ "newTexture", l_lovrGraphicsNewTexture },
|
||||
|
@ -110,6 +115,7 @@ int l_lovrGraphicsInit(lua_State* L) {
|
|||
lua_newtable(L);
|
||||
luaL_register(L, NULL, lovrGraphics);
|
||||
luax_registertype(L, "Buffer", lovrBuffer);
|
||||
luax_registertype(L, "Font", NULL);
|
||||
luax_registertype(L, "Model", lovrModel);
|
||||
luax_registertype(L, "Shader", lovrShader);
|
||||
luax_registertype(L, "Skybox", lovrSkybox);
|
||||
|
@ -311,6 +317,17 @@ int l_lovrGraphicsSetShader(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsGetFont(lua_State* L) {
|
||||
luax_pushtype(L, Font, lovrGraphicsGetFont());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsSetFont(lua_State* L) {
|
||||
Font* font = luax_checktype(L, 1, Font);
|
||||
lovrGraphicsSetFont(font);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsSetProjection(lua_State* L) {
|
||||
float near = luaL_checknumber(L, 1);
|
||||
float far = luaL_checknumber(L, 2);
|
||||
|
@ -531,6 +548,12 @@ int l_lovrGraphicsCube(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsPrint(lua_State* L) {
|
||||
const char* str = luaL_checkstring(L, 1);
|
||||
lovrGraphicsPrint(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Types
|
||||
|
||||
int l_lovrGraphicsNewBuffer(lua_State* L) {
|
||||
|
@ -600,6 +623,20 @@ int l_lovrGraphicsNewBuffer(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsNewFont(lua_State* L) {
|
||||
const char* path = luaL_checkstring(L, 1);
|
||||
//float size = luaL_optnumber(L, 2, 16);
|
||||
int fileSize;
|
||||
void* data = lovrFilesystemRead(path, &fileSize);
|
||||
if (!data) {
|
||||
luaL_error(L, "Could not load font '%s'", path);
|
||||
}
|
||||
FontData* fontData = lovrFontDataCreate(data, fileSize);
|
||||
Font* font = lovrFontCreate(fontData);
|
||||
luax_pushtype(L, Font, font);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_lovrGraphicsNewModel(lua_State* L) {
|
||||
const char* path = lua_tostring(L, 1);
|
||||
int size;
|
||||
|
@ -695,4 +732,3 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
|
|||
luax_pushtype(L, Texture, texture);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ int l_lovrGraphicsGetScissor(lua_State* L);
|
|||
int l_lovrGraphicsSetScissor(lua_State* L);
|
||||
int l_lovrGraphicsGetShader(lua_State* L);
|
||||
int l_lovrGraphicsSetShader(lua_State* L);
|
||||
int l_lovrGraphicsGetFont(lua_State* L);
|
||||
int l_lovrGraphicsSetFont(lua_State* L);
|
||||
int l_lovrGraphicsSetProjection(lua_State* L);
|
||||
int l_lovrGraphicsGetLineWidth(lua_State* L);
|
||||
int l_lovrGraphicsSetLineWidth(lua_State* L);
|
||||
|
@ -62,9 +64,11 @@ int l_lovrGraphicsLine(lua_State* L);
|
|||
int l_lovrGraphicsTriangle(lua_State* L);
|
||||
int l_lovrGraphicsPlane(lua_State* L);
|
||||
int l_lovrGraphicsCube(lua_State* L);
|
||||
int l_lovrGraphicsPrint(lua_State* L);
|
||||
|
||||
// Types
|
||||
int l_lovrGraphicsNewBuffer(lua_State* L);
|
||||
int l_lovrGraphicsNewFont(lua_State* L);
|
||||
int l_lovrGraphicsNewModel(lua_State* L);
|
||||
int l_lovrGraphicsNewShader(lua_State* L);
|
||||
int l_lovrGraphicsNewSkybox(lua_State* L);
|
||||
|
|
Loading…
Reference in New Issue