c++ - 我在 OpenGL 中显示图像时遇到问题
问题描述
我不完全理解 OpenGL 中绑定纹理的概念,我无法为我的项目渲染 jpg 图像,对我可能做错了什么有任何了解吗?
// Shader sources
const GLchar* vertexShaderSource = R"glsl(
#version 150 core
in vec2 position;
in vec3 color;
in vec2 texcoord;
out vec3 Color;
out vec2 Texcoord;
void main()
{
Color = color;
Texcoord = texcoord;
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentShaderSource = R"glsl(
#version 150 core
in vec3 Color;
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D tex;
void main()
{
outColor = texture(tex, Texcoord) * vec4(Color, 1.0);
}
)glsl";
//creating the window
GLFWwindow *window= glfwCreateWindow(1200, 700, "NEX_Tests", NULL, NULL);
if(nullptr== window){
std::cout<<"ERROR HAS OCCURED WHILE LOADING THE WINDOW\n"<<"\n";
glfwTerminate();
return -1;
}
else{
int screenWidth,screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
glfwMakeContextCurrent(window);
glewExperimental=true;
if(GLEW_OK==!glewInit()){
std::cout<<"ERROR HAS OCCURED WHILE INITILIZING THE GLEW LIBRARY\n"<<"\n";
return EXIT_FAILURE;
}
//set the viewing port
glViewport(0, 0, screenWidth, screenHeight);
//creating the vetex array object;
GLuint vao,vbo;
glGenVertexArrays(1,&vao);
glGenBuffers(1,&vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
//creating the element buffer
GLuint ebo;
glGenBuffers(1,&ebo);
GLuint elements[]={
0,1,2,
2,3,0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(elements),elements,GL_STATIC_DRAW);
std::cout<<vbo<<"\n";
// glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,(3* sizeof(GLfloat)),(GLvoid*)0);
// glEnableVertexAttribArray(0);
//glBindBuffer(GL_VERTEX_ARRAY,0);
// glBindVertexArray(0);
//creating and linking the shaders
GLuint vertexShader= glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader,1,&vertexShaderSource,NULL );
glCompileShader(vertexShader);
GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success);
if(!success){
glGetShaderInfoLog(vertexShader, 512,NULL,infoLog);
std::cout<<"ERROR HAS OCCURED WHILE COMPILING THE SHADERS\n"<<infoLog<<std::endl;
}
GLuint fragmentShader= glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader,GL_COMPILE_STATUS,&success);
if(!success){
glGetShaderInfoLog(fragmentShader,512,NULL,infoLog);
std::cout<<"ERROR HAS OCCURED WHILE COMPILING THE SHADERS\n"<<infoLog<<std::endl;
}
GLuint shaderProgram= glCreateProgram();
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
glGetProgramiv(shaderProgram,GL_LINK_STATUS,&success);
if(!success){
glGetProgramInfoLog(shaderProgram,512,NULL,infoLog);
std::cout<<"ERROR HAS OCCURED WHILE LINKING THE SHADERS\n"<<infoLog<<std::endl;
}
//delete the shaders
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//layout of the vertex shader
GLint posAttrib = glGetAttribLocation(shaderProgram,"position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib,0,GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),0);
GLint colAttrib = glGetAttribLocation(shaderProgram,"color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib,2,GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),((void*)(2*sizeof(GLfloat))));
GLint TexAttrib= glGetAttribLocation(shaderProgram,"texcoord");
glEnableVertexAttribArray(TexAttrib);
glVertexAttribPointer(TexAttrib,2,GL_FLOAT,GL_FALSE,7*sizeof(GLfloat),((void*)(5*sizeof(GLfloat))));
//loading the textures
GLuint tex;
glGenTextures(2, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
std::cout<<tex<<"\n";
glActiveTexture(GL_TEXTURE0+ 1);
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);
//loading the image
int me=200,me2=300;
int *width=&me,*height=&me2;
unsigned char* Image= SOIL_load_image("IceKarl.png", width, height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, *width, *height, 0, GL_RGB, GL_UNSIGNED_BYTE, Image);
SOIL_free_image_data(Image);
if(!Image){
std::cout<<"ERROR HAS OCCURED WHILE LOADING IN IMAGE\n";
}
//running loop
while(!glfwWindowShouldClose(window)){
glfwPollEvents();
glClearColor(0.0f, 0.00f, 0.00f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, 0);
//glDrawArrays(GL_TRIANGLES, 0, 6);
// glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
// glBindTexture(GL_TEXTURE_2D,0);
glfwSwapBuffers(window);
}
glDeleteTextures(1,&tex);
glDeleteProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteBuffers(1,&vbo);
glDeleteBuffers(1,&ebo);
glDeleteVertexArrays(1,&vao);
}
glfwTerminate();
return 0;
}
解决方案
的第二个参数glVertexAttribPointer
是属性的元组大小。在您的情况下,这是位置(x, y)的 2 ,颜色(r, g, b)的 3 和纹理坐标(u, v)的 2 :
GLint posAttrib = glGetAttribLocation(shaderProgram,"position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),0);
GLint colAttrib = glGetAttribLocation(shaderProgram,"color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT,GL_FALSE,7* sizeof(GLfloat),((void*)(2*sizeof(GLfloat))));
GLint TexAttrib= glGetAttribLocation(shaderProgram,"texcoord");
glEnableVertexAttribArray(TexAttrib);
glVertexAttribPointer(TexAttrib, 2, GL_FLOAT,GL_FALSE,7*sizeof(GLfloat),((void*)(5*sizeof(GLfloat))));
绘制网格时,必须绑定纹理和顶点数组对象。
glActiveTexture
必须在绑定纹理 ( ) 之前设置纹理单元( glBindTexture
):
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, tex);
您必须将纹理单元索引分配给纹理采样器制服 ( glUniform
):
glUniform1i(tex_loc, 1);
获取纹理采样器 uniform ( glGetUniformLocation
) 的位置索引:
GLuint tex_loc = glGetUniformLocation(shaderProgram, "tex");
在绘制调用之前绑定对象:
int texture_unit = 1;
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(tex_loc, texture_unit);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
生成纹理名称时还有一个问题。生成 1 个纹理名称而不是 2 个:
glGenTextures(2, &tex);
GLuint tex;
glGenTextures(1, &tex);
推荐阅读
- linq - 无论如何使用从url连接的字段名称?
- swift - SwiftUI 不断更新坐标位置
- javascript - 在运行时添加的动态字段在页面重新加载时消失
- python - 如何使用 json.dumps 显示 python 数组
- javascript - 如何在包含我想要匹配的单词的短语上获得正则表达式匹配?
- mysql - 如何根据 MySQL 中的指定位置选择字符串中的特定数字?
- python - 将下拉选择应用于树视图行
- git - 在 Gitlab 中回滚到以前的版本
- pandas - 熊猫数据框列表的箱线图
- python - AttributeError: 'list' 对象没有属性 'replace' out = [j.replace("on", "re") for j in out]