2015-09-21 72 views
2

我一直在難以紋理我製作的飛機。平面上的第一個四邊形紋理正確,但平面的其餘部分似乎只使用紋理的第一個像素,所以最終都以純色爲單位。如果我製造一架巨型飛機,並且只是製造質感,它似乎能夠正常工作,但是當我試圖將飛機分割成幾部分時,我一直都會遇到這個問題。我假設我錯過了座標去的東西,但從我的理解中我認爲他們總是應該在0到1之間?任何幫助表示讚賞。現代OpenGL問題紋理平面

[![在這裏輸入的形象描述] [1] [1]

紋理座標

GLfloat grassTexCoords[] 
{ 
    0.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 0.0f, 
    1.0f, 0.0f, 
    0.0f, 1.0f, 
    1.0f, 1.0f 
}; 

設置VAO

GLuint makePlane() 
{ 
    float size = 5; 
    for (int i = -5; i < 5; ++i) 
    { 
     for (int j = -5; j < 5; ++j) 
     { 
      verts.push_back({ glm::vec3((i * size), -11.f, (j * size)) }); 
      verts.push_back({ glm::vec3((i * size), -11.f, (j * size) + size) }); 
      verts.push_back({ glm::vec3((i * size) + size, -11.f, (j * size)) }); 

      verts.push_back({ glm::vec3((i * size) + size, -11.f, (j * size)) }); 
      verts.push_back({ glm::vec3((i * size), -11.f, (j * size) + size) }); 
      verts.push_back({ glm::vec3((i * size) + size, -11.f, (j * size) + size) }); 
     } 
    } 

    GLuint vbo; 
    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(VertexPos), verts.data(), GL_STATIC_DRAW); 

    GLuint vboTex; 
    glGenBuffers(1, &vboTex); 
    glBindBuffer(GL_ARRAY_BUFFER, vboTex); 
    glBufferData(GL_ARRAY_BUFFER, 2 * 6 * sizeof(GLfloat), &grassTexCoords, GL_STATIC_DRAW); 

    GLuint vao; 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 

    glEnableVertexAttribArray(1); 
    glBindBuffer(GL_ARRAY_BUFFER, vboTex); 
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL); 

    return vao; 
} 

渲染

void render() 
{ 
    glViewport(0, 0, window.getSize().x, window.getSize().y); 
    glClearColor(.4f, .4f, .4f, 1.f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    //1st program 
    glUseProgram(sphereProgram); 
    glEnable(GL_CULL_FACE); 
    glEnable(GL_DEPTH_TEST); 
    glBindVertexArray(vao); 
    glDrawArrays(GL_TRIANGLES, 0, objPointCount); 

    //2nd program 
    glFrontFace(GL_CCW); 
    glDepthMask(GL_FALSE); 
    glUseProgram(cubeProgram); 
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID); 
    glBindVertexArray(cubeVao); 
    glDrawArrays(GL_TRIANGLES, 0, 36); 
    glDepthMask(GL_TRUE); 

    //3rd program 
    glFrontFace(GL_CCW); 
    glDisable(GL_CULL_FACE); 
    glEnable(GL_TEXTURE_2D); 
    sf::Texture::bind(&grassTex); 
    glUseProgram(planeProgram); 
    glBindVertexArray(planeVao); 
    glDrawArrays(GL_TRIANGLES, 0, verts.size()); 
    //----------------------- 

    window.display(); 
    //window.setFramerateLimit(FPS); 
    window.setVerticalSyncEnabled(true); 
} 

頂點着色器

#version 410 

layout (location = 0) in vec3 vertexPos; 
layout (location = 1) in vec2 texCoords; 

uniform mat4 view, proj; 

out vec3 posEye; 
out vec2 coords; 

void main() 
{ 
    coords = texCoords; //repeat texture over plane 
    gl_Position = proj * view * vec4(vertexPos, 1.0); 

    posEye = (view * vec4(vertexPos, 1.0)).xyz; 
} 

片段着色器

#version 410 

in vec3 posEye; 
in vec2 coords; 
out vec4 fragColor; 

uniform sampler2D tex; 

//fog 
const vec3 fogColor = vec3(0.2, 0.2, 0.2); 
const float minFogRad = 300; 
const float maxFogRad = 900; 

void main() 
{ 
    vec4 texture = texture2D(tex, coords); 
    fragColor = texture; 

    float distance = length(-posEye); 
    float fogFactor = (distance - minFogRad)/(maxFogRad - minFogRad); 
    fogFactor = clamp(fogFactor, 0.0, 1.0); 

    fragColor.rgb = mix(fragColor.rgb, fogColor, fogFactor); 
} 
+0

它看起來像你試圖張貼圖像附件。你能再試一次嗎?這可能會幫助其他人更容易回答問題。 –

回答

1

就是,紋理座標爲第四隻是供給(前6個頂點)這裏的問題。所有其他頂點似乎都會得到[0,0],這使得它們只能讀取左上角的紋理元素。這裏的解決方案是爲所有頂點提供足夠的紋理座標。

紋理座標一般不一定在0和1之間。可以通過設置GL_TEXTURE_WRAP_[RST]來指定如何處理[0,1]以外的值。

請注意,在VBO中不提供足夠的數據可能導致OpenGL嘗試讀取緩衝區外時發生崩潰(取決於驅動程序)。

1

您正在使用GL_ARRAY_BUFFER,它存儲每個頂點數據的

的和GL_FLOAT論點glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);聲明瞭,你有2個漂浮在vboTex每個頂點但是你有沒有這樣做,你有2漂浮在每個頂點在第一隻四

以同樣的方式,和GL_FLOAT論點glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);聲明瞭,你有vbo3輛彩車每個頂點你做的事。

最簡單的解決方法是創建一個更大的GL_ARRAY_BUFFER,它爲每個四邊形重複相同的紋理座標。