summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2014-06-23 16:20:53 +0200
committerSean Harmer <sean.harmer@kdab.com>2014-06-28 16:50:59 +0200
commit30f47124e594176ed2da3b8f7df6ca13fe2c5d05 (patch)
tree8972dde67ca9321681fe1d83ce820345e08783d3
parenta6a48a0c838a4f9357b4aa51e9f905ebc00ca454 (diff)
Textures hooked up
This is a first implementation that will need some improvements. Still texture are now handled and can be specified directly as parameters in Material, Effect or Technique which should play nicely along regular uniform QVariant values when we have a custom QML parser. Change-Id: Icd7067f04282fcb15e9edc559aae2bedaaa808c1 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--examples/simple-qml/main.cpp3
-rw-r--r--examples/simple-qml/main.qml2
-rw-r--r--src/quick3d/quick3drenderer/items/quick3dtexture.cpp22
-rw-r--r--src/render/backend/qgraphicscontext.cpp24
-rw-r--r--src/render/backend/qgraphicscontext.h5
-rw-r--r--src/render/backend/quniformvalue.h13
-rw-r--r--src/render/backend/renderer.cpp1
-rw-r--r--src/render/backend/renderview.cpp4
-rw-r--r--src/render/frontend/texture.cpp6
9 files changed, 58 insertions, 22 deletions
diff --git a/examples/simple-qml/main.cpp b/examples/simple-qml/main.cpp
index 1efee589c..f6d4168f1 100644
--- a/examples/simple-qml/main.cpp
+++ b/examples/simple-qml/main.cpp
@@ -42,6 +42,7 @@
#include <Qt3DQuick/quickwindow.h>
#include <Qt3DRenderer/rendereraspect.h>
+#include <exampleresources.h>
#include <QGuiApplication>
#include <QtQml>
@@ -50,6 +51,8 @@ int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
+ initializeAssetResources("../exampleresources/example-assets.qrb");
+
Qt3D::Quick::QuickWindow view;
view.registerAspect(new Qt3D::RendererAspect());
// There should be some synchronising mechanism to make sure
diff --git a/examples/simple-qml/main.qml b/examples/simple-qml/main.qml
index 9d5f3a2c0..413af7907 100644
--- a/examples/simple-qml/main.qml
+++ b/examples/simple-qml/main.qml
@@ -232,7 +232,7 @@ Node {
Material {
id : ballTexturedMaterial
- parameters : [Parameter { name : "tex"; value : Texture { source : "assets/Wood_Cherry_Original_.jpg" } }]
+ parameters : [Parameter { name : "tex"; value : Texture { source : "assets/gltf/wine/Wood_Cherry_Original_.jpg" } }]
effect : Effect {
techniques : [
diff --git a/src/quick3d/quick3drenderer/items/quick3dtexture.cpp b/src/quick3d/quick3drenderer/items/quick3dtexture.cpp
index a757bccfc..f5222a0e5 100644
--- a/src/quick3d/quick3drenderer/items/quick3dtexture.cpp
+++ b/src/quick3d/quick3drenderer/items/quick3dtexture.cpp
@@ -67,14 +67,20 @@ void Quick3DTexture::setSource(QUrl arg)
{
if (m_source != arg) {
m_source = arg;
+ // There is maybe a better way to check for resources files
+ if (m_source.isLocalFile() || m_source.scheme() == QStringLiteral("qrc")) {
+ QString source = m_source.toString().replace(QStringLiteral("qrc"), QStringLiteral(""));
+ QImage img;
+ if (img.load(source)) {
+ parentTexture()->setInternalFormat(img.hasAlphaChannel() ?
+ Texture::RGBA8_UNorm :
+ Texture::RGB8_UNorm);
+ parentTexture()->setFromQImage(img);
+ }
+ else {
+ qWarning() << "Failed to load image : " << source;
+ }
- if (m_source.isLocalFile()) {
- QImage img(m_source.toLocalFile());
- parentTexture()->setInternalFormat(img.hasAlphaChannel() ?
- Texture::RGBA8_UNorm :
- Texture::RGB8_UNorm);
-
- parentTexture()->setFromQImage(img);
} else {
qWarning() << "implement loading from remote URLs";
}
@@ -85,7 +91,7 @@ void Quick3DTexture::setSource(QUrl arg)
void Quick3DTexture::setRectangle(bool r)
{
parentTexture()->setTarget(r ? Texture::TargetRectangle :
- Texture::Target2D);
+ Texture::Target2D);
}
bool Quick3DTexture::isRectangle() const
diff --git a/src/render/backend/qgraphicscontext.cpp b/src/render/backend/qgraphicscontext.cpp
index 9210d8b72..15a80d225 100644
--- a/src/render/backend/qgraphicscontext.cpp
+++ b/src/render/backend/qgraphicscontext.cpp
@@ -49,7 +49,8 @@
#include "parameter.h"
#include "drawstate.h"
#include "qgraphicshelperinterface.h"
-
+#include "renderer.h"
+#include "texturemanager.h"
#include "renderlogging.h"
#include <QOpenGLShaderProgram>
@@ -265,7 +266,7 @@ int QGraphicsContext::activateTexture(TextureScope scope, RenderTexture *tex, in
int err = glGetError();
if (err)
qCWarning(Backend) << "GL error after activating texture" << QString::number(err, 16)
- << tex->textureId() << "on unit" << onUnit;
+ << tex->textureId() << "on unit" << onUnit;
m_textureScores[tex] = 200;
m_pinnedTextureUnits[onUnit] = true;
@@ -475,13 +476,32 @@ QOpenGLShaderProgram* QGraphicsContext::activeShader()
return m_shaderHash[m_activeShader];
}
+void QGraphicsContext::setRenderer(Renderer *renderer)
+{
+ m_renderer = renderer;
+}
+
// It will be easier if the QGraphicContext applies the QUniformPack
// than the other way around
void QGraphicsContext::setUniforms(const QUniformPack &uniforms)
{
// Activate textures and update TextureUniform in the pack
// with the correct textureUnit
+ deactivateTexturesWithScope(TextureScopeMaterial);
+ QHash<QString, const QUniformValue *> uniformValues = uniforms.uniforms();
+ Q_FOREACH (const QUniformPack::NamedTexture &namedTex, uniforms.textures()) {
+ RenderTexture *t = m_renderer->textureManager()->lookupResource(namedTex.texId);
+ int texUnit = -1;
+ const TextureUniform *texUniform = Q_NULLPTR;
+ // TO DO : Rework the way textures are loaded
+ if (t != Q_NULLPTR &&
+ (texUnit = activateTexture(TextureScopeMaterial, t)) != -1 &&
+ uniformValues.contains(namedTex.glslName) &&
+ (texUniform = static_cast<const TextureUniform *>(uniformValues[namedTex.glslName])) != Q_NULLPTR) {
+ const_cast<TextureUniform *>(texUniform)->setTextureUnit(texUnit);
+ }
+ }
m_activeShader->updateUniforms(uniforms);
}
diff --git a/src/render/backend/qgraphicscontext.h b/src/render/backend/qgraphicscontext.h
index 992dd9d1c..241d32d5f 100644
--- a/src/render/backend/qgraphicscontext.h
+++ b/src/render/backend/qgraphicscontext.h
@@ -60,6 +60,7 @@ class QAbstractOpenGLFunctions;
namespace Qt3D {
namespace Render {
+class Renderer;
class QGraphicsHelperInterface;
class DrawStateSet;
class RenderShader;
@@ -117,6 +118,8 @@ public:
*/
QOpenGLShaderProgram* activeShader();
+ void setRenderer(Renderer *renderer);
+
void specifyAttribute(QString nm, AttributePtr attr);
void specifyIndices(AttributePtr attr);
@@ -191,6 +194,8 @@ private:
DrawStateSet* m_stateSet;
+ Renderer *m_renderer;
+
};
} // Render
diff --git a/src/render/backend/quniformvalue.h b/src/render/backend/quniformvalue.h
index a462595a6..82df74dc0 100644
--- a/src/render/backend/quniformvalue.h
+++ b/src/render/backend/quniformvalue.h
@@ -191,27 +191,26 @@ public:
~QUniformPack();
void setUniform(QString glslName, const QUniformValue *val);
-
void setTexture(QString glslName, const QUuid &id);
const QHash<QString, const QUniformValue* > &uniforms() const { return m_uniforms; }
-private:
- QHash<QString, const QUniformValue* > m_uniforms;
-
struct NamedTexture {
- NamedTexture() : location(-1) {}
-
+ NamedTexture() {}
NamedTexture(QString nm, const QUuid &t) :
glslName(nm),
texId(t)
{ }
QString glslName;
- int location;
QUuid texId;
};
+ QVector<NamedTexture> textures() const { return m_textures; }
+
+private:
+ QHash<QString, const QUniformValue* > m_uniforms;
+
QVector<NamedTexture> m_textures;
};
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index bd753429b..7e18a1d51 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -350,6 +350,7 @@ void Renderer::submitRenderViews()
m_graphicsContext = new QGraphicsContext;
QOpenGLContext* ctx = new QOpenGLContext;
m_graphicsContext->setSurface(m_surface);
+ m_graphicsContext->setRenderer(this);
QSurfaceFormat sf = m_surface->format();
ctx->setFormat(sf);
if (!ctx->create())
diff --git a/src/render/backend/renderview.cpp b/src/render/backend/renderview.cpp
index 416a30855..c61944d70 100644
--- a/src/render/backend/renderview.cpp
+++ b/src/render/backend/renderview.cpp
@@ -422,7 +422,9 @@ void RenderView::setShaderAndUniforms(RenderCommand *command, RenderRenderPass *
if (binding->bindingType() == ParameterMapper::Uniform) {
QVariant value = parameters.take(binding->parameterName());
Texture *tex = Q_NULLPTR;
- if (value.type() == QVariant::UserType && (tex = value.value<Qt3D::Texture*>()) != Q_NULLPTR) {
+ if (static_cast<QMetaType::Type>(value.type()) == QMetaType::QObjectStar &&
+ (tex = value.value<Qt3D::Texture*>()) != Q_NULLPTR) {
+ createRenderTexture(tex);
command->m_uniforms.setTexture(binding->shaderVariableName(), tex->uuid());
command->m_uniforms.setUniform(binding->shaderVariableName(), new TextureUniform(tex->uuid()));
}
diff --git a/src/render/frontend/texture.cpp b/src/render/frontend/texture.cpp
index 6157588b5..19ffd2731 100644
--- a/src/render/frontend/texture.cpp
+++ b/src/render/frontend/texture.cpp
@@ -204,9 +204,9 @@ bool Texture::setFromQImage(QImage img, int layer)
Q_D(Texture);
setSize(img.width(), img.height());
- if ((d->m_target != QOpenGLTexture::Target2D) &&
- (d->m_target != QOpenGLTexture::Target2DArray) &&
- (d->m_target == QOpenGLTexture::TargetRectangle))
+ if ((d->m_target != Target2D) &&
+ (d->m_target != Target2DArray) &&
+ (d->m_target == TargetRectangle))
{
qWarning() << Q_FUNC_INFO << "invalid texture target";
setStatus(Error);