c++ - 纹理不绘制 OpenGL
问题描述
尝试在 OpenGL 中绘制纹理时,我遇到了一些奇怪的行为。目前,这个程序对我所做的只是绘制背景颜色,而没有指示正在绘制纹理。我刚刚从 Visual Studio(此代码产生正确的输出)转移到在命令提示符下进行编译。此代码应为背景着色并在屏幕中央绘制一个纹理。
我担心我可能提供了不正确的库进行编译,因为就我而言,我所做的一切都是一样的。然而,不同的库总是说它们不兼容。
主要代码:
#define GLEW_STATIC
#include <GL/glew.h> // window management library
#include <GL/glfw3.h>
#include <GL/glm.hpp>
#include <GL/gtc/matrix_transform.hpp> //
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
int main(int argc, char** argv){
//Initialize GLFW and GLEW...
//Setup and combine shaders...
GLint vertex_att = glGetAttribLocation(program, "vertex");
glVertexAttribPointer(vertex_att, 2, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), 0);
glEnableVertexAttribArray(vertex_att);
GLint color_att = glGetAttribLocation(program, "color");
glVertexAttribPointer(color_att, 3, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), (void *) (2 *sizeof(GLfloat)));
glEnableVertexAttribArray(color_att);
GLint tex_att = glGetAttribLocation(program, "uv");
glVertexAttribPointer(tex_att, 2, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), (void *) (5 *sizeof(GLfloat)));
glEnableVertexAttribArray(tex_att);
glUseProgram(program);
GLuint texture;
glGenTextures(1, &texture);
setthisTexture(texture, "./black.png");
// Create geometry of the square
int size = CreateSquare();
while (!glfwWindowShouldClose(window)){
// Clear background
glClearColor(viewport_background_color_g[0],
viewport_background_color_g[1],
viewport_background_color_g[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//set displacement - 'program' being the shader program
int matrixLocation = glGetUniformLocation(program, "x");
glm::mat4 translate = glm::mat4();
translate = glm::translate(translate, glm::vec3(0.0f, 0.0f, 0.0f));
glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, &translate[0][0]);
glBindTexture(GL_TEXTURE_2D, texture);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glfwPollEvents();
glfwSwapBuffers(window);
}
}
顶点着色器:
#version 130
in vec2 vertex;
in vec3 color;
in vec2 uv;
out vec2 uv_interp;
// Uniform (global) buffer
uniform mat4 x;
// Attributes forwarded to the fragment shader
out vec4 color_interp;
void main(){
vec4 t;
t = vec4(vertex, 0.0, 1.0);
gl_Position = x*t;
color_interp = vec4(color, 1.0);
uv_interp = uv;
}
片段着色器:
#version 130
in vec4 color_interp;
in vec2 uv_interp;
uniform sampler2D onetex;
void main(){
vec4 color = texture2D(onetex, uv_interp);
gl_FragColor = vec4(color.r,color.g,color.b,color.a);
if(gl_FragColor.a < 0.9){
discard;
}
}
设置此纹理:
void setthisTexture(GLuint w, const char *fname)
{
glBindTexture(GL_TEXTURE_2D, w);
int width, height, nrChannels;
unsigned char* image = stbi_load(fname, &width, &height, &nrChannels, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
stbi_image_free(image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
创建广场:
int CreateSquare(void) {
// The face of the square is defined by four vertices and two triangles
// Number of attributes for vertices and faces
// const int vertex_att = 7; // 7 attributes per vertex: 2D (or 3D) position (2), RGB color (3), 2D texture coordinates (2)
// const int face_att = 3; // Vertex indices (3)
GLfloat vertex[] = {
// square (two triangles)
// Position Color Texcoords
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-left
};
GLuint face[] = {
0, 1, 2, // t1
2, 3, 0 //t2
};
GLuint vbo, ebo;
// Create buffer for vertices
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
// Create buffer for faces (index buffer)
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(face), face, GL_STATIC_DRAW);
// Return number of elements in array buffer
return sizeof(face);
}
解决方案
为了使用glVertexAttribPointer
命名GL_ARRAY_BUFFER
缓冲区对象,必须绑定或传递指向顶点数据的指针。
在您的情况下,这意味着
int size = CreateSquare();
必须在之前完成
GLint vertex_att = glGetAttribLocation(program, "vertex");
glVertexAttribPointer(vertex_att, 2, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), 0);
glEnableVertexAttribArray(vertex_att);
.....
注意在函数CreateSquare
中,命名的缓冲区对象vbo
是绑定的:
glBindBuffer(GL_ARRAY_BUFFER, vbo);
由glVertexAttribPointer
调用使用。
请参阅OpenGL 4.6 API 兼容性配置文件规范;10.3.9 缓冲区对象中的顶点数组;第 409 页:
缓冲区对象绑定点被添加到与每个顶点数组类型和索引关联的客户端状态。指定顶点数组的位置和组织的命令将绑定到 ARRAY_BUFFER 的缓冲区对象名称复制到与指定的顶点数组类型或索引对应的绑定点。例如,VertexAttribPointer 命令将 ARRAY_BUFFER_BINDING 的值(与目标 ARRAY_BUFFER 对应的缓冲区绑定的可查询名称)复制到指定索引的客户端状态变量 VERTEX_ATTRIB_-ARRAY_BUFFER_BINDING。
推荐阅读
- linux - 在 Windows/Linux 中没有额外硬件的虚拟 COM
- .net - 在 IIS 上托管 .net Core 2.1 访问解决方案路径被拒绝?
- c# - 定义嵌套 JSON 格式
- java - org.openqa.selenium.remote.internal.ApacheHttpClient 在 Selenium 3.14.0 中已弃用 - 应该改用什么?
- json - 如何使用对象解构在 TypeScript 中导入 JSON?
- c++ - 为派生类重载 << 运算符表示操作数无效
- ios - 如何在 swift iOS 中以编程方式获取 IMEI 号码?
- python - 合并几个数据框,只保留一组colnames
- c# - 使用 LINQ 包含 - 如何确保不跟随特定字符
- javascript - 如何将 Vue 插件发布到 NPM?