簡體   English   中英

我的精靈在紋理 opengl 之間切換

[英]my sprites are switching between textures opengl

我正在使用 glDrawElements 繪制所有在緩沖區中的精靈。 為了告訴精靈在片段着色器中使用什么紋理,我有統一的 sampler2D 紋理 [32]; 每個頂點都有一個索引,它從頂點着色器傳遞給片段着色器:

color = texture(textures[index], fs_in.uv);

當我嘗試使用超過 1 個激活的紋理繪制我的精靈時,它會在右上角獲得錯誤的紋理

http://puu.sh/lyr5j/d8c2cf6c8f.png

我不知道為什么會發生這種情況 嘗試過紋理參數

我似乎找不到任何遇到類似問題的人。

這是我的渲染器的 init 函數(我有意將 texid 作為 float 傳遞,因為我聽說 int 不能正常工作(也嘗試過))

glGenBuffers(1, &m_VDBO); glGenVertexArrays(1, &m_VAO);

        glBindVertexArray(m_VAO);
        glBindBuffer(GL_ARRAY_BUFFER, m_VDBO);
        glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);

        glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
        glEnableVertexAttribArray(SHADER_UV_INDEX);
        glEnableVertexAttribArray(SHADER_COLOR_INDEX);
        glEnableVertexAttribArray(SHADER_TEXID_INDEX);

        glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::vertex));
        glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::uv));
        glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::color));
        glVertexAttribPointer(SHADER_TEXID_INDEX, 1, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *)offsetof(VertexData, VertexData::texID));

        glBindBuffer(GL_ARRAY_BUFFER, 0);

        const GLushort modelindices[] = { 0, 1, 2, 2, 3, 0 };
        GLuint indices[RENDERER_INDICES_SIZE];

        for (int i = 0; i < RENDERER_INDICES_SIZE; i += 6)
        {
            for (int o = 0; o < 6; o++)
            {
                indices[i + o] = modelindices[o] + (i / 6 * 4);
            }
        }

        glGenBuffers(1, &m_IBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, RENDERER_INDICES_SIZE * sizeof(GLuint), indices, GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        glBindVertexArray(0);

沖洗功能

            glBindVertexArray(m_VAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);

        for (int i = 0; i < m_TextureSlots.size(); i++)
        {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, m_TextureSlots[i]);
        }

        glDrawElements(GL_TRIANGLES, m_IndexCount, GL_UNSIGNED_INT, 0);

        m_TextureSlots.clear();
        m_IndexCount = 0;

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);

我很難看出您的問題來自哪里,我唯一能建議的是查看我擁有的 Image2d 類對象構造函數。 現在,我的源依賴於外部類,例如嚴重依賴模板類型的ShaderManager類、 Batch類和BatchManager類以將頂點發送到視頻卡。 這個Image2d也是一個繼承對象。 但是,這可能有助於您跟蹤自己的問題。 根據所使用的 OpenGL 和 GLSL 版本,不同版本的實現有兩種不同的構造函數。 如果我沒記錯的話,版本 2 使用 BatchManager 將頂點發送到視頻卡,而版本 1 沒有在render()方法中看到。

Image2d v1.0

