I have been having difficulty texturing a plane I made. The first quad on the plane is textured properly, but the rest of the plane then only seems to use the first pixel of the texture so it all ends up as a solid color. It seems to work properly if I make one giant plane and just texture that, but when I try to break up the plane into sections I keep getting this issue. I’m assuming I am missing something as far as the coordinates go, but from my understanding I thought they were always supposed to be between 0 and 1? Any help is appreciated.
[![enter image description here][1]][1]
Texture coordinates
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
};
Setting up 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;
}
Rendering
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);
}
Vertex shader
#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;
}
Fragment shader
#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);
}