opengl
- opengl
- opengl学习笔记
- 函数部分
- glAttachShader
- glActiveTexture
- glBindFramebuffer
- glBindRenderbuffer
- glBindTexture
- glBindBufferARB
- glBindBuffer
- glBufferDataARB
- glBufferData
- glBufferSubDataARB
- glBindVertexArray
- glCreateShader
- glCheckFramebufferStatus
- glCullFace
- glCallList
- glCallLists
- glColorPointer
- glCopyBufferSubData
- glCreateProgram;
- glCompileShader
- glDrawBuffer
- glDepthMask
- glDeleteLists
- glDepthFunc
- glDrawArrays
- glDrawArraysInstanced
- glDrawElements
- glDrawElementsInstanced
- glDrawRangeElements
- glDeleteShader
- glDeleteBuffers
- glDeleteBuffersARB
- glDisableClientState
- glEndList
- glEnable
- glEdgeFlagPointer
- glEnableVertexAttribArray
- glEnableClientState
- glFramebufferTexture2D
- glFramebufferRenderbuffer
- glFrustum
- glFlush & glFinish
- glGenerateMipmap
- glGenFramebuffers
- glGenTextures
- glGenLists
- glGetRenderbufferParameteriv
- glGetFloatv(GL_MODELVIEW_MATRIX, m)
- glGenVertexArrays
- glGenerateMipmaps
- glGenBuffersARB
- glGenBuffers
- glGetUniformLocation
- glGetProgramiv
- glGetProgramInfoLog
- glGetShaderiv
- glGetShaderInfoLog
- glGetAttribLocation
- glGetIntegerv
- glIndexPointer
- glIsBuffer
- glLoadMatrix{fd}(m)
- glLoadIdentity
- glLoadTransposeMatrix{fd}(m)
- glLinkProgram
- glLoadMatrixf
- glListBase
- glMatrixMode
- glMapBuffer
- glMapBufferARB
- glMultMatrix{fd}(m)
- glMultTransposeMatrix{fd}(m)
- glNewList
- glNormalPointer
- glOrtho
- glPolygonMode
- glPushMatrix
- glPopMatrix
- glReadPixels
- glReadBuffer
- glRenderbufferStorage
- glTexImage2D
- glTexParameter
- glTexCoordPointer
- glUnmapBufferARB
- glUniform1i
- glUniform1f
- glUniform2fv
- glUniform2f
- glUniform3fv
- glUniform3f
- glUniform4f
- glUniform4fv
- glUniformMatrix2fv
- glUniformMatrix3fv
- glUniformMatrix4fv
- glUseProgram
- gluLookAt
- gluOrtho2D
- gluPerspective
- glVertexPointer
- glVertexAttribPointer
- glVertexAttribDivisor
- glPatchParameteri
- glPatchParameteriv
- glViewport
- glVertexAttrib1f
- glVertexAttrib2f
- glVertexAttrib3f
- glVertexAttrib4f
- glShaderSource
- OpenGL Macro
- 函数部分
- GLFW
- GLM
- GLSL
- opengl学习笔记
opengl
opengl学习笔记
函数部分
- 顶点数组对象:Vertex Array Object,VAO
- 顶点缓冲对象:Vertex Buffer Object,VBO
- 索引缓冲对象:Element Buffer Object,EBO或IBO
- 纹理缓冲对象:Texture Buffer Object,TBO
- 变量缓冲对象:Uniform Buffer Object,UBO
- 帧 缓 冲对象:Frame Buffer Object,FBO
- 渲染缓冲对象:Render Buffer Object,RBO
- 像素缓存对象:pixel Buffer Object,PBO
glAttachShader
glAttachShader(ID, vertex);
把glsl写的着色器附加到着色器小程序上.
glActiveTexture
激活纹理单元
glActiveTexture(GL_TEXTURE0); //在绑定纹理之前先激活纹理单元
glBindTexture(GL_TEXTURE_2D, texture);
glBindFramebuffer
当FBO创建以后,在使用它之前需要先绑定它。
void glBindFramebuffer(GLenum target, GLuint id)
第一个参数target需要是GL_FRAMEBUFFER,第二个参数是帧缓冲区对象的ID。当一个FBO绑定以后,所有的OpenGL操作将会作用在这个绑定的帧缓冲区对象上。ID为0的帧缓冲区对象是”窗口系统提供的“帧缓冲区。因此为了解除当前正在使用的帧缓冲区(FBO),使用glBindFramebuffer()绑定到0。
glBindRenderbuffer
void glGenRenderbuffers(GLsizei n, GLuint* ids)
void glDeleteRenderbuffers(GLsizei n, const Gluint* ids)
当一个渲染缓冲区创建以后,它会返回一个非零的正数。0为OpenGL保存。
glBindTexture
邦定纹理
glBindBufferARB
glBindBufferARB(GLenum target,GLuint id);
当缓冲区对象创建以后,在使用缓冲区对象之前我们需要将缓冲区对象的标示绑定。glBindBufferARB()需要两个参数:target和ID。
target是告诉VBO这个缓冲区对象是用来存储顶点数组数据还是用来存储索引数组数据的:GL_ARRAY_BUFFER_ARB或 GL_ELEMENT_ARRAY_BUFFER_ARB 。任何顶点属性,如顶点坐标,纹理坐标,法向量,和颜色信息需要使用GL_ARRAY_BUFFER_ARB作为target。而像glDraw[Range]Elements()函数使用的索引数组则需要与GL_ELEMENT_ARRAY_BUFFER_ARB绑定。注意这个target标示帮助VBO决定顶点缓冲区的最佳位置,例如,有些系统将会将索引数组放置在AGP或系统内存中,而将顶点数组放置在显卡内存中。
当glBindBufferARB()被首次调用的时候,VBO使用大小为0的内存区初始化这个缓冲区并且设置了这个VBO的初始状态,例如usage和访问属性。
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
最后一行将缓冲区对象绑定到0将关闭VBO操作。这是一个使用VBO之外关闭VBO的好方法,这样正常的顶点数组操作将会被再次激活。
glBindBuffer
OpenGL有很多缓冲对象类型,顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER,OpenGL允许我们同时绑定多个缓冲,只要它们是不同的缓冲类型。我们可以使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上
glBindBuffer(GL_ARRAY_BUFFER, VBO); //把新创建的VBO绑定到GL_ARRAY_BUFFER
绑定顶点缓冲到GL_ARRAY_BUFFER
glBufferDataARB
当缓冲区初始化以后你可以使用glBufferDataARB()将数组复制到缓冲区对象中。
void glBufferDataARB(GLenum target, GLsizei size, const void* data, GLenum usage)
第一个参数target可能是GL_ARRAY_BUFFER_ARB或GL_ELEMENT_ARRAY_BUFFER_ARB。size是将要传输的数据的字节数。第3个参数是指向数据源的指针,如果这个指针是NULL,那么VBO将会只保留指定大小的存储空间。最后一个参数usage是另一个VBO中的性能参数,指示这个缓冲区会被怎么使用,static(静态的),dynamic(动态的),stream(流),read(读),copy(复制),draw(绘制)。
VBO为usage标示指定了9中枚举的值:
GL_STATIC_DRAW_ARB
GL_STATIC_READ_ARB
GL_STATIC_COPY_ARB
GL_DYNAMIC_DRAW_ARB
GL_DYNAMIC_READ_ARB
GL_DYNAMIC_COPY_ARB
GL_STREAM_DRAW_ARB
GL_STREAM_READ_ARB
GL_STREAM_COPY_ARB
“static”意味着VBO中的数据不能被改变(指定一次使用多次),“dynamic”意味着数据将会频繁地改变(指定多次使用多次),“stream”意味着数据在每一帧中都会被改变(指定一次使用一次)。“draw”意味着数据被传输至GPU渲染(从应用程序到OpenGL),“read”意味着数据被客户端的应用程序所读取(从OpenGL到应用程序),“copy0”意味着既可以用来“draw”也可以用来“read”。
注意只有"draw"标示可以被VBO使用,“copy”和“read”标示对像素缓冲区对象(PBO)和帧缓冲区对象(FBO)才有意义。
VBO内存管理会根据usage的值为缓冲区对象选择最合适的内存位置,例如,GL_STATIC_DRAW_ARB 和GL_STREAM_DRAW_ARB将会选择显卡内存,GL_DYNAMIC_DRAW_ARB将会选择AGP内存。任何与_READ_相关的缓冲区既可以使用系统内存也可以是用AGP内存,因为数据应该很容易被访问到。
glBufferData
把顶点数据复制到顶点缓冲显存中。
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
参数:
- 目标缓冲的类型:GL_ARRAY_BUFFER
- 指定传输数据的大小(以字节为单位), 用一个简单的sizeof计算出顶点数据大小就行。
- 发送的实际数据。
- 指定了我们希望显卡如何管理给定的数据。它有三种形式:
- GL_STATIC_DRAW :数据不会或几乎不会改变。
- GL_DYNAMIC_DRAW:数据会被改变很多。
- GL_STREAM_DRAW :数据每次绘制时都会改变。
glBufferSubDataARB
void glBufferSubDataARB(GLenum target, GLint offset, GLsizei size, void* data)
和glBufferDataARB()比较类似,glBufferSubDataARB()用来将数据复制到VBO中,但是它只将部分数据复制到已经存在的缓冲区中,从给定的偏移量开始。(缓冲区的总大小必须在使用glBufferSubDataARB()之前使用glBufferDataARB()设置)
glBindVertexArray
绑定VAO对象
glBindVertexArray(VAO); //绑定VAO
对应的使用:
glBindVertexArray(0); //解除绑定
glCreateShader
创建shader着色器
GLuint vertexShader;
vertexShader=glCreateShader(GL_VERTEX_SHADER); //创建一个顶点着色器
glCheckFramebufferStatus
当一个可附加的镜像(纹理对象或渲染缓冲区对象)被附加到FBO中以后并且在FBO执行操作之前,你必须使用glCheckFramebufferStatus()来检查FBO的状态是否完整。如果FOB不是完整的,那么任何绘制或读取的命令(glBegin,glCopyTexImage2D()等)都会失败。
GLenum glCheckFramebufferStatus(GLenum target)
glCheckFramebufferStatus()检查附加到当前被绑定的FBO的镜像和帧缓冲的参数。并且这个函数不能在glBegin()和glEnd()之间。target参数必须是GL_FRAMEBUFFER。检查完FBO后会返回一个非零的值。如果所有的条件和规则都满足,会返回GL_FRAMEBUFFER_COMPLETE。否则,它返回一个有关的错误值,这个错误值会告诉违反了那条规则。
FBO中完整的规则如下:
- 附加到帧缓冲区镜像的width和height必须是非零的。
- 如果一个镜像被附加到颜色附加点,那么这个镜像必须有一个可渲染颜色(color-renderable)的内部格式。(GL_RGBA,GL_DEPTH_COMPONENT,GL_LUMINANCE等)
- 如果一个镜像被附加到GL_DEPTH_ATTACHMENT,那么这个镜像必须有可渲染深度(depth-renderable)的内部格式。(GL_DEPTH_COMONENT,GL_DEPTH_COPONENT24等)
- 如果一个镜像被附加到GL_STENCIL_ATTACHMENT,那么这个镜像必须有可渲染模板(stencil-renderable)的内部格式。(GL_STENCIL_INDEX,GL_STENCIL_INDEX8等)
- FBO必须至少有一个附加的镜像。
- 所有附加到FBO的镜像必须有相同的宽体和高度。
- 所有附加到颜色附加点的镜像必须有相同的内部格式。
注意即使上面所有的条件都满足,你的OpenGL驱动(GPU)可能不支持某些内部的格式或参数。如果某个特殊的实现不被OpenGL驱动支持,那么glCheckFramebufferStatus()会返回GL_FRAMEBUFFER_UNSUPPORTED。
glCullFace
剔除面方式。首面要启用glEnable(GL_CULL_FACE)启用面剔除。
glCullFace(GL_FRONT); //剔除正面
glCullFace(GL_BLACK); //剔除背面
glCullFace(GL_FRONT_AND BLACK); //剔除正面和背面
glCallList
glCallLists
// 只绘制部分显示列表 (第1个,第3个,第5个,第7个,第9个)
lists[0]=0; lists[1]=2; lists[2]=4; lists[3]=6; lists[4]=8;
glListBase(index); // 设置基准的位置
glCallLists(5, GL_UNSIGNED_BYTE, lists);
调用显示列表,在上面的例子中,只有5个显示列表会被渲染:第1个,第3个,第5个,第7个,第9个。因此实际的偏移是index+0,index+2,index+4,index+6,index+8,这些偏移会被存储在索引数组中方便后面的渲染。如果glGenLists()函数的返回值是3,那么背渲染的显示列表的实际的索引是:3+0,3+2,3+4,3+6,和3+8。
glCallLists()显示使用字体中相对应的ASCII值做偏移的文字时非常有用。
glColorPointer
指向RGB颜色数组
glCopyBufferSubData
在缓冲区对象之间复制数据。
void glCopyBufferSubData(GLenum readbuffer, GLenum writebuffer
GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size);
//把数据从readbuffer相关联的缓冲区对象复制到writebuffer的缓冲区对象
//从readoffset开始移动size个数据的数量到wirteoffset中
glCreateProgram;
GLuint ID = glCreateProgram();
创建一个运行在显卡的着色器小程序。
glCompileShader
编译着色器
glCompileShader(vertexShader);
参数为传入要编译的着色器。
glDrawBuffer
指定在当前帧缓冲区的哪个颜色缓冲区进行绘制,并不影响深度、模板缓冲区。
void glDrawBuffer (GLenum mode);
GL_FRONT: 单缓存的默认值
GL_FRONT_RIGHT:
GL_NONE:不写入颜色缓冲区,如果存在片段着色器则不启用该着色器
GL_FRONT_LEFT:
GL_FRONT_AND_BACK:
GL_RIGHT:
GL_AUXi: i表示第几个辅助缓存.
GL_LEFT:
GL_BACK_RIGHT:
GL_BACK: 双缓存的默认值
GL_BA
对于帧缓冲区对象而言,可以取GL_COLOR_ATTACHMENT$m$
and GL_NONE,m为0~GL_MAX_COLOR_ATTACHMENTS
注意: 启用多个缓存用于写操作时, 只要其中一个缓存存在, 就不会发生错误. 如果指定的缓存都不存在, 就发生错误.CK_LEFT。
glDepthMask
void glDepthMask(GLboolean flag);
允许或禁止向深度缓冲区写入数据。glDepthMask指定是否允许向深度缓冲区写入数据。如果flag是GL_FLASE,那么向深度缓冲区写入是禁止的。否则,就是允许的。初始时,是允许向深度缓冲区写入数据的。
参数flag:
指定是否允许向深度缓冲区写入数据。如果flag是GL_FLASE,那么向深度缓冲区写入是禁止的。否则,就是允许的。初始时,是允许向深度缓冲区写入数据的。
如果在glBegin和glEnd之间执行glDepthMask,会产生GL_INVALID_OPERATION。注意这只在深度测试被启用的时候有效。
glDeleteLists
删除显示列表
glDepthFunc
glDepthFunc(func);
指定目标像素与当前像素在Z方向上值大小比较。符合该函数关系的目标像素才进行绘制,否则对目标像素不予绘制。
func指定深度比较函数,
GL_NEVER,GL_LESS,GL_EQUAL,GL_LEQUAL,GL_GREATER,GL_NOTE_QUAL,GL_GEQUAL,GL_ALWAYS,缺省值GL_LESS,
GL_NEVER,不通过(输入的深度值不取代参考值)
GL_LESS,如果输入的深度值小于参考值,则通过
GL_EQUAL,如果输入的深度值等于参考值,则通过
GL_LEQUAL,如果输入的深度值小于或等于参考值,则通过
GL_GREATER,如果输入的深度值大于参考值,则通过
GL_NOTE_QUAL,如果输入的深度值不等于参考值,则通过
GL_GEQUAL,如果输入的深度值大于或等于参考值,则通过
GL_ALWAYS,总是通过(输入的深度值取代参考值)
默认情况下使用GL_LESS
,这将丢弃深度值高于或等于当前深度缓冲区的值的片段。
描述:
通过目标像素与当前像素在z方向上值大小的比较是否满足参数指定的条件,来决定在深度(z方向)上是否绘制该目标像素。该函数只有启用“深度测试”时才有效,参考glEnable(GL_DEPTH_TEST)和glDisable(GL_DEPTH_TEST)
glDrawArrays
绘制图元.
glDrawArrays(GL_TRIANGLES,0,3);
参数:
- 第一个参数绘制的图元类型。
- 第二个参数指定顶点数组的起始索引。
- 最后一个参数指定我们打算绘制多少个顶点.
glDrawArraysInstanced
多实例化绘制,和glDrawArray参数一样。除了最后一个参数,用于指定绘制实例的数量。
glDrawElements
当使用EBO索引缓冲对象时,使用些函数替代glDrawArrays来指明我们从索引缓冲绘制图元。
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
参数:
- 第一个参数绘制的图元类型。
图形类型:GL_TRIANGLES 三角形
- 第二个参数指定绘制索引数组的索引个数,也就是索引数组的大小。
- 第三个参数是索引的类型,这里是GL_UNSIGNED_INT,或GL_UNSIGNED_BYTE
- 最后一个参数里我们可以指定EBO中的偏移量,(或者传递一个索引数组,但是这是当你不在使用索引缓冲对象的时候),但是我们会在这里填写0。
glDrawElementsInstanced
使用索引绘制多实例.使用方法和glDrawElements差不多,但后面输入绘制实例的数量。
glDrawRangeElements
// 绘制前面一半的图形 6 - 0 + 1 = 7 个顶点被使用
glDrawRangeElements(GL_TRIANGLES, 0, 6, 18, GL_UNSIGNED_BYTE, indices);
// 绘制后面一半的图形 7 - 1 + 1 = 7 个顶点被使用
glDrawRangeElements(GL_TRIANGLES, 1, 7, 18, GL_UNSIGNED_BYTE, indices+18);
和glDrawElements()比较类似,glDrawRangeElements()也可以在数组中跳跃访问。然而,glDrawRangeElements()还有两个额外的参数(开始和结束位置的索引)来指定顶点的范围。通过添加这个范围限制,OpenGL可以只获得访问有限范围的顶点的来优先渲染,这样可能提高性能。
在glDrawRangeElements()中的额外的参数是开始(start)和结束(end)位置的索引,OpenGL预取end-start+1个顶点数据。索引数组中的值必须在start和end之间。注意并不是start和end之间的所有顶点都必须被引用到,但是如果你指定了一个稀疏的范围,那样将会导致为那些不需要使用的顶点进行的没必要的处理。
glDeleteShader
删除着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteBuffers
删除缓冲区对象
void glDeleteBuffers(GLsizei n, GLuint *buffers);
glDeleteBuffersARB
void glDeleteBuffersARB(GLsizei n, const GLuint* ids)
你可以使用glDeleteBuffersARB()函数来删除一个或多个不再使用的VBO。缓冲区对象被删除掉后,它的内容会丢失掉。
glDisableClientState
glEndList
glNewList(index+9, GL_COMPILE); // 编译最后一个显示列表
...
glEndList();
glEnable
glEnable(GL_DEPTH_TEST);
打开opengGL的各种测试。
状态标志 | 功能 | 说明 |
---|---|---|
GL_DEPTH_TEST | 开启深度测试 | |
GL_LIGHNTING | 开启灯光 | |
GL_FACE_CULL | 开启面剔除 |
glEdgeFlagPointer
指向临界标示数组
glEnableVertexAttribArray
glEnableVertexAttribArray(0);
以顶点属性位置值作为参数,启用顶点属性,顶点属性默认是禁用的,所以设置顶点属性后要打开。
glEnableClientState
glEnableClientState(GL_VERTEX_ARRAY);
激活顶点数组
glFramebufferTexture2D
glFramebufferTexture2D(GLenum target,
GLenum attachmentPoint,
GLenum textureTarget,
GLuint textureId,
GLint level)
glFramebufferTexture2D()将一个二维纹理镜像附加到FBO中。第一个参数必须是GL_FRAMEBUFFER。第二个参数是连接纹理镜像的附加点,一个FBO中有多个颜色附加点(GL_COLOR_ATTACHMENT0, ...,GL_COLOR_ATTACHMENTn),一个深度附加点(GL_DEPTH_ATTACHMENT),和一个模板附加点(GL_STENCIL_ATTACHMENT)。第三个参数,"texture Target"大多数情况下为GL_TEXTURE_2D。第四个参数是纹理对象的标示符。最后一个参数附加纹理的映射级别。
如果textureId的值为0,那么纹理镜像会从PBO中分离。如果一个纹理对象在它还附加到FBO中时被删除了,那么这个纹理对象会自动从当前绑定的FBO中分离。然而,如果它被附加到多个FBO并且被删除了,那么将只会从当前被绑定的FBO中删除,而不会从未绑定的FBO中删除。
glFramebufferRenderbuffer
void glFramebufferRenderbuffer(GLenum target,
GLenum attachmentPoint,
GLenum renderbufferTarget,
GLuint renderbufferId)
可以使用glFramebufferRenderbuffer()将一个渲染缓冲区镜像附加到FBO中。第一个参数和第二个参数和glFramebufferTexture2D()一样。第三个参数必须是GL_RENDERBUFFER。最后一个参数是渲染缓冲区对象的标示。
如果renderbufferId参数被设置成0,那么渲染缓冲区对象将会从FBO中的附加点分离。如果一个渲染缓冲被附加到FBO时被删除了,它会自动从当前被绑定的FBO中分离开来。然而,它不会从其他未被绑定的FBO中分离出来。
glFrustum
glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
创建一个表示透视视图*截头体的矩阵,并把它与当前矩阵相乘。如果观察点为默认情况时,*截头体的视景体是由这个函数的参数定义:(left, bottom, -zNear)和(right, top, -zNear)分别指定了*侧裁剪*面左下角和右上角的(x,y,z)坐标。zNear和zFar分别表示从观察点到*侧和远侧裁剪*面的距离,它们都应该是正值。你可以将其想像为数码相机的视野范围(视景体)。
glFlush & glFinish
与计算机IO缓冲区类似,OpenGL命令不会立即执行。所有命令都先存储在缓冲区中,包括网络缓冲区和图形加速器本身,并等待执行,直到缓冲区满为止。例如,如果一个应用程序在网络上运行,在一个数据包中发送一组命令要比在网络上一次发送一个命令效率高得多。
glFlush():清空这些缓冲区中的所有命令,并强制所有挂起的命令立即执行,而不等待缓冲区满。因此,glFlush()保证在调用glFlush()之后,所有OpenGL命令都将在有限的时间内完成执行。glFlush()不会等到以前的执行完成,并且可能立即返回到您的程序。因此,您可以自由地发送更多命令,即使之前发出的命令还没有完成。
glFinish():会像glFlush()一样刷新缓冲区并强制命令开始执行,但glFinish()会阻塞其他OpenGL命令并等待所有执行完成。因此,直到之前调用的所有命令完成,glFinish()才返回程序。它可以用于同步任务或测量某些OpenGL命令执行的确切时间。
glGenerateMipmap
glGenerateMipmap(GL_TEXTURE_2D);
创建纹理贴图
参数mode取值:
GL_FRONT: 单缓存默认
GL_FRONT_RIGHT:
GL_BACK_RIGHT:
GL_FRONT_LEFT:
GL_NONE:
GL_LEFT:
GL_AUX:
GL_BACK_LEFT:
GL_BACK: 双缓存默认
GL_RIGHT:
注意: 启用缓存用于读取操作时, 指定的缓存必须存在, 否则将发生错误.
glGenFramebuffers
void glGenFramebuffers(GLsizei n, GLuint* ids)
void glDeleteFramebuffers(GLsizei n, const GLuint* ids)
创建帧缓冲,glGenFramebuffers()需要两个参数:第一个参数标示要创建的帧缓冲区的数目,第二个参数表示存放生成的帧缓冲区ID的GLuint类型的变量或数组的地址。它返回为使用的帧缓冲区对象的ID。ID为0标示默认的帧缓冲区,就是”窗口系统提供的“帧缓冲区。
当FBO不再使用的时候可以使用glDeleteFramebuffers()来删除它。
glGenTextures
glGenTextures是用来生成纹理的函数。函数根据纹理参数返回n个纹理索引。纹理名称集合不必是一个连续的整数集合。
glGenTextures(GLsizei n, GLuint *textures);
- n:用来生成纹理的数量
- textures:存储纹理索引的第一个元素指针
(glGenTextures就是用来产生你要操作的纹理对象的索引的,比如你告诉OpenGL,我需要5个纹理对象,它会从没有用到的整数里返回5个给你)
glBindTexture实际上是改变了OpenGL的这个状态,它告诉OpenGL下面对纹理的任何操作都是对它所绑定的纹理对象的,比如glBindTexture(GL_TEXTURE_2D,1)告诉OpenGL下面代码中对2D纹理的任何设置都是针对索引为1的纹理的。
产生纹理函数假定目标纹理的面积是由glBindTexture函数限制的。先前调用glGenTextures产生的纹理索引集不会由后面调用的glGenTextures得到,除非他们首先被glDeleteTextures删除。你不可以在显示列表中包含glGenTextures。
glGenLists
GLuint index = glGenLists(10); // 创建10个显示列表
GLubyte lists[10]; // 最多允许渲染10个显示列表
创建一个或多个显示列表对象,它的参数是需要创建的显示列表的数目,它返回连续的显示列表块中的第一个元素的索引。例如,glGenLists()函数如果返回1并且你创建的显示列表的数目为3的话,那么索引1,2,3是可用的。如果OpenGL创建显示列表失败,它将会返回0。如果你不再使用显示列表,可以使用glDeleteLists()删除它们。
第二步,你需要在glNewList()和glEndList()块之间存储OpenGL命令到显示列表中来优先渲染。这个过程叫做编译。glNewList()需要两个参数,第一个参数是glGenLists()函数返回的索引值,第二个参数是指定模式:是只编译还是编译并执行,GL_COMPLILE,GL_COMPLILE_AND_EXECUTE。
glGetRenderbufferParameteriv
void glGetRenderbufferParameteriv(GLenum target,GLenum param, GLint* value)
你也可以得到现在正在使用的渲染缓冲区的参数。target必须是GL_RENDERBUFFER,第二个参数是要获得的参数的名字,最后一个参数是指向存储返回的整型变量的指针。可使用的渲染缓冲区的参数的名字的名字如下:
GL_RENDERBUFFER_WIDTH
GL_RENDERBUFFER_HEIGHT
GL_RENDERBUFFER_INTERNAL_FORMAT
GL_RENDERBUFFER_RED_SIZE
GL_RENDERBUFFER_GREEN_SIZE
GL_RENDERBUFFER_BLUE_SIZE
GL_RENDERBUFFER_ALPHA_SIZE
GL_RENDERBUFFER_DEPTH_SIZE
GL_RENDERBUFFER_STENCIL_SIZE
glGetFloatv(GL_MODELVIEW_MATRIX, m)
将GL_MODELVIEW矩阵的16个值加载到m中
glGenVertexArrays
创建点顶数组对象VAO
GLuint VAO;
glGenVertexArrays(1, &VAO);
glGenerateMipmaps
创建多级纹理。
就像纹理过滤一样,我们可以使用glTexParameteri将过滤方式设置为前面四种提到的方法之一:
过滤方式 | 描述 |
---|---|
GL_NEAREST_MIPMAP_NEAREST | 使用最邻*的多级渐远纹理来匹配像素大小,并使用邻*插值进行纹理采样 |
GL_LINEAR_MIPMAP_NEAREST | 使用最邻*的多级渐远纹理级别,并使用线性插值进行采样 |
GL_NEAREST_MIPMAP_LINEAR | 在两个最匹配像素大小的多级渐远纹理之间进行线性插值,使用邻*插值进行采样 |
GL_LINEAR_MIPMAP_LINEAR | 在两个邻*的多级渐远纹理之间使用线性插值,并使用线性插值进行采样 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenBuffersARB
glGenBuffersARB(GLsizei n,GLuint* ids);
创建一个缓冲区对象并且返回这个缓冲区对象的标示。它需要两个参数:第一个参数指示要创建的缓冲区对象的个数,第二个参数指示存放返回一个或多个缓冲区标示的GLuint类型变量或数组的地址。生成一个缓冲区对象
glGenBuffers
GLuint VBO;
glGenBuffers(1, &VBO);
生成顶点缓冲VBO,顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER
glGetUniformLocation
获得shader中Uniform定义的位置
glGetUniformLocation(GLuint program, "model");
glGetProgramiv
检查着色器小程序是否编译连接成功
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
glGetProgramInfoLog
与glGetShaderInfoLog一样,但这个是获得小程序的错误消息.
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
glGetShaderiv
检查GLSL语言是否编译成功
GLuint shader;
glShaderSource(shader,1,&vShaderCode,NULL); //源化vertex
glCompileShader(shader); //编译shader
int success;
char infoLog[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
//如果编译失败
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
}
glGetShaderInfoLog
获取shader错误消息
glGetShaderInfoLog(vertex, 1024, NULL, infoLog);
glGetAttribLocation
获取shader中使用attribute定义的变量
GLint glGetAttribLocation(GLuint program,ch *name);
参数:
program – the handle to the program.
name – the name of the variable
glGetIntegerv
glIndexPointer
指向索引颜色数组
glIsBuffer
GLboolean glIsBuffer(GLuint buffer);
判断是否是缓冲区对像
glLoadMatrix{fd}(m)
将当前矩阵替换成矩阵m
glLoadIdentity
函数说明:
OpenGL为我们提供了一个非常简单的恢复初始坐标系的手段,那就是调用glLoadIdentity()命令。该命令是一个无参的无值函数,其功能是用一个4×4的单位矩阵来替换当前矩阵,实际上就是对当前矩阵进行初始化。也就是说,无论以前进行了多少次矩阵变换,在该命令执行后,当前矩阵均恢复成一个单位矩阵,即相当于没有进行任何矩阵变换状态。
单位矩阵就是对角线上都是1,其余元素皆为0的矩阵。
当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心:类似于一个复位操作
1.X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。
2.OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。
3.中心左面的坐标值是负值,右面是正值。
移向屏幕顶端是正值,移向屏幕底端是负值。
移入屏幕深处是负值,移出屏幕则是正值。
glLoadIdentity()该函数的功能是重置当前指定的矩阵为单位矩阵.在语义上,其等同于用单位矩阵调用glLoadMatrix()。但是,在一些情况下,glLoadIdentity()更加效率。
由于某些原因可能使得当前矩阵中的元素有一些不确定的值,这将导致程序对图形对象进行几何变形时得到一个非预期的结果。因此有必要将当前矩阵初始成 一个单位矩阵,即对图形对象不做任何变换。这就是为什么在调用过glMatrixMode()命令后,总是要调用该命令的原因。由于glMatrixMode()命令本身也是一种矩阵变换,它将当前矩阵变成命令参数所规定的形式,若不用单位矩阵来替换它,在此矩阵下绘制出的图形将是难以预计的。
需要注意的是,用单位矩阵替换当前矩阵并不改变当前矩阵模式。
应当说明的是,用一个单位矩阵来替换当前矩阵的做法并非在任何场合下都可以使用。例如,已经进行了3次矩阵变换,而现在打算将当前矩阵恢复到第二次变换后的状态时,该方法将失效。此时可用glPushMatrix()命令将每次变换前的矩阵压入矩阵堆栈,在进行完新矩阵中的各种操作后,再利用glPopMatrix()命令将栈顶的矩阵弹出矩阵堆栈,成为当前矩阵。
glLoadTransposeMatrix{fd}(m)
将当前矩阵换成其转置矩阵
glLinkProgram
glLinkProgram(ID); //链接程序
把附加的着色器与小程序链接.
glLoadMatrixf
结束编译显示列表。
glListBase
OpenGL为了方便起见提供了glListBase()函数指定当glCallLists()函数执行时添加到显示列表索引的基准。
glMatrixMode
glMatrixMode(GL_PROJECTION);
这个函数其实就是对接下来要做什么进行一下声明,也就是在要做下一步之前告诉计算机我要对“什么”进行操作了,这个“什么”在glMatrixMode的“()”里的选项(参数)有3种模式: GL_PROJECTION 投影, GL_MODELVIEW 模型视图, GL_TEXTURE 纹理.
glMapBuffer
更新缓冲区数据。
GLvoid *glMapBuffer(GLenum target, GLenum access);
glMapBufferARB
VBO使用glMapBufferARB()来将缓冲区对象映射到客户端内存中。
void* glMapBufferARB(GLenum target, GLenum access)
如果OpenGL能将缓冲区映射到客户端的内存中,glMapBufferARB()将返回指向缓冲区的指针,否则返回NULL。
第一个参数,target和上面的glBindBufferARB()一样,第二个参数access指定了对那些映射的数据的操作:读,写或者读写都可以。
GL_READ_ONLY_ARB
GL_WRITE_ONLY_ARB
GL_READ_WRITE_ARB
注意glMapBufferARB()将会导致一个同步的问题。如果GPU依然在顶点缓冲区中工作,那么glMapBufferARB()函数将会在GPU结束在指定的缓冲区的工作之后才返回。
为了避免等待,你可以首先使用一个空指针调用glBufferDataARB()函数,然后调用glMapBufferARB()。在这种情况下,之前的数据将会被舍弃,glMapBufferARB()将立即返回一个新分配区域的指针,即使GPU依然在之前的数据上工作。
然而,这种方法只有在你需要更新整个数据集的时候才有效,因为这样将会舍弃之前的数据。如果你只是希望改变部分数据或者只是希望读取数据,你最好不要舍弃之前的数据。
glMultMatrix{fd}(m)
将当前矩阵乘以矩阵m,并且更新当前矩阵
glMultTransposeMatrix{fd}(m)
将当前矩阵乘以其转置矩阵,并且更新当前矩阵
glNewList
glNewList(index, GL_COMPILE); // 编译第一个显示列表
...
glEndList();
需要两个参数,第一个参数是glGenLists()函数返回的索引值,第二个参数是指定模式:是只编译还是编译并执行,GL_COMPLILE,GL_COMPLILE_AND_EXECUTE。
glNormalPointer
指向法向量数组
glNormalPointer(GLenum type, GLsizei stride, const GLvoid* pointer)
-
type:GL_FLOAT, GL_SHORT, GL_INT 或 GL_DOUBLE。
-
stride:下一个法向量的偏移量(节字数)。
-
pointer:指向顶点数组的指针。
注意顶点数组位于你的应用程序之中(系统内存),它在客户机这端。位于服务器端的OpenGL访问它们。这是为什么对于顶点数组会有与众不同的访问方式:使用glEnableClientState()和glDisableClientState()而不是使用glEnable()和glDisable()。
glOrtho
glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble nFar);
创建一个表示正交*行视景体的矩阵,并把它与当前矩阵相乘。如果观察点为默认情况时,正交*行视景体是由这个函数的参数定义:(left, bottom, -zNear)和(right, top, -zNear)分别指定了*侧裁剪*面左下角和右上角的(x,y,z)坐标。zNear和zFar分别表示从观察点到*侧和远侧裁剪*面的距离,它们可以为正值或负值,甚至可以设置为0,但不能取相同的值。你可以将其想像为数码相机的视野范围(视景体)。
glPolygonMode
以线框模式绘制模型
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode(GL_FRONT,GL_LINE);
参数:
- 第一个参数表示我们打算将其应用到所有的三角形的正面和背面。
- 第二个参数告诉我们用线来绘制。
glPushMatrix
将当前的矩阵压入矩阵栈。
glPopMatrix
从当前的矩阵栈中弹出当前的矩阵
glReadPixels
读取一些像素。当前可以简单理解为“把已经绘制好的像素(它可能已经被保存到显卡的显存中)读取到内存”。
void glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,
GLenum type,GLvoid * data)
- x,y:指定帧缓冲区读取的第一个像素的窗口坐标,此位置是矩形像素块的左下角。
- width,height :指定像素矩形的尺寸。 一个宽度和高度对应于单个像素。
- format:指定像素数据的格式。 接受以下符号值:GL_ALPHA,GL_RGB和GL_RGBA。
- type:指定像素数据的数据类型。 必须是GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT_5_6_5,GL_UNSIGNED_SHORT_4_4_4_4或GL_UNSIGNED_SHORT_5_5_5_1之一,format和type需要匹配。,你可以去查询当前opengl支持的匹配的两者值是多少,查询方法如下:
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE,&eReadType);
glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT,&eReadFormat);
这两个接口可以查询匹配的format和type值。 - data:返回像素数据。
glReadBuffer
功能: 选择接下来的函数调用glReadPixels(), glCopyPixels(), glCopyTexImage*(), glCopyTexSubImage*() 和 glCopyConvolutionFilter*()将读取的缓存.
并启用以前被函数glReadBuffer()启用的缓存.
void glReadBuffer(GLenum mode);
glRenderbufferStorage
void glRenderbufferStorage(GLenum target,
GLenum internalFormat,
GLsizei width,
GLsizei height)
当一个渲染缓冲区对象被创建以后,它不包含任何的数据存储区,因此我们必须为它分配空间。这可以使用glRenderbufferStorage()来实现。第一个参数必须是GL_RENDERBUFFER。第二个参数可以是渲染颜色(GL_RGB,GL_RGBA,等),渲染深度(GL_DEPTH_COMPONENT),或者渲染模板格式(GL_STENCIL_INDEX)。width和height是渲染缓冲区镜像的尺寸(以像素为单位)。
width和height的值应该小于GL_MAX_RENDERBUFFER_SIZE的值,否则会产生一个GL_INVALID_VALUE的错误。
glTexImage2D
生成纹理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
- 第一个参数指定了纹理目标(Target)。设置为GL_TEXTURE_2D意味着会生成与当前绑定的纹理对象在同一个目标上的纹理(任何绑定到GL_TEXTURE_1D和GL_TEXTURE_3D的纹理不会受到影响)。
- 第二个参数为纹理指定多级渐远纹理的级别,如果你希望单独手动设置每个多级渐远纹理的级别的话。这里我们填0,也就是基本级别。
- 第三个参数告诉OpenGL我们希望把纹理储存为何种格式。我们的图像只有RGB值,因此我们也把纹理储存为RGB值。
- 第四个和第五个参数设置最终的纹理的宽度和高度。我们之前加载图像的时候储存了它们,所以我们使用对应的变量。
- 下个参数应该总是被设为0(历史遗留问题)。
- 第七第八个参数定义了源图的格式和数据类型。我们使用RGB值加载这个图像,并把它们储存为char(byte)数组,我们将会传入对应值。
- 最后一个参数是真正的图像数据。
glTexParameter
对单独的一个坐标轴设置(s
、t
(如果是使用3D纹理那么还有一个r
)它们和x
、y
、z
是等价的):
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
-
第一个参数指定了纹理目标;我们使用的是2D纹理,因此纹理目标是GL_TEXTURE_2D。
-
第二个参数需要我们指定设置的选项与应用的纹理轴。我们打算配置的是
WRAP
选项,并且指定S
和T
轴。 -
最后一个参数需要我们传递一个环绕方式,在这个例子中OpenGL会给当前激活的纹理设定纹理环绕方式为GL_MIRRORED_REPEAT。
环绕方式(Wrapping) | 描述 |
---|---|
GL_REPEAT | 对纹理的默认行为。重复纹理图像。 |
GL_MIRRORED_REPEAT | 和GL_REPEAT一样,但每次重复图片是镜像放置的。 |
GL_CLAMP_TO_EDGE | 纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。 |
GL_CLAMP_TO_BORDER | 超出的坐标为用户指定的边缘颜色。 |
如果我们选择GL_CLAMP_TO_BORDER选项,我们还需要指定一个边缘的颜色。这需要使用glTexParameter函数的fv
后缀形式,用GL_TEXTURE_BORDER_COLOR作为它的选项,并且传递一个float数组作为边缘的颜色值:
float borderColor[] = { 1.0f, 1.0f, 0.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexCoordPointer
指向纹理坐标数组
glUnmapBufferARB
GLboolean glUnmapBufferARB(GLenum target)
修改完VBO的数据之后,必须解除掉缓冲区对象和客户端内存的映射。glUnmapBufferARB()成功时会返回GL_TRUE。当它返回GL_FALSE时VBO的内容会被破坏。破坏的原因是窗口分辨率的改变或者系统时间发生了。在这种情况下,数据需要被再次提交。
下面是一个使用映射的方法修改VBO的例子:
// 绑定并映射VBO
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
float* ptr = (float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
// 如果映射成功,则更新VBO
if(ptr)
{
updateMyVBO(ptr, ...); // 修改缓冲区数据
glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); // 解除映射
}
// 使用新的VBO绘图
glUniform1i
glUniform1f
glUniform1f(GLint location,GLfloat v0)
glUniform2fv
glUniform2f
glUniform2f(GLint location,GLfloat v0,GLfloat v1)
glUniform3fv
glUniform3f
glUniform3f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2)
glUniform4f
glUniform4f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)
glUniform4fv
glUniformMatrix2fv
glUniformMatrix3fv
glUniformMatrix4fv
glUseProgram
激活运行着色器小程序
glUseProgram(shaderProgram);
gluLookAt
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz);
定义一个视图矩阵,并将其与当前矩阵相乘。目标观察点由eyex,eyey,eyez指定,centerx, centery, centerz指定了视线上的任意一点。upx,upy和upz指定表示哪个方向是向上的(也就是说,在视景体中至下向上的方向)。你可以将其想像为一个数码相机,放置在一定的位置并使镜头指向一个方向。默认值为gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0),表示数码相机位于原点并指向z轴负方向,以y轴的正方向为向上方向。
gluOrtho2D
gluOrtho2D(0.0,200.0,0.0,150.0);
定义剪裁面,通过正交投影,把景物(模型)按照1:1的比例绘制到一个剪裁面上,相当于对世界坐标窗口的一个截取。
gluPerspective
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
创建一个表示透视视图*截头体的矩阵,并把它与当前矩阵相乘。fovy是yz*面上视野的角度,它的值必须在[0.0, 180.0]之间。aspect是这个*截头体的横纵比,也就是宽度除以高度。如果观察点为默认情况时,zNear和zFar分别表示从观察点到*侧和远侧裁剪*面的距离,它们都应该是正值。该函数是glFrustum(...)函数的替代函数。
视景体有两个用途。首先,视景体定义了一个场景如何映射到屏幕上(即通过透视投影还是正投影);其次,视景体定义了哪此场景(或场景的一部分)被剪裁到最终的图像之外。
透视投影:与我们*时眼睛所见到的物体一样,满足*大远小的原则;正投影:不论物体距离观察点的远*,我们所看到物体的大小保持不变。
glVertexPointer
指向顶点坐标数组指针
glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
-
size:顶点的维数,2表示2维的点,3表示3维的点。
-
type:GL_FLOAT, GL_SHORT, GL_INT 或 GL_DOUBLE。
-
stride:下一个顶点的偏移量。
-
pointer:指向顶点数组的指针
glVertexAttribPointer
顶点属性解析
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
-
第一个参数指定我们要配置的顶点属性。还记得我们在顶点着色器中使用layout(location = 0)定义了position顶点属性的位置值(Location)吗?它可以把顶点属性的位置值设置为0。因为我们希望把数据传递到这一个顶点属性中,所以这里我们传入0。
-
第二个参数指定顶点属性的大小。顶点属性是一个vec3,它由3个值组成,所以大小是3。
-
第三个参数指定数据的类型,这里是GL_FLOAT(GLSL中vec*都是由浮点数值组成的)。
-
下个参数定义我们是否希望数据被标准化(Normalize)。如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。我们把它设置为GL_FALSE。
-
第五个参数叫做步长(Stride),它告诉我们在连续的顶点属性组之间的间隔。由于下个组位置数据在3个GLfloat之后,我们把步长设置为3 * sizeof(GLfloat)。要注意的是由于我们知道这个数组是紧密排列的(在两个顶点属性之间没有空隙)我们也可以设置为0来让OpenGL决定具体步长是多少(只有当数值是紧密排列时才可用)。一旦我们有更多的顶点属性,我们就必须更小心地定义每个顶点属性之间的间隔,我们在后面会看到更多的例子(译注: 这个参数的意思简单说就是从这个属性第二次出现的地方到整个数组0位置之间有多少字节)。
最后一个参数的类型是GLvoid*,所以需要我们进行这个奇怪的强制类型转换。它表示位置数据在缓冲中起始位置的偏移量(Offset)。由于位置数据在数组的开头,所以这里是0。我们会在后面详细解释这个参数
glVertexAttribDivisor
glPatchParameteri
void glPatchParameteri(GLenum pname, GLint value);
/**
* 使用value来指定一个patch中的顶点个数。pname必须设置为GL_PATCH_VERTICES。
* 如果value小于零或大于GL_MAX_PATCH_VERTICES,将会产一个GL_INVALID_ENUM的错误。
* 一个patch的默认顶点个数是三。如果一个patch的顶点个数小于参数value值,那么该patch将被忽略,从而不会有几何图形产生。
*/
glPatchParameteriv
glViewport
glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
在窗口中定义一个像素矩形,最终的图像会映射到这个矩形中。(x,y)指定了的视口的左下角,width和height指定了这个视口矩形的宽度和高度。在默认情况下,视口的初始值为(0, 0, winWidth, winHeight),其中winWidth和winHeight指定了窗口大小。你可以将其想像为数码相机的显示屏,是最终成像的地方。
glVertexAttrib1f
void glVertexAttrib1f(GLint location, GLfloat v0);
glVertexAttrib2f
void glVertexAttrib2f(GLint location, GLfloat v0, GLfloat v1);
glVertexAttrib3f
void glVertexAttrib3f(GLint location, GLfloat v0, GLfloat v1,GLfloat v2);
glVertexAttrib4f
void glVertexAttrib4f(GLint location, GLfloat v0, GLfloat v1,,GLfloat v2, GLfloat v3);
或者
GLint glVertexAttrib{1,2,3,4}fv(GLint location, GLfloat *v);
参数:
location – the previously queried location.
v0,v1,v2,v3 – float values.
v – an array of floats.
glShaderSource
把着色器源码附加到着色器对像。
glShaderSource(vertexShader,1,&vertexShaderSource);
- 第1个参数为要编译的着色器对象
- 第2个参数为传递源码的字符串数量这里只有1
- 第3个为顶点着色器真正的源码
- 第4个参数我们先设置为NULL
OpenGL Macro
GL_ARRAY_BUFFER
缓冲类型为VBO,顶点缓冲对象,一般在绑定类型时使用。
GL_ELEMENT_ARRAY_BUFFER
缓冲类型为EBO,索引缓冲对象,一般在绑定类型时使用。
GL_DEPTH_CLAMP
开启深度截取功能
GL_STENCIL_TEST
模板测试
GL_FRONT_AND_BACK
应用正面和背面
GL_LINE
用线来绘制
GL_VERTEX_SHADER
创建的是点顶shader着色器
GL_FRAGMENT_SHADER
创建的是片段着色器
纹理环绕方式
环绕方式(Wrapping) | 描述 |
---|---|
GL_REPEAT | 对纹理的默认行为。重复纹理图像。 |
GL_MIRRORED_REPEAT | 和GL_REPEAT一样,但每次重复图片是镜像放置的。 |
GL_CLAMP_TO_EDGE | 纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。 |
GL_CLAMP_TO_BORDER | 超出的坐标为用户指定的边缘颜色。 |
GL_UNSIGNED_INT
GL_UNSIGNED_BYTE
GL_TRIANGLES
绘制三角形
GL_VERTEX_ARRAY
顶点数组
GL_MAX_COLOR_ATTACHMENTS
查询显卡支持的颜色顶点的最大数。
GLFW
glfwInit
用于初始化opengl。
glfwGetTime
要创建*滑的动画,需要时间源。 GLFW提供一个计时器,该计时器返回自初始化以来的秒数。该时间源在每个*台上都是最准确的,而且精确到微秒或纳秒级。
double time = glfwGetTime();
glfwSwapBuffers
glfwSwapBuffers(window);
GLFW在默认情况下使用两个缓冲区。 这意味着每个窗口有两个渲染缓冲区——前缓冲区和后缓冲区。 前缓冲区是正在显示的缓冲区,后缓冲区是即将显示的缓冲区。
当整个帧已经被渲染时,缓冲器需要彼此交换,因此后缓冲器变为前缓冲器,反之亦然。
glfwSwapInterval
glfwSwapInterval(1);
交换间隔表示交换缓冲区之前等待的帧数,通常称为vsync。 默认情况下,交换间隔为0,但因为屏幕每秒只更新60-75次,所以大部分的画面不会被显示。而且,缓冲区有可能在屏幕更新的中间交换,出现屏幕撕裂的情况。
所以,可以将该间隔设为1,即每帧更新一次。 它可以设置为更高的值,但这可能导致输入延迟。
glfwWindowHint
用于设置opengl版本。
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//如果使用macos需要添加如下一句才会支持窗口显示
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);
#endif
glfwMakeContextCurrent
glfwMakeContextCurrent(window);
设置上下文。
glfwSetInputMode
输出模式。
glfwSetInputMode(window,GLFW_CURSOR,GLFW_CURSOR_DISABLED); //捕捉窗口鼠标
glfwGetWindowSize
获得当前窗口大小
glfwWindowShouldClose
检查窗口是否被关闭。
glfwMakeContextCurrent(window);
glfwDestroyWindow
关闭窗口,此函数一旦被调用,将不会再有任何事件产生,并且该句柄将无效。
glfwDestroyWindow(window);
glfwGetFramebufferSize
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
当窗口大小改变的时候,你可以使用glfwSetFramebufferSizeCallback回调函数重新设置尺寸。
callBlack函数
glfwSetWindowCloseCallback
检查窗口关闭后立即调用,当用户关闭窗口后会立即调用该函数。
glfwSetKeyCallback
glfwSetKeyCallback(window,key_callback); //设置键盘回调函数
glfwSetCursorPosCallback
glfwSetCursorPosCallback(window,mouse_callback); //设置鼠标回调函数
glfwSetFramebufferSizeCallback
设置帧缓冲大小回调函数。
glfwSetFramebufferSizeCallback(window,FramebufferSizeCallback);
GLFW Macro
-
action 按键动作
- GLFW_RELEASE 松开
- GLFW_PRESS 按下
- GLFW_REPEAT 重复,一直按着
-
mods 按键模式
- GLFW_MOD_SHIFT 按下Shift键
- GLFW_MOD_CONTROL 按下Ctrl键
- GLFW_MOD_ALT 按下Alt键
- GLFW_MOD_SUPER
-
key 键盘按键
- GLFW_KEY_W 键盘w键
bool keyPressedStatus[1024]; // 按键情况记录 if (keyPressedStatus[GLFW_KEY_W]) camera.handleKeyPress(FORWARD, deltaTime);
-
GLFW_KEY_S 键盘s键。
-
GLFW_KEY_A 键盘a键。
-
GLFW_KEY_D 键盘d键。
-
FORWARD 向前
-
BACKWARD 后
-
LEFT 左
-
RIGHT 右
GLM
pitch
roll
yaw
pi
pi=3.1415926
log
ceil
floor
clamp
cross
dot
max
最大值
min
最小值
mix
normalize
归一化
glm::mat3
glm::mat4
glm::make_mat4
//创建矩阵
float initArray[16]; initArray[0]=1; //..赋值其余数据 glm::mat4 matCreate=glm::make_mat4(initArray);
glm::make_quat
创建四元数
glm::fquat
四元数
glm::value_ptr
//矩阵到数组
float* matArray=glm::value_ptr(mat);
glm::mat4_cast
转为mat4
glm::fquat poseQuat = glm::fquat(qw,qx,qy,qz);
glm::mat4 poseMat = glm::mat4_cast(poseQuat); //将一个四元数转换为mat4矩阵
glm::ortho
创建正射投影矩阵
glm::ortho(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
前两个参数指定了*截头体的左右坐标,第三和第四参数指定了*截头体的底部和上部。通过这四个参数我们定义了**面和远*面的大小,然后第五和第六个参数则定义了**面和远*面的距离。这个指定的投影矩阵将处于这些x,y,z范围之间的坐标转换到标准化设备坐标系中。
glm::perspective
创建一个透视投影矩阵
glm::mat4 proj = glm::perspective(45.0f, (float)width/(float)height, 0.1f, 100.0f);
参数:
- 定义fov值,表示视野,这里设定45.0f
- 第二个参数设置宽高比,由视口的高除以宽。
- 第三和第四个参数设置了截头体的*和远*面。
glm::frustum
视锥体
glm::mat4 Projection = glm::frustum(-1.234897f*0.1f, 1.234897f*0.1f, -1.234897f*0.1f, 1.2/34897f*0.1f, 0.1f, 1000.0f);
glm::radians
glm::radians(45.0);
角度转弧度。
glm::translate
位移
glm::scale
缩放
glm::mat4 trans = glm::mat4(1.0f); //创建初始单位矩阵
trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5)); //缩放0.5
glm::rotate
旋转
glm::mat4 trans = glm::mat4(1.0f); //创建初始单位矩阵
trans = glm::rotate(trans, 90.0f, glm::vec3(0.0, 0.0, 1.0)); //围绕z轴旋转90度
GLSL
https://blog.csdn.net/jeffasd/article/details/52139262
基本类型
类型 | 描述 | 例子 |
---|---|---|
void | 跟C语言的void类似,表示空类型。作为函数的返回类型,表示这个函数不返回值。 | |
bool | 布尔类型,可以是true 和false,以及可以产生布尔型的表达式。 | |
int | 整型 代表至少包含16位的有符号的整数。可以是十进制的,十六进制的,八进制的。 | |
float | 浮点型 | |
bvec2 | 包含2个布尔成分的向量 | |
bvec3 | 包含3个布尔成分的向量 | |
bvec4 | 包含4个布尔成分的向量 | |
ivec2 | 包含2个整型成分的向量 | |
ivec3 | 包含3个整型成分的向量 | |
ivec4 | 包含4个整型成分的向量 | |
mat2或mat2x2 | 2x2的浮点数矩阵类型 | |
mat3或mat3x3 | 3x3的浮点数矩阵类型 | |
mat4x4 | 4x4的浮点矩阵 | |
mat2x3 | 2列3行的浮点矩阵(OpenGL的矩阵是列主顺序的) | |
mat2x4 | 2列4行的浮点矩阵 | |
mat3x2 | 3列2行的浮点矩阵 | |
mat3x4 | 3列4行的浮点矩阵 | |
mat4x2 | 4列2行的浮点矩阵 | |
mat4x3 | 4列3行的浮点矩阵 | |
sampler1D | 用于内建的纹理函数中引用指定的1D纹理的句柄。只可以作为一致变量或者函数参数使用 | |
sampler2D | 二维纹理句柄 | |
sampler3D | 三维纹理句柄 | |
samplerCube | cube map纹理句柄 | |
sampler1DShadow | 一维深度纹理句柄 | |
sampler2DShadow | 二维深度纹理句柄 | |
attribute
随不同顶点变化的全局变量,事实上属性变量可以在任何时刻更新,由OpenGL应用程序传给顶点shader。这个修饰符只能用在顶点shader中,在shader中它是一个只读变量。
uniform
定义一个变量,可在glsl外使用glGetUniformLocation()读取赋值。
varying
用于顶点shader和片断shader间传递的插值数据,在顶点shader中可写,在片断shader中只读。
clamp
把一个参数固定在0.0-1.0之间。用于保证一些值不会超出[0,1]以外。
normalize
法线归一化,把较大的数归一到0.0-1.0之间方便计算。
reflect
reflect(-lightDir,norm);
反射,第一个参数是从光源指向片段位置的向量。第二个参数要求是一个法向量。
transpose
texture
纹理函数
inverse
反转
sampler2D
2D采样器。
max
求最大值
dot
矩阵的点乘。
pow
求幂函数
mat2
2X2矩阵
mat3
3X3矩阵。
mat4
4X4矩阵
vec2
2维向量
vec2(1.0,2.0);
vec3
3维向量
vec3(1.0,0.0,1.0);
vec4
4维向量
vec4(vec3(1.0),1.0);
frac
截取浮点数的小数部分
floor
向下取整,即保留浮点数的整数部分
trunc
丢弃浮点数的小数部分
int
同trunc
fmod
浮点数求余
GLSL内置变量
gl_Position
顶点变换
gl_ProjectionMatrix
gl_ModelViewMatrix
gl_ModelViewProjectionMatrix
是gl_ProjectionMatrix 和 gl_ModelViewMatrix 的乘积.
gl_Color
vec4类型,输入属性表示顶点的主颜色。
gl_FragColor
片断着色器中的颜色值
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
在某此glsl版本中,可能会出现不可用。我们也可以用以下语句进行color输出。
#version 330 core
in vec3 fColor;
out vec4 color;
void main() {
color = vec4(fColor,1.0f);
}
gl_FragCoord
gl_FragCoord是fragment shader的输入变量只读。gl_FragCoord 的 X 和 y 表示该片段的屏幕空间坐标 ((0,0) 在左下角)。gl_FragCoord 还包含一个 z 坐标,它包含了片段的实际深度值。此 z 坐标值是与深度缓冲区的内容进行比较的值。
gl_InstanceID
宣染多实例时获取每个实例id,gl_InstanceID的初值是0,它在每个实例渲染时都会增加1。如果我们渲染43个实例,那么在顶点着色器gl_InstanceID的值最后就是42。每个实例都拥有唯一的值意味着我们可以索引到一个位置数组,并将每个实例摆放在世界空间的不同的位置上。
#version 330 core
layout (location = 0) in vec2 position;
layout (location = 1) in vec3 color;
out vec3 fColor;
uniform vec2 offsets[100];
void main()
{
vec2 offset = offsets[gl_InstanceID];
gl_Position = vec4(position + offset, 0.0f, 1.0f);
fColor = color;
}