// ----------------------------------------------------------------------------
// Image2d()
Image2d::Image2d( float fWidth, float fHeight, TextureInfo::FilterQuality filterQuality, bool generateMipMap, const std::string& strTextureFilename, const std::string& strId ) :
VisualMko( glm::uvec2(), strId ),
m_vboTexture( 0 ),
m_vboPosition( 0 ),
m_vboIndices( 0 ),
m_vao( 0 ) {

    if ( fWidth <= 0 || fHeight <= 0 ) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " Invalid image size (" << fWidth << "," << fHeight << ") must be more then 0 in each dimension.";
        throw ExceptionHandler( strStream );
    }

    // Save TextureId
    TextureFileReader textureFileReader( strTextureFilename );
    m_textureInfo = textureFileReader.getOrCreateTextureInfo( filterQuality, generateMipMap, false );

    // Define Texture Co-Ordinates
    std::vector<float> vTextureCoordinates;
    vTextureCoordinates.push_back( 0.0f );
    vTextureCoordinates.push_back( 1.0f );

    vTextureCoordinates.push_back( 0 );
    vTextureCoordinates.push_back( 0 );

    vTextureCoordinates.push_back( 1.0f );
    vTextureCoordinates.push_back( 1.0f );

    vTextureCoordinates.push_back( 1.0f );
    vTextureCoordinates.push_back( 0 );

    // Define Vertex Positions (x,y,z)
    std::vector<float> vVertexPositions;
    vVertexPositions.push_back( 0 );
    vVertexPositions.push_back( fHeight );
    vVertexPositions.push_back( 0 );

    vVertexPositions.push_back( 0 );
    vVertexPositions.push_back( 0 );
    vVertexPositions.push_back( 0 );

    vVertexPositions.push_back( fWidth );
    vVertexPositions.push_back( fHeight );
    vVertexPositions.push_back( 0 );

    vVertexPositions.push_back( fWidth );
    vVertexPositions.push_back( 0 );
    vVertexPositions.push_back( 0 );

    // Define 2 Triangle Faces
    std::vector<unsigned char> vIndices;
    vIndices.push_back( 0 );
    vIndices.push_back( 1 );
    vIndices.push_back( 2 );
    vIndices.push_back( 3 );

    // Create Vertex Array Object
    glGenVertexArrays( 1, &m_vao );
    glBindVertexArray( m_vao ); // Start Array

    m_pShaderManager->setAttribute( A_COLOR, COLOR_WHITE );

    // Create Position Buffer And Store On Video Card
    glGenBuffers( 1, & m_vboPosition );
    glBindBuffer( GL_ARRAY_BUFFER, m_vboPosition );
    glBufferData( GL_ARRAY_BUFFER, vVertexPositions.size() * sizeof( vVertexPositions[0] ), &vVertexPositions[0], GL_STATIC_DRAW );
    m_pShaderManager->enableAttribute( A_POSITION );

    // Create Texture Coordinate Buffer
    glGenBuffers( 1, &m_vboTexture );
    glBindBuffer( GL_ARRAY_BUFFER, m_vboTexture );
    glBufferData( GL_ARRAY_BUFFER, vTextureCoordinates.size() * sizeof( vTextureCoordinates[0] ), &vTextureCoordinates[0], GL_STATIC_DRAW );
    m_pShaderManager->enableAttribute( A_TEXTURE_COORD0 );

    // Create Index Buffer
    glGenBuffers( 1, &m_vboIndices );
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_vboIndices );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, vIndices.size() * sizeof( vIndices[0] ), &vIndices[0], GL_STATIC_DRAW );

    glBindVertexArray( 0 ); // Stop Array

    // Disable Attribute Pointers
    m_pShaderManager->disableAttribute( A_POSITION );
    m_pShaderManager->disableAttribute( A_TEXTURE_COORD0 );

    // THIS MUST BE AFTER Vertex Array Buffer Is Unbound!
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); // Stop Buffer Index
    glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Stop Buffer

    // We have a Valid Image2d Save Filename
    m_strFilename = strTextureFilename;

} // Image2D - v1.0

Image2D - v2.0

