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. Issues with VBO to texture tiles on a grid
QtWS25 Last Chance

Issues with VBO to texture tiles on a grid

Scheduled Pinned Locked Moved Unsolved Game Development
openglc++ qt5 gui
1 Posts 1 Posters 279 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.
  • C Offline
    C Offline
    Cixi25
    wrote on 7 Nov 2023, 21:53 last edited by
    #1

    Hello everyone, i've got an issue using Qt 5, C++ and OepnGL. I'm using instanced drawing to draw a tiles grid on my window. To assign the correct texture on each tile, I use a VBO with divisor to send one value for each tile instance. But i've got trouble with initializing my VBO, and more troubles modifying it with glMapBufferRange. Her is my code and some explanations:

    // Method called after initializeGL() to set VAO and VBO. My VBO is here  filled with 0, which corresponds in my Fragment Shader to a green color. 
    // I tried to change the binding index to 5 (here and in my Vertex Shader of course) just to test, some issues are resolved but others appears... it seems strange
    void MainWindow::loadVAO_VBO()
    {
        makeCurrent();
    
        // VAO / VBO
        QVector<GLuint> texIndex;
        for ( uint i=0;i<m_numberOfTiles;++i )
            texIndex.append(0);
        glGenVertexArrays(1, &m_vaoID);
        glBindVertexArray(m_vaoID);
    
            glCreateBuffers(1, &m_vboID);
            glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
            glVertexAttribDivisor(0, 1);
    
            glNamedBufferStorage(m_vboID,
                                 m_numberOfTiles * sizeof(GLuint),
                                 texIndex.constData(),
                                 GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
            glVertexArrayAttribFormat(m_vaoID,
                                      0, // Attrib Index
                                      1,
                                      GL_UNSIGNED_INT,
                                      GL_FALSE,
                                      0);
            glVertexArrayAttribBinding(m_vaoID,
                                       0, // Attrib Index
                                       0); // Binding Index
            glVertexArrayVertexBuffer(m_vaoID,
                                      0, // Binding Index
                                      m_vboID,
                                      (GLintptr)0,
                                      sizeof(GLuint));
            glEnableVertexAttribArray(0); // Binding Index
    
            glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        glBindVertexArray(0);
    }
    
    // When user clicks on a tile on the screen, I change 0 to 1 in the VBO,  so the Fragment Shader will change the green color to a texture. 
    void MainWindow::mousePressEvent(QMouseEvent *e)
    {
        if ( e->buttons() & Qt::LeftButton )
        {
            // here I get back the index of the value I want to modify in my  VBO. No error here
            uint index = getTileIndex(m_overflewTile);
    
    
            // VERTICES VBO
            makeCurrent();
    
            glFinish();
            glBindBuffer(GL_ARRAY_BUFFER, m_vboID);
    
            // We get back the good pointer in our VBO
            void *data = glMapNamedBufferRange(m_vboID, // id
                                               index * sizeof(GLuint), // offset
                                               sizeof(GLuint), // size
                                               GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); // flags
    
            // We convert data in uint
            GLuint *buffer = (GLuint*)data;
            qDebug() << *buffer; // no error here, i get 0 or 1 when expected
    
            // We modify the value in the VBO
            *buffer = 1;
            //m_tilesMap[m_overflewTile] = 1;
    
            glUnmapNamedBuffer(m_vboID);
    
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
    
        update();
    }
    

    And here are my 2 shaders:

    // VERTEX SHADER
    #version 450
    
    
    layout (location = 0) uniform float screenWidth;// In pixel
    layout (location = 1) uniform float screenHeight;// In pixel
    layout (location = 2) uniform float rectsSize; // In pixel
    
    // Here is my attrib index 0 the VBO uses. It will be used in Fragment Shader to texture the fragment
    layout (location = 0) in uint vs_in_texType;
    
    out vec2 texCoord;
    out uint vs_out_texType;
    
    
    void main()
    {
        vec3 origin = vec3(1.0, -1.0, 0.0);
        float rectW = 2.0*rectsSize / screenWidth;
        float rectH = rectW * screenWidth/screenHeight; // to make squares
    
        vec3[4] vertices = vec3[4](vec3(  0.0, -rectH, 0.0) - origin,
                                   vec3(rectW, -rectH, 0.0) - origin,
                                   vec3(rectW,    0.0, 0.0) - origin,
                                   vec3(  0.0,    0.0, 0.0) - origin);
        vec2[4] texCoords = vec2[4](vec2(0.0, 1.0),
                                    vec2(1.0, 1.0),
                                    vec2(1.0, 0.0),
                                    vec2(0.0, 0.0));
    
        uint i = 0;
        if ( gl_VertexID <= 2 )
        {
            i = gl_VertexID;
        }
        else if ( gl_VertexID == 3 )
        {
            i = 0;
        }
        else if ( gl_VertexID == 4 )
        {
            i = 2;
        }
        else if ( gl_VertexID == 5 )
        {
            i = 3;
        }
    
    
        uint rectsInARow = uint(screenWidth) / uint(rectsSize);
        float xOffset = (gl_InstanceID % rectsInARow) * rectW;
        float yOffset = (gl_InstanceID / rectsInARow) * rectH;
        vec3 offset = vec3(xOffset, -yOffset, 0.0);
    
        texCoord = texCoords[i];
        vs_out_texType = vs_in_texType; // We simply pass it to the Fragment Shader
    
        gl_Position = vec4(vertices[i] + offset, 1.0);
    }
    
    // FRAGMENT SHADER
    #version 450
    
    // I only have one texture but it contains several seamless textures in it
    layout (binding = 0) uniform sampler2D textu;
    
    in vec2 texCoord;
    flat in uint vs_out_texType; // Here we get our 0 or 1 from Vertex Shader
    
    out vec4 color;
    
    
    void main()
    {
        if (vs_out_texType == 0)
            color = vec4(0.3, 0.7, 0.4, 1.0); // green color
        else if (vs_out_texType == 1)
            color = texture(textu, vec2(texCoord.x / 6.0, texCoord.y / 3.0)); // Texture
        //else // if (vs_out_texture == 0)
            //color = vec4(0.3, 0.7, 0.4, 1.0);
    }
    

    When I click on a tile, it correctly changes my value in the VBO to 1, but the value once arrived in the Vertex Shader seems to be more than 1000 000 000 (I made some tests !).
    If someone can help me with this I'd be very grateful !
    Thanks, Cixi

    1 Reply Last reply
    0

    1/1

    7 Nov 2023, 21:53

    • Login

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