Sprite switches direction, update vbo on render

This commit is contained in:
Doyle Thai 2016-06-19 00:34:20 +10:00
parent bb57f080c9
commit d44ddf9371
6 changed files with 81 additions and 40 deletions

Binary file not shown.

View File

@ -23,7 +23,7 @@ void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate, v3 color)
shader_uniformSet1i(renderer->shader, "tex", 0); shader_uniformSet1i(renderer->shader, "tex", 0);
glCheckError(); glCheckError();
glBindVertexArray(renderer->quadVAO); glBindVertexArray(renderer->vao);
glCheckError(); glCheckError();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glCheckError(); glCheckError();

View File

@ -57,7 +57,8 @@ Texture genTexture(const GLuint width, const GLuint height,
glTexImage2D(GL_TEXTURE_2D, 0, tex.internalFormat, tex.width, tex.height, 0, glTexImage2D(GL_TEXTURE_2D, 0, tex.internalFormat, tex.width, tex.height, 0,
tex.imageFormat, GL_UNSIGNED_BYTE, image); tex.imageFormat, GL_UNSIGNED_BYTE, image);
glCheckError(); glCheckError();
glGenerateMipmap(GL_TEXTURE_2D);
// TODO(doyle): Not needed for sprites? glGenerateMipmap(GL_TEXTURE_2D);
/* Set parameter of currently bound texture */ /* Set parameter of currently bound texture */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex.wrapS); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex.wrapS);

View File

