Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. How to creating a skybox using samplerCube and the QOpenGLTexture class?
QtWS25 Last Chance

How to creating a skybox using samplerCube and the QOpenGLTexture class?

Scheduled Pinned Locked Moved Game Development
4 Posts 3 Posters 6.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    felet
    wrote on 5 Mar 2014, 14:08 last edited by
    #1

    Hi, I'm trying to create a skybox using the samplerCube mapping in the shader program. As I understand it, it should be possible to use the coordinates of the skybox vertices for mapping the texture to the skybox. I would like to do this using the QOpenGLTexture class.

    Does any one know how to setup the QOpenGLTexture to use samplerCube mapping? I would like to use a texture that looks like this one: http://www.keithlantz.net/wp-content/uploads/2011/10/skybox_texture.jpg (from http://www.keithlantz.net/2011/10/rendering-a-skybox-using-a-cube-map-with-opengl-and-glsl/) Guess I should use QOpenGLTexture::BindingTargetCubeMap somehow(?).

    Here is a short example program where I try to implement a skybox:

    main.cpp
    @
    int main(int argc, char **argv)
    {
    QGuiApplication app(argc, argv);
    // Setup OpenGL window
    OpenGLWindow window;
    return app.exec();
    }
    @

    OpenGLWindow.hpp
    @
    #include "Skybox.hpp"

    class OpenGLWindow : public QWindow, protected QOpenGLFunctions
    {
    Q_OBJECT

    Skybox* m_skybox;
    bool m_update_pending;
    bool m_animating;

    QOpenGLContext *m_context;
    QOpenGLShaderProgram m_program;

    QMatrix4x4 m_projectionMatrix;

    QOpenGLVertexArrayObject m_vao;

    public:
    explicit OpenGLWindow(QWindow *parent = 0)
    : QWindow(parent)
    , m_update_pending(false)
    , m_animating(true)
    , m_context(0)
    {
    setSurfaceType(OpenGLSurface);
    QSurfaceFormat format;
    format.setDepthBufferSize(24);
    format.setMajorVersion(3);
    format.setMinorVersion(3);
    format.setProfile(QSurfaceFormat::CoreProfile);
    setFormat(format);
    resize(640, 480);
    show();
    create();

    m_context = new QOpenGLContext(this);
    m_context->setFormat(format);
    m_context->create();
    m_context->makeCurrent(this);

    initializeOpenGLFunctions();

    m_vao.create();
    m_vao.bind();

    m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, "simple.vert");
    m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, "simple.frag");
    m_program.link()

    m_skybox = new Skybox(m_program);

    m_projectionMatrix.setToIdentity();
    m_projectionMatrix.perspective(90.0f, 640.0f/480.0f, 0.1f, 30.0f);

    glViewport(0, 0, width(), height());
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    }

    void render()
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_CULL_FACE);

    m_program.bind();

    glDisable(GL_DEPTH_TEST);
    // Set camera position
    QMatrix4x4 viewMatrix;
    viewMatrix.setToIdentity();
    QVector3D eye(0.0f, 0.0f, 0.0f);
    QVector3D center(1.0f, 1.0f, 1.0f);
    QVector3D up(0.0f, 1.0f, 0.0f);
    viewMatrix.lookAt(eye, center, up);

    // Render skybox
    m_skybox->draw(viewMatrix, m_projectionMatrix);

    glEnable(GL_DEPTH_TEST);

    // Render other stuff .....
    }

    void setAnimating(bool animating)
    {
    m_animating = animating;

    if (animating)
    renderLater();
    }

    public slots:
    void renderLater()
    {
    if (!m_update_pending)
    {
    m_update_pending = true;
    QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
    }
    }

    void renderNow()
    {
    if (!isExposed())
    return;

    m_context->makeCurrent(this);

    render();

    m_context->swapBuffers(this);

    if (m_animating)
    renderLater();
    }

    protected:
    bool event(QEvent *event)
    {
    switch (event->type()) {
    case QEvent::UpdateRequest:
    m_update_pending = false;
    renderNow();
    return true;
    default:
    return QWindow::event(event);
    }
    }
    void exposeEvent(QExposeEvent *event)
    {
    Q_UNUSED(event);

    if (isExposed())
    renderNow();
    }
    };
    @

    Skybox.hpp
    @
    #define NUMB_VER 36

    class Skybox
    {
    private:
    static QOpenGLBuffer m_vertexPositionBuffer;
    static const GLfloat m_vertices[NUMB_VER*3];
    QOpenGLShaderProgram& m_program;
    QOpenGLTexture m_texture;

    public:
    ~Skybox(){};

    explicit Skybox(QOpenGLShaderProgram& program)
    : m_program(program)
    , m_texture(QImage(QString("skybox_texture.jpg")).mirrored())
    {
    m_vertexPositionBuffer.create();
    m_vertexPositionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    m_vertexPositionBuffer.bind();
    m_vertexPositionBuffer.allocate(m_vertices, NUMB_VER3sizeof(GLfloat));

    m_texture.setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
    m_texture.setMagnificationFilter(QOpenGLTexture::Linear);
    }

    inline void draw(const QMatrix4x4& viewMatrix, const QMatrix4x4& projectionMatrix)
    {
    // Remove translates but keep rotations of the camera
    QMatrix4x4 modelViewMatrix = viewMatrix;
    modelViewMatrix.setColumn(3, QVector4D(0.0f, 0.0f, 0.0f, 1.0f));

    const QMatrix3x3 normalMatrix = modelViewMatrix.normalMatrix();
    const QMatrix4x4 mvp = projectionMatrix * modelViewMatrix;

    m_program.bind();
    m_program.setUniformValue("modelViewMatrix", modelViewMatrix);
    m_program.setUniformValue("normalMatrix", normalMatrix);
    m_program.setUniformValue("projectionMatrix", projectionMatrix);
    m_program.setUniformValue("mvp", mvp);

    m_vertexPositionBuffer.bind();
    m_program.enableAttributeArray("vertexPosition");
    m_program.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3);

    m_texture.bind();

    glDrawArrays(GL_TRIANGLES, 0, NUMB_VER);
    }
    };
    @

    Skybox.cpp
    @
    #include "Skybox.hpp"

    QOpenGLBuffer Skybox::m_vertexPositionBuffer;

    const GLfloat Skybox::m_vertices[NUMB_VER*3] =
    {
    -1.0f, 1.0f, -1.0f,
    -1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,
    1.0f, 1.0f, -1.0f,
    -1.0f, 1.0f, -1.0f,

    -1.0f, -1.0f, 1.0f,
    -1.0f, -1.0f, -1.0f,
    -1.0f, 1.0f, -1.0f,
    -1.0f, 1.0f, -1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, -1.0f, 1.0f,

    1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,

    -1.0f, -1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, -1.0f, 1.0f,
    -1.0f, -1.0f, 1.0f,

    -1.0f, 1.0f, -1.0f,
    1.0f, 1.0f, -1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, -1.0f,

    -1.0f, -1.0f, -1.0f,
    -1.0f, -1.0f, 1.0f,
    1.0f, -1.0f, -1.0f,
    1.0f, -1.0f, -1.0f,
    -1.0f, -1.0f, 1.0f,
    1.0f, -1.0f, 1.0f
    };
    @

    Thanks in advance!

    1 Reply Last reply
    0
    • F Offline
      F Offline
      felet
      wrote on 5 Mar 2014, 14:11 last edited by
      #2

      ... and here are the shader programs

      simple.vert
      @
      #version 330

      in vec3 vertexPosition;

      uniform mat4 modelViewMatrix;
      uniform mat4 normalMatrix;
      uniform mat4 projectionMatrix;
      uniform mat4 mvp;

      //uniform sampler2D texUnit1;
      uniform samplerCube texUnit1;

      out vec3 position;

      void main()
      {
      position = vertexPosition;

      gl_Position = mvp*vec4(vertexPosition, 1.0);
      }
      @

      simple.frag
      @
      #version 330

      in vec3 position;

      //uniform sampler2D texUnit1;
      uniform samplerCube texUnit1;

      out vec4 gl_Color;

      void main()
      {
      gl_Color = texture(texUnit1, position);
      }
      @

      1 Reply Last reply
      0
      • M Offline
        M Offline
        minimoog77
        wrote on 10 Mar 2014, 09:30 last edited by
        #3

        You need to use manual upload of each cube face using:

        http://qt-project.org/doc/qt-5/qopengltexture.html#setData

        1 Reply Last reply
        0
        • A Offline
          A Offline
          Angioedema
          wrote on 23 Dec 2015, 15:03 last edited by
          #4

          Hi,

          Do you find a way to use it ? I tried it, but impossible I have a read access violation ... Could you please send an example ?

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved