Convert the Cube program to use entities.
This commit is contained in:
parent
c94fd602e8
commit
ecdeaf0b94
11 changed files with 225 additions and 190 deletions
182
src/cube.cc
182
src/cube.cc
|
@ -1,184 +1,4 @@
|
|||
#ifdef _arch_dreamcast
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glkos.h>
|
||||
#include <GL/glu.h>
|
||||
#include <stb_image/stb_image.h>
|
||||
#define SANIC_LOCATION "/rd/sanic.png"
|
||||
#define CUBE_LOCATION "/rd/cube.obj"
|
||||
#else
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <GL/glu.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <stb/stb_image.h>
|
||||
#define SANIC_LOCATION "./sanic.png"
|
||||
#define CUBE_LOCATION "./cube.obj"
|
||||
#endif
|
||||
|
||||
#include <tiny_obj_loader.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#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<Vector3> vertexes{};
|
||||
std::vector<Vector3> normals{};
|
||||
std::vector<Vector3> 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;
|
||||
|
|
60
src/cube/Cube.cc
Normal file
60
src/cube/Cube.cc
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "Cube.hh"
|
||||
#include "CubeEntity.hh"
|
||||
#include <GL/glu.h>
|
||||
|
||||
#ifdef _arch_dreamcast
|
||||
#define SANIC_LOCATION "/rd/sanic.png"
|
||||
#define CUBE_LOCATION "/rd/cube.obj"
|
||||
#include <stb_image/stb_image.h>
|
||||
#include <GL/glext.h>
|
||||
#else
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define SANIC_LOCATION "./sanic.png"
|
||||
#define CUBE_LOCATION "./cube.obj"
|
||||
#include <stb/stb_image.h>
|
||||
#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();
|
||||
}
|
13
src/cube/Cube.hh
Normal file
13
src/cube/Cube.hh
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef CUBE_HH
|
||||
#define CUBE_HH
|
||||
#include <engine/engine.hh>
|
||||
#include "CubeEntity.hh"
|
||||
class Cube : public Engine {
|
||||
public:
|
||||
CubeEntity* entity;
|
||||
void gameLoop() override;
|
||||
void initScreen() override;
|
||||
Cube();
|
||||
unsigned int texture;
|
||||
};
|
||||
#endif
|
119
src/cube/CubeEntity.cc
Normal file
119
src/cube/CubeEntity.cc
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include "CubeEntity.hh"
|
||||
#include <engine/entity.hh>
|
||||
#include <stdexcept>
|
||||
|
||||
#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<Engine::Vector3> vertexes{};
|
||||
std::vector<Engine::Vector3> normals{};
|
||||
std::vector<Engine::Vector3> 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;
|
||||
}
|
16
src/cube/CubeEntity.hh
Normal file
16
src/cube/CubeEntity.hh
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef CUBE_ENTITY_HH
|
||||
#define CUBE_ENTITY_HH
|
||||
#include <engine/entity.hh>
|
||||
|
||||
#include <tiny_obj_loader.h>
|
||||
|
||||
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
|
7
src/cube/meson.build
Normal file
7
src/cube/meson.build
Normal file
|
@ -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)
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue