WIP
This commit is contained in:
parent
d4b7655d50
commit
a80f894163
|
@ -84,12 +84,13 @@ endif ()
|
||||||
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
set(QTK_RESOURCES "${CMAKE_SOURCE_DIR}/resources")
|
||||||
set(QTK_OSX_ICONS ${CMAKE_SOURCE_DIR}/resources/icons/osx/kilroy.icns)
|
set(QTK_OSX_ICONS ${CMAKE_SOURCE_DIR}/resources/icons/osx/kilroy.icns)
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# External Dependencies
|
|
||||||
################################################################################
|
|
||||||
# Point CMAKE_PREFIX_PATH to Qt6 install directory
|
# Point CMAKE_PREFIX_PATH to Qt6 install directory
|
||||||
# If Qtk is built within Qt Creator this is not required.
|
# If Qtk is built within Qt Creator this is not required.
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
||||||
|
if (QTK_PREFIX_QTCREATOR)
|
||||||
|
# TODO: This might be a bit strange and needs more testing.
|
||||||
|
set(CMAKE_INSTALL_PREFIX "${QT_INSTALL_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(
|
set(
|
||||||
QT_CREATOR_DIR
|
QT_CREATOR_DIR
|
||||||
|
@ -97,8 +98,9 @@ set(
|
||||||
CACHE PATH "Qt Creator path used to install Qtk plugins for Qt Designer."
|
CACHE PATH "Qt Creator path used to install Qtk plugins for Qt Designer."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Print all QTK options and their values at the end of configuration.
|
# Print all QTK options and their values at the end of configuration.
|
||||||
|
# We initialize this list here so that we can append to it as needed.
|
||||||
|
# All variables in this list will be printed at the end of configuration.
|
||||||
get_cmake_property(VAR_NAMES VARIABLES)
|
get_cmake_property(VAR_NAMES VARIABLES)
|
||||||
list(FILTER VAR_NAMES INCLUDE REGEX "^[qQ][tT][kK]_.*$")
|
list(FILTER VAR_NAMES INCLUDE REGEX "^[qQ][tT][kK]_.*$")
|
||||||
list(SORT VAR_NAMES)
|
list(SORT VAR_NAMES)
|
||||||
|
@ -143,6 +145,7 @@ set(
|
||||||
CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX QTK_PLUGIN_INSTALL_DIR QT6_INSTALL_PREFIX
|
CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX QTK_PLUGIN_INSTALL_DIR QT6_INSTALL_PREFIX
|
||||||
QT_INSTALL_DIR
|
QT_INSTALL_DIR
|
||||||
)
|
)
|
||||||
|
# Add QT6_INSTALL_PLUGINS to VAR_NAMES so it is printed at end of configuration.
|
||||||
list(APPEND VAR_NAMES QT6_INSTALL_PLUGINS)
|
list(APPEND VAR_NAMES QT6_INSTALL_PLUGINS)
|
||||||
|
|
||||||
# Find Assimp.
|
# Find Assimp.
|
||||||
|
@ -184,6 +187,8 @@ if(QTK_EXAMPLE)
|
||||||
add_subdirectory(example-app EXCLUDE_FROM_ALL)
|
add_subdirectory(example-app EXCLUDE_FROM_ALL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Print all QTK options and their values at the end of configuration. This also
|
||||||
|
# prints any additional variables that we have added to VAR_NAMES and VAR_PATHS.
|
||||||
foreach(VAR_NAME IN LISTS VAR_NAMES VAR_PATHS)
|
foreach(VAR_NAME IN LISTS VAR_NAMES VAR_PATHS)
|
||||||
if(VAR_NAME IN_LIST VAR_PATHS)
|
if(VAR_NAME IN_LIST VAR_PATHS)
|
||||||
# Print absolute if variable is path
|
# Print absolute if variable is path
|
||||||
|
|
16
README.md
16
README.md
|
@ -40,16 +40,16 @@ and [Qt Creator](https://github.com/qt-creator/qt-creator).
|
||||||
Simply open the root `CMakeLists.txt` with either of these editors and
|
Simply open the root `CMakeLists.txt` with either of these editors and
|
||||||
configurations will be loaded.
|
configurations will be loaded.
|
||||||
|
|
||||||
This project has been ported to **Qt 6.5.0**, which is not yet available in
|
This project has been ported to **Qt 6.6.0**, which is not yet available in
|
||||||
Ubuntu apt repositories.
|
Ubuntu apt repositories.
|
||||||
To run this project, you will *need* to
|
To run this project, you will *need* to
|
||||||
install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for
|
install [Qt6 Open Source Binaries](https://www.qt.io/download-qt-installer) for
|
||||||
your system, **version 6.5.0** or later.
|
your system, **version 6.6.0** or later.
|
||||||
Be sure to take note of the Qt6 installation directory, as we will need it to
|
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.
|
correctly set our `CMAKE_PREFIX_PATH` in the next steps.
|
||||||
|
|
||||||
If you are building on **Windows / Mac**, consider setting
|
If you are building on **Windows / Mac**, consider setting
|
||||||
the `-DASSIMP_NEW_INTERFACE` build flag.
|
the `-DQTK_ASSIMP_NEW_INTERFACE` cmake build option.
|
||||||
|
|
||||||
If the build is configured with all options enabled, we can subsequently install
|
If the build is configured with all options enabled, we can subsequently install
|
||||||
individual components as needed with cmake.
|
individual components as needed with cmake.
|
||||||
|
@ -59,7 +59,7 @@ sudo apt update -y && sudo apt install libassimp-dev cmake build-essential git c
|
||||||
git clone https://github.com/shaunrd0/qtk
|
git clone https://github.com/shaunrd0/qtk
|
||||||
cd qtk
|
cd qtk
|
||||||
# Configure the build with all components enabled
|
# Configure the build with all components enabled
|
||||||
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
|
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.6.0/gcc_64
|
||||||
# Build all targets
|
# Build all targets
|
||||||
cmake --build build-all/
|
cmake --build build-all/
|
||||||
````
|
````
|
||||||
|
@ -75,7 +75,7 @@ Windows / Mac / Linux) and may be easier
|
||||||
to configure.
|
to configure.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DQTK_SUBMODULES=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.5.0/gcc_64
|
cmake -B build-all -DQTK_GUI=ON -DQTK_PLUGINS=ON -DQTK_EXAMPLE=ON -DQTK_SUBMODULES=ON -DCMAKE_PREFIX_PATH=$HOME/Qt/6.6.0/gcc_64
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Qtk GUI
|
#### Qtk GUI
|
||||||
|
@ -149,9 +149,9 @@ cmake --build build-all/ --target qtk_plugins -- -j $(nproc)
|
||||||
# The path here should be initialized during build configuration, so no need for --prefix
|
# The path here should be initialized during build configuration, so no need for --prefix
|
||||||
cmake --install build-all/ --component qtk_plugins
|
cmake --install build-all/ --component qtk_plugins
|
||||||
-- Install configuration: "Release"
|
-- Install configuration: "Release"
|
||||||
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_library.a
|
-- Up-to-date: /home/shaun/Qt/6.6.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_library.a
|
||||||
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_plugin_library.a
|
-- Up-to-date: /home/shaun/Qt/6.6.0/gcc_64/../../Tools/QtCreator/lib/Qt/lib/libqtk_plugin_library.a
|
||||||
-- Up-to-date: /home/shaun/Qt/6.5.0/gcc_64/../../Tools/QtCreator/lib/Qt/plugins/designer/libqtk_collection.so
|
-- Up-to-date: /home/shaun/Qt/6.6.0/gcc_64/../../Tools/QtCreator/lib/Qt/plugins/designer/libqtk_collection.so
|
||||||
```
|
```
|
||||||
|
|
||||||
To uninstall after a previous installation, we can run the following command
|
To uninstall after a previous installation, we can run the following command
|
||||||
|
|
|
@ -24,7 +24,7 @@ void ExampleScene::init() {
|
||||||
setSkybox(skybox);
|
setSkybox(skybox);
|
||||||
|
|
||||||
std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR;
|
std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR;
|
||||||
spartanPath += "/../resources/models/spartan/spartan.obj";
|
spartanPath += "/resources/models/spartan/spartan.obj";
|
||||||
auto spartan = new Model("spartan", spartanPath.c_str());
|
auto spartan = new Model("spartan", spartanPath.c_str());
|
||||||
addObject(spartan);
|
addObject(spartan);
|
||||||
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
|
spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f);
|
||||||
|
|
|
@ -1,6 +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 QTK_EXAMPLE_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@"
|
#define QTK_EXAMPLE_SOURCE_DIR "@CMAKE_SOURCE_DIR@"
|
||||||
|
|
||||||
#endif // QTK_RESOURCES_H_IN_H
|
#endif // QTK_RESOURCES_H_IN_H
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.8 MiB |
|
@ -1,5 +1,6 @@
|
||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/textures">
|
<qresource prefix="/textures">
|
||||||
|
<file alias="plaster.png">images/plaster.png</file>
|
||||||
<file alias="crate.png">images/crate.png</file>
|
<file alias="crate.png">images/crate.png</file>
|
||||||
<file alias="stone.png">images/stone.png</file>
|
<file alias="stone.png">images/stone.png</file>
|
||||||
<file alias="wood.png">images/wood.png</file>
|
<file alias="wood.png">images/wood.png</file>
|
||||||
|
|
|
@ -41,6 +41,11 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
|
||||||
&Qtk::ToolBox::updateFocus);
|
&Qtk::ToolBox::updateFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fix / use MainWindow in Qt Designer to add these dock widgets.
|
||||||
|
// For now we will add them manually, but we should be able to do this in the
|
||||||
|
// designer. At the moment if you edit the UI in designer the dock widget
|
||||||
|
// areas below will override the designer settings.
|
||||||
|
|
||||||
// Dock the toolbox widget to the main window.
|
// Dock the toolbox widget to the main window.
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, ui_->qtk__ToolBox);
|
addDockWidget(Qt::LeftDockWidgetArea, ui_->qtk__ToolBox);
|
||||||
// Add an option to toggle active widgets in the GUI's toolbar 'view' menu.
|
// Add an option to toggle active widgets in the GUI's toolbar 'view' menu.
|
||||||
|
@ -82,7 +87,7 @@ Qtk::QtkWidget * MainWindow::getQtkWidget(const QString & name) {
|
||||||
return views_[name];
|
return views_[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshScene(QString sceneName) {
|
void MainWindow::refreshScene(const QString & sceneName) {
|
||||||
// TODO: Select TreeView using sceneName
|
// TODO: Select TreeView using sceneName
|
||||||
ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
|
ui_->qtk__TreeView->updateView(getQtkWidget()->getScene());
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,13 @@ class MainWindow : public QMainWindow {
|
||||||
*/
|
*/
|
||||||
static MainWindow * getMainWindow();
|
static MainWindow * getMainWindow();
|
||||||
|
|
||||||
|
static std::pair<QString, Qtk::DebugContext> parseError(
|
||||||
|
const QOpenGLDebugMessage & msg);
|
||||||
|
|
||||||
|
static void log(const QString & message);
|
||||||
|
|
||||||
|
static void log(const QOpenGLDebugMessage & msg);
|
||||||
|
|
||||||
Qtk::QtkWidget * getQtkWidget(int64_t index = 0);
|
Qtk::QtkWidget * getQtkWidget(int64_t index = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +76,7 @@ class MainWindow : public QMainWindow {
|
||||||
* Trigger a refresh for widgets related to a scene that has been updated.
|
* Trigger a refresh for widgets related to a scene that has been updated.
|
||||||
* @param sceneName The name of the scene that has been modified.
|
* @param sceneName The name of the scene that has been modified.
|
||||||
*/
|
*/
|
||||||
void refreshScene(QString sceneName);
|
void refreshScene(const QString & sceneName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
|
@ -37,10 +37,10 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>A custom widget tool tip.</string>
|
<string>Object details and configuration panel.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis">
|
<property name="whatsThis">
|
||||||
<string>Custom widget what's this?</string>
|
<string>When an object is double-clicked in the TreeView for a scene, this panel will display relevant details and options.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -66,10 +66,10 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="Qtk::QtkWidget" name="qtk::QtkWidget">
|
<widget class="Qtk::QtkWidget" name="qtk::QtkWidget">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>A custom widget tool tip.</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis">
|
<property name="whatsThis">
|
||||||
<string>Custom widget what's this?</string>
|
<string>Qtk scene view rendered using OpenGL.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -91,10 +91,10 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>A custom widget tool tip.</string>
|
<string>TreeView of objects within the current scene.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="whatsThis">
|
<property name="whatsThis">
|
||||||
<string>Custom widget what's this?</string>
|
<string>TreeView of objects within the current scene. Double-click to select an object and snap to it's position.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -77,6 +77,7 @@ void QtkWidget::initializeGL() {
|
||||||
// Connect the frameSwapped signal to call the update() function
|
// Connect the frameSwapped signal to call the update() function
|
||||||
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
|
||||||
|
|
||||||
|
toggleConsole();
|
||||||
// Initialize OpenGL debug context
|
// Initialize OpenGL debug context
|
||||||
mDebugLogger = new QOpenGLDebugLogger(this);
|
mDebugLogger = new QOpenGLDebugLogger(this);
|
||||||
if(mDebugLogger->initialize()) {
|
if(mDebugLogger->initialize()) {
|
||||||
|
@ -154,8 +155,8 @@ void QtkWidget::dragEnterEvent(QDragEnterEvent * event) {
|
||||||
|
|
||||||
void QtkWidget::dropEvent(QDropEvent * event) {
|
void QtkWidget::dropEvent(QDropEvent * event) {
|
||||||
mConsole->sendLog(event->mimeData()->text());
|
mConsole->sendLog(event->mimeData()->text());
|
||||||
if(event->mimeData()->hasUrls()) {
|
|
||||||
auto urls = event->mimeData()->urls();
|
auto urls = event->mimeData()->urls();
|
||||||
|
if(!urls.isEmpty()) {
|
||||||
if(urls.size() > 1) {
|
if(urls.size() > 1) {
|
||||||
qDebug() << "Cannot accept drop of multiple files.";
|
qDebug() << "Cannot accept drop of multiple files.";
|
||||||
event->ignore();
|
event->ignore();
|
||||||
|
@ -168,7 +169,7 @@ void QtkWidget::dropEvent(QDropEvent * event) {
|
||||||
mScene->loadModel(url);
|
mScene->loadModel(url);
|
||||||
event->acceptProposedAction();
|
event->acceptProposedAction();
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Unsupported file type.";
|
qDebug() << "Unsupported file type: " + url.fileName() + "\n";
|
||||||
event->ignore();
|
event->ignore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ void Model::flipTexture(const std::string & fileName, bool flipX, bool flipY) {
|
||||||
texture.mTexture->destroy();
|
texture.mTexture->destroy();
|
||||||
texture.mTexture->create();
|
texture.mTexture->create();
|
||||||
texture.mTexture->setData(
|
texture.mTexture->setData(
|
||||||
*OpenGLTextureFactory::initImage(fullPath.c_str(), flipX, flipY));
|
OpenGLTextureFactory::initImage(fullPath.c_str(), flipX, flipY));
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,9 @@ void Model::loadModel(const std::string & path) {
|
||||||
// Optimizes drawing so that overlapping objects are not overwritten
|
// Optimizes drawing so that overlapping objects are not overwritten
|
||||||
// + Since the topmost object will be drawn first
|
// + Since the topmost object will be drawn first
|
||||||
sortModelMeshes();
|
sortModelMeshes();
|
||||||
|
if(mTexturesLoaded.empty()) {
|
||||||
|
mTexturesLoaded.emplace_back("basic", ":/textures/plaster2.png");
|
||||||
|
}
|
||||||
|
|
||||||
// Object finished loading, insert it into ModelManager
|
// Object finished loading, insert it into ModelManager
|
||||||
mManager.insert(getName().c_str(), this);
|
mManager.insert(getName().c_str(), this);
|
||||||
|
@ -238,7 +241,7 @@ ModelMesh::Textures Model::loadMaterialTextures(
|
||||||
// Add the texture to the textures container
|
// Add the texture to the textures container
|
||||||
textures.push_back(texture);
|
textures.push_back(texture);
|
||||||
// Add the texture to the loaded textures to avoid loading it twice
|
// Add the texture to the loaded textures to avoid loading it twice
|
||||||
mTexturesLoaded.push_back(texture);
|
mTexturesLoaded.push_back(textures.back());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,10 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
|
||||||
shader.setUniformValue((name + number).c_str(), i);
|
shader.setUniformValue((name + number).c_str(), i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always reset active texture to GL_TEXTURE0 before we draw.
|
||||||
|
// This is important for models with no textures.
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
// Draw the mesh
|
// Draw the mesh
|
||||||
glDrawElements(
|
glDrawElements(
|
||||||
GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT, mIndices.data());
|
GL_TRIANGLES, mIndices.size(), GL_UNSIGNED_INT, mIndices.data());
|
||||||
|
@ -62,7 +66,6 @@ void ModelMesh::draw(QOpenGLShaderProgram & shader) {
|
||||||
}
|
}
|
||||||
shader.release();
|
shader.release();
|
||||||
mVAO->release();
|
mVAO->release();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
|
@ -30,6 +30,21 @@ namespace Qtk {
|
||||||
* Struct to store model textures. 3D Models may have multiple.
|
* Struct to store model textures. 3D Models may have multiple.
|
||||||
*/
|
*/
|
||||||
struct QTKAPI ModelTexture {
|
struct QTKAPI ModelTexture {
|
||||||
|
ModelTexture() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ModelTexture.
|
||||||
|
*
|
||||||
|
* @param id Texture ID for this texture.
|
||||||
|
* @param type Type of texture in string format.
|
||||||
|
* @param path Path to the texture on disk.
|
||||||
|
*/
|
||||||
|
ModelTexture(const std::string & type, const std::string & path) :
|
||||||
|
mType(type), mPath(path) {
|
||||||
|
mTexture = OpenGLTextureFactory::initTexture(path.c_str());
|
||||||
|
mID = mTexture->textureId();
|
||||||
|
}
|
||||||
|
|
||||||
/** Texture ID for for this texture. */
|
/** Texture ID for for this texture. */
|
||||||
GLuint mID {};
|
GLuint mID {};
|
||||||
QOpenGLTexture * mTexture {};
|
QOpenGLTexture * mTexture {};
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace Qtk {
|
||||||
void loadModel(const std::string & name, const std::string & path) {
|
void loadModel(const std::string & name, const std::string & path) {
|
||||||
// Add the dropped model to the load queue.
|
// Add the dropped model to the load queue.
|
||||||
// This is consumed during rendering of the scene if not empty.
|
// This is consumed during rendering of the scene if not empty.
|
||||||
mModelLoadQueue.push({name, path});
|
mModelLoadQueue.emplace(name, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
|
|
@ -9,19 +9,18 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QImageReader>
|
#include <QImageReader>
|
||||||
|
|
||||||
|
#include "app/qtkmainwindow.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
using namespace Qtk;
|
using namespace Qtk;
|
||||||
|
|
||||||
QImage * OpenGLTextureFactory::initImage(
|
QImage OpenGLTextureFactory::initImage(
|
||||||
const char * image, bool flipX, bool flipY) {
|
const char * image, bool flipX, bool flipY) {
|
||||||
// Qt6 limits loaded images to 256MB by default
|
// Qt6 limits loaded images to 256MB by default
|
||||||
QImageReader::setAllocationLimit(512);
|
QImageReader::setAllocationLimit(1024);
|
||||||
auto loadedImage = new QImage(QImage(image).mirrored(flipX, flipY));
|
auto loadedImage = QImage(image).mirrored(flipX, flipY);
|
||||||
if(loadedImage->isNull()) {
|
if(loadedImage.isNull()) {
|
||||||
qDebug() << "[Qtk::OpenGLTextureFactory] Error loading image: " << image
|
return defaultTexture();
|
||||||
<< "\nSupported types: " << QImageReader::supportedImageFormats();
|
|
||||||
return Q_NULLPTR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadedImage;
|
return loadedImage;
|
||||||
|
@ -29,13 +28,12 @@ QImage * OpenGLTextureFactory::initImage(
|
||||||
|
|
||||||
QOpenGLTexture * OpenGLTextureFactory::initTexture(
|
QOpenGLTexture * OpenGLTextureFactory::initTexture(
|
||||||
const char * texture, bool flipX, bool flipY) {
|
const char * texture, bool flipX, bool flipY) {
|
||||||
QImage * image = initImage(texture, flipX, flipY);
|
QImage image = initImage(texture, flipX, flipY);
|
||||||
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
||||||
newTexture->setData(*image);
|
newTexture->setData(image);
|
||||||
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
||||||
newTexture->setMinMagFilters(
|
newTexture->setMinMagFilters(
|
||||||
QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
||||||
delete image;
|
|
||||||
return newTexture;
|
return newTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +69,7 @@ QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
||||||
QImage faceImage(faceTextures[i]);
|
QImage faceImage(faceTextures[i]);
|
||||||
if(faceImage.isNull()) {
|
if(faceImage.isNull()) {
|
||||||
qDebug() << "Error loading cube map image\n";
|
qDebug() << "Error loading cube map image\n";
|
||||||
|
faceImage = defaultTexture();
|
||||||
}
|
}
|
||||||
faceImage = faceImage.convertToFormat(QImage::Format_RGBA8888);
|
faceImage = faceImage.convertToFormat(QImage::Format_RGBA8888);
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,9 @@ namespace Qtk {
|
||||||
* Can be absolute or Qt resource path.
|
* Can be absolute or Qt resource path.
|
||||||
* @param flipX If true the image will be flipped on X axis.
|
* @param flipX If true the image will be flipped on X axis.
|
||||||
* @param flipY If true the image will be flipped on Y axis.
|
* @param flipY If true the image will be flipped on Y axis.
|
||||||
* @return Pointer to an initialized QImage object.
|
* @return QImage object.
|
||||||
*/
|
*/
|
||||||
static QImage * initImage(
|
static QImage initImage(
|
||||||
const char * image, bool flipX = false, bool flipY = false);
|
const char * image, bool flipX = false, bool flipY = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,6 +132,14 @@ namespace Qtk {
|
||||||
const char * right, const char * top, const char * front,
|
const char * right, const char * top, const char * front,
|
||||||
const char * left, const char * bottom, const char * back);
|
const char * left, const char * bottom, const char * back);
|
||||||
|
|
||||||
|
/// The texture used in place of a missing texture.
|
||||||
|
static QImage defaultTexture() {
|
||||||
|
// Use plaster for default texture if image fails to load.
|
||||||
|
// This prevents segfaults when loading a texture that doesn't exist.
|
||||||
|
// TODO: Replace with a '?' texture to indicate missing texture.
|
||||||
|
return QImage(":/textures/plaster.png");
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Private ctor to prevent creating instances of this class
|
// Private ctor to prevent creating instances of this class
|
||||||
OpenGLTextureFactory() = default;
|
OpenGLTextureFactory() = default;
|
||||||
|
|
Loading…
Reference in New Issue