#include "DefaultCubemapSceneContent.h" const QString DefaultCubemapSceneContent::g_scene_name=QObject::tr("Cubemap"); /** * Default constructor * */ DefaultCubemapSceneContent::DefaultCubemapSceneContent(SceneInterface* plugin): SceneContent(plugin) { for (unsigned int i=0; i<6; ++i) m_textureIndex[i] = 0; } /** * Destructor. * */ DefaultCubemapSceneContent::~DefaultCubemapSceneContent() { for (unsigned int i=0; i<6; ++i) if (glIsTexture(m_textureIndex[i])) glDeleteTextures(1, &m_textureIndex[i]); } /** * Implements the copy from other contents. * * This method is used by the copy constructor. * * @param content The source content to copy from. * * @return true if the copy is ok, false otherwise. The copy can fail if * SceneContent is not a DefaultCubemapSceneContent. * * @seealso is_equal_to * */ bool DefaultCubemapSceneContent::copy_from(const SceneContent& data) { if (!SceneContent::copy_from(data)) return false; Q_ASSERT(NULL!=plugin()); Q_ASSERT(NULL!=data.plugin()); const DefaultCubemapSceneContent& _data = static_cast(data); setTexture (CUBEMAP_FACE_FRONT, _data.getTexture(CUBEMAP_FACE_FRONT)); setTexture (CUBEMAP_FACE_BACK, _data.getTexture(CUBEMAP_FACE_BACK)); setTexture (CUBEMAP_FACE_LEFT, _data.getTexture(CUBEMAP_FACE_LEFT)); setTexture (CUBEMAP_FACE_RIGHT, _data.getTexture(CUBEMAP_FACE_RIGHT)); setTexture (CUBEMAP_FACE_TOP, _data.getTexture(CUBEMAP_FACE_TOP)); setTexture (CUBEMAP_FACE_BOTTOM, _data.getTexture(CUBEMAP_FACE_BOTTOM)); return true; } /** * Implements the egality-test with other contents. * * This could be an operator==. * * @param content The content to compare with. * * @return true if the content are equal, false otherwise. The test can * fail if the contents have different parameters, but also it * SceneContent is not a DefaultCubemapSceneContent. * * @seealso copy_from * */ bool DefaultCubemapSceneContent::is_equal_to(const SceneContent& data) const { if (!SceneContent::is_equal_to(data)) return false; const DefaultCubemapSceneContent& _data = static_cast(data); return getTexture(CUBEMAP_FACE_FRONT) ==_data.getTexture(CUBEMAP_FACE_FRONT) && getTexture(CUBEMAP_FACE_BACK) ==_data.getTexture(CUBEMAP_FACE_BACK) && getTexture(CUBEMAP_FACE_LEFT) ==_data.getTexture(CUBEMAP_FACE_LEFT) && getTexture(CUBEMAP_FACE_RIGHT) ==_data.getTexture(CUBEMAP_FACE_RIGHT) && getTexture(CUBEMAP_FACE_TOP) ==_data.getTexture(CUBEMAP_FACE_TOP) && getTexture(CUBEMAP_FACE_BOTTOM)==_data.getTexture(CUBEMAP_FACE_BOTTOM); } /** * Draws the cubemap. * * @param glWidget The QGLWidget that own the OpenGL context. * @param cameraMatrix The camera matrix that must be use. * */ void DefaultCubemapSceneContent::draw(QGLWidget* glWidget, const float* cameraMatrix) { Q_UNUSED(cameraMatrix); glPushMatrix(); glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); for (unsigned int i=0; i<6; ++i) { if (!glIsTexture(m_textureIndex[i]) && !m_textureFileNames[i].isEmpty()) { m_textureIndex[i] = glWidget->bindTexture(m_textureFileNames[i]); } } glBindTexture(GL_TEXTURE_2D, m_textureIndex[(int)CUBEMAP_FACE_FRONT]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MAX); glVertex3f(-SIZE, -SIZE, -SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MAX); glVertex3f( SIZE, -SIZE, -SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MIN); glVertex3f(-SIZE, SIZE, -SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MIN); glVertex3f( SIZE, SIZE, -SIZE); glEnd(); glBindTexture(GL_TEXTURE_2D, m_textureIndex[(int)CUBEMAP_FACE_BACK]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MAX); glVertex3f(-SIZE, -SIZE, SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MIN); glVertex3f(-SIZE, SIZE, SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MAX); glVertex3f( SIZE, -SIZE, SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MIN); glVertex3f( SIZE, SIZE, SIZE); glEnd(); glBindTexture(GL_TEXTURE_2D, m_textureIndex[(int)CUBEMAP_FACE_LEFT]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MAX); glVertex3f(-SIZE, -SIZE, -SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MAX); glVertex3f(-SIZE, -SIZE, SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MIN); glVertex3f(-SIZE, SIZE, -SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MIN); glVertex3f(-SIZE, SIZE, SIZE); glEnd(); glBindTexture(GL_TEXTURE_2D, m_textureIndex[(int)CUBEMAP_FACE_RIGHT]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MAX); glVertex3f( SIZE, -SIZE, -SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MIN); glVertex3f( SIZE, SIZE, -SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MAX); glVertex3f( SIZE, -SIZE, SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MIN); glVertex3f( SIZE, SIZE, SIZE); glEnd(); glBindTexture(GL_TEXTURE_2D, m_textureIndex[(int)CUBEMAP_FACE_TOP]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MAX); glVertex3f(-SIZE, SIZE, -SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MAX); glVertex3f( SIZE, SIZE, -SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MIN); glVertex3f(-SIZE, SIZE, SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MIN); glVertex3f( SIZE, SIZE, SIZE); glEnd(); glBindTexture(GL_TEXTURE_2D, m_textureIndex[(int)CUBEMAP_FACE_BOTTOM]); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MIN); glVertex3f(-SIZE, -SIZE, -SIZE); glTexCoord2f(TEXCOORD_MIN, TEXCOORD_MAX); glVertex3f(-SIZE, -SIZE, SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MIN); glVertex3f( SIZE, -SIZE, -SIZE); glTexCoord2f(TEXCOORD_MAX, TEXCOORD_MAX); glVertex3f( SIZE, -SIZE, SIZE); glEnd(); glPopAttrib(); glPopMatrix(); } /** * Sets the name of the texture for a face of the cubemap. * * @param face The face of which we want to set the name of the texture. * @param fileName The new name of the texture. * */ void DefaultCubemapSceneContent::setTexture(CUBEMAP_FACE face, const QString& fileName) { if ((int)face < 0 || (int)face > 5) return; if (m_textureFileNames[(int)face] == fileName) return; if (glIsTexture(m_textureIndex[(int)face])) glDeleteTextures(1, &m_textureIndex[(int)face]); m_textureIndex[(int)face] = 0; m_textureFileNames[(int)face] = fileName; } /** * Gets the name of the texture for a face. * * @param face The face of which we want to know the name of the texture. * * @return A QString with the name of the texture. * */ QString DefaultCubemapSceneContent::getTexture(CUBEMAP_FACE face) const { if ((int)face < 0 || (int)face > 5) return QString::null; return m_textureFileNames[(int)face]; } /** * Loads the cubemap from a QDomElement. * * @param element The QDomElement to read from. * */ void DefaultCubemapSceneContent::initFromDOMElement(const QDomElement& element) { if (!element.isNull()) { SceneContent::initFromDOMElement(element); QDomElement texture = element.firstChildElement("texture"); while (!texture.isNull()) { if (texture.attribute("face") == "front") setTexture(CUBEMAP_FACE_FRONT, texture.attribute("fileName")); else if (texture.attribute("face") == "back") setTexture(CUBEMAP_FACE_BACK, texture.attribute("fileName")); else if (texture.attribute("face") == "left") setTexture(CUBEMAP_FACE_LEFT, texture.attribute("fileName")); else if (texture.attribute("face") == "right") setTexture(CUBEMAP_FACE_RIGHT, texture.attribute("fileName")); else if (texture.attribute("face") == "top") setTexture(CUBEMAP_FACE_TOP, texture.attribute("fileName")); else if (texture.attribute("face") == "bottom") setTexture(CUBEMAP_FACE_BOTTOM, texture.attribute("fileName")); texture = texture.nextSiblingElement("texture"); } } } /** * Writes the cubemap in a QDomDocument. * * @param name The name of the element. * @param doc The document whom belongs the element. * * @return The QDomElement to add. * */ QDomElement DefaultCubemapSceneContent::domElement(const QString& name, QDomDocument& doc) const { QDomElement de = SceneContent::domElement(name, doc); for (unsigned int i=0; i<6; ++i) { QDomElement texture = doc.createElement("texture"); switch (i) { case 0: texture.setAttribute("face", "front"); break; case 1: texture.setAttribute("face", "back"); break; case 2: texture.setAttribute("face", "left"); break; case 3: texture.setAttribute("face", "right"); break; case 4: texture.setAttribute("face", "top"); break; case 5: texture.setAttribute("face", "bottom"); break; } texture.setAttribute("fileName", m_textureFileNames[i]); de.appendChild(texture); } return de; }