C++ 跟进:异步屏幕外查询性能
我最近问了一个问题: 我听说,但还不能确认,渲染到窗口比渲染到帧缓冲区更昂贵。首先,有人能对此发表评论吗?我能否以比窗口更快的速度将多个场景绘制到帧缓冲区?是否有其他选择,例如PBuffer或PBO 我已经开始使用帧缓冲区,但我无法让查询正常工作。以下是我目前设置的一些psuedo代码:C++ 跟进:异步屏幕外查询性能,c++,opengl,asynchronous,glfw,C++,Opengl,Asynchronous,Glfw,我最近问了一个问题: 我听说,但还不能确认,渲染到窗口比渲染到帧缓冲区更昂贵。首先,有人能对此发表评论吗?我能否以比窗口更快的速度将多个场景绘制到帧缓冲区?是否有其他选择,例如PBuffer或PBO 我已经开始使用帧缓冲区,但我无法让查询正常工作。以下是我目前设置的一些psuedo代码: glfwWindowHint(GLFW_VISIBLE, GL_FALSE); window = glfwCreateWindow(1, 1, "OpenGL", NULL, NULL); glfwMake
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
window = glfwCreateWindow(1, 1, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, size, size);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
glEnable(GL_DEPTH_TEST);
glGenQueries(numberOfQueries, queries);
for (scene in scenesToRender)
{
glClear(GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_LESS);
drawShadingObjects(scene);
glBeginQuery(GL_SAMPLES_PASSED, queries[index]);
glDepthFunc(GL_LEQUAL);
drawShadedObject(scene);
glEndQuery(GL_SAMPLES_PASSED);
}
collectQueryResults();
deleteBuffers();
到目前为止,所有查询都运行,但所有查询都返回“0”。当绘制到帧缓冲区时查询是否与绘制到窗口缓冲区时查询有所不同
我的两个问题是:
试着这样做:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
using namespace std;
const unsigned int sz = 1024;
void drawScene( unsigned int multiplier )
{
glViewport( 0, 0, sz, sz );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef( (float)glfwGetTime() * 50.f * multiplier, 0.f, 0.f, 1.f);
glBegin(GL_TRIANGLES);
glColor3f(1.f, 0.f, 0.f);
glVertex3f(-0.6f, -0.4f, 0.f);
glColor3f(0.f, 1.f, 0.f);
glVertex3f(0.6f, -0.4f, 0.f);
glColor3f(0.f, 0.f, 1.f);
glVertex3f(0.f, 0.6f, 0.f);
glEnd();
}
bool available( const vector< GLuint >& queries )
{
for( size_t i = 0; i < queries.size(); ++i )
{
GLuint available = 0;
glGetQueryObjectuiv( queries[i], GL_QUERY_RESULT_AVAILABLE, &available );
if( GL_FALSE == available )
return false;
}
return true;
}
int main()
{
glfwInit();
GLFWwindow* window = glfwCreateWindow( 400, 400, "Simple example", NULL, NULL );
glfwMakeContextCurrent( window );
glewInit();
if( !glewIsSupported( "GL_VERSION_2_1" ) )
return -1;
if( !glewIsSupported( "GL_EXT_framebuffer_object" ) )
return -1;
GLuint fbo = 0;
glGenFramebuffersEXT( 1, &fbo );
glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, fbo );
GLuint rbo0 = 0;
glGenRenderbuffersEXT( 1, &rbo0 );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo0 );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_RGBA, sz, sz );
glFramebufferRenderbufferEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rbo0 );
GLuint rbo1 = 0;
glGenRenderbuffersEXT( 1, &rbo1 );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo1 );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, sz, sz );
glFramebufferRenderbufferEXT( GL_DRAW_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo1 );
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
return -1;
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
vector< GLuint > queries( 10 );
glGenQueries( queries.size(), &queries[0] );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo );
for( size_t i = 0; i < queries.size(); ++i )
{
glBeginQuery( GL_SAMPLES_PASSED, queries[i] );
drawScene( i + 1 );
glEndQuery( GL_SAMPLES_PASSED );
}
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
// wait for queries to become available
unsigned int cnt = 0;
while( !available( queries ) )
{
cnt++;
}
// all queries available, display query results
cout << "cnt: " << cnt << endl;
for( size_t i = 0; i < queries.size(); ++i )
{
GLuint samples = 0;
glGetQueryObjectuiv( queries[i], GL_QUERY_RESULT, &samples );
cout << i << ": " << samples << endl;
}
cout << endl;
glfwDestroyWindow( window );
glfwTerminate();
return 0;
}
那么您有一个查询还是多个查询?您的
glgenquerys()
和glBeginQuery()
调用似乎不一致。它应该是多个查询。我会解决的。这个想法是,在绘制其他场景时,可能会发生一些异步查询。您的代码在我的机器上运行良好,我已经实现了与我的代码(主要包括FBO的颜色附件)的显著差异。无论出于何种原因,我似乎仍在渲染到默认帧缓冲区(即1x1窗口)。你知道这可能是什么原因吗?我在绘图之前绑定到“fbo”。使用glGetIntegerv(GL\u draw\u FRAMEBUFFER\u binding,&int)
后,它似乎正在渲染到我定义的帧缓冲区,但出于任何原因,大小仅为1x1。帧缓冲区继承了窗口的大小,即使renderbuffer存储设置为512x512。@NealKruis:绑定FBO后是否设置视口?绑定FBO后是否设置视图矩阵。现在我想知道窗口是否可能设置了一个剪切矩形,这会影响我的渲染。@NealKruis:不是视图矩阵,而是视口,via。请参阅中的“解释FBO与窗口的宽度/高度不同时会发生什么情况?”问题。
cnt: 1884
0: 157288
1: 157288
2: 157289
3: 157288
4: 157287
5: 157286
6: 157292
7: 157286
8: 157289
9: 157288