// ----------------------------------------------------------------------------
// Image2d()
Image2d::Image2d( const glm::uvec2& origin, const glm::uvec2& size, const std::string& strTextureFilename, const std::string& strId ) :
VisualMko( size, strId ),
m_vboTexture( 0 ),
m_vboPosition( 0 ),
m_vboIndices( 0 ),
m_vao( 0 ) {

    m_version = 2;

    TextureFileReader textureFileReader( strTextureFilename );
    m_textureInfo = textureFileReader.getOrCreateTextureInfo( TextureInfo::FILTER_NONE, false, false );
    m_config.uTextureId = m_textureInfo.uTextureId;

    if ( 0 == m_textureInfo.size.x || 0 == m_textureInfo.size.y ) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << "size of " << strTextureFilename << " is invalid " << m_textureInfo.size;
        throw ExceptionHandler( strStream );
    }

    // Verify Image Fits Inside Texture
    if ( m_textureInfo.size.x < size.x + origin.x || m_textureInfo.size.y < size.y + origin.y ) {
        std::ostringstream strStream;
        strStream << __FUNCTION__ << " " << strTextureFilename << " size is " << m_textureInfo.size
            << " which is too small for an image that is " << size
            << " pixels in size, with an origin point set at " << origin ;
        throw ExceptionHandler( strStream );
    }

    glm::vec2 textureCoordScaleFactor( 1.0f / static_cast<float>( m_textureInfo.size.x ),
        1.0f / static_cast<float>( m_textureInfo.size.y ) );

    glm::vec2 textureCoordBottomLeft = glm::vec2( textureCoordScaleFactor.x * origin.x,
                                                  textureCoordScaleFactor.y * ( m_textureInfo.size.y - origin.y - size.y ) );
    glm::vec2 textureCoordTopRight   = glm::vec2( textureCoordScaleFactor.x * ( origin.x + size.x ),
                                                  textureCoordScaleFactor.y * ( m_textureInfo.size.y - origin.y ) );

    // Set Colors And Texture Coordinates (Position Will Be Updated In Render Function)
    m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordBottomLeft.x, textureCoordTopRight.y ) ) );
    m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordBottomLeft.x, textureCoordBottomLeft.y ) ) );
    m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordTopRight.x,   textureCoordTopRight.y ) ) );
    m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordTopRight.x,   textureCoordBottomLeft.y ) ) );

} // Image2d - v2.0

這是我的render()方法

// ----------------------------------------------------------------------------
// render()
void Image2d::render() {
    if ( 1 == m_version ) {
        m_pShaderManager->setTexture( 0, U_TEXTURE0_SAMPLER_2D, m_textureInfo.uTextureId );

        glBindVertexArray( m_vao );
        glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, nullptr );
        glBindVertexArray( 0 );
    } else {
        // Version 2.0
        // Update Vertices
        if ( m_transformMatrix.updateTranslation || m_transformMatrix.updateScale || m_transformMatrix.updateRotation ) {
            m_transformMatrix.updateTranslation = m_transformMatrix.updateScale = m_transformMatrix.updateRotation = false;

            // Order Of Operations Matter Here!
            glm::mat4 matrix; // Identity

            if ( m_transformMatrix.hasTranslation ) {
                matrix[3][0] = m_transformMatrix.translation.x;
                matrix[3][1] = m_transformMatrix.translation.y;
            }

            if ( m_transformMatrix.hasRotation ) {
                matrix = glm::rotate( matrix, m_transformMatrix.fRotationAngleRadians, glm::vec3( 0.0f, 0.0f, -1.0f ) );
            }

            if ( m_transformMatrix.hasScale ) {
                matrix = matrix * glm::mat4( m_transformMatrix.scale.x,                       0.0f, 0.0f, 0.0f,
                                                                   0.0f, m_transformMatrix.scale.y, 0.0f, 0.0f,
                                                                   0.0f,                      0.0f, 1.0f, 0.0f,
                                                                   0.0f,                      0.0f, 0.0f, 1.0f );
            }

            // Center Offset
            if ( m_offsetPosition.x != 0 || m_offsetPosition.y != 0 ) {
                matrix = glm::translate( matrix, glm::vec3( -m_offsetPosition.x, -m_offsetPosition.y, 0.0f ) );
            }

            // Apply Transformation To All 4 Vertices
            m_vVertices[0].position = glm::vec2( matrix * glm::vec4(        0,        0, 0, 1.0f ) );
            m_vVertices[1].position = glm::vec2( matrix * glm::vec4(        0, m_size.y, 0, 1.0f ) );
            m_vVertices[2].position = glm::vec2( matrix * glm::vec4( m_size.x,        0, 0, 1.0f ) );
            m_vVertices[3].position = glm::vec2( matrix * glm::vec4( m_size.x, m_size.y, 0, 1.0f ) );
        }
        renderBatch();
    }
} // render

確保您在glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);中指定的大小glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW); 是准確的。 還要確保在適當的時間停止 VertexArray 並禁用屬性指針。 您綁定的所有內容都必須是未綁定的,對於某些類型,訂單確實很重要!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM