Port project over to C, some C++ left

This commit is contained in:
Doyle Thai 2016-06-18 00:40:40 +10:00
parent bcb847c18c
commit 3c51010e77
19 changed files with 275 additions and 414 deletions

View File

@ -1,5 +1,5 @@
{ {
ColumnLimit: 100, ColumnLimit: 80,
TabWidth: 4, TabWidth: 4,
IndentWidth: 4, # 1 tab IndentWidth: 4, # 1 tab
UseTab: ForIndentation, UseTab: ForIndentation,

View File

@ -122,7 +122,6 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="src\AssetManager.cpp" /> <ClCompile Include="src\AssetManager.cpp" />
<ClCompile Include="src\dengine.cpp" /> <ClCompile Include="src\dengine.cpp" />
<ClCompile Include="src\Entity.cpp" />
<ClCompile Include="src\Renderer.cpp" /> <ClCompile Include="src\Renderer.cpp" />
<ClCompile Include="src\Shader.cpp" /> <ClCompile Include="src\Shader.cpp" />
<ClCompile Include="src\WorldTraveller.cpp" /> <ClCompile Include="src\WorldTraveller.cpp" />

View File

@ -36,9 +36,6 @@
<ClCompile Include="src\WorldTraveller.cpp"> <ClCompile Include="src\WorldTraveller.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Entity.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="data\shaders\default.vert.glsl" /> <None Include="data\shaders\default.vert.glsl" />

View File

@ -1,17 +1,14 @@
#include <Dengine\AssetManager.h> #include <Dengine/AssetManager.h>
#define STBI_FAILURE_USERMSG #define STBI_FAILURE_USERMSG
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <STB/stb_image.h> #include <STB/stb_image.h>
#include <fstream> #include <fstream>
namespace Dengine std::map<std::string, Texture> textures;
{ std::map<std::string, Shader> shaders;
std::map<std::string, Texture> AssetManager::textures; Texture *asset_getTexture(const std::string name)
std::map<std::string, Shader> AssetManager::shaders;
Texture *AssetManager::getTexture(const std::string name)
{ {
// NOTE(doyle): Since we're using a map, the count of an object can // NOTE(doyle): Since we're using a map, the count of an object can
// only be 1 or 0 // only be 1 or 0
@ -21,29 +18,31 @@ Texture *AssetManager::getTexture(const std::string name)
return nullptr; return nullptr;
} }
const i32 AssetManager::loadTextureImage(const std::string path, const std::string name) const i32 asset_loadTextureImage(const std::string path, const std::string name)
{ {
/* Open the texture image */ /* Open the texture image */
i32 imgWidth, imgHeight, bytesPerPixel; i32 imgWidth, imgHeight, bytesPerPixel;
stbi_set_flip_vertically_on_load(TRUE); stbi_set_flip_vertically_on_load(TRUE);
u8 *image = stbi_load(path.c_str(), &imgWidth, &imgHeight, &bytesPerPixel, 0); u8 *image =
stbi_load(path.c_str(), &imgWidth, &imgHeight, &bytesPerPixel, 0);
if (!image) if (!image)
{ {
std::cerr << "stdbi_load() failed: " << stbi_failure_reason() << std::endl; std::cerr << "stdbi_load() failed: " << stbi_failure_reason()
<< std::endl;
return -1; return -1;
} }
Texture tex; Texture tex = genTexture(CAST(GLuint)(imgWidth), CAST(GLuint)(imgHeight),
tex.generate(static_cast<GLuint>(imgWidth), static_cast<GLuint>(imgHeight), CAST(GLint)(bytesPerPixel), image);
static_cast<GLint>(bytesPerPixel), image); glCheckError();
stbi_image_free(image); stbi_image_free(image);
textures[name] = tex; textures[name] = tex;
return 0; return 0;
} }
Shader *AssetManager::getShader(const std::string name) Shader *asset_getShader(const std::string name)
{ {
if (shaders.count(name) == 1) if (shaders.count(name) == 1)
return &shaders[name]; return &shaders[name];
@ -96,19 +95,19 @@ INTERNAL GLuint createShaderFromPath(std::string path, GLuint shadertype)
return result; return result;
} }
const i32 AssetManager::loadShaderFiles(const std::string vertexPath, const i32 asset_loadShaderFiles(const std::string vertexPath,
const std::string fragmentPath, const std::string name) const std::string fragmentPath,
const std::string name)
{ {
GLuint vertexShader = createShaderFromPath(vertexPath, GL_VERTEX_SHADER); GLuint vertexShader = createShaderFromPath(vertexPath, GL_VERTEX_SHADER);
GLuint fragmentShader = createShaderFromPath(fragmentPath, GL_FRAGMENT_SHADER); GLuint fragmentShader =
createShaderFromPath(fragmentPath, GL_FRAGMENT_SHADER);
Shader shader; Shader shader;
i32 result = shader.loadProgram(vertexShader, fragmentShader); i32 result = shader_loadProgram(&shader, vertexShader, fragmentShader);
if (result) if (result)
return result; return result;
shaders[name] = shader; shaders[name] = shader;
return 0; return 0;
} }
}

View File

@ -1,44 +0,0 @@
#include <Dengine/Entity.h>
#include <Dengine/AssetManager.h>
namespace Dengine
{
Entity::Entity()
: pos(glm::vec2(0, 0))
, dPos(glm::vec2(0, 0))
, size(glm::vec2(0, 0))
, tex(nullptr)
{
}
Entity::Entity(const glm::vec2 pos, const Texture *tex)
{
this->pos = pos;
this->dPos = glm::vec2(0, 0);
this->tex = tex;
this->size = glm::vec2(tex->getWidth(), tex->getHeight());
}
Entity::Entity(const glm::vec2 pos, glm::vec2 size, const Texture *tex)
{
this->pos = pos;
this->dPos = glm::vec2(0, 0);
this->tex = tex;
this->size = size;
}
Entity::Entity(const glm::vec2 pos, const std::string texName)
{
Texture *tex = AssetManager::getTexture(texName);
this->pos = pos;
this->dPos = glm::vec2(0, 0);
this->tex = tex;
this->size = glm::vec2(tex->getWidth(), tex->getHeight());
}
Entity::~Entity()
{
}
}

View File

@ -4,74 +4,35 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp> #include <glm/gtx/transform.hpp>
namespace Dengine void renderer_entity(Renderer *renderer, Entity *entity, GLfloat rotate,
glm::vec3 color)
{ {
Renderer::Renderer(Shader *shader) shader_use(renderer->shader);
{
this->shader = shader;
this->initRenderData();
}
Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
void Renderer::drawEntity(Entity *entity, GLfloat rotate, glm::vec3 color)
{
this->shader->use();
glm::mat4 transMatrix = glm::translate(glm::vec3(entity->pos, 0.0f)); glm::mat4 transMatrix = glm::translate(glm::vec3(entity->pos, 0.0f));
glm::mat4 rotateMatrix = glm::rotate(rotate, glm::vec3(0.0f, 0.0f, 1.0f)); glm::mat4 rotateMatrix = glm::rotate(rotate, glm::vec3(0.0f, 0.0f, 1.0f));
glCheckError();
// NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size // NOTE(doyle): We draw everything as a unit square in OGL. Scale it to size
glm::mat4 scaleMatrix = glm::scale(glm::vec3(entity->size, 1.0f)); glm::mat4 scaleMatrix = glm::scale(glm::vec3(entity->size, 1.0f));
glm::mat4 model = transMatrix * rotateMatrix * scaleMatrix; glm::mat4 model = transMatrix * rotateMatrix * scaleMatrix;
shader_uniformSetMat4fv(renderer->shader, "model", model);
this->shader->uniformSetMat4fv("model", model); glCheckError();
// TODO(doyle): Unimplemented // TODO(doyle): Unimplemented
// this->shader->uniformSetVec3f("spriteColor", color); // this->shader->uniformSetVec3f("spriteColor", color);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
entity->tex->bind(); glCheckError();
this->shader->uniformSet1i("tex", 0); glBindTexture(GL_TEXTURE_2D, entity->tex->id);
glCheckError();
shader_uniformSet1i(renderer->shader, "tex", 0);
glCheckError();
glBindVertexArray(this->quadVAO); glBindVertexArray(renderer->quadVAO);
glCheckError();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glCheckError();
glBindVertexArray(0); glBindVertexArray(0);
} glCheckError();
void Renderer::initRenderData()
{
// NOTE(doyle): Draws a series of triangles (three-sided polygons) using
// vertices v0, v1, v2, then v2, v1, v3 (note the order)
glm::vec4 vertices[] = {
// x y s t
{0.0f, 1.0f, 0.0f, 1.0f}, // Top left
{0.0f, 0.0f, 0.0f, 0.0f}, // Bottom left
{1.0f, 1.0f, 1.0f, 1.0f}, // Top right
{1.0f, 0.0f, 1.0f, 0.0f}, // Bottom right
};
GLuint VBO;
/* Create buffers */
glGenVertexArrays(1, &this->quadVAO);
glGenBuffers(1, &VBO);
/* Bind buffers */
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(this->quadVAO);
/* Configure VBO */
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/* Configure VAO */
const GLuint numVertexElements = 4;
const GLuint vertexSize = sizeof(glm::vec4);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, numVertexElements, GL_FLOAT, GL_FALSE, vertexSize, (GLvoid *)0);
/* Unbind */
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
} }

View File

@ -1,55 +1,46 @@
#include <Dengine\Shader.h> #include <Dengine/Shader.h>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
namespace Dengine const i32 shader_loadProgram(Shader *const shader, const GLuint vertexShader,
const GLuint fragmentShader)
{ {
Shader::Shader() shader->id = glCreateProgram();
: id(0) glAttachShader(shader->id, vertexShader);
{ glAttachShader(shader->id, fragmentShader);
} glLinkProgram(shader->id);
Shader::~Shader() {}
const i32 Shader::loadProgram(const GLuint vertexShader, const GLuint fragmentShader)
{
this->id = glCreateProgram();
glAttachShader(this->id, vertexShader);
glAttachShader(this->id, fragmentShader);
glLinkProgram(this->id);
glDeleteShader(fragmentShader); glDeleteShader(fragmentShader);
glDeleteShader(vertexShader); glDeleteShader(vertexShader);
GLint success; GLint success;
GLchar infoLog[512]; GLchar infoLog[512];
glGetProgramiv(this->id, GL_LINK_STATUS, &success); glGetProgramiv(shader->id, GL_LINK_STATUS, &success);
if (!success) if (!success)
{ {
glGetProgramInfoLog(this->id, 512, NULL, infoLog); glGetProgramInfoLog(shader->id, 512, NULL, infoLog);
std::cout << "glLinkProgram failed: " << infoLog << std::endl; printf("glLinkProgram failed: %s\n", infoLog);
return -1; return -1;
} }
return 0; return 0;
} }
void Shader::uniformSet1i(const GLchar *name, const GLuint data) void shader_uniformSet1i(Shader *const shader, const GLchar *name,
const GLuint data)
{ {
GLint uniformLoc = glGetUniformLocation(this->id, name); GLint uniformLoc = glGetUniformLocation(shader->id, name);
glUniform1i(uniformLoc, data); glUniform1i(uniformLoc, data);
} }
void Shader::uniformSetMat4fv(const GLchar *name, const glm::mat4 data) void shader_uniformSetMat4fv(Shader *const shader, const GLchar *name,
const glm::mat4 data)
{ {
GLint uniformLoc = glGetUniformLocation(this->id, name); GLint uniformLoc = glGetUniformLocation(shader->id, name);
glCheckError();
glUniformMatrix4fv(uniformLoc, 1, GL_FALSE, glm::value_ptr(data)); glUniformMatrix4fv(uniformLoc, 1, GL_FALSE, glm::value_ptr(data));
glCheckError();
} }
void Shader::use() const { glUseProgram(this->id); } void shader_use(const Shader *const shader) { glUseProgram(shader->id); }
}

View File

@ -1,21 +1,5 @@
#include <Dengine\Texture.h> #include <Dengine\Texture.h>
namespace Dengine
{
Texture::Texture()
: id(0)
, width(0)
, height(0)
, internalFormat(GL_RGBA)
, imageFormat(GL_RGB)
, wrapS(GL_REPEAT)
, wrapT(GL_REPEAT)
, filterMinification(GL_LINEAR)
, filterMagnification(GL_LINEAR)
{
glGenTextures(1, &this->id);
}
enum BytesPerPixel enum BytesPerPixel
{ {
Greyscale = 1, Greyscale = 1,
@ -24,7 +8,7 @@ enum BytesPerPixel
RGBA = 4, RGBA = 4,
}; };
INTERNAL GLint getGLFormat(BytesPerPixel bytesPerPixel, b32 srgb) INTERNAL GLint getGLFormat(i32 bytesPerPixel, b32 srgb)
{ {
switch (bytesPerPixel) switch (bytesPerPixel)
{ {
@ -44,32 +28,54 @@ INTERNAL GLint getGLFormat(BytesPerPixel bytesPerPixel, b32 srgb)
} }
} }
void Texture::generate(const GLuint width, const GLuint height, const GLint bytesPerPixel, Texture genTexture(const GLuint width, const GLuint height,
const u8 *const image) const GLint bytesPerPixel, const u8 *const image)
{ {
// TODO(doyle): Let us set the parameters gl params as well // TODO(doyle): Let us set the parameters gl params as well
this->width = width; glCheckError();
this->height = height; Texture tex = {};
tex.width = width;
tex.height = height;
tex.internalFormat = GL_RGBA;
tex.wrapS = GL_REPEAT;
tex.wrapT = GL_REPEAT;
tex.filterMinification = GL_LINEAR;
tex.filterMagnification = GL_LINEAR;
glBindTexture(GL_TEXTURE_2D, this->id); glGenTextures(1, &tex.id);
glCheckError();
glBindTexture(GL_TEXTURE_2D, tex.id);
glCheckError();
/* Load image into texture */ /* Load image into texture */
// TODO(doyle) Figure out the gl format // TODO(doyle) Figure out the gl format
this->imageFormat = getGLFormat(static_cast<enum BytesPerPixel>(bytesPerPixel), FALSE); tex.imageFormat = getGLFormat(bytesPerPixel, FALSE);
glCheckError();
glTexImage2D(GL_TEXTURE_2D, 0, this->internalFormat, this->width, this->height, 0, glTexImage2D(GL_TEXTURE_2D, 0, tex.internalFormat, tex.width, tex.height, 0,
this->imageFormat, GL_UNSIGNED_BYTE, image); tex.imageFormat, GL_UNSIGNED_BYTE, image);
glCheckError();
glActiveTexture(GL_TEXTURE0);
// TODO(doyle): Don't forget about thsi!
glTexSubImage2D(GL_TEXTURE_2D, 0, 3, 3, 55, 55, GL_RGBA, GL_UNSIGNED_BYTE,
image);
glCheckError();
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
/* Set parameter of currently bound texture */ /* Set parameter of currently bound texture */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, this->wrapS); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex.wrapS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, this->wrapT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex.wrapT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, this->filterMinification); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, this->filterMagnification); tex.filterMinification);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
tex.filterMagnification);
glCheckError();
/* Unbind and clean up */ /* Unbind and clean up */
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} glCheckError();
void Texture::bind() const { glBindTexture(GL_TEXTURE_2D, this->id); } return tex;
} }