@ -2,80 +2,91 @@
#include <Dengine/Math.h> #include <Dengine/Math.h>
#include <WorldTraveller/WorldTraveller.h> #include <WorldTraveller/WorldTraveller.h>
void updateBufferObject(GLuint vbo, v4 texNDC)
{
// TODO(doyle): We assume that vbo and vao are assigned
v4 vertices[] = {
// x y s t
{0.0f, 1.0f, texNDC.x, texNDC.y}, // Top left
{0.0f, 0.0f, texNDC.x, texNDC.w}, // Bottom left
{1.0f, 1.0f, texNDC.z, texNDC.y}, // Top right
{1.0f, 0.0f, texNDC.z, texNDC.w}, // Bottom right
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// TODO(doyle): glBufferSubData
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void worldTraveller_gameInit(GameState *state) void worldTraveller_gameInit(GameState *state)
{ {
/* Initialise assets */ /* Initialise assets */
asset_loadTextureImage( asset_loadTextureImage(
"data/textures/WorldTraveller/TerraSprite.png", texlist_hero); "data/textures/WorldTraveller/TerraSprite.png", texlist_hero);
glCheckError(); glCheckError();
state->state = state_active;
Renderer *renderer = &state->renderer;
asset_loadShaderFiles("data/shaders/sprite.vert.glsl", asset_loadShaderFiles("data/shaders/sprite.vert.glsl",
"data/shaders/sprite.frag.glsl", shaderlist_sprite); "data/shaders/sprite.frag.glsl", shaderlist_sprite);
glCheckError(); glCheckError();
renderer->shader = asset_getShader(shaderlist_sprite); state->state = state_active;
shader_use(renderer->shader); state->heroLastDirection = direction_east;
mat4 projection = mat4_ortho(0.0f, CAST(f32) state->width, 0.0f,
CAST(f32) state->height, 0.0f, 1.0f);
shader_uniformSetMat4fv(renderer->shader, "projection", projection);
glCheckError();
/* Init hero */ /* Init hero */
Entity *hero = &state->hero; Entity *hero = &state->hero;
hero->tex = asset_getTexture(texlist_hero); hero->tex = asset_getTexture(texlist_hero);
hero->size = V2(91.0f, 146.0f); hero->size = V2(91.0f, 146.0f);
hero->pos = V2(0.0f, 0.0f);
//v2 screenCentre = V2(state->width / 2.0f, state->height / 2.0f); Texture *heroSheet = hero->tex;
//v2 heroOffsetToCentre =
// V2(-(hero->size.x / 2.0f), -(hero->size.y / 2.0f));
//v2 heroCentered = v2_add(screenCentre, heroOffsetToCentre);
hero->pos = V2(0.0f, 0.0f);
glCheckError();
Texture *heroSheet = asset_getTexture(texlist_hero);
v2 sheetSize = V2(CAST(f32)heroSheet->width, CAST(f32)heroSheet->height); v2 sheetSize = V2(CAST(f32)heroSheet->width, CAST(f32)heroSheet->height);
if (sheetSize.x != sheetSize.y) if (sheetSize.x != sheetSize.y)
{ {
printf( printf(
"worldTraveller_gameInit() warning: Sprite sheet is not square: " "worldTraveller_gameInit() warning: Sprite sheet is not square: "
"%dx%dpx\n", "%dx%dpx\n",
CAST(i32) sheetSize.x, CAST(i32) sheetSize.y); CAST(i32) sheetSize.w, CAST(i32) sheetSize.h);
} }
f32 uvNormalisedFactor = sheetSize.x; f32 ndcFactor = sheetSize.w;
v2 heroStartPixel = V2(219.0f, 14.0f); v2 heroStartPixel = V2(219.0f, 498.0f);
v4 heroRect = v4 heroRect = V4(heroStartPixel.x,
V4(heroStartPixel.x, heroStartPixel.y, heroStartPixel.x + hero->size.x, heroStartPixel.y,
heroStartPixel.y + hero->size.y); heroStartPixel.x + hero->size.w,
v4 heroUVNormalised = v4_scale(heroRect, 1.0f/uvNormalisedFactor); heroStartPixel.y - hero->size.h);
heroUVNormalised.y = 1.0f - heroUVNormalised.y; v4 heroTexNDC = v4_scale(heroRect, 1.0f/ndcFactor);
heroUVNormalised.w = 1.0f - heroUVNormalised.w;
/* Init renderer */ /* Init renderer */
Renderer *renderer = &state->renderer;
renderer->shader = asset_getShader(shaderlist_sprite);
shader_use(renderer->shader);
const mat4 projection = mat4_ortho(0.0f, CAST(f32) state->width, 0.0f,
CAST(f32) state->height, 0.0f, 1.0f);
shader_uniformSetMat4fv(renderer->shader, "projection", projection);
glCheckError();
// NOTE(doyle): Draws a series of triangles (three-sided polygons) using // NOTE(doyle): Draws a series of triangles (three-sided polygons) using
// vertices v0, v1, v2, then v2, v1, v3 (note the order) // vertices v0, v1, v2, then v2, v1, v3 (note the order)
v4 vertices[] = { v4 vertices[] = {
// x y s t // x y s t
{0.0f, 1.0f, heroUVNormalised.x, heroUVNormalised.y}, // Top left {0.0f, 1.0f, heroTexNDC.x, heroTexNDC.y}, // Top left
{0.0f, 0.0f, heroUVNormalised.x, heroUVNormalised.w}, // Bottom left {0.0f, 0.0f, heroTexNDC.x, heroTexNDC.w}, // Bottom left
{1.0f, 1.0f, heroUVNormalised.z, heroUVNormalised.y}, // Top right {1.0f, 1.0f, heroTexNDC.z, heroTexNDC.y}, // Top right
{1.0f, 0.0f, heroUVNormalised.z, heroUVNormalised.w}, // Bottom right {1.0f, 0.0f, heroTexNDC.z, heroTexNDC.w}, // Bottom right
}; };
GLuint VBO;
/* Create buffers */ /* Create buffers */
glGenVertexArrays(1, &renderer->quadVAO); glGenVertexArrays(1, &renderer->vao);
glGenBuffers(1, &VBO); glGenBuffers(1, &renderer->vbo);
glCheckError(); glCheckError();
/* Bind buffers */ /* Bind buffers */
glBindBuffer(GL_ARRAY_BUFFER, VBO); glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo);
glBindVertexArray(renderer->quadVAO); glBindVertexArray(renderer->vao);
/* Configure VBO */ /* Configure VBO */
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
@ -119,10 +130,12 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
if (state->keys[GLFW_KEY_RIGHT]) if (state->keys[GLFW_KEY_RIGHT])
{ {
ddPos.x = 1.0f; ddPos.x = 1.0f;
state->heroLastDirection = direction_east;
} }
if (state->keys[GLFW_KEY_LEFT]) if (state->keys[GLFW_KEY_LEFT])
{ {
ddPos.x = -1.0f; ddPos.x = -1.0f;
state->heroLastDirection = direction_west;
} }
if (state->keys[GLFW_KEY_UP]) if (state->keys[GLFW_KEY_UP])
@ -174,6 +187,22 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
parseInput(state, dt); parseInput(state, dt);
glCheckError(); glCheckError();
Entity *hero = &state->hero;
Texture *heroSheet = hero->tex;
f32 ndcFactor = CAST(f32)heroSheet->width;
v2 heroStartPixel = V2(219.0f, 498.0f); // direction == east
if (state->heroLastDirection == direction_west)
heroStartPixel = V2(329.0f, 498.0f);
v4 heroRect = V4(heroStartPixel.x,
heroStartPixel.y,
heroStartPixel.x + hero->size.w,
heroStartPixel.y - hero->size.h);
v4 heroTexNDC = v4_scale(heroRect, 1.0f/ndcFactor);
updateBufferObject(state->renderer.vbo, heroTexNDC);
/* Render */ /* Render */
renderer_entity(&state->renderer, &state->hero, 0.0f, V3(0, 0, 0)); renderer_entity(&state->renderer, &state->hero, 0.0f, V3(0, 0, 0));
// TODO(doyle): Clean up lines // TODO(doyle): Clean up lines

View File

@ -8,7 +8,8 @@
typedef struct Renderer typedef struct Renderer
{ {
Shader *shader; Shader *shader;
GLuint quadVAO; GLuint vao;
GLuint vbo;
} Renderer; } Renderer;
void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate, void renderer_entity(Renderer *renderer, Entity *entity, f32 rotate,

View File

@ -15,6 +15,15 @@ enum State
state_win state_win
}; };
enum Direction
{
direction_north,
direction_west,
direction_south,
direction_east,
direction_num,
};
typedef struct GameState typedef struct GameState
{ {
enum State state; enum State state;
@ -23,6 +32,7 @@ typedef struct GameState
Renderer renderer; Renderer renderer;
Entity hero; Entity hero;
enum Direction heroLastDirection;
} GameState; } GameState;
void worldTraveller_gameInit(GameState *state); void worldTraveller_gameInit(GameState *state);