From ecdeaf0b940cd56d433460ec828516912bdb5937 Mon Sep 17 00:00:00 2001 From: Fries Date: Sun, 31 Mar 2024 12:01:57 -0700 Subject: [PATCH] Convert the Cube program to use entities. --- src/cube.cc | 182 +------------------ src/cube/Cube.cc | 60 ++++++ src/cube/Cube.hh | 13 ++ src/cube/CubeEntity.cc | 119 ++++++++++++ src/cube/CubeEntity.hh | 16 ++ src/cube/meson.build | 7 + src/engine/controller/desktopController.cc | 2 +- src/engine/controller/dreamcastController.cc | 3 +- src/engine/engine.cc | 6 +- src/engine/engine.hh | 4 +- src/meson.build | 3 +- 11 files changed, 225 insertions(+), 190 deletions(-) create mode 100644 src/cube/Cube.cc create mode 100644 src/cube/Cube.hh create mode 100644 src/cube/CubeEntity.cc create mode 100644 src/cube/CubeEntity.hh create mode 100644 src/cube/meson.build diff --git a/src/cube.cc b/src/cube.cc index e35d684..497f0ce 100644 --- a/src/cube.cc +++ b/src/cube.cc @@ -1,184 +1,4 @@ -#ifdef _arch_dreamcast -#include -#include -#include -#include -#include -#define SANIC_LOCATION "/rd/sanic.png" -#define CUBE_LOCATION "/rd/cube.obj" -#else -#define STB_IMAGE_IMPLEMENTATION -#include -#include -#include -#define SANIC_LOCATION "./sanic.png" -#define CUBE_LOCATION "./cube.obj" -#endif - -#include - -#include -#include -#include - -#include "engine/engine.hh" - -class Cube : public Engine { - unsigned int texture; - tinyobj::ObjReader reader; - - bool parseObj(std::string objFile, tinyobj::ObjReader& reader, - char* message); - void cube(); - void displayStuff(); - void gameLoop() override { displayStuff(); } - void initScreen() override; - void model(); -}; - -void Cube::model() { - const tinyobj::attrib_t& attrib = reader.GetAttrib(); - auto& shapes = reader.GetShapes(); - angle += 1.0f; - glRotatef(angle, 1.0f, 0.0f, 1.0f); - - int drawCalls = 0; - - for (size_t s = 0; s < shapes.size(); s++) { - // Loop over faces(polygon) - size_t index_offset = 0; - std::vector vertexes{}; - std::vector normals{}; - std::vector textureCoords{}; - - for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { - size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]); - - // glBegin(GL_TRIANGLES); - // Loop over vertices in the face. - for (size_t v = 0; v < fv; v++) { - // access to vertex - tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; - tinyobj::real_t vx = - attrib.vertices[3 * size_t(idx.vertex_index) + 0]; - tinyobj::real_t vy = - attrib.vertices[3 * size_t(idx.vertex_index) + 1]; - tinyobj::real_t vz = - attrib.vertices[3 * size_t(idx.vertex_index) + 2]; - Vector3 vertex = {vx, vy, vz}; - vertexes.push_back(vertex); - // glVertex3f(vx, vy, vz); - // drawCalls += 1; - - // Check if `normal_index` is zero or positive. negative = no - // normal data - if (idx.normal_index >= 0) { - tinyobj::real_t nx = - attrib.normals[3 * size_t(idx.normal_index) + 0]; - tinyobj::real_t ny = - attrib.normals[3 * size_t(idx.normal_index) + 1]; - tinyobj::real_t nz = - attrib.normals[3 * size_t(idx.normal_index) + 2]; - Vector3 normal = {nx, ny, nz}; - normals.push_back(normal); - // glNormal3f(nx, ny, nz); - // drawCalls += 1; - } else { - normals.push_back(Vector3::zero); - } - - // Check if `texcoord_index` is zero or positive. negative = no - // texcoord data - if (idx.texcoord_index >= 0) { - tinyobj::real_t tx = - attrib.texcoords[2 * size_t(idx.texcoord_index) + 0]; - tinyobj::real_t ty = - attrib.texcoords[2 * size_t(idx.texcoord_index) + 1]; - Vector3 textureCoord = {tx, ty, 0}; - textureCoords.push_back(textureCoord); - // glTexCoord2f(tx, ty); - // drawCalls += 1; - } else { - textureCoords.push_back(Vector3::zero); - } - } - index_offset += fv; - - // glEnd(); - } - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, &vertexes[0]); - glNormalPointer(GL_FLOAT, 0, &normals[0]); - glTexCoordPointer(2, GL_FLOAT, 0, &textureCoords[0]); - glDrawArrays(GL_TRIANGLES, 0, vertexes.size()); - // glDrawElements(GL_TRIANGLES, shapes[s].mesh.indices.size(), - // GL_UNSIGNED_INT, &shapes[s].mesh.indices[0]); - drawCalls += 1; - } - // printf("Draw Calls: %i\n", drawCalls); - drawCalls = 0; - - // glDrawArrays(GL_QUADS, 0, susSize); -} - -bool Cube::parseObj(std::string objFile, tinyobj::ObjReader& reader, - char* message) { - tinyobj::ObjReaderConfig readerConfig; - readerConfig.mtl_search_path = "./"; - if (!reader.ParseFromFile(objFile, readerConfig)) { - if (!reader.Error().empty()) { - sprintf(message, "TinyOBJReader: %s", reader.Error().c_str()); - return false; - } - } - return true; -} - -void Cube::displayStuff() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glLoadIdentity(); - glTranslatef(0.0f, 0.0f, -5.0f); - glRotatef(90, 0.0f, 1.0f, 0.5f); - model(); - SwapBuffers(); -} - -void Cube::initScreen() { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(45.0f, 640.0f / 480.0f, 0.1f, 100.0f); - glMatrixMode(GL_MODELVIEW); - glEnable(GL_TEXTURE_2D); - glEnable(GL_DEPTH_TEST); - glFrontFace(GL_CW); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - - int width, height, nr_channels; - unsigned char* data = - stbi_load(SANIC_LOCATION, &width, &height, &nr_channels, 0); - - if (data) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, - GL_UNSIGNED_BYTE, data); -#ifdef _arch_dreamcast - glGenerateMipmap(GL_TEXTURE_2D); -#endif - } else { - printf("Texture failed to load.\n"); - } - - stbi_image_free(data); - - char* message = new char; - if (!parseObj(CUBE_LOCATION, reader, message)) - throw std::runtime_error(message); -} +#include "cube/Cube.hh" int main() { Cube engine; diff --git a/src/cube/Cube.cc b/src/cube/Cube.cc new file mode 100644 index 0000000..7c67bfa --- /dev/null +++ b/src/cube/Cube.cc @@ -0,0 +1,60 @@ +#include "Cube.hh" +#include "CubeEntity.hh" +#include + +#ifdef _arch_dreamcast +#define SANIC_LOCATION "/rd/sanic.png" +#define CUBE_LOCATION "/rd/cube.obj" +#include +#include +#else +#define STB_IMAGE_IMPLEMENTATION +#define SANIC_LOCATION "./sanic.png" +#define CUBE_LOCATION "./cube.obj" +#include +#endif + +Cube::Cube() { + entity = new CubeEntity(this, nullptr); +} + +void Cube::initScreen() { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0f, 640.0f / 480.0f, 0.1f, 100.0f); + glMatrixMode(GL_MODELVIEW); + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + glFrontFace(GL_CW); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + + int width, height, nr_channels; + unsigned char* data = + stbi_load(SANIC_LOCATION, &width, &height, &nr_channels, 0); + + if (data) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, data); +#ifdef _arch_dreamcast + glGenerateMipmap(GL_TEXTURE_2D); +#endif + } else { + printf("Texture failed to load.\n"); + } + + stbi_image_free(data); +} + +void Cube::gameLoop() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -5.0f); + glRotatef(90, 0.0f, 1.0f, 0.5f); + Entity::drawEntity(entity); + SwapBuffers(); +} diff --git a/src/cube/Cube.hh b/src/cube/Cube.hh new file mode 100644 index 0000000..1aceede --- /dev/null +++ b/src/cube/Cube.hh @@ -0,0 +1,13 @@ +#ifndef CUBE_HH +#define CUBE_HH +#include +#include "CubeEntity.hh" +class Cube : public Engine { + public: + CubeEntity* entity; + void gameLoop() override; + void initScreen() override; + Cube(); + unsigned int texture; +}; +#endif diff --git a/src/cube/CubeEntity.cc b/src/cube/CubeEntity.cc new file mode 100644 index 0000000..651c8b1 --- /dev/null +++ b/src/cube/CubeEntity.cc @@ -0,0 +1,119 @@ +#include "CubeEntity.hh" +#include +#include + +#ifdef _arch_dreamcast +#define SANIC_LOCATION "/rd/sanic.png" +#define CUBE_LOCATION "/rd/cube.obj" +#else +#define STB_IMAGE_IMPLEMENTATION +#define SANIC_LOCATION "./sanic.png" +#define CUBE_LOCATION "./cube.obj" +#endif + + +CubeEntity::CubeEntity(Engine* engine, Entity* parent) : Entity(engine, parent) { + char* message = new char; + if (!parseObj(CUBE_LOCATION, reader, message)) + throw std::runtime_error(message); +} + +void CubeEntity::draw() { + const tinyobj::attrib_t& attrib = reader.GetAttrib(); + auto& shapes = reader.GetShapes(); + angle += 1.0f; + glRotatef(angle, 1.0f, 0.0f, 1.0f); + + int drawCalls = 0; + + for (size_t s = 0; s < shapes.size(); s++) { + // Loop over faces(polygon) + size_t index_offset = 0; + std::vector vertexes{}; + std::vector normals{}; + std::vector textureCoords{}; + + for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) { + size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]); + + // glBegin(GL_TRIANGLES); + // Loop over vertices in the face. + for (size_t v = 0; v < fv; v++) { + // access to vertex + tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v]; + tinyobj::real_t vx = + attrib.vertices[3 * size_t(idx.vertex_index) + 0]; + tinyobj::real_t vy = + attrib.vertices[3 * size_t(idx.vertex_index) + 1]; + tinyobj::real_t vz = + attrib.vertices[3 * size_t(idx.vertex_index) + 2]; + Engine::Vector3 vertex = {vx, vy, vz}; + vertexes.push_back(vertex); + // glVertex3f(vx, vy, vz); + // drawCalls += 1; + + // Check if `normal_index` is zero or positive. negative = no + // normal data + if (idx.normal_index >= 0) { + tinyobj::real_t nx = + attrib.normals[3 * size_t(idx.normal_index) + 0]; + tinyobj::real_t ny = + attrib.normals[3 * size_t(idx.normal_index) + 1]; + tinyobj::real_t nz = + attrib.normals[3 * size_t(idx.normal_index) + 2]; + Engine::Vector3 normal = {nx, ny, nz}; + normals.push_back(normal); + // glNormal3f(nx, ny, nz); + // drawCalls += 1; + } else { + normals.push_back(Engine::Vector3::zero); + } + + // Check if `texcoord_index` is zero or positive. negative = no + // texcoord data + if (idx.texcoord_index >= 0) { + tinyobj::real_t tx = + attrib.texcoords[2 * size_t(idx.texcoord_index) + 0]; + tinyobj::real_t ty = + attrib.texcoords[2 * size_t(idx.texcoord_index) + 1]; + Engine::Vector3 textureCoord = {tx, ty, 0}; + textureCoords.push_back(textureCoord); + // glTexCoord2f(tx, ty); + // drawCalls += 1; + } else { + textureCoords.push_back(Engine::Vector3::zero); + } + } + index_offset += fv; + + // glEnd(); + } + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, &vertexes[0]); + glNormalPointer(GL_FLOAT, 0, &normals[0]); + glTexCoordPointer(2, GL_FLOAT, 0, &textureCoords[0]); + glDrawArrays(GL_TRIANGLES, 0, vertexes.size()); + // glDrawElements(GL_TRIANGLES, shapes[s].mesh.indices.size(), + // GL_UNSIGNED_INT, &shapes[s].mesh.indices[0]); + drawCalls += 1; + } + // printf("Draw Calls: %i\n", drawCalls); + drawCalls = 0; + + // glDrawArrays(GL_QUADS, 0, susSize); +} + +bool CubeEntity::parseObj(std::string objFile, tinyobj::ObjReader& reader, + char* message) { + tinyobj::ObjReaderConfig readerConfig; + readerConfig.mtl_search_path = "./"; + if (!reader.ParseFromFile(objFile, readerConfig)) { + if (!reader.Error().empty()) { + sprintf(message, "TinyOBJReader: %s", reader.Error().c_str()); + return false; + } + } + return true; +} diff --git a/src/cube/CubeEntity.hh b/src/cube/CubeEntity.hh new file mode 100644 index 0000000..13f1c0b --- /dev/null +++ b/src/cube/CubeEntity.hh @@ -0,0 +1,16 @@ +#ifndef CUBE_ENTITY_HH +#define CUBE_ENTITY_HH +#include + +#include + +class CubeEntity : public Entity { + void draw() override; + tinyobj::ObjReader reader; + bool parseObj(std::string objFile, tinyobj::ObjReader& reader, + char* message); + float angle; + public: + CubeEntity(Engine* engine, Entity* parent); +}; +#endif diff --git a/src/cube/meson.build b/src/cube/meson.build new file mode 100644 index 0000000..91a9d86 --- /dev/null +++ b/src/cube/meson.build @@ -0,0 +1,7 @@ +cubed_sources = [ + 'Cube.cc', + 'CubeEntity.cc' +] + +cube = static_library('cube', cubed_sources, dependencies: deps, include_directories: incdirs) +cube_dep = declare_dependency(link_with: [cube], include_directories: incdirs) diff --git a/src/engine/controller/desktopController.cc b/src/engine/controller/desktopController.cc index 7db0689..2f5fdce 100644 --- a/src/engine/controller/desktopController.cc +++ b/src/engine/controller/desktopController.cc @@ -14,7 +14,7 @@ bool DesktopController::InitializeController() { glfwUpdateGamepadMappings(mappings.str().c_str()); } if (glfwJoystickIsGamepad(GLFW_JOYSTICK_1)) { - glfwGetGamepadState(GLFW_JOYSTICK_1, &controllerState); + PollController(); return true; } return false; diff --git a/src/engine/controller/dreamcastController.cc b/src/engine/controller/dreamcastController.cc index 734467f..b41da2d 100644 --- a/src/engine/controller/dreamcastController.cc +++ b/src/engine/controller/dreamcastController.cc @@ -5,8 +5,7 @@ DreamcastController::DreamcastController() { } bool DreamcastController::InitializeController() { - maple_device_t* cont = nullptr; - cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); + maple_device_t* cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); if (cont->valid) { this->controller = cont; this->controller_state = (cont_state_t*)maple_dev_status(controller); diff --git a/src/engine/engine.cc b/src/engine/engine.cc index ac5021f..fdbf94f 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -88,9 +88,9 @@ void Engine::pressButton(Controller::Button button, } } -const Engine::Vector3 Engine::Vector3::zero = {0, 0, 0}; +constexpr Engine::Vector3 Engine::Vector3::zero = {0, 0, 0}; -Engine::Vector3 Engine::Vector3::operator/(float amount) { +Engine::Vector3 Engine::Vector3::operator/(float amount) const { return {this->x / amount, this->y / amount, this->z / amount}; } @@ -101,6 +101,6 @@ void Engine::Vector3::operator/=(float amount) { float Engine::getDeltaTime() const { return deltaTime; } -Engine::Vector3 Engine::Vector3::operator+(Engine::Vector3 vector) { +Engine::Vector3 Engine::Vector3::operator+(Engine::Vector3 vector) const { return {this->x + vector.x, this->y + vector.y, this->z + vector.z}; } diff --git a/src/engine/engine.hh b/src/engine/engine.hh index db90971..4ccc4d8 100644 --- a/src/engine/engine.hh +++ b/src/engine/engine.hh @@ -50,9 +50,9 @@ class Engine { virtual ~Engine(); Controller* controller = nullptr; struct Vector3 { - Vector3 operator/(float amount); + Vector3 operator/(float amount) const; void operator/=(float amount); - Vector3 operator+(Vector3 vector); + Vector3 operator+(Vector3 vector) const; float x; float y; float z; diff --git a/src/meson.build b/src/meson.build index f682f45..a6a3d91 100644 --- a/src/meson.build +++ b/src/meson.build @@ -62,11 +62,12 @@ incdirs += [srcinc] subdir('hello') subdir('gl') +subdir('cube') subdir('flappyBird') executable('hello.elf', ['hello.cc'], dependencies: [deps] + [hello_dep], include_directories: incdirs) executable('gl.elf', ['gl.cc'], dependencies: [deps] + [glcc_dep], include_directories: incdirs) if host_machine.system() != 'windows' - executable('cube.elf', cube_sources, dependencies: deps, include_directories: incdirs) + executable('cube.elf', cube_sources, dependencies: [deps] + [cube_dep], include_directories: incdirs) endif executable('flappyBird.elf', ['flappyBird.cc'], dependencies: [deps] + [flappy_dep], include_directories: incdirs)