簡體   English   中英

顯示OpenGL純色而不是紋理

[英]OpenGL solid color displayed instead of texture

因此,我查看了本網站和其他網站中的所有類似問題,但未能找到答案為什么我的紋理無法加載。 我確定紋理可以正確讀取,但是,只是沒有正確應用它。 這是我的代碼:

獲取紋理:

 glGenTextures(NumTextures, textures);

glActiveTexture( GL_TEXTURE0 );

// load and bind tree texture
readPPM6("textures/tree_trunk.pbm", treeTex);

glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB,
    GL_UNSIGNED_BYTE, treeTex);

綁定對象:

// VAO[Tree]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vElements[TreeE]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*treeIndices.size(), treeIndices.data(), GL_STATIC_DRAW);

glBindVertexArray(vArrays[TreeA]);
glBindBuffer(GL_ARRAY_BUFFER, vBuffers[TreeB]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*treeVertices.size() + sizeof(vec2) * 90, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat)*treeVertices.size(), treeVertices.data());
glBufferSubData(GL_ARRAY_BUFFER, sizeof(GLfloat)*treeVertices.size(), sizeof(vec2)*90,
    treeTexCoords);
glUseProgram( texture );
vPosition = glGetAttribLocation( texture, "vPosition" );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(vPosition);
vTexCoord = glGetAttribLocation( texture, "vTexCoord" );
glVertexAttribPointer( vTexCoord, 2, GL_FLOAT, GL_FALSE, 0,
    (const void*) ((sizeof(GLfloat) * treeVertices.size())));
glEnableVertexAttribArray( vTexCoord ); 
glUniform1i(glGetUniformLocation(texture, "texture"), 0);
glBindVertexArray(0);

繪制樹:

glUseProgram(texture);

proj_loc = glGetUniformLocation(texture, "projection");
model_view_loc = glGetUniformLocation(texture, "modelview");
glUniformMatrix4fv(proj_loc, 1, GL_TRUE, projmat);
glUniformMatrix4fv(model_view_loc, 1, GL_TRUE, modelmat);

glEnable(GL_PRIMITIVE_RESTART);
glPrimitiveRestartIndex(0xFFFF);

glBindVertexArray(vArrays[TreeA]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vElements[TreeE]);

glEnable(GL_TEXTURE_2D);    

glActiveTexture( GL_TEXTURE0 ); 

glBindTexture(GL_TEXTURE_2D, textures[0]);
glDrawElements(GL_TRIANGLE_STRIP, treeIndices.size(), GL_UNSIGNED_SHORT, NULL);

glDisable(GL_PRIMITIVE_RESTART);
glDisable(GL_TEXTURE_2D);

glUseProgram(0);
glBindVertexArray(0);

樹的創建方式:

getCylinderVertices(treeVertices, 10.0, 3.0, 10);
getCylinderIndices(treeIndices, 10);

getConeVertices(treeVertices, 10.0, 15.0, 6.0, 10);
for (int i = 0; i < 10; i++)
{
    treeIndices.push_back(60+i*3);
    treeIndices.push_back(60+i*3+1);
    treeIndices.push_back(60+i*3+2);
    treeIndices.push_back(0xFFFF);
}

treeTexCoords = new vec2[90];
for (int i = 0; i < 10; i++)
{
    treeTexCoords[i*6] = vec2(0.0, 0.0);
    treeTexCoords[i*6+1] = vec2(0.0, 0.2);
    treeTexCoords[i*6+2] = vec2(0.0, 0.0);
    treeTexCoords[i*6+3] = vec2(1.0, 0.2);
    treeTexCoords[i*6+4] = vec2(1.0, 0.0);
    treeTexCoords[i*6+5] = vec2(0.0, 0.0);
}

for (int i = 0; i < 30; i++)
{
    treeTexCoords[60+i] = vec2(0.0,0.0);
}

頂點着色器:

    #version 330 core

attribute vec4 vPosition;
uniform mat4 projection;
uniform mat4 modelview;

attribute vec4 vertex;
attribute vec3 normal;
attribute vec2 vTexCoord;

out vec2 texCoord;

void main() 
{ 
    texCoord    = vTexCoord;
    gl_Position = projection*modelview*vPosition;
}

片段着色器:

 #version 330 core

in  vec2 texCoord;

uniform sampler2D texture;

void main() 
{ 
    gl_FragColor = texture2D(texture, texCoord);
}

解決緩沖區子數據分配問題后,這是當前樹的外觀: http : //i.imgur.com/dMBq9xN.jpg

供參考,這是我正在使用的圖像: http : //i.imgur.com/QuuQQ5i.jpg

我已經解決了最后一個問題,讀者正在閱讀作為圖像一部分的終點線,因此一切都轉移到了下一種顏色。 謝謝大家的幫助。

我很驚訝這段代碼不會導致崩潰, sizeof (vec2) * 90是您在第二次調用glBufferSubData (...)應該使用的值,因為紋理坐標數組中的浮點分量的數量是頂點位置數組中的組件數。 當您用數據填充緩沖區時,您將同時超過VBO的存儲空間和客戶端內存中的紋理坐標數組。

sizeof (treeTexCoords)絕對不是您想要的,因為您已經動態分配了該數組! 如果嘗試使用指向分配有new內存的指針來執行大小調整操作,則可以使用sizeof (...)來獲取靜態大小的數組的大小,但您得到的只是指針本身的大小。 因此,您的系統上的sizeof (treeTexCoords)可能是48

glBindVertexArray (vArrays [TreeA]);
glBindBuffer      (GL_ARRAY_BUFFER, vBuffers [TreeB]);

//
// @CORRECTION #1
//
glBufferData      (GL_ARRAY_BUFFER, sizeof (GLfloat) * treeVertices.size () + 
                                    sizeof (vec2)    * 90,
                                        NULL, GL_STATIC_DRAW);
glBufferSubData   (GL_ARRAY_BUFFER, 0,
                                    sizeof (GLfloat) * treeVertices.size (),
                                        treeVertices.data ());
//
// @CORRECTION #2
//
glBufferSubData   (GL_ARRAY_BUFFER, sizeof (GLfloat) * treeVertices.size (), 
                                    sizeof (vec2)    * 90,
                                        treeTexCoords);

修正#1分配了適當的存儲量(而不是所有頂點+ 1指針的足夠存儲量)。

更正#2只能讀取到treeTexCoords的末尾,而不是treeTexCoords它。

根據treeVertices的聲明方式,可能還會有其他問題-您可以編輯問題以顯示treeVertices的聲明嗎? 我假設它像std::vector <GLfloat>

暫無
暫無

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

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