glBindTexture(GL_TEXTURE_2D, 0) glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0)

本文详细介绍了OpenGL中如何通过调用不同API来恢复默认状态,包括glBindTexture、glBindFramebuffer等,帮助理解OpenGL的状态机特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

glBindTexture(GL_TEXTURE_2D, 0) glBindFramebuffer(GL_FRAMEBUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0) 含义详解


void glBindTexture(GLenum  target, GLuint  texture);

官方解释:https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glBindTexture.xml

The value zero is reserved to represent the default texture for each texture target. 


texture 指明一张纹理的名字

在每个纹理目标中,0被保留用以代表默认纹理。


当一张纹理被第一次绑定时,它假定成为指定的目标类型。例如,一张纹理若第一次被绑定到GL_TEXTURE_1D上,就变成了一张一维纹理;若第一次被绑定到GL_TEXTURE_2D上,就变成了一张二维纹理。

由于OpenGL是状态机,当使用glBindTexture绑定一张纹理后,如果不再绑定新的纹理,则OpenGL之后的操作都会对应此纹理,当一个纹理与目标绑定时,该目标之前的绑定关系将自动被打破。


纹理名称与相应的纹理内容位于当前GL rendering上下文的共享对象空间中。


glBindVertexArray

https://www.khronos.org/opengl/wiki/GLAPI/glBindVertexArray

https://www.khronos.org/registry/OpenGL-Refpages/es3.0/

void glBindVertexArray(GLuint array​);

zero to break the existing vertex array object binding.

 zero to bind the default vertex array object binding


glBindFramebuffer

https://www.khronos.org/opengl/wiki/GLAPI/glBindFramebuffer

https://www.khronos.org/registry/OpenGL-Refpages/es3.0/

void glBindFramebuffer(GLenum target​, GLuint framebuffer​);

In order that access to the default framebuffer is not lost, it is treated as a framebuffer object with the name of zero. The default framebuffer is therefore rendered to and read from while zero is bound to the corresponding targets.

zero to break the existing binding of a framebuffer object to target .


glBindRenderbuffer

https://www.khronos.org/opengl/wiki/GLAPI/glBindRenderbuffer

zero to break the existing binding of a renderbuffer object to target .


glBindBuffer

void glBindBuffer(GLenum target​, GLuint buffer​);

https://www.khronos.org/opengl/wiki/GLAPI/glBindBuffer

值零保留,但每个缓冲区对象目标没有默认缓冲区对象。 相反,缓冲区设置为零有效地解除绑定先前绑定的任何缓冲区对象,并恢复该缓冲区对象目标的客户端内存使用(如果该目标支持的话)。 


常用的恢复OpenGL默认状态的代码:

glBindVertexArray(0);//VAO绑定到默认的VAO处,一般用于打破之前的VAO绑定关系,使OpenGLVAO绑定状态恢复到默认状态

glBindFramebuffer(GL_FRAMEBUFFER, 0);//framebuffer绑定到默认的FBO处,一般用于打破之前的FBO绑定关系,使OpenGLFBO绑定状态恢复到默认状态。

glBindTexture(GL_TEXTURE_2D, 0); //2D纹理绑定到默认的纹理,一般用于打破之前的纹理绑定关系,使OpenGL的纹理绑定状态恢复到默认状态。

glBindRenderbuffer(GL_RENDERBUFFER, 0); //将渲染buffer绑定到默认的渲染buffer,一般用于打破之前的渲染buffer绑定关系,使OpenGL的渲染buffer绑定状态恢复到默认状态。

glBindBuffer(GL_ARRAY_BUFFER, 0);//将顶点数据buffer和之前的绑定关系进行解绑 用于打破之前的顶点数据buffer的绑定关系,使OpenGL的顶点数据buffer绑定状态恢复到默认状态。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);//将顶点索引数据buffer和之前的绑定关系进行解绑 用于打破之前的顶点索引数据buffer的绑定关系,使OpenGL的顶点索引数据buffer绑定状态恢复到默认状态。








