gpt4 book ai didi

c++ - 现代 OpenGL 问题纹理平面

转载 作者:搜寻专家 更新时间:2023-10-31 02:20:28 24 4
gpt4 key购买 nike

我一直难以为我制作的飞机制作纹理。平面上的第一个四边形纹理正确,但平面的其余部分似乎只使用纹理的第一个像素,所以它最终都是纯色。如果我制作一架巨大的飞机并对其进行纹理处理,它似乎可以正常工作,但是当我尝试将飞机分成几部分时,我一直遇到这个问题。我假设就坐标而言我遗漏了一些东西,但根据我的理解,我认为它们总是应该在 0 和 1 之间?感谢您的帮助。

[![在此处输入图片描述][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);
}

最佳答案

这里的问题是,纹理坐标只提供给第一个四边形(前 6 个顶点)。所有其他顶点似乎都得到 [0,0],这导致它们只读取左上角的纹素。这里的解决方案是为所有顶点提供足够的纹理坐标。

纹理坐标通常不一定在 0 和 1 之间。可以通过设置 GL_TEXTURE_WRAP_[RST] 指定如何处理 [0,1] 之外的值。

请注意,当 OpenGL 尝试读取缓冲区外的数据时,在 VBO 中没有提供足够的数据会导致崩溃(取决于驱动程序)。

关于c++ - 现代 OpenGL 问题纹理平面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32689194/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com