View File

@ -4,65 +4,85 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <cstdlib> void worldTraveller_gameInit(GameState *state)
namespace WorldTraveller
{
// TODO(doyle): Entity list for each world
// TODO(doyle): Jumping mechanics
// TODO(doyle): Collision
Game::Game(i32 width, i32 height)
{
this->width = width;
this->height = height;
for (i32 i = 0; i < NUM_KEYS; i++)
this->keys[i] = FALSE;
}
Game::~Game() { delete this->renderer; }
void Game::init()
{ {
/* Initialise assets */ /* Initialise assets */
std::string texFolder = "data/textures/WorldTraveller/";
Dengine::AssetManager::loadShaderFiles("data/shaders/sprite.vert.glsl", asset_loadTextureImage("data/textures/WorldTraveller/elisa-spritesheet1.png",
"hero");
glCheckError();
state->state = state_active;
Renderer *renderer = &state->renderer;
asset_loadShaderFiles("data/shaders/sprite.vert.glsl",
"data/shaders/sprite.frag.glsl", "sprite"); "data/shaders/sprite.frag.glsl", "sprite");
glCheckError();
Dengine::AssetManager::loadTextureImage(texFolder + "hero.png", "hero"); renderer->shader = asset_getShader("sprite");
Dengine::AssetManager::loadTextureImage(texFolder + "wall.png", "wall"); shader_use(renderer->shader);
Dengine::AssetManager::loadTextureImage(texFolder + "hitMarker.png", "hitMarker"); glm::mat4 projection = glm::ortho(0.0f, CAST(GLfloat) state->width, 0.0f,
CAST(GLfloat) state->height, 0.0f, 1.0f);
shader_uniformSetMat4fv(renderer->shader, "projection", projection);
glCheckError();
this->shader = Dengine::AssetManager::getShader("sprite"); /* Init renderer */
this->shader->use(); // NOTE(doyle): Draws a series of triangles (three-sided polygons) using
// vertices v0, v1, v2, then v2, v1, v3 (note the order)
glm::vec4 vertices[] = {
// x y s t
{0.0f, 1.0f, 0.0f, 1.0f}, // Top left
{0.0f, 0.0f, 0.0f, 0.0f}, // Bottom left
{1.0f, 1.0f, 1.0f, 1.0f}, // Top right
{1.0f, 0.0f, 1.0f, 0.0f}, // Bottom right
};
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(this->width), 0.0f, GLuint VBO;
static_cast<GLfloat>(this->height), 0.0f, 1.0f); /* Create buffers */
this->shader->uniformSetMat4fv("projection", projection); glGenVertexArrays(1, &renderer->quadVAO);
glGenBuffers(1, &VBO);
glCheckError();
GLuint projectionLoc = glGetUniformLocation(this->shader->id, "projection"); /* Bind buffers */
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(renderer->quadVAO);
/* Init game state */ /* Configure VBO */
this->state = state_active; glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
this->renderer = new Dengine::Renderer(this->shader); glCheckError();
/* Configure VAO */
const GLuint numVertexElements = 4;
const GLuint vertexSize = sizeof(glm::vec4);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, numVertexElements, GL_FLOAT, GL_FALSE, vertexSize,
(GLvoid *)0);
glCheckError();
/* Unbind */
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glCheckError();
/* Init hero */ /* Init hero */
this->hero = Dengine::Entity(glm::vec2(0, 0), "hero");
glm::vec2 screenCentre = glm::vec2(this->width / 2.0f, this->height / 2.0f); Entity *hero = &state->hero;
glm::vec2 heroOffsetToCentre = glm::vec2(-((i32)hero.size.x / 2), -((i32)hero.size.y / 2)); hero->tex = asset_getTexture("hero");
hero->size = glm::vec2(100, 100);
glm::vec2 screenCentre =
glm::vec2(state->width / 2.0f, state->height / 2.0f);
glm::vec2 heroOffsetToCentre =
glm::vec2(-((i32)hero->size.x / 2), -((i32)hero->size.y / 2));
glm::vec2 heroCentered = screenCentre + heroOffsetToCentre; glm::vec2 heroCentered = screenCentre + heroOffsetToCentre;
hero.pos = heroCentered; hero->pos = heroCentered;
srand(static_cast<u32>(glfwGetTime())); srand(CAST(u32)(glfwGetTime()));
glCheckError();
} }
void Game::update(const f32 dt) INTERNAL void parseInput(GameState *state, const f32 dt)
{ {
/* /*
Equations of Motion Equations of Motion
@ -78,24 +98,24 @@ void Game::update(const f32 dt)
glm::vec2 ddPos = glm::vec2(0, 0); glm::vec2 ddPos = glm::vec2(0, 0);
if (this->keys[GLFW_KEY_SPACE]) if (state->keys[GLFW_KEY_SPACE])
{ {
} }
if (this->keys[GLFW_KEY_RIGHT]) if (state->keys[GLFW_KEY_RIGHT])
{ {
ddPos.x = 1.0f; ddPos.x = 1.0f;
} }
if (this->keys[GLFW_KEY_LEFT]) if (state->keys[GLFW_KEY_LEFT])
{ {
ddPos.x = -1.0f; ddPos.x = -1.0f;
} }
if (this->keys[GLFW_KEY_UP]) if (state->keys[GLFW_KEY_UP])
{ {
ddPos.y = 1.0f; ddPos.y = 1.0f;
} }
if (this->keys[GLFW_KEY_DOWN]) if (state->keys[GLFW_KEY_DOWN])
{ {
ddPos.y = -1.0f; ddPos.y = -1.0f;
} }
@ -108,42 +128,33 @@ void Game::update(const f32 dt)
ddPos *= 0.70710678118f; ddPos *= 0.70710678118f;
} }
const f32 heroSpeed = static_cast<f32>((22.0f * METERS_TO_PIXEL)); // m/s^2 f32 heroSpeed = CAST(f32)(22.0f * METERS_TO_PIXEL); // m/s^2
if (state->keys[GLFW_KEY_LEFT_SHIFT])
{
heroSpeed = CAST(f32)(22.0f * 5.0f * METERS_TO_PIXEL);
}
ddPos *= heroSpeed; ddPos *= heroSpeed;
// TODO(doyle): Counteracting force on player's acceleration is arbitrary // TODO(doyle): Counteracting force on player's acceleration is arbitrary
ddPos += -(5.5f * hero.dPos); Entity *hero = &state->hero;
ddPos += -(5.5f * hero->dPos);
glm::vec2 newHeroP = (0.5f * ddPos) * Dengine::Math::squared(dt) + (hero.dPos * dt) + hero.pos; glm::vec2 newHeroP =
(0.5f * ddPos) * squared(dt) + (hero->dPos * dt) + hero->pos;
hero.dPos = (ddPos * dt) + hero.dPos; hero->dPos = (ddPos * dt) + hero->dPos;
hero.pos = newHeroP; hero->pos = newHeroP;
} }
void Game::render() void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
{ {
/* Update */
parseInput(state, dt);
glCheckError();
Dengine::Renderer *renderer = this->renderer; /* Render */
renderer_entity(&state->renderer, &state->hero);
Dengine::Entity wall = Dengine::Entity(glm::vec2(0, 0), "wall"); // TODO(doyle): Clean up lines
glm::vec2 maxTilesOnScreen = // Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
glm::vec2((this->width / wall.size.x), (this->height / wall.size.y));
Dengine::Entity hitMarker = Dengine::Entity(glm::vec2(100, 100), "hitMarker");
for (i32 x = 0; x < maxTilesOnScreen.x; x++)
{
for (i32 y = 0; y < maxTilesOnScreen.y; y++)
{
if (x == 0 || x == maxTilesOnScreen.x - 1 || y == 0 || y == maxTilesOnScreen.y - 1)
{
wall.pos = glm::vec2(x * wall.tex->getWidth(), y * wall.tex->getHeight());
renderer->drawEntity(&wall);
} }
}
}
renderer->drawEntity(&hero);
renderer->drawEntity(&hitMarker);
}
} // namespace Dengine

