#include #include #include #include #include #include #include #include "engine.hh" class Cube : public Engine { unsigned int texture; tinyobj::ObjReader reader; bool parseObj(std::string objFile, tinyobj::ObjReader& reader); 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; 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]; 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]; glNormal3f(nx, ny, nz); drawCalls += 1; } // 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]; glTexCoord2f(tx, ty); drawCalls += 1; } } index_offset += fv; glEnd(); } } printf("Draw Calls: %i\n", drawCalls); drawCalls = 0; // glDrawArrays(GL_QUADS, 0, susSize); } bool Cube::parseObj(std::string objFile, tinyobj::ObjReader& reader) { tinyobj::ObjReaderConfig readerConfig; readerConfig.mtl_search_path = "./"; if (!reader.ParseFromFile(objFile, readerConfig)) { if (!reader.Error().empty()) { printf("TinyOBJReader: %s\n", 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(); glKosSwapBuffers(); } void Cube::initScreen() { glKosInit(); 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("/rd/sanic.png", &width, &height, &nr_channels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { printf("Texture failed to load.\n"); } stbi_image_free(data); if (!parseObj("/rd/cube.obj", reader)) return; } int main() { Cube engine; engine.initializeEngine(); engine.initializeGameLoop(); }