2015-11-25 48 views
-1

我正在使用glDrawElements繪製所有在緩衝區中的精靈。 爲了讓精靈知道片段着色器中的紋理,我使用了統一的sampler2D紋理[32];每個頂點有一個指標,這是傳遞給片段着色器從頂點着色器:我的小精靈之間切換紋理opengl

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

當我嘗試畫我的精靈擁有超過1質感積極它得到了錯誤的紋理右上角

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

我不知道爲什麼會這樣嘗試紋理參數

我似乎無法找到任何人誰也有類似的問題。

這是我的渲染器的初始化函數(我purposly傳遞texid爲float,因爲我已經聽到整數起不到很好的(也試過))

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); 
+1

你的代碼是未定義的行爲。採樣器陣列在OpenGL中很特別。您不能使用從頂點屬性派生的非統一表達式作爲索引。我已經在[這個答案]中詳細解釋了這個問題(http://stackoverflow.com/questions/27972661/glsl-data-distortion/27973129#27973129)。 – derhass

回答

0

這是我很難看到你的問題是從,我可以建議的唯一的事情正在看一個Image2d類對象的構造函數,我來了。現在,我的源代碼取決於外部類,如ShaderManager類嚴重依賴模板類型,Batch類和BatchManager類將頂點發送到視頻卡。此Image2d也是一個繼承對象。但是,這可能會有助於您追蹤自己的問題。對於不同版本的實現,有兩種不同的構造函數,具體取決於正在使用哪種版本的OpenGL和GLSL。如果我沒有記錯的話,版本2使用BatchManager將頂點發送到版本1不支持的視頻卡,在render()方法中可以看到版本1。

Image2d 1.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 - 2.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); 上做準確。還要確保在適當的時候停止VertexArray並禁用屬性指針。你綁定的所有東西都必須解除綁定,對於某些類型,Order很重要!