使用帧缓冲区进行三维交互
来源:互联网 发布:学会python要多久 编辑:程序博客网 时间:2024/05/01 19:42
帧缓冲区是图形绘制流水线的末端,图形流水线绘制出来的画面被保存在默认的帧缓冲区对象中供显示终端使用。我们也可以创建自己的缓冲区对象,将图形流水线的处理结果保存下来做进一步的使用,比如可以使用帧缓冲区对象进行三维图形的交互编辑操作。
三维图形交互编辑的基本思路是使用同样的数据绘制两次,第一次绘制的时候绑定自己创建的缓冲区对象,并在帧缓冲区中保存最终屏幕中各个像素对应的实际坐标和图元编号,然后通过void glReadPixels(GLint x,GLint y, GLsizei width,GLsizeiheight,GLenum format,GLenum type,GLvoid * data)读取这些信息。第一次渲染获得的信息可以判断当前鼠标点击的是哪一个图元,以及鼠标位置的实际坐标,第二次渲染绑定到默认的缓冲区对象,并利用这些信息对选中的图元进行高亮显示。
假设现在有两个三角形,我们需要将选中的三角形高亮显示,那么我们可以做如下操作:
1. 创建一个缓冲区对象
glGenFramebuffers(1,&fboHandle);
glBindFramebuffer(GL_FRAMEBUFFER,fboHandle);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1,&targetTex);
glBindTexture(GL_TEXTURE_2D,targetTex);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,800, 800, 0, GL_RGBA,
GL_UNSIGNED_BYTE,NULL);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,targetTex, 0);
GLuint depthBuf;
glGenRenderbuffers(1,&depthBuf);
glBindRenderbuffer(GL_RENDERBUFFER,depthBuf);
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT,
800, 800);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER,depthBuf);
GLenum drawBufs[] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1,drawBufs);
//检测帧缓冲区的状态
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!= GL_FRAMEBUFFER_COMPLETE)
{
cerr << "Frame buffererror" << endl;
_getch();
//exit(1);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
2. 创建两个着色器程序,第一渲染的时候绑定到帧缓冲区fboHandle,使用的着色器程序如下:
//vertex shader
#version430
layout(location= 0) in vec4 position;
out vec3pixelCoords;
voidmain()
{
pixelCoords = position.xyz;
gl_Position = position;
}
//fragment shader
#version430
layout(location= 0) out vec4 fragColor;
in vec3pixelCoords;
in vec2coords;
voidmain()
{
//第四个分量会被裁剪到0.0~1.0
//gl_PrimitiveID的默认值是0
fragColor = vec4(pixelCoords.xyz,float(gl_PrimitiveID + 1) * 0.1);
}
需要特别注意的是,创建帧缓冲区的时候使用的纹理格式是RGBA,所以fragColor的四个分量范围会被裁剪到[0.0, 1.0]。gl_PrimitiveID是GLSL的内置变量,代表图元的编号,它的默认值是0,而第一个图元的gl_PrimitiveID值也是0,为加以区别,在传递的时候加了1。
3. 第一次渲染后,读取帧缓冲区中的内容
glBindFramebuffer(GL_READ_BUFFER,fboHandle);
glReadBuffer(GL_COLOR_ATTACHMENT0);
float pixels[4];
glReadPixels(x,y, 1, 1, GL_RGBA,GL_FLOAT,(void*)pixels);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_READ_BUFFER, 0);
像素x,y对应的实际坐标和图元被读取到pixels[4]后,对第二次渲染使用的着色器程序变量进行设置
int selectID = pixels[3] *10.0 + 0.5;
GLint loc =glGetUniformLocation(renderProgram, "selectPrimitiveID");
if (loc < 0)
{
cerr << "ERROR : 无法获取参数selectPrimitieID" << endl;
}
4.第二次渲染绑定到默认的缓冲区对象,使用的着色器程序如下:
//vertex shader
#version430
layout(location= 0) in vec4 position;
layout(location= 1) in vec2 texCoord;
out vec2coords;
voidmain()
{
coords = texCoord;
gl_Position = position;
}
//fragment shader
#version430
layout(location= 0) out vec4 fragColor;
uniformsampler2D Tex;
uniformint selectPrimitiveID;
in vec2coords;
voidmain()
{
fragColor = texture2D(Tex, coords);
if(gl_PrimitiveID == (selectPrimitiveID - 1)&& selectPrimitiveID > 0)
{
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
}
绑定到默认的缓冲区后,被选中的三角形将会高亮显示。
- 使用帧缓冲区进行三维交互
- 三维交互开发(3)-使用脚本
- wpf三维模型中进行二维交互介绍
- 使用DirectInput进行交互
- 使用后缓冲区进行物体选择
- dxsudio三维交互初见
- Jsp中使用xmlhttp进行数据交互~
- Jsp中使用xmlhttp进行数据交互~
- Jsp中使用xmlhttp进行数据交互
- Androguard使用androlyze.py进行交互分析
- python 使用mechanize进行web网页交互
- 使用HttpURLConnection 与 sae 进行数据交互
- 使用 okhttp 与 sae 进行数据交互
- Python使用paramiko进行远程交互
- 使用WebViewJavascriptBridge进行iOS与H5交互
- PHP:使用PDO与数据库进行交互
- 使用vue-resource进行数据交互
- 使用vue-resource进行数据交互
- AlertDialog的初步了解
- 新手必看之UILabel
- Codeforces Round #328 (Div. 2)
- Django中与Html相关的filter
- UFT
- 使用帧缓冲区进行三维交互
- 王爽第九章依据位移进行转移的jmp指令
- hdu1248寒冰王座【完全背包入门题】
- HANA学院(7)- (5)从SAP HANA Studio连接到SAP HANA
- jfinal集成spring cxf做webservice服务
- [sicily]1509. Rails
- 软件工程师进阶系列——万变不离其宗(设计模式下午题大盘点)
- linux 套接口缓存
- 正确理解hadoop 2.x 的环形缓冲区: (一) MR环形缓冲区的结构