Renderer calculates NDC coordinates from screen coords

This commit is contained in:
Doyle Thai 2016-06-29 20:44:35 +10:00
parent fa83daac60
commit d8ee46611f
7 changed files with 108 additions and 111 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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); }
} }

View File

@ -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));

View File

@ -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;

View File

@ -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;
} }

View File

@ -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