2014-10-06 67 views
2

我正在使用鼠标绘制3D对象。如何加快OpenGL中纹理的绘制速度? (3.3 +/4.1)

Teapot with stack overflow written on it

我这样做是正确的,现在的方式是,我包通过片段着色器于RG像素为这样的UV坐标:

in highp vec2 UV; 
out vec4 fragColor; 
void main() 
{ 
    fragColor.r = UV.x; 
    fragColor.g = UV.y; 
} 

我使那些为米屏幕上的FBO,然后在鼠标下读取像素以获得CPU端的UV坐标。

float pixel_array[4]; 

CALL_GL(glReadBuffer(GL_COLOR_ATTACHMENT0)); 
CALL_GL(glReadPixels(normMouseX*WINDOW_WIDTH,normMouseY*WINDOW_HEIGHT,1,1,GL_RGBA,GL_FLOAT,pixel_array)); 

float u = pixel_array[0]; 
float v = pixel_array[1]; 

然后,我使用这些UV坐标在正确的位置“绘制”纹理。

CALL_GL(glBindTexture(GL_TEXTURE_2D, mesh.diffuseTexture)); 
CALL_GL(glTexSubImage2D(GL_TEXTURE_2D, 
     0, 
     u*diffuseTextureWidth, 
     v*diffuseTextureHeight, 
     5, 
     5, 
     GL_RGBA, 
     GL_UNSIGNED_BYTE, 
     brush_pixels)); 

问题是,根据纹理的分辨率,这个过程非常缓慢。有什么方法可以加快速度吗?

回答

4

我将它们渲染到离屏FBO,然后使用鼠标下的readPixel获取CPU侧的UV坐标。

确保只在需要时才从该纹理进行回读。还试图破解回读。读取单个像素并且往往效率低下。读取完整纹理后(更改视图后)会更有效。

要加速绘制到纹理而不是glTexSubImage2D -ing它,只需将它绑定到FBO作为颜色附件并使用常规OpenGL绘图操作绘制到它。

+0

呵呵,我一直认为从GPU上读取任何东西都很慢。尽管你的答案比我的好,但甚至没有想过使用OpenGL操作来绘制(哦讽刺)。 – BWG 2014-10-06 18:23:46

+1

@BWG:当GPU和CPU之间的连接是通过AGP的非对称带宽时,它过去很慢。今天,我们得到了具有> 10GiB/s对称带宽的PCI-E 3。使用PBO和良好对齐的访问并为读出缓冲区选择原生像素格式和布局,GPU可以执行异步DMA传输。但从技术上讲,您可以在Shader Model 3 GPU上执行*所有操作,包括将画笔放置在目标纹理上。在顶点着色器中,您可以从几何缓冲区纹理读取数据,并根据读回的UV坐标变形 - 放置一个“刷子”网格,然后绘制它。 – datenwolf 2014-10-06 18:31:19

+0

对不起,什么是几何缓冲区?谷歌它没有取得好成绩? – BWG 2014-10-06 19:44:14