用FBO绘制到渲染缓冲区
Draw to renderbuffer with FBO
我的问题非常接近这个:FBO和渲染到renderbuffer。我目前正在尝试在renderbuffer上渲染一个简单的三角形,就像本教程中一样。我的程序是Igor Pro的一个插件,它使用OpenGL执行屏幕外渲染。
不幸的是,当我试图读取像素值时,我只得到零。我已经知道initBuffers
函数是有效的,问题出在display
函数上。
2)我想渲染一个顶点数据列表,而不使用直接模式。我以前用vbo做过一个实现。我可以重用这些代码吗?
我的代码如下:/*
RenderTriangle.cpp
*/
#include "VC10triangulation.h"
#include "XOPStandardHeaders.h" // Include ANSI headers, Mac headers, IgorXOP.h, XOP.h and XOPSupport.h
#include <vector>
// Prototypes
HOST_IMPORT int main(IORecHandle ioRecHandle);
// Global Variables
const int windowSize = 512;
int size,el_size;
float* waveX=NULL;
float* waveY=NULL;
float* waveZ=NULL;
GLuint framebuffer, renderbuffer;
// Custom error codes
#define OLD_IGOR 1 + FIRST_XOP_ERR
#define NON_EXISTENT_WAVE 2 + FIRST_XOP_ERR
#define REQUIRES_SP_OR_DP_WAVE 3 + FIRST_XOP_ERR
#pragma pack(2) // All structures passed to Igor are two-byte aligned.
typedef struct WaveParams {
waveHndl waveZ;
waveHndl waveY;
waveHndl waveX;
double result;
} WaveParams, *WaveParamsPtr;
#pragma pack() // Restore default structure alignment
// Prototypes of the OpenGL callbacks
void initBuffers(void);
void display(void);
void readPixels(void);
void initBuffers(void){
GLenum status;
//Generate the fbo where we will bind a render buffer object
glGenFramebuffers(1,&framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,framebuffer);
//Generate render buffer object
glGenRenderbuffers(1,&renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER,renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA8, windowSize, windowSize);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
XOPNotice("Error Framebuffer Complete");
else
XOPNotice("Framebuffer Complete");
}
void display(void){//display a simple triangle
glViewport(0,0,windowSize,windowSize);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClearColor(1.0f, 0.0f, 0.0f,0.5f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);// Drawing Using Triangles
glColor3f(1.0f, 0.0f, 0.0f);glVertex3f( 0.0f, 1.0f, 0.0f);// Top
glColor3f(1.0f, 0.0f, 0.0f);glVertex3f(-1.0f,-1.0f, 0.0f);// Bottom Left
glColor3f(1.0f, 0.0f, 0.0f);glVertex3f( 1.0f,-1.0f, 0.0f);// Bottom Right
glEnd();// Finished Drawing The Triangle
glFlush();
}
// Idle callback function for OpenGL API
void readPixels(void){
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
float* pixels = (float*)malloc(windowSize*windowSize*sizeof(float));
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, windowSize, windowSize, GL_DEPTH_COMPONENT, GL_FLOAT, pixels);
waveHndl waveH;
char waveName[MAX_OBJ_NAME+1];
DataFolderHandle dfH;
CountInt dimensionSizes[MAX_DIMENSIONS+1];
float* wp;
IndexInt p;
double offset, delta;
int err;
strcpy(waveName, "wave1");
dfH = NULL; // Put wave in the current data folder
MemClear(dimensionSizes, sizeof(dimensionSizes));
dimensionSizes[ROWS] = windowSize; // Make 1D wave with 100 points
dimensionSizes[COLUMNS] = windowSize;
if (MDMakeWave(&waveH, waveName, dfH, dimensionSizes, NT_FP32, 1))
XOPNotice("Can't create wave when reading pixel values");
wp = (float*)WaveData(waveH); // Get a pointer to the wave data
for(p = 0; p < windowSize*windowSize; p++)
*wp++ = pixels[p]; // Store point number in wave
}
void deleteBuffers(){
glDeleteFramebuffers(1,&framebuffer);
glDeleteRenderbuffers(1,&renderbuffer);
}
// Main function for the XOP
extern "C" int
RenderTriangle(WaveParamsPtr p)
{
//Pointers to the input waves
waveX=(float*)WaveData(p->waveX);
waveY=(float*)WaveData(p->waveY);
waveZ=(float*)WaveData(p->waveZ);
//Creates the window
char *myargv [1];
int myargc=1, windowHandle;
myargv [0]=strdup ("RenderTriangle");
glutInit(&myargc,myargv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_DEPTH | GLUT_RGB);
glutInitWindowSize(windowSize,windowSize);
windowHandle = glutCreateWindow("OpenGL");
//Init glew library
glewInit();
//Creates the fbo and render buffer object
initBuffers();
display();
readPixels();
//Deletes the fbo and render buffer object
deleteBuffers();
p->result = 1;
return 0;
}
static XOPIORecResult
RegisterFunction()
{
int funcIndex;
funcIndex = (int)GetXOPItem(0); // Which function invoked ?
switch (funcIndex) {
case 0: // y = RenderTriangle(w,x) (curve fitting function).
return (XOPIORecResult)RenderTriangle; // This function is called using the direct method.
break;
}
return 0;
}
/* XOPEntry()
This is the entry point from the host application to the XOP for all
messages after the INIT message.
*/
extern "C" void
XOPEntry(void)
{
XOPIORecResult result = 0;
switch (GetXOPMessage()) {
case FUNCADDRS:
result = RegisterFunction(); // This tells Igor the address of our function.
break;
}
SetXOPResult(result);
}
/* main(ioRecHandle)
This is the initial entry point at which the host application calls XOP.
The message sent by the host must be INIT.
main() does any necessary initialization and then sets the XOPEntry field of the
ioRecHandle to the address to be called for future messages.
*/
HOST_IMPORT int
main(IORecHandle ioRecHandle)
{
XOPInit(ioRecHandle); // Do standard XOP initialization.
SetXOPEntry(XOPEntry); // Set entry point for future calls.
if (igorVersion < 600) {
SetXOPResult(OLD_IGOR);
return EXIT_FAILURE;
}
SetXOPResult(0);
return EXIT_SUCCESS;
}
你需要一个工作的OpenGL上下文为其余的功能,你没有创建一个!您正在使用GLUT作为框架,但是GLUT仅在调用glutCreateWindow
时创建渲染上下文。在此之前,您根本没有活动RC,其余部分将无法工作。
也许Igor本身在某个时候创建了一个OpenGL上下文,而你正在把它放入那个。
比起使用GLUT,你应该使用系统级api来存储当前上下文状态(如果上下文在当前线程中处于活动状态,则为上下文句柄)
如果还没有完成:为你的插件创建一个屏幕外渲染上下文(使用PBuffer或不可见窗口与FBOs一起)
使用自己的上下文进行渲染
还原1中保存的上下文状态
我建议另一个教程:http://www.songho.ca/opengl/gl_fbo.html
但是关于你的代码:
直接渲染到纹理会更简单。这样就没有理由使用glReadPixels了。整个操作将更快,更容易实施。
创建空纹理,并通过glFramebufferTexture2D
将其添加到FBO,渲染后,您可以在纹理中获得结果。
同样,这里有一个使用renderbuffers的示例。
如何在OpenGL上渲染屏幕外?
1)创建上下文2)创建FBO(存储颜色,深度,模板)和绑定3)画4)读回(根据2))
我不确定是否说整个操作将更快,更容易实现纹理是正确的。这完全取决于我们想要做什么(glReadPixels是同步的)。
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- Xaudio2在更改缓冲区或循环时弹出声音
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 多线程双缓冲区
- Android P-9.0.0_r53 Logcat主缓冲区超出定义大小
- 套接字读取后,我在缓冲区中看到意外输入
- std::带有自定义缓冲区的 iostream 不允许我写入
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- OpenGL 16 位模板缓冲区?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 在 openGL 中多次绑定缓冲区
- 将FBO混合到默认帧缓冲区上
- 用FBO绘制到渲染缓冲区