【问题标题】:OpenGL solid color displayed instead of textureOpenGL纯色显示而不是纹理
【发布时间】:2013-12-18 15:25:47
【问题描述】:

因此,我查看了本网站和其他网站中的所有类似问题,但我未能找到我的纹理无法加载的原因。我确信纹理被正确读取,但是,它只是没有正确应用。这是我的代码:

获取纹理:

 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

我已经解决了最后一个问题,读者正在阅读作为图像一部分的端线,因此所有内容都转移到了下一种颜色。谢谢大家的帮助。

【问题讨论】:

  • 如果更改 tree_trunk.pbm 图像,树的颜色会改变吗?以确保文件本身已加载并在着色器中使用)。此外,尝试更改片段着色器以显示 uv,以确保正确设置 texCoord:gl_FragColor = vec4(texCoord.x, texCoord.y, 1.0, 1.0);
  • 图片变化时颜色变化。当我按照您的建议更改碎片颜色时,一切都变成了蓝色。所以,不知何故,我猜想所有的 u,v 都设置为 0.0、0.0 或者没有创建纹理坐标。如何确保坐标设置正确?
  • 您是否尝试过从着色器中移除未使用的“顶点”和“法线”属性?

标签: c++ opengl mapping textures


【解决方案1】:

我很惊讶这段代码没有导致崩溃,sizeof (vec2) * 90 是您在第二次调用 glBufferSubData (...) 时应该使用的,因为纹理坐标数组中的浮点组件数是组件数的一半在您的顶点位置数组中。当您用数据填充缓冲区时,您将超出 VBO 的存储空间和客户端内存中的纹理坐标数组。

sizeof (treeTexCoords) 绝对不是您想要的,因为您已经动态分配了该数组!虽然您可以使用sizeof (...) 来获取静态大小数组的大小,但如果您尝试使用指向由new 分配的内存的指针来执行此操作,您将得到的只是指针本身的大小。因此,sizeof (treeTexCoords) 在您的系统上可能是 4 或 8。

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 的末尾,而不是超出它。

根据treeVertices 的声明方式,可能存在其他问题 - 您可以编辑您的问题以显示treeVertices 的声明吗?我假设它类似于std::vector &lt;GLfloat&gt;。

【讨论】:

  • 是的,我昨天意识到这个问题并修复了它,是的,treeVertices 是一个矢量,我将发布我现在得到的图像,也许我阅读图像实际上有问题。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
相关资源
最近更新 更多