2021-09-03 16:56:57 +00:00
|
|
|
/*##############################################################################
|
|
|
|
## Author: Shaun Reed ##
|
2022-03-06 16:54:05 +00:00
|
|
|
## Legal: All Content (c) 2022 Shaun Reed, all rights reserved ##
|
2021-09-03 16:56:57 +00:00
|
|
|
## About: Texture class to help with texture and image initializations ##
|
|
|
|
## ##
|
|
|
|
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
|
|
|
##############################################################################*/
|
|
|
|
|
2021-09-12 16:49:59 +00:00
|
|
|
#include <QDebug>
|
2021-09-03 16:56:57 +00:00
|
|
|
#include <QImageReader>
|
2022-11-24 22:26:53 +00:00
|
|
|
#include <utility>
|
2021-09-03 16:56:57 +00:00
|
|
|
|
|
|
|
#include <texture.h>
|
|
|
|
|
2022-08-07 17:12:12 +00:00
|
|
|
using namespace Qtk;
|
2021-09-03 16:56:57 +00:00
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
QImage * OpenGLTextureFactory::initImage(
|
|
|
|
const char * image, bool flipX, bool flipY) {
|
2022-03-06 16:54:05 +00:00
|
|
|
// Qt6 limits loaded images to 256MB by default
|
|
|
|
QImageReader::setAllocationLimit(512);
|
2021-09-03 16:56:57 +00:00
|
|
|
auto loadedImage = new QImage(QImage(image).mirrored(flipX, flipY));
|
2022-11-24 22:26:53 +00:00
|
|
|
if(loadedImage->isNull()) {
|
2021-09-03 16:56:57 +00:00
|
|
|
qDebug() << "Error loading image: " << image << "\n";
|
|
|
|
qDebug() << QImageReader::supportedImageFormats();
|
|
|
|
return Q_NULLPTR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return loadedImage;
|
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
QOpenGLTexture * OpenGLTextureFactory::initTexture2D(
|
|
|
|
const char * texture, bool flipX, bool flipY) {
|
2021-09-03 16:56:57 +00:00
|
|
|
QImage * image = initImage(texture, flipX, flipY);
|
|
|
|
auto newTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
|
|
|
|
newTexture->setData(*image);
|
|
|
|
newTexture->setWrapMode(QOpenGLTexture::Repeat);
|
2022-11-24 22:26:53 +00:00
|
|
|
newTexture->setMinMagFilters(
|
|
|
|
QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
2021-09-03 16:56:57 +00:00
|
|
|
delete image;
|
|
|
|
return newTexture;
|
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(const char * tile) {
|
|
|
|
return initCubeMap(
|
|
|
|
QImage(tile), QImage(tile), QImage(tile), QImage(tile), QImage(tile),
|
|
|
|
QImage(tile));
|
2021-09-03 16:56:57 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
|
|
|
const char * right, const char * top, const char * front, const char * left,
|
|
|
|
const char * bottom, const char * back) {
|
|
|
|
return initCubeMap(
|
|
|
|
QImage(right), QImage(top), QImage(front), QImage(left), QImage(bottom),
|
|
|
|
QImage(back));
|
2021-09-03 16:56:57 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
QOpenGLTexture * OpenGLTextureFactory::initCubeMap(
|
|
|
|
const QImage & right, const QImage & top, const QImage & front,
|
|
|
|
const QImage & left, const QImage & bottom, const QImage & back) {
|
2021-09-03 16:56:57 +00:00
|
|
|
auto texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
|
2022-11-24 22:26:53 +00:00
|
|
|
std::vector<QImage> faceTextures = {std::move(right), std::move(top),
|
|
|
|
std::move(front), std::move(left),
|
|
|
|
std::move(bottom), std::move(back)};
|
2021-09-03 16:56:57 +00:00
|
|
|
// Initialize skybox cubemap texture
|
|
|
|
texture->create();
|
|
|
|
texture->bind();
|
|
|
|
// For each cube map face
|
|
|
|
std::vector<QOpenGLTexture::CubeMapFace> faces = {
|
|
|
|
QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapPositiveY,
|
|
|
|
QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeX,
|
2022-11-24 22:26:53 +00:00
|
|
|
QOpenGLTexture::CubeMapNegativeY, QOpenGLTexture::CubeMapNegativeZ};
|
2021-09-03 16:56:57 +00:00
|
|
|
int i = 0;
|
2022-11-24 22:26:53 +00:00
|
|
|
for(const auto & face : faces) {
|
2021-09-03 16:56:57 +00:00
|
|
|
QImage faceImage(faceTextures[i]);
|
2022-11-24 22:26:53 +00:00
|
|
|
if(faceImage.isNull()) {
|
2021-09-03 16:56:57 +00:00
|
|
|
qDebug() << "Error loading cube map image\n";
|
|
|
|
}
|
|
|
|
faceImage = faceImage.convertToFormat(QImage::Format_RGBA8888);
|
|
|
|
|
|
|
|
// On the first iteration, set format and allocate texture storage
|
2022-11-24 22:26:53 +00:00
|
|
|
if(face == QOpenGLTexture::CubeMapPositiveX) {
|
2021-09-03 16:56:57 +00:00
|
|
|
// This also needs to happen on the first iteration, anyways
|
2022-11-24 22:26:53 +00:00
|
|
|
texture->setSize(
|
|
|
|
faceImage.width(), faceImage.height(), faceImage.depth());
|
2021-09-03 16:56:57 +00:00
|
|
|
texture->setFormat(QOpenGLTexture::RGBA8_UNorm);
|
|
|
|
texture->allocateStorage();
|
|
|
|
}
|
|
|
|
|
2022-11-24 22:26:53 +00:00
|
|
|
texture->setData(
|
|
|
|
0, 0, face, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8,
|
|
|
|
faceImage.constBits());
|
2021-09-03 16:56:57 +00:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
texture->setWrapMode(QOpenGLTexture::ClampToEdge);
|
|
|
|
texture->generateMipMaps();
|
|
|
|
texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
|
|
|
|
texture->setMagnificationFilter(QOpenGLTexture::Linear);
|
|
|
|
texture->release();
|
|
|
|
return texture;
|
|
|
|
}
|