c++ - OpenGL,纹理输出为纯色

标签 c++ opengl textures terrain

我试图对我的地形进行纹理处理,但它似乎要么采用纹理的平均颜色,要么从纹理中选取一种颜色并在所有地方使用它。我看过其他解决方案,但它们对我没有帮助。我是新手所以这可能是一个简单的错误

纹理是从 SOIL2 生成的

生成纹理

int texID = SOIL_load_OGL_texture(
    filename.c_str(),
    SOIL_LOAD_AUTO,
    SOIL_CREATE_NEW_ID,
    SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
    );

生成 UV 坐标(删除了对我的问题不重要的内容)

int i=0;
for (int z = 0; z < m_Size; z++) // loop through columns
{
    for (int x = 0; x < m_Size; x++) // loop through rows
    {
        model.mesh.uvs[i] = Math::Vector2(x / m_Size, z / m_Size); //Terrain is square
        i++;
    }

创建纹理缓冲区

if (model->mesh.numOfUVs != 0)
{
    glGenBuffers(1, &model->textureBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, model->textureBufferID);
    glBufferData(GL_ARRAY_BUFFER, model->mesh.numOfUVs * sizeof(Math::Vector2), model->mesh.uvs, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Math::Vector2), (void*)(0));     
}

绘制地形(非完整代码)

            glBindVertexArray(ID);

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, model->textureID1);
            unsigned int textureLocation = glGetUniformLocation(shaderID, "grassTex");
            glUniform1i(textureLocation, 0);

            glUniformMatrix4fv(glGetUniformLocation(shaderID, "MVP"), 1, false, &newMVP.mat[0][0]);

            glDrawElements(GL_TRIANGLES, model->mesh.numOfIndices, GL_UNSIGNED_INT, (void*)0);


            glBindVertexArray(0);

垂直着色器

#version 330 core

layout(location = 0) in vec2 texturecoord;

uniform mat4 MVP;

out vec2 texcoord;

void main(){
    texcoord = texturecoord;
    gl_Position = MVP * vec4(in_position, 1);
}

片段着色器

#version 330 core

layout(location = 0) out vec4 out_colour;

in vec2 texcoord;
uniform sampler2D grassTex;

void main()
{
    out_colour = texture2D(grassTex, texcoord);
}

如果有些事情没有意义,那可能是因为我删除了很多代码以尝试减少我发布的代码量

它看起来像什么(图片中有 3 个纹理,但我删除了这篇文章中的代码,因为我认为它与我使用的纹理数量没有任何关系) https://imgur.com/a/rSPp7Ru

最佳答案

问题是整数除法。当你除以整数时,你得到一个整数。这是您生成 UV 坐标的地方。

for (int z = 0; z < m_Size; z++) // loop through columns
{
    for (int x = 0; x < m_Size; x++) // loop through rows
    {
        model.mesh.uvs[i] = Math::Vector2(x / m_Size, z / m_Size); //Terrain is square
        i++;
    }
}

xz 总是小于 m_Size。这意味着 x/m_Sizez/m_Size 始终是 0 因为您不能将 0.2 存储在整数。由于所有 UV 坐标都是 0, 0,因此您只能看到整个三角形中纹理的一个角(我认为是左下角)。

要解决此问题,请将其中一个操作数转换为 floatdouble

model.mesh.uvs[i] = Math::Vector2(
  static_cast<float>(x) / m_Size, 
  static_cast<float>(z) / m_Size
);

如果将 float 除以 intint 将提升为 float,因此 float 将执行除法。

关于c++ - OpenGL,纹理输出为纯色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55770999/

相关文章:

c++ - 在两个不同的顶点数组对象中使用顶点缓冲区

OpenGL 填充多边形颜色 "bleeding"

opengl - GPU 驱动程序如何解释 GLSL 的 "coherent"内存限定符以进行多 channel 渲染?

javascript - TextureLoader 中的 onLoad 不起作用?

c++ - OpenWatcom/VisualStudio 在重新调用约定方面的互操作性

c++ - 将输出帧保存为图像文件 CUDA 解码器

c++ - 如何使 [std::operator""s] 在命名空间中可见?

opengl - 计算四边形的顶点法线

没有颜色的Opengl纹理渲染

c++ - 访问冲突错误 - ucrtbased.dll