#include<glad/glad.h> #include<GLFW/glfw3.h> #include<glm/glm.hpp> #include<glm/gtc/type_ptr.hpp> #include<glm/gtc/matrix_transform.hpp> #include<iostream> #define STB_IMAGE_IMPLEMENTATION #include"stb/stb_image.h" #define Wwidth 1080 #define Wheight 960 //顶点着色器源码 const char* vertexShaderSource = "#version 330 core \n" "layout ( location = 0 ) in vec3 aPos; \n" //顶点位置 "layout ( location = 1 ) in vec3 aColor;\n" //顶点颜色 "layout ( location = 2 ) in vec2 aTex1; \n" //纹理1坐标 "layout ( location = 3 ) in vec2 aTex2; \n" //纹理2坐标 "out vec3 verColor; \n" "out vec2 tex1Coord; \n" "out vec2 tex2Coord; \n" "uniform mat4 transform; \n" "void main() \n" "{ \n" " gl_Position = transform " " *vec4(aPos, 1.0f); \n" " verColor = aColor; \n" " tex1Coord = aTex1; \n" " tex2Coord = aTex2; \n" "} \n" ; //片段着色器源码 const char* fragmentShaderSource = "#version 330 core \n" "in vec3 verColor; \n" "in vec2 tex1Coord; \n" "in vec2 tex2Coord; \n" "uniform sampler2D ourTexture1; \n" "uniform sampler2D ourTexture2; \n" "out vec4 fragColor; \n" "void main() \n" "{ \n" " fragColor = mix( " " texture(ourTexture1, tex1Coord), " " texture(ourTexture2, tex2Coord), " " 0.9 ) *vec4(verColor, 0.0f); \n" "} \n" ; void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } int main() { //初始化并配置glfw if(!glfwInit()) { perror("failed to init glfw"); return -1; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //创建glfw上下文窗口 GLFWwindow* window = glfwCreateWindow(Wwidth, Wheight, "纹理", NULL, NULL); if (!window) { printf("failed to create glfw window"); return -1; } //将当前glfw窗口上下文绑定到当前线程上下文 glfwMakeContextCurrent(window); //设置帧缓冲回调函数 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); //启动glad if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("failed to load glad"); return -1; } //启动顶点着色器 GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); int success; char infoLog[512]; //获取编译状态 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if(!success) { //生成日志信息 glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); printf("%s\n", infoLog); return -1; } /***************************************************着色器****************************************************/ /*************************************************************************************************************/ //启动顶点着色器 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); printf("%s\n", infoLog); return -1; } //生成着色器项目 GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); //获取链接状态 glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if(!success) { //生成日志信息 glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); printf("%s\n", infoLog); } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); /*************************************************************************************************************/ //顶点属性数组 float vertices[] = { //顶点坐标 //顶点颜色 //纹理1坐标 //纹理2坐标 -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 2.0f, -1.0f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 2.0f, -1.0f, 2.0f }; //索引数组 GLuint indices[] = { 0, 1, 2, 2, 3, 0 }; //创建 顶点数组对象, 顶点缓冲对象, 索引缓冲对象 GLuint VAO, VBO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); //绑定顶点数组对象 glBindVertexArray(VAO); //绑定顶点缓冲对象 glBindBuffer(GL_ARRAY_BUFFER, VBO); //填充VBO数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //绑定索引缓冲对象,并填充数据 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //设置顶点位置属性,并启用 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)0); glEnableVertexAttribArray(0); //设置顶点颜色属性,并启用 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)(3*sizeof(float))); glEnableVertexAttribArray(1); //设置纹理1位置属性,并启用 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)(6*sizeof(float))); glEnableVertexAttribArray(2); //设置纹理2位置属性,并启用 glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)(8*sizeof(float))); glEnableVertexAttribArray(3); /*************************************************************************************************************/ //创建纹理 GLuint texture1, texture2; glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); int width, height, nrchannels; stbi_set_flip_vertically_on_load(true); unsigned char* datas = stbi_load("C:\\Users\\fusheng\\Desktop\\opengl\\texture\\pear.png", &width, &height, &nrchannels, 0); if(datas) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, datas); glGenerateMipmap(GL_TEXTURE_2D); printf("yes\n"); } else { printf("failed to load png %s\n", stbi_failure_reason()); } stbi_image_free(datas); glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); const GLfloat borderColor[] = { 0.95f, 0.95f, 0.95f, 0.0f}; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); datas = stbi_load("C:\\Users\\fusheng\\Desktop\\opengl\\texture\\tt.png", &width, &height, &nrchannels, 0); if(datas) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, datas); glGenerateMipmap(GL_TEXTURE_2D); } else { printf("failed to load jpg %s\n", stbi_failure_reason()); } stbi_image_free(datas); /*************************************************************************************************************/ glUseProgram(shaderProgram); GLuint uniformLocation = glGetUniformLocation(shaderProgram, "ourTexture1"); glUniform1i(uniformLocation, 0); uniformLocation = glGetUniformLocation(shaderProgram, "ourTexture2"); glUniform1i(uniformLocation, 1); while(!glfwWindowShouldClose(window)) { glClearColor(0.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); glm::mat4 transform = glm::mat4(1.0f); transform = glm::translate(transform, glm::vec3(0.5, -0.5, 0.0)); transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0, 0.0f, 1.0f)); glUseProgram(shaderProgram); GLuint transformLocation = glGetUniformLocation(shaderProgram, "transform"); glUniformMatrix4fv(transformLocation, 1, GL_FALSE, glm::value_ptr(transform)); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &EBO); glDeleteProgram(shaderProgram); glfwTerminate(); return 0; }
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值