Compare commits

..

2 Commits

Author SHA1 Message Date
Shaun Reed 802107fdd4 Assimp IOSystem for Qt Resource paths 2023-01-15 16:05:08 -05:00
Shaun Reed 55dd8e5c3c Test packaging
+ Update assimp to latest
2023-01-15 10:14:24 -05:00
22 changed files with 377 additions and 86126 deletions

View File

@ -114,6 +114,8 @@ endif()
# Find Assimp # Find Assimp
if(QTK_UPDATE_SUBMODULES) if(QTK_UPDATE_SUBMODULES)
message(STATUS "[Qtk] Updating submodules...") message(STATUS "[Qtk] Updating submodules...")
set(ASSIMP_BUILD_TESTS OFF)
set(ASSIMP_INSTALL OFF)
submodule_update("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/") submodule_update("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/") add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/extern/assimp/assimp/")
else() else()

View File

@ -34,8 +34,8 @@ and see some examples in the `resources/models/` directory.
Qtk was developed and tested using CLion and [Qt Creator](https://github.com/qt-creator/qt-creator). Qtk was developed and tested using CLion and [Qt Creator](https://github.com/qt-creator/qt-creator).
Simply open the root `CMakeLists.txt` with either of these editors and configurations will be loaded. Simply open the root `CMakeLists.txt` with either of these editors and configurations will be loaded.
This project has been ported to Qt6, which is not yet available in Ubuntu apt repositories. This project has been ported to **Qt 6.5.0**, which is not yet available in Ubuntu apt repositories.
To run this project, you will *need* to install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for your system. To run this project, you will *need* to install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for your system, **version 6.5.0** or later.
Be sure to take note of the Qt6 installation directory, as we will need it to correctly set our `CMAKE_PREFIX_PATH` in the next steps. Be sure to take note of the Qt6 installation directory, as we will need it to correctly set our `CMAKE_PREFIX_PATH` in the next steps.
#### Linux #### Linux

@ -1 +1 @@
Subproject commit bd64cc88dff17f118ecf32ebcbacaf566f6b6449 Subproject commit eb328ce69dd7b06977aed125e967a41e835b8431

View File

@ -1,5 +1,5 @@
# Created by RapidCompact v4.3.2 | www.rapidcompact.com # Created by RapidCompact v4.3.2 | www.rapidcompact.com
mtllib rapid.mtl mtllib bird.mtl
o mesh_0 o mesh_0
v 290.631131412626928068 748.484123578408002686 -224.342122210487644907 v 290.631131412626928068 748.484123578408002686 -224.342122210487644907
v 282.356783853739386814 751.945844816198814442 -222.136356657249308455 v 282.356783853739386814 751.945844816198814442 -222.136356657249308455

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 KiB

View File

@ -1,16 +0,0 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl Lion
Ns 500.000001
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.800000 0.800000 0.800000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Bump normal.jpg
map_Kd diffuse.jpg
map_Ns roughness.jpg
refl specular.jpg

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

View File

@ -52,4 +52,79 @@
<file alias="skybox.frag">skybox/skybox.frag</file> <file alias="skybox.frag">skybox/skybox.frag</file>
<file alias="skybox.vert">skybox/skybox.vert</file> <file alias="skybox.vert">skybox/skybox.vert</file>
</qresource> </qresource>
<qresource prefix="/models">
<file>models/spartan/spartan.obj</file>
<file>models/alien-hominid/alien.obj</file>
<file>models/spartan/spartan.mtl</file>
<file>models/spartan/Spartan_Ears_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Undersuit_Mat_Specular.png</file>
<file>models/spartan/Spartan_Undersuit_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Undersuit_Mat_Normal.png</file>
<file>models/spartan/Spartan_Undersuit_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Undersuit_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Undersuit_Mat_AO.png</file>
<file>models/spartan/Spartan_Shoulder_Mat_Specular.png</file>
<file>models/spartan/Spartan_Shoulder_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Shoulder_Mat_Normal.png</file>
<file>models/spartan/Spartan_Shoulder_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Shoulder_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Shoulder_Mat_AO.png</file>
<file>models/spartan/Spartan_Legs_Mat_Specular.png</file>
<file>models/spartan/Spartan_Legs_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Legs_Mat_Normal.png</file>
<file>models/spartan/Spartan_Legs_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Legs_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Legs_Mat_AO.png</file>
<file>models/spartan/Spartan_Helmet_Mat_Specular.png</file>
<file>models/spartan/Spartan_Helmet_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Helmet_Mat_Normal.png</file>
<file>models/spartan/Spartan_Helmet_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Helmet_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Helmet_Mat_AO.png</file>
<file>models/spartan/Spartan_Ears_Mat_Specular.png</file>
<file>models/spartan/Spartan_Ears_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Ears_Mat_Normal.png</file>
<file>models/spartan/Spartan_Ears_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Ears_Mat_AO.png</file>
<file>models/spartan/Spartan_Chest_Mat_Specular.png</file>
<file>models/spartan/Spartan_Chest_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Chest_Mat_Normal.png</file>
<file>models/spartan/Spartan_Chest_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Chest_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Chest_Mat_AO.png</file>
<file>models/spartan/Spartan_Arms_Mat_Specular.png</file>
<file>models/spartan/Spartan_Arms_Mat_Roughness.png</file>
<file>models/spartan/Spartan_Arms_Mat_Normal.png</file>
<file>models/spartan/Spartan_Arms_Mat_Metallic.png</file>
<file>models/spartan/Spartan_Arms_Mat_BaseColor.png</file>
<file>models/spartan/Spartan_Arms_Mat_AO.png</file>
<file>models/spartan/lambert1_Roughness.png</file>
<file>models/spartan/lambert1_Nrm.png</file>
<file>models/spartan/lambert1_Colour-Opacity.png</file>
<file>models/backpack/specular.jpg</file>
<file>models/backpack/roughness.jpg</file>
<file>models/backpack/diffuse.jpg</file>
<file>models/backpack/normal.png</file>
<file>models/backpack/backpack.obj</file>
<file>models/backpack/backpack.mtl</file>
<file>models/backpack/ao.jpg</file>
<file>models/alien-hominid/specular.png</file>
<file>models/alien-hominid/roughness.png</file>
<file>models/alien-hominid/normal.png</file>
<file>models/alien-hominid/diffuse.png</file>
<file>models/alien-hominid/blaster_specular.png</file>
<file>models/alien-hominid/blaster_roughness.png</file>
<file>models/alien-hominid/blaster_normal.png</file>
<file>models/alien-hominid/blaster_emissive.png</file>
<file>models/alien-hominid/blaster_diffuse.png</file>
<file>models/alien-hominid/alien.mtl</file>
<file>models/scythe/scythe.obj</file>
<file>models/scythe/scythe.mtl</file>
<file>models/scythe/diffuse.png</file>
<file>models/bird/occlusion.jpg</file>
<file>models/bird/normal.jpg</file>
<file>models/bird/diffuse.jpg</file>
<file>models/bird/bird.obj</file>
<file>models/bird/bird.mtl</file>
</qresource>
</RCC> </RCC>

View File

@ -15,11 +15,9 @@ set(
debugconsole.cpp debugconsole.ui debugconsole.cpp debugconsole.ui
toolbox.cpp toolbox.ui toolbox.cpp toolbox.ui
treeview.cpp treeview.ui treeview.cpp treeview.ui
qtkmainwindow.cpp qtkmainwindow.ui
) )
set( set(
QTK_PLUGIN_LIBRARY_HEADERS QTK_PLUGIN_LIBRARY_HEADERS
qtkmainwindow.h
qtkwidget.h qtkwidget.h
debugconsole.h debugconsole.h
toolbox.h toolbox.h
@ -53,16 +51,16 @@ install(
# Qtk Widget Collection Plugin # Qtk Widget Collection Plugin
################################################################################ ################################################################################
# Create a Qt Designer plugin for a collection of widgets from our library. # Create a Qt Designer plugin for a collection of widgets from our library.
qt_add_plugin(qtk-collection) qt_add_plugin(qtk_collection STATIC)
target_sources( target_sources(
qtk-collection PRIVATE qtk_collection PRIVATE
widgetplugincollection.cpp widgetplugincollection.h widgetplugincollection.cpp widgetplugincollection.h
widgetplugin.cpp widgetplugin.h widgetplugin.cpp widgetplugin.h
) )
target_link_libraries(qtk-collection PUBLIC qtk-plugin-library) target_link_libraries(qtk_collection PUBLIC qtk-plugin-library)
install( install(
TARGETS qtk-collection TARGETS qtk_collection
RUNTIME DESTINATION "${QTK_PLUGIN_INSTALL_DIR}" RUNTIME DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
BUNDLE DESTINATION "${QTK_PLUGIN_INSTALL_DIR}" BUNDLE DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
LIBRARY DESTINATION "${QTK_PLUGIN_INSTALL_DIR}" LIBRARY DESTINATION "${QTK_PLUGIN_INSTALL_DIR}"
@ -75,10 +73,11 @@ install(
set( set(
QTK_APP_SOURCES QTK_APP_SOURCES
examplescene.cpp examplescene.h examplescene.cpp examplescene.h
qtkmainwindow.cpp qtkmainwindow.h qtkmainwindow.ui
main.cpp main.cpp
) )
qt6_add_resources(QTK_APP_SOURCES "${QTK_RESOURCES}/resources.qrc") qt6_add_big_resources(QTK_APP_SOURCES "${QTK_RESOURCES}/resources.qrc")
configure_file( configure_file(
resources.h.in resources.h.in
"${CMAKE_CURRENT_BINARY_DIR}/resources.h" "${CMAKE_CURRENT_BINARY_DIR}/resources.h"
@ -105,10 +104,10 @@ install(
qt_generate_deploy_app_script( qt_generate_deploy_app_script(
TARGET qtk-main TARGET qtk-main
FILENAME_VARIABLE deploy_script FILENAME_VARIABLE QTK_DEPLOY_SCRIPT
NO_UNSUPPORTED_PLATFORM_ERROR NO_UNSUPPORTED_PLATFORM_ERROR
) )
install(SCRIPT ${deploy_script}) install(SCRIPT ${QTK_DEPLOY_SCRIPT})
if(WIN32) if(WIN32)
get_target_property(_qt6_qmake_location Qt6::qmake IMPORTED_LOCATION) get_target_property(_qt6_qmake_location Qt6::qmake IMPORTED_LOCATION)

View File

@ -41,7 +41,7 @@ void ExampleScene::init() {
myCube->setColor(RED); myCube->setColor(RED);
addObject(myCube); addObject(myCube);
auto mySpartan = new Model("My spartan", PATH("/models/spartan/spartan.obj")); auto mySpartan = new Model("My spartan", ":/models/models/spartan/spartan.obj");
mySpartan->getTransform().setTranslation(0.0f, 0.5f, 0.0f); mySpartan->getTransform().setTranslation(0.0f, 0.5f, 0.0f);
mySpartan->getTransform().setScale(0.5f); mySpartan->getTransform().setScale(0.5f);
addObject(mySpartan); addObject(mySpartan);
@ -79,35 +79,30 @@ void ExampleScene::init() {
// 3D Model loading // 3D Model loading
auto model = addObject( auto model = addObject(
new Qtk::Model("backpack", PATH("/models/backpack/backpack.obj"))); new Qtk::Model("backpack", ":/models/models/backpack/backpack.obj"));
auto test = PATH("/models/backpack/backpack.obj");
// Sometimes model textures need flipped in certain directions // Sometimes model textures need flipped in certain directions
model->flipTexture("diffuse.jpg", false, true); model->flipTexture("diffuse.jpg", false, true);
model->getTransform().setTranslation(0.0f, 0.0f, -10.0f); model->getTransform().setTranslation(0.0f, 0.0f, -10.0f);
model = addObject(new Qtk::Model("bird", PATH("/models/bird/bird.obj"))); model = addObject(new Qtk::Model("bird", ":/models/models/bird/bird.obj"));
model->getTransform().setTranslation(2.0f, 2.0f, -10.0f); model->getTransform().setTranslation(2.0f, 2.0f, -10.0f);
// Sometimes the models are very large // Sometimes the models are very large
model->getTransform().scale(0.0025f); model->getTransform().scale(0.0025f);
model->getTransform().rotate(-110.0f, 0.0f, 1.0f, 0.0f); model->getTransform().rotate(-110.0f, 0.0f, 1.0f, 0.0f);
model = addObject(new Qtk::Model("lion", PATH("/models/lion/lion.obj")));
model->getTransform().setTranslation(-3.0f, -1.0f, -10.0f);
model->getTransform().scale(0.15f);
model = addObject( model = addObject(
new Qtk::Model("alien", PATH("/models/alien-hominid/alien.obj"))); new Qtk::Model("alien", ":/models/models/alien-hominid/alien.obj"));
model->getTransform().setTranslation(2.0f, -1.0f, -5.0f); model->getTransform().setTranslation(2.0f, -1.0f, -5.0f);
model->getTransform().scale(0.15f); model->getTransform().scale(0.15f);
model = model =
addObject(new Qtk::Model("scythe", PATH("/models/scythe/scythe.obj"))); addObject(new Qtk::Model("scythe", ":/models/models/scythe/scythe.obj"));
model->getTransform().setTranslation(-6.0f, 0.0f, -10.0f); model->getTransform().setTranslation(-6.0f, 0.0f, -10.0f);
model->getTransform().rotate(-90.0f, 1.0f, 0.0f, 0.0f); model->getTransform().rotate(-90.0f, 1.0f, 0.0f, 0.0f);
model->getTransform().rotate(90.0f, 0.0f, 1.0f, 0.0f); model->getTransform().rotate(90.0f, 0.0f, 1.0f, 0.0f);
model = addObject( model = addObject(
new Qtk::Model("masterChief", PATH("/models/spartan/spartan.obj"))); new Qtk::Model("masterChief", ":/models/models/spartan/spartan.obj"));
model->getTransform().setTranslation(-1.5f, 0.5f, -2.0f); model->getTransform().setTranslation(-1.5f, 0.5f, -2.0f);
@ -233,7 +228,7 @@ void ExampleScene::init() {
/* Test alien Model with phong lighting and specular mapping. */ /* Test alien Model with phong lighting and specular mapping. */
model = addObject(new Qtk::Model( model = addObject(new Qtk::Model(
"alienTest", PATH("/models/alien-hominid/alien.obj"), "alienTest", ":/models/models/alien-hominid/alien.obj",
":/shaders/model-specular.vert", ":/shaders/model-specular.frag")); ":/shaders/model-specular.vert", ":/shaders/model-specular.frag"));
model->getTransform().setTranslation(3.0f, -1.0f, 10.0f); model->getTransform().setTranslation(3.0f, -1.0f, 10.0f);
model->getTransform().scale(0.15f); model->getTransform().scale(0.15f);
@ -259,7 +254,7 @@ void ExampleScene::init() {
/* Test spartan Model with phong lighting, specular and normal mapping. */ /* Test spartan Model with phong lighting, specular and normal mapping. */
model = addObject(new Qtk::Model( model = addObject(new Qtk::Model(
"spartanTest", PATH("/models/spartan/spartan.obj"), "spartanTest", ":/models/models/spartan/spartan.obj",
":/shaders/model-normals.vert", ":/shaders/model-normals.frag")); ":/shaders/model-normals.vert", ":/shaders/model-normals.frag"));
model->getTransform().setTranslation(0.0f, -1.0f, 10.0f); model->getTransform().setTranslation(0.0f, -1.0f, 10.0f);
model->getTransform().scale(2.0f); model->getTransform().scale(2.0f);

View File

@ -1,8 +1,6 @@
#ifndef QTK_RESOURCES_H_IN_H #ifndef QTK_RESOURCES_H_IN_H
#define QTK_RESOURCES_H_IN_H #define QTK_RESOURCES_H_IN_H
#define RESOURCES "@CMAKE_SOURCE_DIR@/resources" // Not currently in use, but will be in the future.
#define PATH(a) RESOURCES a
#endif // QTK_RESOURCES_H_IN_H #endif // QTK_RESOURCES_H_IN_H

View File

@ -12,13 +12,15 @@ set(
QTK_LIBRARY_PUBLIC_HEADERS QTK_LIBRARY_PUBLIC_HEADERS
camera3d.h camera3d.h
input.h input.h
shape.h
meshrenderer.h meshrenderer.h
model.h model.h
modelmesh.h modelmesh.h
object.h object.h
qtkapi.h qtkapi.h
qtkiostream.h
qtkiosystem.h
scene.h scene.h
shape.h
skybox.h skybox.h
texture.h texture.h
transform3D.h transform3D.h
@ -28,18 +30,20 @@ set(
QTK_LIBRARY_SOURCES QTK_LIBRARY_SOURCES
camera3d.cpp camera3d.cpp
input.cpp input.cpp
shape.cpp
meshrenderer.cpp meshrenderer.cpp
model.cpp model.cpp
modelmesh.cpp modelmesh.cpp
object.cpp object.cpp
qtkiostream.cpp
qtkiosystem.cpp
scene.cpp scene.cpp
shape.cpp
skybox.cpp skybox.cpp
texture.cpp texture.cpp
transform3D.cpp transform3D.cpp
) )
qt6_add_resources(QTK_LIBRARY_SOURCES "${QTK_RESOURCES}/resources.qrc") qt6_add_big_resources(QTK_LIBRARY_SOURCES "${QTK_RESOURCES}/resources.qrc")
qt_add_library(qtk-library STATIC) qt_add_library(qtk-library STATIC)
target_sources(qtk-library PRIVATE ${QTK_LIBRARY_SOURCES}) target_sources(qtk-library PRIVATE ${QTK_LIBRARY_SOURCES})
target_sources( target_sources(

View File

@ -7,11 +7,10 @@
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## ## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/ ##############################################################################*/
#include <QFileInfo>
#include "model.h" #include "model.h"
#include "scene.h" #include "scene.h"
#include "texture.h" #include "texture.h"
#include "qtkiosystem.h"
using namespace Qtk; using namespace Qtk;
@ -65,27 +64,27 @@ Model * Qtk::Model::getInstance(const char * name) {
void Model::loadModel(const std::string & path) { void Model::loadModel(const std::string & path) {
Assimp::Importer import; Assimp::Importer import;
// If using a Qt Resource path, use QtkIOSystem for file handling.
// JIC a relative path was used, get the absolute file path if (path.front() == ':') {
QFileInfo info(path.c_str()); import.SetIOHandler(new QtkIOSystem());
info.makeAbsolute(); }
mDirectory = info.absoluteFilePath().toStdString(); // Used as base path for loading model textures.
mDirectory = path.substr(0, path.find_last_of('/'));
// Import the model, converting non-triangular geometry to triangles // Import the model, converting non-triangular geometry to triangles
// + And flipping texture UVs, etc.. // + And flipping texture UVs, etc..
// Assimp options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html // Assimp options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html
const aiScene * scene = import.ReadFile( const aiScene * scene = import.ReadFile(
mDirectory, aiProcess_Triangulate | aiProcess_FlipUVs path.c_str(), aiProcess_Triangulate | aiProcess_FlipUVs
| aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals
| aiProcess_OptimizeMeshes | aiProcess_SplitLargeMeshes); | aiProcess_CalcTangentSpace | aiProcess_OptimizeMeshes
| aiProcess_SplitLargeMeshes);
// If there were errors, print and return // If there were errors, print and return
if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
qDebug() << "Error::ASSIMP::" << import.GetErrorString() << "\n"; qDebug() << "Error::ASSIMP::" << import.GetErrorString() << "\n";
return; return;
} }
// If there were no errors, find the directory that contains this model
mDirectory = mDirectory.substr(0, mDirectory.find_last_of('/'));
// Pass the pointers to the root node and the scene to recursive function // Pass the pointers to the root node and the scene to recursive function
// + Base case breaks when no nodes left to process on model // + Base case breaks when no nodes left to process on model
@ -182,7 +181,6 @@ ModelMesh Model::processMesh(aiMesh * mesh, const aiScene * scene) {
if(mesh->mMaterialIndex >= 0) { if(mesh->mMaterialIndex >= 0) {
// Get the material attached to the model using Assimp // Get the material attached to the model using Assimp
aiMaterial * material = scene->mMaterials[mesh->mMaterialIndex]; aiMaterial * material = scene->mMaterials[mesh->mMaterialIndex];
// Get all diffuse textures from the material // Get all diffuse textures from the material
ModelMesh::Textures diffuseMaps = loadMaterialTextures( ModelMesh::Textures diffuseMaps = loadMaterialTextures(
material, aiTextureType_DIFFUSE, "texture_diffuse"); material, aiTextureType_DIFFUSE, "texture_diffuse");

82
src/qtk/qtkiostream.cpp Normal file
View File

@ -0,0 +1,82 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: Custom IO stream for Qtk to support Qt Resource paths in Assimp ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include "qtkiostream.h"
using namespace Qtk;
/*******************************************************************************
* Constructors, Destructors
******************************************************************************/
QtkIOStream::QtkIOStream(const char * pFile, const char * pMode) :
mFile(pFile) {
QString mode(pMode);
bool read = mode.contains('r');
bool write = mode.contains('w');
if(read && write) {
mFile.open(QIODevice::ReadWrite);
} else if(read) {
mFile.open(QIODevice::ReadOnly);
} else if(write) {
mFile.open(QIODevice::WriteOnly);
} else {
qDebug() << "[Qtk::QtkIOStream] Invalid file open mode: " << mode << "\n";
}
}
/*******************************************************************************
* Public Member Functions
******************************************************************************/
size_t QtkIOStream::Read(void * pvBuffer, size_t pSize, size_t pCount) {
size_t read = 0;
do {
auto readSize = mFile.read((char *)pvBuffer + read, pSize);
if(readSize < 0) {
qDebug() << "[Qtk::QtkIOStream] Failed to read (" << pSize
<< ") bytes from file at: " << mFile.filesystemFileName().c_str()
<< "\n";
return -1;
}
read += readSize;
} while(pCount--);
return read;
}
size_t QtkIOStream::Write(const void * pvBuffer, size_t pSize, size_t pCount) {
size_t wrote = 0;
do {
auto writeSize = mFile.write((char *)pvBuffer + wrote, pSize);
if(writeSize < 0) {
qDebug() << "[Qtk::QtkIOStream] Failed to write buffer with size ("
<< pSize
<< ") to file at: " << mFile.filesystemFileName().c_str()
<< "\n";
return -1;
}
wrote += writeSize;
} while(pCount--);
return wrote;
}
aiReturn QtkIOStream::Seek(size_t pOffset, aiOrigin pOrigin) {
return mFile.seek(pOffset) ? aiReturn_SUCCESS : aiReturn_FAILURE;
}
size_t QtkIOStream::Tell() const {
return mFile.pos();
}
size_t QtkIOStream::FileSize() const {
return mFile.size();
}
void QtkIOStream::Flush() {
mFile.flush();
}

85
src/qtk/qtkiostream.h Normal file
View File

@ -0,0 +1,85 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: Custom IO stream for Qtk to support Qt Resource paths in Assimp ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <QFile>
#include <QFileInfo>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#ifndef QTK_QTKIOSTREAM_H
#define QTK_QTKIOSTREAM_H
namespace Qtk {
/**
* Custom Assimp IO stream to support QtkIOSystem file handling.
* Allows direct use of Qt Resource paths for loading models in Assimp.
*/
class QtkIOStream : public Assimp::IOStream {
friend class QtkIOSystem;
protected:
/** Constructor protected for private usage by QtkIOSystem */
QtkIOStream(const char * pFile, const char * pMode);
public:
~QtkIOStream() = default;
/**
* Reads data into pvBuffer in pCount batches of length pSize.
* The final pvBuffer will contain data read from all batches.
*
* @param pvBuffer Buffer to read data into.
* @param pSize Size in bytes for each read.
* @param pCount Number of reads to perform.
* @return Length of total bytes read into pvBuffer, or -1 on failure.
*/
size_t Read(void * pvBuffer, size_t pSize, size_t pCount) override;
/**
* Writes data from pvBuffer in pCount batches of length pSize.
* The final mFile member will contain all input data from pvBuffer.
*
* @param pvBuffer Buffer to write data from.
* @param pSize Size in bytes for each write.
* @param pCount Number of writes to perfom.
* @return Length of total bytes wrote into buffer, or -1 on failure.
*/
size_t Write(const void * pvBuffer, size_t pSize, size_t pCount) override;
/**
* Change the current read position in the mFile Qt resource.
*
* @param pOffset Offset position to set.
* @param pOrigin Origin position to use for relative offset.
* @return aiReturn_SUCCESS, or aiReturn_FAILURE on failure.
*/
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override;
/**
* @return The current position in mFile.
*/
[[nodiscard]] size_t Tell() const override;
/**
* @return The total size of mFile.
*/
[[nodiscard]] size_t FileSize() const override;
/**
* Flushes buffered data to mFile.
*/
void Flush() override;
private:
// Corresponding file for Qt Resource path.
QFile mFile;
};
} // namespace Qtk
#endif // QTK_QTKIOSTREAM_H

39
src/qtk/qtkiosystem.cpp Normal file
View File

@ -0,0 +1,39 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: Custom IO system for Qtk to support Qt Resource paths in Assimp ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include "qtkiosystem.h"
using namespace Qtk;
/*******************************************************************************
* Public Member Functions
******************************************************************************/
bool QtkIOSystem::Exists(const char * pFile) const {
return QFileInfo::exists(pFile);
}
char QtkIOSystem::getOsSeparator() const {
#ifndef _WIN32
return '/';
#else
return '\\';
#endif
}
Assimp::IOStream * QtkIOSystem::Open(const char * pFile, const char * pMode) {
if(!QFileInfo::exists(pFile)) {
qDebug() << "[Qtk::QtkIOSystem] failed to open file: " << pFile << "\n";
return nullptr;
}
return new QtkIOStream(pFile, pMode);
}
void QtkIOSystem::Close(Assimp::IOStream * pFile) {
delete pFile;
}

53
src/qtk/qtkiosystem.h Normal file
View File

@ -0,0 +1,53 @@
/*##############################################################################
## Author: Shaun Reed ##
## Legal: All Content (c) 2023 Shaun Reed, all rights reserved ##
## About: Custom IO system for Qtk to support Qt Resource paths in Assimp ##
## ##
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
##############################################################################*/
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include "qtkapi.h"
#include "qtkiostream.h"
#ifndef QTK_QTKIOSYSTEM_H
#define QTK_QTKIOSYSTEM_H
namespace Qtk {
/**
* Assimp IO system for loading models with assimp, using Qt Resource paths.
*/
class QtkIOSystem : public Assimp::IOSystem {
public:
QtkIOSystem() = default;
~QtkIOSystem() = default;
/**
* @param pFile File path to check.
* @return True if the file exists, else false.
*/
bool Exists(const char * pFile) const override;
/**
* @return Path separator for platform OS.
*/
[[nodiscard]] char getOsSeparator() const override;
/**
* @param pFile File to open for read / writing.
* @param pMode Mode to open file. See `man fopen`.
* @return QtkIOStream for the opened file.
*/
Assimp::IOStream * Open(
const char * pFile, const char * pMode = "rb") override;
/**
* @param pFile File to close.
*/
void Close(Assimp::IOStream * pFile) override;
};
} // namespace Qtk
#endif // QTK_QTKIOSYSTEM_H

View File

@ -19,8 +19,8 @@ QImage * OpenGLTextureFactory::initImage(
QImageReader::setAllocationLimit(512); QImageReader::setAllocationLimit(512);
auto loadedImage = new QImage(QImage(image).mirrored(flipX, flipY)); auto loadedImage = new QImage(QImage(image).mirrored(flipX, flipY));
if(loadedImage->isNull()) { if(loadedImage->isNull()) {
qDebug() << "Error loading image: " << image << "\n"; qDebug() << "[Qtk::OpenGLTextureFactory] Error loading image: " << image
qDebug() << QImageReader::supportedImageFormats(); << "\nSupported types: " << QImageReader::supportedImageFormats();
return Q_NULLPTR; return Q_NULLPTR;
} }