Renderer calculates NDC coordinates from screen coords
This commit is contained in:
parent
fa83daac60
commit
d8ee46611f
@ -120,8 +120,10 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
stbtt_InitFont(&fontInfo, fontFileRead.buffer,
|
stbtt_InitFont(&fontInfo, fontFileRead.buffer,
|
||||||
stbtt_GetFontOffsetForIndex(fontFileRead.buffer, 0));
|
stbtt_GetFontOffsetForIndex(fontFileRead.buffer, 0));
|
||||||
|
|
||||||
assetManager->codepointRange = V2i(32, 127);
|
Font *font = &assetManager->font;
|
||||||
v2i codepointRange = assetManager->codepointRange;
|
font->codepointRange = V2i(32, 127);
|
||||||
|
|
||||||
|
v2i codepointRange = font->codepointRange;
|
||||||
const i32 numGlyphs = codepointRange.y - codepointRange.x;
|
const i32 numGlyphs = codepointRange.y - codepointRange.x;
|
||||||
|
|
||||||
i32 glyphIndex = 0;
|
i32 glyphIndex = 0;
|
||||||
@ -178,6 +180,7 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
"unoptimal\n");
|
"unoptimal\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -196,10 +199,12 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
if ((largestGlyphDimension.h & 1) == 1)
|
if ((largestGlyphDimension.h & 1) == 1)
|
||||||
largestGlyphDimension.h += 1;
|
largestGlyphDimension.h += 1;
|
||||||
|
|
||||||
i32 glyphsPerRow = (MAX_TEXTURE_SIZE / largestGlyphDimension.w) + 1;
|
font->charSize = largestGlyphDimension;
|
||||||
|
|
||||||
|
i32 glyphsPerRow = (MAX_TEXTURE_SIZE / font->charSize.w) + 1;
|
||||||
|
|
||||||
#ifdef WT_DEBUG
|
#ifdef WT_DEBUG
|
||||||
i32 glyphsPerCol = MAX_TEXTURE_SIZE / largestGlyphDimension.h;
|
i32 glyphsPerCol = MAX_TEXTURE_SIZE / font->charSize.h;
|
||||||
if ((glyphsPerRow * glyphsPerCol) <= numGlyphs)
|
if ((glyphsPerRow * glyphsPerCol) <= numGlyphs)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
@ -209,7 +214,6 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
|
||||||
u32 *fontBitmap = CAST(u32 *)calloc(
|
u32 *fontBitmap = CAST(u32 *)calloc(
|
||||||
squared(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL, sizeof(u32));
|
squared(TARGET_TEXTURE_SIZE) * TARGET_BYTES_PER_PIXEL, sizeof(u32));
|
||||||
const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL;
|
const i32 pitch = MAX_TEXTURE_SIZE * TARGET_BYTES_PER_PIXEL;
|
||||||
@ -237,20 +241,18 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
{
|
{
|
||||||
TexAtlas *fontAtlas = &assetManager->texAtlas[texlist_font];
|
TexAtlas *fontAtlas = &assetManager->texAtlas[texlist_font];
|
||||||
#ifdef WT_DEBUG
|
#ifdef WT_DEBUG
|
||||||
printf("codepoint: %d\n", activeGlyph.codepoint);
|
|
||||||
printf("atlasIndex: %d\n", atlasIndex);
|
|
||||||
ASSERT(activeGlyph.codepoint < ARRAY_COUNT(fontAtlas->texRect));
|
ASSERT(activeGlyph.codepoint < ARRAY_COUNT(fontAtlas->texRect));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
v2 origin = V2(CAST(f32)(glyphIndex * largestGlyphDimension.w),
|
v2 origin = V2(CAST(f32)(glyphIndex * font->charSize.w),
|
||||||
CAST(f32) row);
|
CAST(f32) row);
|
||||||
fontAtlas->texRect[atlasIndex++] =
|
fontAtlas->texRect[atlasIndex++] =
|
||||||
getRect(origin, V2(CAST(f32) largestGlyphDimension.w,
|
getRect(origin, V2(CAST(f32) font->charSize.w,
|
||||||
CAST(f32) largestGlyphDimension.h));
|
CAST(f32) font->charSize.h));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy over exactly one row of pixels */
|
/* Copy over exactly one row of pixels */
|
||||||
i32 numPixelsToPad = largestGlyphDimension.w;
|
i32 numPixelsToPad = font->charSize.w;
|
||||||
if (verticalPixelsBlitted < activeGlyph.dimensions.h)
|
if (verticalPixelsBlitted < activeGlyph.dimensions.h)
|
||||||
{
|
{
|
||||||
const i32 srcPitch =
|
const i32 srcPitch =
|
||||||
@ -269,13 +271,13 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
* pointer by the remaining distance
|
* pointer by the remaining distance
|
||||||
*/
|
*/
|
||||||
numPixelsToPad =
|
numPixelsToPad =
|
||||||
largestGlyphDimension.w - activeGlyph.dimensions.w;
|
font->charSize.w - activeGlyph.dimensions.w;
|
||||||
}
|
}
|
||||||
destRow += numPixelsToPad;
|
destRow += numPixelsToPad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A row of glyphs has been fully formed on the atlas */
|
/* A row of glyphs has been fully formed on the atlas */
|
||||||
if (verticalPixelsBlitted++ >= largestGlyphDimension.h)
|
if (verticalPixelsBlitted++ >= font->charSize.h)
|
||||||
{
|
{
|
||||||
verticalPixelsBlitted = 0;
|
verticalPixelsBlitted = 0;
|
||||||
startingGlyphIndex += glyphsPerRow;
|
startingGlyphIndex += glyphsPerRow;
|
||||||
@ -294,14 +296,11 @@ const i32 asset_loadTTFont(AssetManager *assetManager, const char *filePath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Texture tex = genTexture(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4,
|
Texture tex = genTexture(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, 4,
|
||||||
CAST(u8 *) fontBitmap);
|
CAST(u8 *)fontBitmap);
|
||||||
assetManager->textures[texlist_font] = tex;
|
assetManager->textures[texlist_font] = tex;
|
||||||
#else
|
|
||||||
i32 letter = 1;
|
font->tex = &assetManager->textures[texlist_font];
|
||||||
Texture tex = genTexture(glyphBitmaps[letter].dimensions.w, glyphBitmaps[letter].dimensions.h, 4,
|
font->atlas = &assetManager->texAtlas[texlist_font];
|
||||||
CAST(u8 *)glyphBitmaps[letter].pixels);
|
|
||||||
assetManager.textures[texlist_font] = tex;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i32 i = 0; i < numGlyphs; i++)
|
for (i32 i = 0; i < numGlyphs; i++)
|
||||||
free(glyphBitmaps[i].pixels);
|
free(glyphBitmaps[i].pixels);
|
||||||
|
@ -43,3 +43,30 @@ void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glCheckError();
|
glCheckError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderQuad renderer_createQuad(Renderer *renderer, v4 quadRect, v4 texRect,
|
||||||
|
Texture *tex)
|
||||||
|
{
|
||||||
|
// NOTE(doyle): Draws a series of triangles (three-sided polygons) using
|
||||||
|
// vertices v0, v1, v2, then v2, v1, v3 (note the order)
|
||||||
|
RenderQuad result = {0};
|
||||||
|
|
||||||
|
v4 quadRectNdc = quadRect;
|
||||||
|
quadRectNdc.e[0] *= renderer->vertexNdcFactor.w;
|
||||||
|
quadRectNdc.e[1] *= renderer->vertexNdcFactor.h;
|
||||||
|
quadRectNdc.e[2] *= renderer->vertexNdcFactor.w;
|
||||||
|
quadRectNdc.e[3] *= renderer->vertexNdcFactor.h;
|
||||||
|
|
||||||
|
v2 texNdcFactor = V2(1.0f / tex->width, 1.0f / tex->height);
|
||||||
|
v4 texRectNdc = texRect;
|
||||||
|
texRectNdc.e[0] *= texNdcFactor.w;
|
||||||
|
texRectNdc.e[1] *= texNdcFactor.h;
|
||||||
|
texRectNdc.e[2] *= texNdcFactor.w;
|
||||||
|
texRectNdc.e[3] *= texNdcFactor.h;
|
||||||
|
|
||||||
|
result.vertex[0] = V4(quadRectNdc.x, quadRectNdc.y, texRectNdc.x, texRectNdc.y); // Top left
|
||||||
|
result.vertex[1] = V4(quadRectNdc.x, quadRectNdc.w, texRectNdc.x, texRectNdc.w); // Bottom left
|
||||||
|
result.vertex[2] = V4(quadRectNdc.z, quadRectNdc.y, texRectNdc.z, texRectNdc.y); // Top right
|
||||||
|
result.vertex[3] = V4(quadRectNdc.z, quadRectNdc.w, texRectNdc.z, texRectNdc.w); // Bottom right
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@ INTERNAL void updateBufferObject(Renderer *const renderer,
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void worldTraveller_gameInit(GameState *state)
|
void worldTraveller_gameInit(GameState *state, v2i windowSize)
|
||||||
{
|
{
|
||||||
AssetManager *assetManager = &state->assetManager;
|
AssetManager *assetManager = &state->assetManager;
|
||||||
/* Initialise assets */
|
/* Initialise assets */
|
||||||
@ -131,14 +131,19 @@ void worldTraveller_gameInit(GameState *state)
|
|||||||
|
|
||||||
/* Init renderer */
|
/* Init renderer */
|
||||||
Renderer *renderer = &state->renderer;
|
Renderer *renderer = &state->renderer;
|
||||||
|
renderer->size = V2(CAST(f32)windowSize.x, CAST(f32)windowSize.y);
|
||||||
|
// NOTE(doyle): Value to map a screen coordinate to NDC coordinate
|
||||||
|
renderer->vertexNdcFactor =
|
||||||
|
V2(1.0f / renderer->size.w, 1.0f / renderer->size.h);
|
||||||
renderer->shader = asset_getShader(assetManager, shaderlist_sprite);
|
renderer->shader = asset_getShader(assetManager, shaderlist_sprite);
|
||||||
shader_use(renderer->shader);
|
shader_use(renderer->shader);
|
||||||
|
|
||||||
const mat4 projection = mat4_ortho(0.0f, CAST(f32) state->width, 0.0f,
|
const mat4 projection =
|
||||||
CAST(f32) state->height, 0.0f, 1.0f);
|
mat4_ortho(0.0f, renderer->size.w, 0.0f, renderer->size.h, 0.0f, 1.0f);
|
||||||
shader_uniformSetMat4fv(renderer->shader, "projection", projection);
|
shader_uniformSetMat4fv(renderer->shader, "projection", projection);
|
||||||
glCheckError();
|
glCheckError();
|
||||||
|
|
||||||
|
|
||||||
/* Create buffers */
|
/* Create buffers */
|
||||||
glGenVertexArrays(1, &renderer->vao);
|
glGenVertexArrays(1, &renderer->vao);
|
||||||
glGenBuffers(1, &renderer->vbo);
|
glGenBuffers(1, &renderer->vbo);
|
||||||
@ -301,8 +306,9 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
|
|||||||
glCheckError();
|
glCheckError();
|
||||||
|
|
||||||
AssetManager *assetManager = &state->assetManager;
|
AssetManager *assetManager = &state->assetManager;
|
||||||
|
Renderer *renderer = &state->renderer;
|
||||||
|
|
||||||
World *const world = &state->world[state->currWorldIndex];
|
World *const world = &state->world[state->currWorldIndex];
|
||||||
TexAtlas *const worldAtlas =
|
TexAtlas *const worldAtlas =
|
||||||
asset_getTextureAtlas(assetManager, world->texType);
|
asset_getTextureAtlas(assetManager, world->texType);
|
||||||
Texture *const worldTex = asset_getTexture(assetManager, world->texType);
|
Texture *const worldTex = asset_getTexture(assetManager, world->texType);
|
||||||
@ -312,119 +318,90 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
|
|||||||
RenderQuad worldQuads[ARRAY_COUNT(world->tiles)] = {0};
|
RenderQuad worldQuads[ARRAY_COUNT(world->tiles)] = {0};
|
||||||
i32 quadIndex = 0;
|
i32 quadIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
/* Render background tiles */
|
/* Render background tiles */
|
||||||
const v2 tileSize = V2(CAST(f32) state->tileSize, CAST(f32) state->tileSize);
|
const v2 tileSize = V2(CAST(f32) state->tileSize, CAST(f32) state->tileSize);
|
||||||
const v2 vertexNdcFactor = V2(1.0f / state->width, 1.0f / state->height);
|
|
||||||
for (i32 i = 0; i < ARRAY_COUNT(world->tiles); i++)
|
for (i32 i = 0; i < ARRAY_COUNT(world->tiles); i++)
|
||||||
{
|
{
|
||||||
Tile tile = world->tiles[i];
|
Tile tile = world->tiles[i];
|
||||||
v2 tilePosInPixel = v2_scale(tile.pos, tileSize.x);
|
v2 tilePosInPixel = v2_scale(tile.pos, tileSize.x);
|
||||||
|
|
||||||
if ((tilePosInPixel.x < state->width && tilePosInPixel.x >= 0) &&
|
if ((tilePosInPixel.x < renderer->size.w && tilePosInPixel.x >= 0) &&
|
||||||
(tilePosInPixel.y < state->height && tilePosInPixel.y >= 0))
|
(tilePosInPixel.y < renderer->size.h && tilePosInPixel.y >= 0))
|
||||||
{
|
{
|
||||||
const v4 tileTexRect = worldAtlas->texRect[terraincoords_ground];
|
const v4 texRect = worldAtlas->texRect[terraincoords_ground];
|
||||||
const v4 texRectNdc = v4_scale(tileTexRect, texNdcFactor);
|
|
||||||
|
|
||||||
const v4 tileRect = getRect(tilePosInPixel, tileSize);
|
const v4 tileRect = getRect(tilePosInPixel, tileSize);
|
||||||
v4 tileRectNdc = tileRect;
|
|
||||||
|
|
||||||
tileRectNdc.e[0] *= vertexNdcFactor.w;
|
RenderQuad tileQuad = renderer_createQuad(
|
||||||
tileRectNdc.e[1] *= vertexNdcFactor.h;
|
&state->renderer, tileRect, texRect, worldTex);
|
||||||
tileRectNdc.e[2] *= vertexNdcFactor.w;
|
|
||||||
tileRectNdc.e[3] *= vertexNdcFactor.h;
|
|
||||||
|
|
||||||
RenderQuad tileQuad = renderer_createQuad(tileRectNdc, texRectNdc);
|
|
||||||
worldQuads[quadIndex++] = tileQuad;
|
worldQuads[quadIndex++] = tileQuad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const v2 screenSize = V2(CAST(f32)state->width, CAST(f32)state->height);
|
updateBufferObject(renderer, worldQuads, quadIndex);
|
||||||
updateBufferObject(&state->renderer, worldQuads, quadIndex);
|
renderer_object(renderer, V2(0.0f, 0.0f), renderer->size, 0.0f,
|
||||||
renderer_object(&state->renderer, V2(0.0f, 0.0f), screenSize, 0.0f,
|
|
||||||
V3(0, 0, 0), worldTex);
|
V3(0, 0, 0), worldTex);
|
||||||
|
|
||||||
/* Render font sheet */
|
Font *font = &assetManager->font;
|
||||||
Texture *font = asset_getTexture(assetManager, texlist_font);
|
|
||||||
v4 fontTexRect = V4(0.0f, 1.0f, 1.0f, 0.0);
|
|
||||||
RenderQuad fontQuad = renderer_createDefaultQuad(fontTexRect);
|
|
||||||
updateBufferObject(&state->renderer, &fontQuad, 1);
|
|
||||||
renderer_object(&state->renderer, V2(300.0f, -300.0f),
|
|
||||||
V2(CAST(f32)font->width, CAST(f32)font->height), 0.0f,
|
|
||||||
V3(0, 0, 0), font);
|
|
||||||
|
|
||||||
char *string = "hello world";
|
char *string = "hello world";
|
||||||
|
|
||||||
i32 strLen = 11;
|
i32 strLen = 11;
|
||||||
quadIndex = 0;
|
quadIndex = 0;
|
||||||
RenderQuad *stringQuads = CAST(RenderQuad *)calloc(strLen, sizeof(RenderQuad));
|
RenderQuad *stringQuads = CAST(RenderQuad *)calloc(strLen, sizeof(RenderQuad));
|
||||||
TexAtlas *fontAtlas = asset_getTextureAtlas(assetManager, texlist_font);
|
|
||||||
|
|
||||||
v2 eachCharSize = getRectSize(fontAtlas->texRect[0]);
|
|
||||||
f32 xPosOnScreen = 20.0f;
|
f32 xPosOnScreen = 20.0f;
|
||||||
for (i32 i = 0; i < strLen; i++)
|
for (i32 i = 0; i < strLen; i++)
|
||||||
{
|
{
|
||||||
// NOTE(doyle): Atlas packs fonts tightly, so offset the codepoint to
|
// NOTE(doyle): Atlas packs fonts tightly, so offset the codepoint to
|
||||||
// its actual atlas index, i.e. we skip the first 31 glyphs
|
// its actual atlas index, i.e. we skip the first 31 glyphs
|
||||||
i32 atlasIndex = string[i] - assetManager->codepointRange.x;
|
i32 atlasIndex = string[i] - font->codepointRange.x;
|
||||||
|
|
||||||
const v4 charTexRect = fontAtlas->texRect[atlasIndex];
|
v4 charTexRect = font->atlas->texRect[atlasIndex];
|
||||||
v4 charTexRectNdc = v4_scale(charTexRect, texNdcFactor);
|
renderer_flipTexCoord(&charTexRect, FALSE, TRUE);
|
||||||
renderer_flipTexCoord(&charTexRectNdc, FALSE, TRUE);
|
|
||||||
|
|
||||||
const v4 charRectOnScreen =
|
const v4 charRectOnScreen =
|
||||||
getRect(V2(xPosOnScreen, 100.0f), eachCharSize);
|
getRect(V2(xPosOnScreen, 100.0f),
|
||||||
xPosOnScreen += eachCharSize.w;
|
V2(CAST(f32) font->charSize.w, CAST(f32) font->charSize.w));
|
||||||
v4 charRectOnScreenNdc = charRectOnScreen;
|
xPosOnScreen += font->charSize.w;
|
||||||
|
|
||||||
charRectOnScreenNdc.e[0] *= vertexNdcFactor.w;
|
RenderQuad charQuad = renderer_createQuad(
|
||||||
charRectOnScreenNdc.e[1] *= vertexNdcFactor.h;
|
&state->renderer, charRectOnScreen, charTexRect, font->tex);
|
||||||
charRectOnScreenNdc.e[2] *= vertexNdcFactor.w;
|
|
||||||
charRectOnScreenNdc.e[3] *= vertexNdcFactor.h;
|
|
||||||
|
|
||||||
RenderQuad charQuad =
|
|
||||||
renderer_createQuad(charRectOnScreenNdc, charTexRectNdc);
|
|
||||||
stringQuads[quadIndex++] = charQuad;
|
stringQuads[quadIndex++] = charQuad;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBufferObject(&state->renderer, stringQuads, quadIndex);
|
updateBufferObject(&state->renderer, stringQuads, quadIndex);
|
||||||
renderer_object(&state->renderer, V2(0.0f, 100.0f), screenSize, 0.0f,
|
renderer_object(&state->renderer, V2(0.0f, 100.0f), renderer->size, 0.0f,
|
||||||
V3(0, 0, 0), font);
|
V3(0, 0, 0), font->tex);
|
||||||
free(stringQuads);
|
free(stringQuads);
|
||||||
|
|
||||||
/* Render entities */
|
/* Render entities */
|
||||||
// NOTE(doyle): Factor to normalise sprite sheet rect coords to -1, 1
|
|
||||||
Entity *const hero = &state->entityList[state->heroIndex];
|
|
||||||
|
|
||||||
ASSERT(state->freeEntityIndex < ARRAY_COUNT(state->entityList));
|
ASSERT(state->freeEntityIndex < ARRAY_COUNT(state->entityList));
|
||||||
for (i32 i = 0; i < state->freeEntityIndex; i++)
|
for (i32 i = 0; i < state->freeEntityIndex; i++)
|
||||||
{
|
{
|
||||||
Entity *const entity = &state->entityList[i];
|
Entity *const entity = &state->entityList[i];
|
||||||
SpriteAnim *anim = &entity->anim[entity->currAnimIndex];
|
SpriteAnim *anim = &entity->anim[entity->currAnimIndex];
|
||||||
|
|
||||||
v4 currFrameRect = anim->rect[anim->currRectIndex];
|
v4 texRect = anim->rect[anim->currRectIndex];
|
||||||
anim->currDuration -= dt;
|
anim->currDuration -= dt;
|
||||||
if (anim->currDuration <= 0.0f)
|
if (anim->currDuration <= 0.0f)
|
||||||
{
|
{
|
||||||
anim->currRectIndex++;
|
anim->currRectIndex++;
|
||||||
anim->currRectIndex = anim->currRectIndex % anim->numRects;
|
anim->currRectIndex = anim->currRectIndex % anim->numRects;
|
||||||
currFrameRect = anim->rect[anim->currRectIndex];
|
texRect = anim->rect[anim->currRectIndex];
|
||||||
anim->currDuration = anim->duration;
|
anim->currDuration = anim->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
v4 texRectNdc = v4_scale(currFrameRect, texNdcFactor);
|
|
||||||
if (entity->direction == direction_east)
|
if (entity->direction == direction_east)
|
||||||
{
|
{
|
||||||
// NOTE(doyle): Flip the x coordinates to flip the tex
|
// NOTE(doyle): Flip the x coordinates to flip the tex
|
||||||
renderer_flipTexCoord(&texRectNdc, TRUE, FALSE);
|
renderer_flipTexCoord(&texRect, TRUE, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderQuad quad = renderer_createDefaultQuad(texRectNdc);
|
RenderQuad entityQuad =
|
||||||
updateBufferObject(&state->renderer, &quad, 1);
|
renderer_createDefaultQuad(&state->renderer, texRect, entity->tex);
|
||||||
|
updateBufferObject(&state->renderer, &entityQuad, 1);
|
||||||
renderer_entity(&state->renderer, entity, 0.0f, V3(0, 0, 0));
|
renderer_entity(&state->renderer, entity, 0.0f, V3(0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(doyle): Clean up lines
|
// TODO(doyle): Clean up lines
|
||||||
// Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
|
// Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,10 +35,10 @@ int main()
|
|||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||||
|
|
||||||
v2 windowSize = V2(1600.0f, 900.0f);
|
v2i windowSize = V2i(1600, 900);
|
||||||
|
|
||||||
GLFWwindow *window = glfwCreateWindow(
|
GLFWwindow *window =
|
||||||
CAST(i32) windowSize.x, CAST(i32) windowSize.y, "Dengine", NULL, NULL);
|
glfwCreateWindow(windowSize.x, windowSize.y, "Dengine", NULL, NULL);
|
||||||
|
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
@ -60,13 +60,9 @@ int main()
|
|||||||
// regardless of success. Catch it once by calling glGetError
|
// regardless of success. Catch it once by calling glGetError
|
||||||
glGetError();
|
glGetError();
|
||||||
|
|
||||||
i32 frameBufferSizeX;
|
v2i frameBufferSize = V2i(0, 0);
|
||||||
i32 frameBufferSizeY;
|
glfwGetFramebufferSize(window, &frameBufferSize.w, &frameBufferSize.h);
|
||||||
glfwGetFramebufferSize(window, &frameBufferSizeX, &frameBufferSizeY);
|
glViewport(0, 0, frameBufferSize.x, frameBufferSize.y);
|
||||||
const v2 frameBufferSize =
|
|
||||||
V2(CAST(f32) frameBufferSizeX, CAST(f32) frameBufferSizeY);
|
|
||||||
|
|
||||||
glViewport(0, 0, CAST(i32)frameBufferSize.x, CAST(i32)frameBufferSize.y);
|
|
||||||
|
|
||||||
glfwSetKeyCallback(window, key_callback);
|
glfwSetKeyCallback(window, key_callback);
|
||||||
glfwSetCursorPosCallback(window, mouse_callback);
|
glfwSetCursorPosCallback(window, mouse_callback);
|
||||||
@ -80,10 +76,7 @@ int main()
|
|||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
GameState worldTraveller = {0};
|
GameState worldTraveller = {0};
|
||||||
worldTraveller.width = CAST(i32)frameBufferSize.x;
|
worldTraveller_gameInit(&worldTraveller, frameBufferSize);
|
||||||
worldTraveller.height = CAST(i32)frameBufferSize.y;
|
|
||||||
|
|
||||||
worldTraveller_gameInit(&worldTraveller);
|
|
||||||
|
|
||||||
glfwSetWindowUserPointer(window, CAST(void *)(&worldTraveller));
|
glfwSetWindowUserPointer(window, CAST(void *)(&worldTraveller));
|
||||||
|
|
||||||
|
@ -32,14 +32,21 @@ typedef struct TexAtlas
|
|||||||
v4 texRect[128];
|
v4 texRect[128];
|
||||||
} TexAtlas;
|
} TexAtlas;
|
||||||
|
|
||||||
|
typedef struct Font
|
||||||
|
{
|
||||||
|
TexAtlas *atlas;
|
||||||
|
Texture *tex;
|
||||||
|
v2i codepointRange;
|
||||||
|
v2i charSize;
|
||||||
|
} Font;
|
||||||
|
|
||||||
// TODO(doyle): Switch to hash based lookup
|
// TODO(doyle): Switch to hash based lookup
|
||||||
typedef struct AssetManager
|
typedef struct AssetManager
|
||||||
{
|
{
|
||||||
Texture textures[256];
|
Texture textures[256];
|
||||||
TexAtlas texAtlas[256];
|
TexAtlas texAtlas[256];
|
||||||
Shader shaders[256];
|
Shader shaders[256];
|
||||||
|
Font font;
|
||||||
v2i codepointRange;
|
|
||||||
} AssetManager;
|
} AssetManager;
|
||||||
|
|
||||||
GLOBAL_VAR AssetManager assetManager;
|
GLOBAL_VAR AssetManager assetManager;
|
||||||
|
@ -11,6 +11,9 @@ typedef struct Renderer
|
|||||||
GLuint vao;
|
GLuint vao;
|
||||||
GLuint vbo;
|
GLuint vbo;
|
||||||
i32 numVertexesInVbo;
|
i32 numVertexesInVbo;
|
||||||
|
v2 vertexNdcFactor;
|
||||||
|
v2 size;
|
||||||
|
|
||||||
} Renderer;
|
} Renderer;
|
||||||
|
|
||||||
typedef struct RenderQuad
|
typedef struct RenderQuad
|
||||||
@ -24,6 +27,9 @@ void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate,
|
|||||||
void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
void renderer_object(Renderer *renderer, v2 pos, v2 size, f32 rotate, v3 color,
|
||||||
Texture *tex);
|
Texture *tex);
|
||||||
|
|
||||||
|
RenderQuad renderer_createQuad(Renderer *renderer, v4 quadRect, v4 texRect,
|
||||||
|
Texture *tex);
|
||||||
|
|
||||||
INTERNAL inline void renderer_flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY)
|
INTERNAL inline void renderer_flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY)
|
||||||
{
|
{
|
||||||
if (flipX)
|
if (flipX)
|
||||||
@ -41,23 +47,12 @@ INTERNAL inline void renderer_flipTexCoord(v4 *texCoords, b32 flipX, b32 flipY)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL inline RenderQuad renderer_createQuad(v4 quadRectNdc, v4 texRectNdc)
|
INTERNAL inline RenderQuad renderer_createDefaultQuad(Renderer *renderer,
|
||||||
{
|
v4 texRect, Texture *tex)
|
||||||
// NOTE(doyle): Draws a series of triangles (three-sided polygons) using
|
|
||||||
// vertices v0, v1, v2, then v2, v1, v3 (note the order)
|
|
||||||
RenderQuad result = {0};
|
|
||||||
result.vertex[0] = V4(quadRectNdc.x, quadRectNdc.y, texRectNdc.x, texRectNdc.y); // Top left
|
|
||||||
result.vertex[1] = V4(quadRectNdc.x, quadRectNdc.w, texRectNdc.x, texRectNdc.w); // Bottom left
|
|
||||||
result.vertex[2] = V4(quadRectNdc.z, quadRectNdc.y, texRectNdc.z, texRectNdc.y); // Top right
|
|
||||||
result.vertex[3] = V4(quadRectNdc.z, quadRectNdc.w, texRectNdc.z, texRectNdc.w); // Bottom right
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
INTERNAL inline RenderQuad renderer_createDefaultQuad(v4 texRectNdc)
|
|
||||||
{
|
{
|
||||||
RenderQuad result = {0};
|
RenderQuad result = {0};
|
||||||
v4 defaultVertices = V4(0.0f, 1.0f, 1.0f, 0.0f);
|
v4 defaultQuad = V4(0.0f, renderer->size.h, renderer->size.w, 0.0f);
|
||||||
result = renderer_createQuad(defaultVertices, texRectNdc);
|
result = renderer_createQuad(renderer, defaultQuad, texRect, tex);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,6 @@ typedef struct GameState
|
|||||||
{
|
{
|
||||||
enum State state;
|
enum State state;
|
||||||
b32 keys[NUM_KEYS];
|
b32 keys[NUM_KEYS];
|
||||||
i32 width, height;
|
|
||||||
|
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
i32 heroIndex;
|
i32 heroIndex;
|
||||||
@ -46,6 +45,6 @@ typedef struct GameState
|
|||||||
AssetManager assetManager;
|
AssetManager assetManager;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
void worldTraveller_gameInit(GameState *state);
|
void worldTraveller_gameInit(GameState *state, v2i windowSize);
|
||||||
void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt);
|
void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user