[英]OpenGL texture issue on plane drawn using glDrawArrays()
我正在嘗試將紋理應用於由使用 glDrawArrays() 繪制的 6 個頂點組成的平面。繪制的第一個三角形似乎繪制正確,但第二個三角形的紋理似乎沒有正確對齊並且看起來被壓扁了。 我在嘗試使用 glDrawElements() 使用索引緩沖區進行繪制時也遇到了同樣的問題。
我的頂點數組 Object 創建看起來像這樣
// Position and Color data
GLfloat verts[] = {
// Vertex Positions // Colors (r,g,b,a) //Texture Coordinates
-5, -1, 5, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // front left vertex
-5, -1, -5, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // back left vertex
5, -1, 5, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, // front right vertex
-5, -1, -5, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // back left vertex
5, -1, -5, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,// back right vertex
5, -1, 5, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f // front right vertex
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
const GLuint floatsPerUV = 2;
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glBindVertexArray(mesh.vao);
// Create buffer: for the vertex data
glGenBuffers(1, &mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
// Strides between vertex coordinates is 9 (x, y, z, r, g, b, a). A tightly packed stride is 0.
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor + floatsPerUV);// The number of floats before each
mesh.nVertices = 6;
// Create Vertex Attribute Pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * (floatsPerVertex + floatsPerColor)));
glEnableVertexAttribArray(2);
我的頂點和片段着色器是:
// Vertex Shader source code
const GLchar* vertexShaderSource = GLSL(440,
layout(location = 0) in vec3 position; // Vertex data from Vertex Attrib Pointer 0
layout(location = 1) in vec4 color; // Color data from Vertex Attrib Pointer 1
layout(location = 2) in vec2 textureCoordinate; // Texture cooridnates from vertex attirb pointer 2
out vec4 vertexColor; // Variable to transfer color data to the fragment shader
out vec2 vertexTextureCoordinate; // Varible to transfer texture coordinates to fragment shaders
// Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f); // Transforms vertices to clip coordinates
vertexColor = color; // References incoming color data
vertexTextureCoordinate = textureCoordinate; // references income texture data
}
);
// Fragment Shader Source Code
const GLchar* fragmentShaderSource = GLSL(440,
in vec4 vertexColor; // Variable to hold incoming color data from vertex shader
in vec2 vertexTextureCoordinate;
out vec4 fragmentColor;
uniform sampler2D uTexture;
void main()
{
fragmentColor = texture(uTexture, vertexTextureCoordinate); // sends texture to GPU for rendering
}
);
這是我的渲染 function 中的代碼(我已經將代碼剪切到我繪制平面和變量設置的位置:
// Enable z-depth
glEnable(GL_DEPTH_TEST);
// Clear the frame and z buffers
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
// Scales object
glm::mat4 scale = glm::scale(glm::vec3(1.0f, 1.0f, 1.0f));
// Rotate shape
glm::mat4 rotation = glm::rotate(45.0f, glm::vec3(1.0f, 1.0f, 0.0f));
// Place object at x, y, z
glm::mat4 translation = glm::translate(glm::vec3(-1.0f, 0.0f, 0.0f));
// Model matrix: transformations are applied right-to-left order
glm::mat4 model = translation * rotation * scale;
// Transforms the camera: move the camera back (z axis)
glm::mat4 view = gCamera.GetViewMatrix();
glm::mat4 projection;
// Create perspective projection
if (!perspectiveSwitch)
{
projection = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);
}
else
{
projection = glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, 0.1f, 100.0f);
}
// Select shader program to be used
glUseProgram(gProgramId);
// Retrives and passes transfrom matrices to the shader program
GLint modelLoc = glGetUniformLocation(gProgramId, "model");
GLint viewLoc = glGetUniformLocation(gProgramId, "view");
GLint projLoc = glGetUniformLocation(gProgramId, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
// Object remains same size
scale = glm::scale(glm::vec3(1.0f, 1.0f, 1.0f));
// object remains unrotated
rotation = glm::rotate(0.0f, glm::vec3(1.0f, 1.0f, 1.0f));
// Place object at the origin
translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));
// Model matrix: transformations are applied right-to-left order
model = translation * rotation * scale;
//Send updated model information for next object
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
// Activate the VBO contained within the mesh's VAO
glBindVertexArray(gPlane.vao);
// Bind texture for draw
glBindTexture(GL_TEXTURE_2D, tableTexture);
//Draws the triangles
glDrawArrays(GL_TRIANGLES, 0, gPlane.nVertices);
// Deactivate the Vertex Array Object
glBindVertexArray(0);
// glfw: swap buffers and poll IO events
glfwSwapBuffers(gWindow); // Flips the back buffer with the front buffer
這是我渲染的 object 應用了紋理后的樣子和紋理的原始圖像。
(我似乎無法在帖子中添加多張圖片,所以我不得不鏈接其中一張)
發現我在我的屬性指針中為值的數量傳遞了錯誤的值。
我不小心傳入了顏色屬性值的數量,而不是紋理坐標屬性值的數量。
// I had put this
glVertexAttribPointer(2, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * (floatsPerVertex + floatsPerColor)));
// Instead of this
glVertexAttribPointer(2, floatsPerUV, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * (floatsPerVertex + floatsPerColor)));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.