diff --git a/.vscode/launch.json b/.vscode/launch.json index a0a74ee..7e005d7 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,33 +1,91 @@ { "configurations": [ - { - "name": "(gdb) Launch gl.elf", - "type": "cppdbg", - "request": "launch", - "program": "${workspaceFolder}/build/gl.elf", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", - "miDebuggerServerAddress": "localhost:3263", - "debugServerPath": "/usr/bin/flycast", - "debugServerArgs": "${workspaceFolder}/build/gl.elf", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - }, - { - "description": "Set SuperH architechture", - "text": "set architecture sh4" - } - ], - "avoidWindowsConsoleRedirection": false, - "internalConsoleOptions": "openOnSessionStart" - } + { + "name": "(gdb) Launch gl.elf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/gl.elf", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", + "miDebuggerServerAddress": "localhost:3263", + "debugServerPath": "/usr/bin/flycast", + "debugServerArgs": "${workspaceFolder}/build/gl.elf", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set SuperH architechture", + "text": "set architecture sh4" + } + ], + "avoidWindowsConsoleRedirection": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": "(gdb) Launch cube.elf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/cube.elf", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", + "miDebuggerServerAddress": "localhost:3263", + "debugServerPath": "/usr/bin/flycast", + "debugServerArgs": "${workspaceFolder}/build/cube.elf", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set SuperH architechture", + "text": "set architecture sh4" + } + ], + "avoidWindowsConsoleRedirection": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": "(gdb, lxdream-nitro) Launch cube.elf", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/cube.elf", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/opt/toolchains/dc/sh-elf/bin/sh-elf-gdb", + "miDebuggerServerAddress": "localhost:3263", + "debugServerPath": "/home/user/Downloads/lxdream-nitro/builddir/lxdream-nitro", + "debugServerArgs": "-d -g 3263 -e ${workspaceFolder}/build/cube.elf", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set SuperH architechture", + "text": "set architecture sh4" + } + ], + "avoidWindowsConsoleRedirection": false, + "internalConsoleOptions": "openOnSessionStart" + } ] } diff --git a/cube.cc b/cube.cc new file mode 100644 index 0000000..1064663 --- /dev/null +++ b/cube.cc @@ -0,0 +1,145 @@ +#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(); +} diff --git a/engine.cc b/engine.cc index 26d2c67..1eab9c3 100644 --- a/engine.cc +++ b/engine.cc @@ -1,3 +1,5 @@ +#define TINYOBJLOADER_IMPLEMENTATION + #include "engine.hh" #include @@ -65,9 +67,7 @@ void Engine::pressButton(cont_state_t* controller_state, int button, } void Engine::glVertex3fNormalized(float x, float y, float z) { - int xSize, ySize; - xSize = 640; - ySize = 480; + constexpr int xSize = 640, ySize = 480; glVertex3f(x * xSize, y * ySize, z); } diff --git a/engine.hh b/engine.hh index 3d4e0f4..9533bba 100644 --- a/engine.hh +++ b/engine.hh @@ -8,7 +8,7 @@ class Engine { protected: - const float microSecond = 0.000001f; + static constexpr float microSecond = 0.000001f; float angle = 0; float deltaTime = 1.0 / 60.0; @@ -17,7 +17,7 @@ class Engine { bool thirtyfps; unsigned int buttonsPressed; - void initScreen(); + virtual void initScreen(); void printSystemInformation(); virtual void gameLoop(){}; void pressButton(cont_state_t* controller_state, int button, diff --git a/meson.build b/meson.build index a6a3a2a..a79a5f4 100644 --- a/meson.build +++ b/meson.build @@ -9,12 +9,18 @@ kosportsinc = include_directories('/opt/toolchains/dc/kos-ports/include') GL = cc.find_library('GL', required: true) math = cc.find_library('m', required: true) +stb_image = cc.find_library('stb_image', required: true) +subdir('romdisk') +tinyobjloader = subproject('tinyobjloader') +tinyobjloader_dep = tinyobjloader.get_variable('tinyobjloader_dep') # pcx = cc.find_library('pcx', required: true) # kosutils = cc.find_library('kosutils', required: true) deps = [ GL, - math + math, + stb_image, + tinyobjloader_dep ] incdirs = [ @@ -24,5 +30,11 @@ incdirs = [ kosportsinc ] -executable('hello.elf', ['hello.cc', 'engine.cc'], dependencies: deps, include_directories: incdirs) -executable('gl.elf', ['gl.cc', 'engine.cc'], dependencies: deps, include_directories: incdirs) +engine = static_library('engine', ['engine.cc'], dependencies: deps, include_directories: incdirs) +engine_dep = declare_dependency(link_with: engine, include_directories: incdirs) + +deps += [engine_dep] + +executable('hello.elf', ['hello.cc'], dependencies: deps, include_directories: incdirs) +executable('gl.elf', ['gl.cc'], dependencies: deps, include_directories: incdirs) +executable('cube.elf', ['cube.cc', romdsk_o], dependencies: deps, include_directories: incdirs) diff --git a/romdisk/cube.mtl b/romdisk/cube.mtl new file mode 100644 index 0000000..763e0ab --- /dev/null +++ b/romdisk/cube.mtl @@ -0,0 +1,2 @@ +# Blender 4.0.2 MTL File: 'None' +# www.blender.org diff --git a/romdisk/cube.obj b/romdisk/cube.obj new file mode 100644 index 0000000..ba883db --- /dev/null +++ b/romdisk/cube.obj @@ -0,0 +1,45 @@ +# Blender 4.0.2 +# www.blender.org +mtllib cube.mtl +o Cube +v -1.000000 -1.000000 1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 -1.000000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vt 0.625000 0.000000 +vt 0.375000 0.250000 +vt 0.375000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.500000 +vt 0.625000 0.500000 +vt 0.375000 0.750000 +vt 0.625000 0.750000 +vt 0.375000 1.000000 +vt 0.125000 0.750000 +vt 0.125000 0.500000 +vt 0.875000 0.500000 +vt 0.625000 1.000000 +vt 0.875000 0.750000 +s 0 +f 2/1/1 3/2/1 1/3/1 +f 4/4/2 7/5/2 3/2/2 +f 8/6/3 5/7/3 7/5/3 +f 6/8/4 1/9/4 5/7/4 +f 7/5/5 1/10/5 3/11/5 +f 4/12/6 6/8/6 8/6/6 +f 2/1/1 4/4/1 3/2/1 +f 4/4/2 8/6/2 7/5/2 +f 8/6/3 6/8/3 5/7/3 +f 6/8/4 2/13/4 1/9/4 +f 7/5/5 5/7/5 1/10/5 +f 4/12/6 2/14/6 6/8/6 diff --git a/romdisk/meson.build b/romdisk/meson.build new file mode 100644 index 0000000..ded6997 --- /dev/null +++ b/romdisk/meson.build @@ -0,0 +1,24 @@ +romdiskcomp = find_program('/opt/toolchains/dc/kos/utils/genromfs/genromfs') +bin2o = find_program('/opt/toolchains/dc/kos/utils/bin2o/bin2o') +cc = find_program('/opt/toolchains/dc/sh-elf/bin/sh-elf-gcc') +kos_libs =['-L/opt/toolchains/dc/kos/lib/dreamcast','-L/opt/toolchains/dc/kos/addons/lib/dreamcast','-L/opt/toolchains/dc/kos/../kos-ports/lib'] + +romdisk_path = join_paths(meson.current_source_dir()) + +romdisk_img = custom_target('romdisk.img', + output : 'romdisk.img', + build_always_stale: true, + command: [ + romdiskcomp, '-f', '@OUTPUT@', '-d', romdisk_path, '-v', '-x', '.svn', '-x', '.keepme', '-x', 'meson.build' + ]) + +romdsk = custom_target('romdisk_tmp.o', + output : 'romdisk_tmp.o', + input: [romdisk_img], + command: [ + bin2o, '@INPUT@', 'romdisk', '@OUTPUT@' + ]) + +romdsk_o = custom_target('romdisk.o', output: 'romdisk.o', input: [romdsk], command: [ + cc, '-o', '@OUTPUT@', '-r', '@INPUT@', '-Wl,--whole-archive', kos_libs, '-lromdiskbase' +]) diff --git a/romdisk/sanic.png b/romdisk/sanic.png new file mode 100644 index 0000000..5677e21 Binary files /dev/null and b/romdisk/sanic.png differ diff --git a/subprojects/.gitignore b/subprojects/.gitignore new file mode 100644 index 0000000..68a882e --- /dev/null +++ b/subprojects/.gitignore @@ -0,0 +1,3 @@ +* +!*.wrap +!.gitignore diff --git a/subprojects/tinyobjloader.wrap b/subprojects/tinyobjloader.wrap new file mode 100644 index 0000000..42e30f9 --- /dev/null +++ b/subprojects/tinyobjloader.wrap @@ -0,0 +1,8 @@ +[wrap-git] +url = https://github.com/tinyobjloader/tinyobjloader +revision = cab4ad7254cbf7eaaafdb73d272f99e92f166df8 +depth = 1 +method = cmake + +[provide] +tinyobjloader = tinyobjloader_dep