View File

@ -11,23 +11,18 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <cstdint> #include <stdio.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
void key_callback(GLFWwindow *window, int key, int scancode, int action, int mode) void key_callback(GLFWwindow *window, int key, int scancode, int action, int mode)
{ {
WorldTraveller::Game *game = GameState *game = CAST(GameState *)(glfwGetWindowUserPointer(window));
static_cast<WorldTraveller::Game *>(glfwGetWindowUserPointer(window));
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{ {
glfwSetWindowShouldClose(window, GL_TRUE); glfwSetWindowShouldClose(window, GL_TRUE);
} }
if (key >= 0 && key < WorldTraveller::NUM_KEYS) if (key >= 0 && key < NUM_KEYS)
{ {
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
game->keys[key] = TRUE; game->keys[key] = TRUE;
@ -50,11 +45,11 @@ int main()
glm::ivec2 windowSize = glm::ivec2(1280, 720); glm::ivec2 windowSize = glm::ivec2(1280, 720);
GLFWwindow *window = glfwCreateWindow(windowSize.x, windowSize.y, "Dengine", nullptr, nullptr); GLFWwindow *window = glfwCreateWindow(windowSize.x, windowSize.y, "Dengine", NULL, NULL);
if (!window) if (!window)
{ {
std::cout << "glfwCreateWindow() failed: Failed to create window" << std::endl; printf("glfwCreateWindow() failed: Failed to create window\n");
glfwTerminate(); glfwTerminate();
return -1; return -1;
} }
@ -65,7 +60,7 @@ int main()
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) if (glewInit() != GLEW_OK)
{ {
std::cout << "glewInit() failed: Failed to initialise GLEW" << std::endl; printf("glewInit() failed: Failed to initialise GLEW\n");
return -1; return -1;
} }
// NOTE(doyle): glewInit() bug that sets the gl error flag after init // NOTE(doyle): glewInit() bug that sets the gl error flag after init
@ -87,12 +82,16 @@ int main()
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK); glCullFace(GL_BACK);
WorldTraveller::Game game = WorldTraveller::Game(frameBufferSize.x, frameBufferSize.y); GameState worldTraveller = {};
game.init(); worldTraveller.state = state_active;
worldTraveller.width = frameBufferSize.x;
worldTraveller.height = frameBufferSize.y;
glfwSetWindowUserPointer(window, static_cast<void *>(&game)); worldTraveller_gameInit(&worldTraveller);
f32 startTime = static_cast<f32>(glfwGetTime()); glfwSetWindowUserPointer(window, CAST(void *)(&worldTraveller));
f32 startTime = CAST(f32)(glfwGetTime());
f32 secondsElapsed = 0.0f; // Time between current frame and last frame f32 secondsElapsed = 0.0f; // Time between current frame and last frame
#if 0 #if 0
@ -109,23 +108,20 @@ int main()
/* Main game loop */ /* Main game loop */
while (!glfwWindowShouldClose(window)) while (!glfwWindowShouldClose(window))
{ {
/* Check and call events */ /* Check and call events */
glfwPollEvents(); glfwPollEvents();
game.update(secondsElapsed);
/* Rendering commands here*/ /* Rendering commands here*/
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
game.render(); worldTraveller_gameUpdateAndRender(&worldTraveller, secondsElapsed);
glCheckError(); glCheckError();
/* Swap the buffers */ /* Swap the buffers */
glfwSwapBuffers(window); glfwSwapBuffers(window);
f32 endTime = static_cast<f32>(glfwGetTime()); f32 endTime = (f32)glfwGetTime();
secondsElapsed = endTime - startTime; secondsElapsed = endTime - startTime;
#if 0 #if 0
@ -144,9 +140,12 @@ int main()
{ {
f32 msPerFrame = secondsElapsed * 1000.0f; f32 msPerFrame = secondsElapsed * 1000.0f;
f32 framesPerSecond = 1.0f / secondsElapsed; f32 framesPerSecond = 1.0f / secondsElapsed;
std::stringstream ss;
ss << "Dengine | " << msPerFrame << " ms/f | " << framesPerSecond << " fps"; char textBuffer[256];
glfwSetWindowTitle(window, ss.str().c_str()); snprintf(textBuffer, ARRAY_COUNT(textBuffer), "Dengine | %f ms/f | %f fps", msPerFrame,
framesPerSecond);
glfwSetWindowTitle(window, textBuffer);
titleUpdateFrequencyInSeconds = 0.5f; titleUpdateFrequencyInSeconds = 0.5f;
} }

View File

@ -9,22 +9,30 @@
#include <map> #include <map>
#include <string> #include <string>
namespace Dengine enum Assets
{ {
class AssetManager asset_vertShader,
asset_fragShader,
asset_hero,
};
struct AssetManager
{ {
public: Textures textures[256];
static std::map<std::string, Texture> textures; Shaders shaders[256];
static std::map<std::string, Shader> shaders; };
extern std::map<std::string, Texture> textures;
extern std::map<std::string, Shader> shaders;
/* Texture */ /* Texture */
static Texture *getTexture(const std::string name); Texture *asset_getTexture(const std::string name);
static const i32 loadTextureImage(const std::string path, const std::string name); const i32 asset_loadTextureImage(const std::string path,
const std::string name);
/* Shaders */ /* Shaders */
static Shader *getShader(const std::string name); Shader *asset_getShader(const std::string name);
static const i32 loadShaderFiles(const std::string vertexPath, const std::string fragmentPath, const i32 asset_loadShaderFiles(const std::string vertexPath,
const std::string fragmentPath,
const std::string name); const std::string name);
};
}
#endif #endif

View File

@ -1,7 +1,8 @@
#ifndef DENGINE_COMMON_H #ifndef DENGINE_COMMON_H
#define DENGINE_COMMON_H #define DENGINE_COMMON_H
#include <cstdint> #include <stdint.h>
#include <stdlib.h>
typedef uint8_t u8; typedef uint8_t u8;
typedef uint32_t u32; typedef uint32_t u32;
@ -20,4 +21,7 @@ typedef double f64;
#define INTERNAL static #define INTERNAL static
#define LOCAL_PERSIST static #define LOCAL_PERSIST static
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
#define CAST(type) (type)
#endif #endif

View File

@ -6,23 +6,12 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
namespace Dengine struct Entity
{ {
class Entity
{
public:
Entity();
Entity(const glm::vec2 pos, const Texture *tex);
Entity(const glm::vec2 pos, const glm::vec2 size, const Texture *tex);
Entity(const glm::vec2 pos, const std::string texName);
~Entity();
glm::vec2 pos; // Position glm::vec2 pos; // Position
glm::vec2 dPos; // Velocity glm::vec2 dPos; // Velocity
glm::vec2 size; glm::vec2 size;
const Texture *tex; Texture *tex;
}; };
}
#endif #endif

View File

@ -3,17 +3,10 @@
#include <Dengine/Common.h> #include <Dengine/Common.h>
namespace Dengine inline f32 squared(const f32 a)
{
class Math
{
public:
static inline f32 squared(const f32 a)
{ {
f32 result = a * a; f32 result = a * a;
return result; return result;
} }
};
}
#endif
#endif

View File

@ -5,40 +5,38 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <iostream> #include <stdio.h>
#include <string>
inline GLenum glCheckError_(const char *file, int line) inline GLenum glCheckError_(const char *file, int line)
{ {
GLenum errorCode; GLenum errorCode;
while ((errorCode = glGetError()) != GL_NO_ERROR) while ((errorCode = glGetError()) != GL_NO_ERROR)
{ {
std::string error;
switch (errorCode) switch (errorCode)
{ {
case GL_INVALID_ENUM: case GL_INVALID_ENUM:
error = "INVALID_ENUM"; printf("INVALID_ENUM | ");
break; break;
case GL_INVALID_VALUE: case GL_INVALID_VALUE:
error = "INVALID_VALUE"; printf("INVALID_VALUE | ");
break; break;
case GL_INVALID_OPERATION: case GL_INVALID_OPERATION:
error = "INVALID_OPERATION"; printf("INVALID_OPERATION | ");
break; break;
case GL_STACK_OVERFLOW: case GL_STACK_OVERFLOW:
error = "STACK_OVERFLOW"; printf("STACK_OVERFLOW | ");
break; break;
case GL_STACK_UNDERFLOW: case GL_STACK_UNDERFLOW:
error = "STACK_UNDERFLOW"; printf("STACK_UNDERFLOW | ");
break; break;
case GL_OUT_OF_MEMORY: case GL_OUT_OF_MEMORY:
error = "OUT_OF_MEMORY"; printf("OUT_OF_MEMORY | ");
break; break;
case GL_INVALID_FRAMEBUFFER_OPERATION: case GL_INVALID_FRAMEBUFFER_OPERATION:
error = "INVALID_FRAMEBUFFER_OPERATION"; printf("INVALID_FRAMEBUFFER_OPERATION | ");
break; break;
} }
std::cout << error << " | " << file << " (" << line << ")" << std::endl; printf("%s (%d)\n", file, line);
} }
return errorCode; return errorCode;
} }

View File

@ -8,22 +8,13 @@
#include <GLM/glm.hpp> #include <GLM/glm.hpp>
namespace Dengine struct Renderer
{ {
class Renderer
{
public:
Renderer(Shader *shader);
~Renderer();
void drawEntity(Entity *entity, GLfloat rotate = 0.0f, glm::vec3 color = glm::vec3(1.0f));
private:
Shader *shader; Shader *shader;
GLuint quadVAO; GLuint quadVAO;
void initRenderData();
}; };
}
void renderer_entity(Renderer *renderer, Entity *entity, GLfloat rotate = 0.0f,
glm::vec3 color = glm::vec3(1.0f));
#endif #endif

View File

@ -6,25 +6,20 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <string> struct Shader
namespace Dengine
{ {
class Shader
{
public:
GLuint id; GLuint id;
Shader();
~Shader();
const i32 loadProgram(const GLuint vertexShader, const GLuint fragmentShader);
void uniformSet1i(const GLchar *name, const GLuint data);
void uniformSetMat4fv(const GLchar *name, const glm::mat4 data);
void use() const;
}; };
}
const i32 shader_loadProgram(Shader *const shader,
const GLuint vertexShader,
const GLuint fragmentShader);
void shader_uniformSet1i(Shader *const shader, const GLchar *name,
const GLuint data);
void shader_uniformSetMat4fv(Shader *const shader, const GLchar *name,
const glm::mat4 data);
void shader_use(const Shader *const shader);
#endif #endif

View File

@ -4,26 +4,8 @@
#include <Dengine/Common.h> #include <Dengine/Common.h>
#include <Dengine/OpenGL.h> #include <Dengine/OpenGL.h>
namespace Dengine struct Texture
{ {
class Texture
{
public:
// Constructor (sets default texture modes)
Texture();
// Generates texture from image data
void generate(const GLuint width, const GLuint height, const GLint bytesPerPixel,
const u8 *const image);
// Binds the texture as the current active GL_TEXTURE_2D texture object
void bind() const;
inline const GLuint getWidth() const { return this->width; }
inline const GLuint getHeight() const { return this->height; }
inline const GLuint getID() const { return this->id; }
private:
// Holds the ID of the texture object, used for all texture operations to // Holds the ID of the texture object, used for all texture operations to
// reference to this particlar texture // reference to this particlar texture
GLuint id; GLuint id;
@ -45,5 +27,9 @@ private:
// Filtering mode if texture pixels > screen pixels // Filtering mode if texture pixels > screen pixels
GLuint filterMagnification; GLuint filterMagnification;
}; };
}
// Generates texture from image data
Texture genTexture(const GLuint width, const GLuint height, const GLint bytesPerPixel,
const u8 *const image);
#endif #endif

View File

@ -9,21 +9,8 @@
#include <Dengine/Renderer.h> #include <Dengine/Renderer.h>
#include <Dengine/Shader.h> #include <Dengine/Shader.h>
namespace WorldTraveller #define NUM_KEYS 1024
{ #define METERS_TO_PIXEL 100
GLOBAL_VAR const i32 NUM_KEYS = 1024;
GLOBAL_VAR const f32 METERS_TO_PIXEL = 100;
enum Cardinal
{
cardinal_north = 0,
cardinal_west = 1,
cardinal_south = 2,
cardinal_east = 3,
cardinal_num,
cardinal_null
};
enum State enum State
{ {
@ -32,25 +19,16 @@ enum State
state_win state_win
}; };
class Game struct GameState
{ {
public:
State state; State state;
GLboolean keys[NUM_KEYS]; GLboolean keys[NUM_KEYS];
i32 width, height; i32 width, height;
Game(i32 width, i32 height); Renderer renderer;
~Game(); Entity hero;
void init();
void update(const f32 dt);
void render();
private:
Dengine::Shader *shader;
Dengine::Renderer *renderer;
Dengine::Entity hero;
}; };
}
void worldTraveller_gameInit(GameState *state);
void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt);
#endif #endif