OpenGL除了颜色缓冲区、深度缓冲区、模板缓冲区之外,还有累积缓冲区。累积缓冲区允许你把渲染到颜色缓冲区的值,拷贝到累积缓冲区。在多次拷贝操作到累积缓冲区时,可以用不同方式的把颜色缓冲区内容和当前累积缓冲区的内容进行重复混合。当在累积缓冲区完成一幅图像之后,可以拷回颜色缓冲区,然后通过SwapBuffers显示到屏幕上。
累积缓冲区的操作通过void glAccum(GLenum op, GLfloat value);控制。第一个参数表示对累积缓冲区所进行的操作。第二个参数是浮点数用于指定缩放因子。
由于累积缓冲区会带来大内存的开销,所以在实时应用程序中比较少用。但在非实时的应用程序中,可以产生实时应用程序无法做到的效果。例如,你可以多次渲染场景,并在每次渲染时进行抖动零点几个像素,这样就可以产生整个场景的反走样的效果,比多重采样的效果还要好。还可以模糊前景或背景,然后清晰的渲染一个物体来模拟,照相机景深的效果
void DrawGemometry() { glPushMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawGround(); glColor3f(1.0f, 0.0f, 0.0f); glTranslatef(0.0f, 0.3f, -3.5f); glRotatef(-yRot*2.0f, 0.0f, 1.0f, 0.0f); glTranslatef(1.0f, 0.0f, 0.0f); glutSolidSphere(0.1f, 17, 13); glPopMatrix(); } void RenderScene() { yRot = 35.0f; pass = 10.0f; for ( i = 0; i < 2; ++i) { yRot += 0.75f; DrawGemometry(); //复制到累积缓冲区 if (i == 0) { glAccum(GL_LOAD, 0.5f);// 1 } else { //累加到累积缓冲区 glAccum(GL_ACCUM, (0.5f * 1 / pass));//2 } } glAccum(GL_RETURN, 1.0f); glutSwapBuffers(); }
在for循环10中,DrawGemometry将图元绘制到颜色缓冲区中,
glAccum(GL_LOAD, 0.5f);将颜色缓冲区的内容替换到累积缓冲区,
glAccum(GL_ACCUM, (0.5f * 1 / pass)) 将颜色缓冲区的内容添加到累积缓冲区,这样10次内容就都保存到了累积缓冲区。
glAccum(GL_RETURN, 1.0f);将累积缓冲区的内容拷贝到颜色缓冲区然后再进行翻页显示到屏幕上
void glAccum (GLenum op, GLfloat value);
op:GL_ACCUM,读取当前缓冲区中每个像素,把R,G,B,A值与value值相乘,然后把结果添加到累积缓冲区
GL_LOAD:于ACCUM功能基本相同,不同的是ACCUM是把结果添加到累积缓冲区,GL_LOAD是把结果替换到累积缓冲区
GL_RETURN从累积缓冲区接收值,把他们与value值相乘,然后把结果放入颜色缓冲区中
GL_ADD,把每个像素值与与value值相加,超出范围不会截取
GL_MULIT:把每个像素值与与value值相乘,范围控制在【-1,+1】
颜色通道屏蔽
void glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
例如,屏蔽R通道 glColorMask(GL_FALSE,GL_TRUE,GL_TRUE,GL_TRUE);
剔除操作
glEnalbe(GL_CULL_FACE) 开启剔除操作效果
glDisable(GL_CULL_FACE) 关闭剔除操作效果
glCullFace()参数包括GL_FRONT和GL_BACK。表示禁用多边形正面或者背面上的光照、阴影和颜色计算及操作,消除不必要的渲染计算。
例如某对象无论如何位置变化,我们都只能看到构成其组成的多边形的某一面时,可使用该函数。
抖动
抖动允许只有少量离散颜色的显示系统来模拟更宽范围的颜色。例如,灰色可以通过白点和黑点的混合来模拟。白点多于黑点呈现浅灰色,黑点多于白点呈现深灰色。这种技巧对于只支持8位和16位的显示系统非常有用。抖动的效果可以大幅度地改善低端颜色系统的图像质量。在默认情况下,抖动是打开的。可以通过glEnable(GL_DITHER)/glDisable(GL_DITHER)来打开或关闭它。在高颜色分辨率的显示系统中,OpenGL的实现可能不需要抖动,会禁用抖动来避免性能的开销。
#include "header.h" GLfloat fLightPos[4] = { -100.0f, 100.0f, 50.0f, 1.0f }; GLfloat fNoLight[] = { 0.0f, 0.0f, 0.0f, 0.0f }; GLfloat fLowLight[] = { 0.25f, 0.25f, 0.25f, 1.0f }; GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f }; static GLfloat yRot; void DrawGround() { GLfloat fExtent = 20.0f; GLfloat y = -0.0f; GLfloat step = 0.5f; GLfloat x, z; int iColor = 0; glShadeModel(GL_FLAT); for (x = -fExtent; x <= fExtent; x += step) { glBegin(GL_TRIANGLE_STRIP); for (z = fExtent; z >= -fExtent; z -= step) { if ((iColor % 2) == 0) { glColor4f(0.0f, 0.0f, 0.0f, 0.5f); } else { glColor4f(1.0f, 1.0f, 1.0f, 0.5f); } glVertex3f(x, y, z); glVertex3f(x + step, y, z); iColor++; } glEnd(); } glShadeModel(GL_SMOOTH); } void DrawGemometry() { glPushMatrix(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawGround(); glColor3f(1.0f, 0.0f, 0.0f); glTranslatef(0.0f, 0.3f, -3.5f); glRotatef(-yRot*2.0f, 0.0f, 1.0f, 0.0f); glTranslatef(1.0f, 0.0f, 0.0f); glutSolidSphere(0.1f, 17, 13); glPopMatrix(); } GLfloat pass = 10.0f; int i; void RenderScene() { yRot = 35.0f; pass = 10.0f; for ( i = 0; i < 20; ++i) { yRot += 0.75f; DrawGemometry(); //复制到累积缓冲区 if (i == 0) { glAccum(GL_LOAD, 0.5f); } else { //累加到累积缓冲区 glAccum(GL_ACCUM, (0.5f * 1 / pass)); } } glAccum(GL_RETURN, 1.0f); glColorMask(GL_FALSE,GL_TRUE,GL_TRUE,GL_TRUE); glutSwapBuffers(); } GLfloat faspect; void ChangeSize(GLsizei w, GLsizei h) { if (h == 0) h = 1; glViewport(0, 0, w, h); faspect = (GLfloat)w/(GLfloat)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(35.0f, faspect, 1.0f, 50.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, -0.4f, 0.0f); glutPostRedisplay(); } void SetupRC() { glClearColor(0.25f, 0.25f, 0.25f, 1.0f); glClearAccum(0,0,0,0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CCW); //设置光照 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fNoLight); glLightfv(GL_LIGHT0, GL_AMBIENT, fLowLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight); glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight); glLightfv(GL_LIGHT0, GL_POSITION, fLightPos); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); //开启颜色追踪 glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); glMateriali(GL_FRONT, GL_SHININESS, 128); } int main(int args, char **argv) { glutInit(&args, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_ACCUM); glutInitWindowSize(800, 600); glutCreateWindow("累积缓冲区"); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); SetupRC(); glutMainLoop(); return 0; }
相关推荐
**glClearAccum**: 设置累积缓冲区的清除值。 - **功能描述**:定义累积缓冲区的清除值。 **glClearColor**: 设置颜色清除值。 - **功能描述**:定义颜色缓冲区的清除颜色。 **glClearDepth**: 设置深度清除值。 -...
1. **初始化OpenGL上下文**:创建GLFW或SDL这样的窗口系统,设置OpenGL版本,并创建一个绘图缓冲区。 2. **设置模型视图矩阵**:通常,你将使用`glMatrixMode(GL_MODELVIEW)`切换到模型视图矩阵,这是应用几何变换...
1. `glAccum`:这个函数用于操作累加缓冲区,累加缓冲区在高级渲染技术中用于实现抗锯齿、光照累积等效果。 2. `glAlphaFunc`:定义了alpha测试的条件,允许根据指定的比较函数和参照值决定像素是否应该被写入帧...
但是它并不是一个真正的缓冲区,因为 OpenGL 并没有为它分配存储空间去存储渲染所需的几何、像素数据,我们可以认为它是一个指针的集合,这些指针指向了颜色缓冲区、深度缓冲区、模板缓冲区、累积缓冲区等这些真正的...
OpenGL是计算机图形学中的一种广泛应用的编程接口,用于在各种操作系统和硬件上生成二维和三维图像。本资源是一个专门展示OpenGL重要函数功能的演示程序,它通过一个可执行的小工程,帮助用户直观地理解图形变换和...
OpenGL的帧缓冲区包含了颜色缓冲区、深度缓冲区、模板缓冲区和累积缓冲区等,为了有效地使用这些缓冲区,需要指定特定的像素格式。在Windows环境下,通常使用PIXELFORMATDESCRIPTOR结构体来定义这些属性。这些属性...
每个子例程都有详细的描述,例如`glAccum`用于累积缓冲区操作,`glAlphaFunc`用于设置像素选择测试,而`glBindTexture`则用于绑定纹理对象到指定的目标。 此外,手册还涵盖了OpenGL的初始化、状态管理、渲染管道、...
- **功能**: 对当前像素缓冲区执行累积操作。通常用于图像处理和特殊效果。 **2. glAddSwapHintRectWIN** - **功能**: Windows特有函数,为提高交换缓冲区效率提供暗示。 **3. glAlphaFunc** - **功能**: 设置透明...
OpenGL中涉及多种类型的缓冲区,包括但不限于: - **像素缓存**:主要用于存储最终输出到屏幕上的像素数据。在RGBA模式下,每个像素的值由红、绿、蓝、alpha四个分量组成;而在索引模式下,则存储的是颜色索引。 - ...
8. **渲染流程**:典型的OpenGL渲染流程包括初始化、设置投影和模型视图矩阵、处理输入、清除缓冲区、绘制几何形状、交换缓冲区和检查退出条件。在本示例中,可能会有一个主循环来处理这些步骤。 9. **深度测试**:...
copy.c演示回读帧缓冲区和缩放像素的程序。 depth.c用于测试深度缓冲的简单程序。 logo.c测试不是那么简单,它可以进行各种各样的工作(有关更多详细信息,请参见源代码)。 nurb.c简单的nurb(非均匀有理b样条...
GLKView是基于OpenGL ES的视图,它包含了对OpenGL ES上下文的配置和管理,同时提供了将OpenGL ES渲染的目标设置为其自身的缓冲区的能力。 GLKBaseEffect是GLKit框架中的核心类,它封装了许多基本的OpenGL ES着色器...
- **清屏操作**:使用 `glClear` 清除颜色缓冲区和深度缓冲区。 - **绘制圆环** - 使用 `glLineWidth` 设置线条宽度。 - 外圈圆和内圈圆分别使用不同的半径进行绘制。 - 循环 `circle_points` 次,每次计算一个...
在OpenGL中,帧缓冲区可以被用来实现双缓冲、累积缓冲、浮点缓冲等技术。 纹理映射 纹理映射是一种将图像应用于3D模型的技术。它可以用于实现各种图形效果,如木纹、石纹、金属纹等。在OpenGL中,纹理映射可以被...
累积缓冲区是OpenGL提供的一种特性,它允许将多个帧的渲染结果存储并合并,从而实现抗闪烁效果或者复杂的光照运算。在早期的硬件中,这尤其有用,因为它们可能无法在单个帧内稳定地渲染复杂的场景。累积缓冲区可以...
19. `glDrawBuffer`:设置帧缓冲区的绘制目标,可以是颜色缓冲区、累积缓冲区等。 20. `glEdgeFlag, glEdgeFlagPointer`:用于定义图形的边缘标志,控制边缘的可见性。 21. `glEnable, glDisable, ...
7. **帧缓冲和渲染循环**:在主程序中通常有一个无限循环,不断地清除帧缓冲,执行绘制命令,然后交换缓冲区以显示结果,这就是所谓的渲染循环。 通过这个OpenGL光照的实例,开发者可以学习到如何综合运用这些技术...
累积缓冲器用于解决颜色缓冲器的精度问题,特别适用于需要高精度颜色合成的场景,如透明效果。模板缓冲器则作为一个额外的控制层,可以用来创建遮罩或限制绘制区域,例如仅在特定区域内绘制物体。 **纹理映射** ...