summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@nokia.com>2011-04-20 12:37:21 +0200
committerYoann Lopes <yoann.lopes@nokia.com>2011-04-20 12:37:21 +0200
commit45e88bbb6940e07d7cfb6658db0429dd3732185f (patch)
treea1b2feafca51f7c2064ddb197e4be9bc18abb88c
parentfa925f30817c8da3b0bcdee4ff0a64ddddd14ad5 (diff)
Properly save and restore Ogre GL state.
-rw-r--r--ogreitem.cpp1
-rw-r--r--ogrenode.cpp86
-rw-r--r--ogrenode.h15
-rw-r--r--resources/GrassandSky.jpgbin0 -> 345001 bytes
-rw-r--r--resources/example.qml70
5 files changed, 143 insertions, 29 deletions
diff --git a/ogreitem.cpp b/ogreitem.cpp
index a527366..30f47d4 100644
--- a/ogreitem.cpp
+++ b/ogreitem.cpp
@@ -44,6 +44,7 @@ QSGNode *OgreItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
node = new OgreNode();
node->setSize(QSize(width(), height()));
+ node->setAAEnabled(smooth());
node->update();
m_camera = static_cast<QObject *>(node->camera());
diff --git a/ogrenode.cpp b/ogrenode.cpp
index be6df62..467bd53 100644
--- a/ogrenode.cpp
+++ b/ogrenode.cpp
@@ -1,4 +1,6 @@
#include <OGRE/RenderSystems/GL/OgreGLTexture.h>
+#include <OGRE/RenderSystems/GL/OgreGLFrameBufferObject.h>
+#include <OGRE/RenderSystems/GL/OgreGLFBORenderTexture.h>
#include "ogrenode.h"
#include "cameranodeobject.h"
@@ -27,8 +29,12 @@ OgreNode::OgreNode()
: QSGGeometryNode()
, m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
, m_texture(0)
+ , m_samples(0)
+ , m_AAEnabled(false)
+ , m_renderTexture(0)
+ , m_ogreFBO(0)
, m_initialized(false)
- , m_dirtySize(false)
+ , m_dirtyFBO(false)
{
setMaterial(&m_materialO);
setOpaqueMaterial(&m_material);
@@ -955,38 +961,66 @@ static void printGLState()
qDebug() << "============";
}
-void OgreNode::preprocess()
+void OgreNode::saveOgreState()
{
- glPopAttrib();
- const QGLContext *ctx = QGLContext::currentContext();
- ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 2);
- ctx->functions()->glUseProgram(0);
+ m_ogreFBO = getOgreFBO();
- m_renderTexture->update(false);
+ const QGLContext *ctx = QGLContext::currentContext();
glPushAttrib(GL_ALL_ATTRIB_BITS);
-
ctx->functions()->glBindBuffer(GL_ARRAY_BUFFER, 0);
ctx->functions()->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
ctx->functions()->glBindRenderbuffer(GL_RENDERBUFFER, 0);
ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}
+void OgreNode::restoreOgreState()
+{
+ const QGLContext *ctx = QGLContext::currentContext();
+ glPopAttrib();
+ ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_ogreFBO);
+ ctx->functions()->glUseProgram(0);
+}
+
+GLuint OgreNode::getOgreFBO()
+{
+ if (!m_renderTexture)
+ return 0;
+
+ Ogre::GLFrameBufferObject *ogreFbo = 0;
+ m_renderTexture->getCustomAttribute("FBO", &ogreFbo);
+ Ogre::GLFBOManager *manager = ogreFbo->getManager();
+ manager->bind(m_renderTexture);
+
+ GLint id;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &id);
+
+ const QGLContext *ctx = QGLContext::currentContext();
+ ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+
+ return id;
+}
+
+void OgreNode::preprocess()
+{
+ restoreOgreState();
+ m_renderTexture->update(true);
+ saveOgreState();
+}
+
void OgreNode::update()
{
+ restoreOgreState();
+
if (!m_initialized)
init();
- if (m_dirtySize)
- updateSize();
+ if (m_dirtyFBO)
+ updateFBO();
- const QGLContext *ctx = QGLContext::currentContext();
- ctx->functions()->glBindBuffer(GL_ARRAY_BUFFER, 0);
- ctx->functions()->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- ctx->functions()->glBindRenderbuffer(GL_RENDERBUFFER, 0);
- ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ saveOgreState();
}
-void OgreNode::updateSize()
+void OgreNode::updateFBO()
{
if (m_renderTexture)
Ogre::TextureManager::getSingleton().remove("RttTex");
@@ -998,7 +1032,8 @@ void OgreNode::updateSize()
m_size.height(),
0,
Ogre::PF_R8G8B8A8,
- Ogre::TU_RENDERTARGET);
+ Ogre::TU_RENDERTARGET, 0, false,
+ m_AAEnabled ? m_samples : 0);
m_renderTexture = rtt_texture->getBuffer()->getRenderTarget();
@@ -1014,7 +1049,6 @@ void OgreNode::updateSize()
QRectF(0, 0, m_size.width(), m_size.height()),
QRectF(0, 0, 1, 1));
-
Ogre::GLTexture *nativeTexture = static_cast<Ogre::GLTexture *>(rtt_texture.get());
delete m_texture;
@@ -1033,12 +1067,26 @@ void OgreNode::setSize(const QSize &size)
return;
m_size = size;
- m_dirtySize = true;
+ m_dirtyFBO = true;
markDirty(DirtyGeometry);
}
+void OgreNode::setAAEnabled(bool enable)
+{
+ if (m_AAEnabled == enable)
+ return;
+
+ m_AAEnabled = enable;
+ m_dirtyFBO = true;
+ markDirty(DirtyMaterial);
+}
+
void OgreNode::init()
{
+ const QGLContext *ctx = QGLContext::currentContext();
+ QGLFormat format = ctx->format();
+ m_samples = format.sampleBuffers() ? format.samples() : 0;
+
m_root = new Ogre::Root;
m_root->loadPlugin(Ogre::String(OGRE_PLUGIN_DIR) + "/RenderSystem_GL");
diff --git a/ogrenode.h b/ogrenode.h
index 5da7c66..83cb63a 100644
--- a/ogrenode.h
+++ b/ogrenode.h
@@ -31,13 +31,20 @@ public:
void setSize(const QSize &size);
QSize size() const { return m_size; }
+ void setAAEnabled(bool enable);
+
CameraNodeObject *camera() const { return m_cameraObject; }
void update();
- void updateSize();
+ void updateFBO();
void init();
+ GLuint getOgreFBO();
+
+ void saveOgreState();
+ void restoreOgreState();
+
void preprocess();
private:
@@ -46,6 +53,8 @@ private:
QSGGeometry m_geometry;
QSGPlainTexture *m_texture;
+ int m_samples;
+ bool m_AAEnabled;
QSize m_size;
Ogre::Root *m_root;
@@ -56,10 +65,12 @@ private:
Ogre::TexturePtr rtt_texture;
Ogre::RenderWindow *m_window;
+ GLuint m_ogreFBO;
+
CameraNodeObject *m_cameraObject;
bool m_initialized;
- bool m_dirtySize;
+ bool m_dirtyFBO;
};
#endif // OGRENODE_H
diff --git a/resources/GrassandSky.jpg b/resources/GrassandSky.jpg
new file mode 100644
index 0000000..95f7991
--- /dev/null
+++ b/resources/GrassandSky.jpg
Binary files differ
diff --git a/resources/example.qml b/resources/example.qml
index c7be670..87603ee 100644
--- a/resources/example.qml
+++ b/resources/example.qml
@@ -5,15 +5,14 @@ Rectangle {
id: ogre
width: 1024
height: 768
- gradient: Gradient {
- GradientStop { position: 0.0; color: "#000000" }
- GradientStop { position: 0.40; color: "#232323" }
- GradientStop { position: 0.55; color: "#232323" }
- GradientStop { position: 0.85; color: "#000000" }
- GradientStop { position: 1.0; color: "#000000" }
- }
-
+ color: "black"
+ Image {
+ id: back
+ anchors.fill: parent
+ source: "GrassandSky.jpg"
+ Behavior on opacity { NumberAnimation { } }
+ }
OgreItem {
id: ogreitem
@@ -43,10 +42,19 @@ Rectangle {
}
PropertyChanges {
+ target: toolbar4
+ anchors.top: ogreitem.top
+ anchors.topMargin: 5
+ }
+ PropertyChanges {
target: toolbar3
anchors.top: ogreitem.top
anchors.topMargin: 5
}
+ PropertyChanges {
+ target: back
+ opacity: 0
+ }
}
]
}
@@ -152,6 +160,52 @@ Rectangle {
}
Rectangle {
+ id: toolbar4
+ width: 25
+ height: 25
+ radius: 5
+ gradient: Gradient {
+ GradientStop {
+ position: 0
+ color: "#c83e3e3e"
+ }
+
+ GradientStop {
+ position: 1
+ color: "#c8919191"
+ }
+ }
+ anchors.top: toolbar1.top
+ anchors.right: toolbar3.left
+ anchors.rightMargin: 6
+ border.color: "#1a1a1a"
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: { ogreitem.smooth = !ogreitem.smooth }
+ }
+
+ Text {
+ anchors.fill: parent
+ text: "AA"
+ font.bold: true
+ font.pixelSize: parent.height * 0.55
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+
+ Rectangle {
+ height: parent.height
+ width: 2
+ anchors.centerIn: parent
+ color: "#BB1111"
+ rotation: 40
+ visible: !ogreitem.smooth
+ }
+ }
+ border.width: 2
+ }
+
+ Rectangle {
id: toolbar3
width: 25
height: 25