简体   繁体   English

如何在OpenGL中绘制纹理

[英]How do draw to a texture in OpenGL

Now that my OpenGL application is getting larger and more complex, I am noticing that it's also getting a little slow on very low-end systems such as Netbooks. 现在我的OpenGL应用程序变得越来越大,越来越复杂,我注意到它在像上网本这样的低端系统上也变得有点慢。 In Java, I am able to get around this by drawing to a BufferedImage then drawing that to the screen and updating the cached render every one in a while. 在Java中,我能够通过绘制到BufferedImage来解决这个问题,然后将其绘制到屏幕上,并在一段时间内更新缓存的渲染。 How would I go about doing this in OpenGL with C++? 我将如何使用C ++在OpenGL中执行此操作?

I found a few guides but they seem to only work on newer hardware/specific Nvidia cards. 我找到了一些指南,但它们似乎只适用于较新的硬件/特定Nvidia卡。 Since the cached rendering operations will only be updated every once in a while, i can sacrifice speed for compatability. 由于缓存的渲染操作只会偶尔更新一次,因此我可以牺牲速度来实现兼容性。

glBegin(GL_QUADS);
       setColor(DARK_BLUE); 
       glVertex2f(0, 0);                  //TL
       glVertex2f(appWidth, 0);           //TR
       setColor(LIGHT_BLUE);
       glVertex2f(appWidth, appHeight);   //BR
       glVertex2f(0, appHeight);          //BR
glEnd();

This is something that I am especially concerned about. 这是我特别关注的事情。 A gradient that takes up the entire screen is being re-drawn many times per second. 占据整个屏幕的渐变每秒重新绘制多次。 How can I cache it to a texture then just draw that texture to increase performance? 如何将其缓存到纹理然后只绘制该纹理以提高性能?

Also, a trick I use in Java is to render it to a 1 X height texture then scale that to width x height to increase the performance and lower memory usage. 另外,我在Java中使用的一个技巧是将其渲染为1 X高度纹理,然后将其缩放到width x height以提高性能并降低内存使用量。 Is there such a trick with openGL? openGL有这么一招吗?

If you don't want to use Framebuffer Objects for compatibility reasons (but they are pretty widely available), you don't want to use the legacy (and non portable) Pbuffers either. 如果您出于兼容性原因不想使用Framebuffer对象 (但它们可以广泛使用),您也不希望使用旧版(和非可移植版) Pbuffers That leaves you with the simple possibility of reading the contents of the framebuffer with glReadPixels and creating a new texture with that data using glTexImage2D . 这使您可以使用glReadPixels读取帧缓冲区的内容,并使用glTexImage2D创建包含该数据的新纹理。

Let me add that I don't really think that in your case you are going to gain much. 让我补充一点,我并不认为在你的情况下你会获得更多。 Drawing a texture onscreen requires at least texel access per pixel, that's not really a huge saving if the alternative is just interpolating a color as you are doing now! 在屏幕上绘制纹理至少需要每个像素访问纹理元素,如果替代方法只是像现在一样插入颜色,那么这并不是一个巨大的节省!

I sincerely doubt drawing from a texture is less work than drawing a gradient. 我真诚地怀疑从纹理绘制比绘制渐变更少工作。

In drawing a gradient: 在绘制渐变时:

  • Color is interpolated at every pixel 在每个像素处插入颜色

In drawing a texture: 在绘制纹理时:

  • Texture coordinate is interpolated at every pixel 纹理坐标在每个像素处插值
  • Color is still interpolated at every pixel 在每个像素处仍然插入颜色
  • Texture lookup for every pixel 每个像素的纹理查找
  • Multiply lookup color with current color 将查找颜色与当前颜色相乘

Not that either of these are slow, but drawing untextured polygons is pretty much as fast as it gets. 并非这些都是缓慢的,但绘制无纹理的多边形几乎和它一样快。

Consider using a display list rather than a texture. 考虑使用显示列表而不是纹理。 Texture reads (especially for large ones) are a good deal slower than 8 or 9 function calls. 纹理读取(特别是对于大型读取)比8或9个函数调用慢得多。

Before doing any optimization you should make sure you fully understand the bottlenecks. 在进行任何优化之前,您应该确保完全理解瓶颈。 You'll probably be surprised at the result. 你可能会对结果感到惊讶。

Hey there, thought I'd give you some insight in to this. 嘿那里,以为我会给你一些见解。

There's essentially two ways to do it. 基本上有两种方法可以做到这一点。

Frame Buffer Objects (FBOs) for more modern hardware, and the back buffer for a fall back. 帧缓冲对象(FBO)用于更现代的硬件,后缓冲用于后退。

The article from one of the previous posters is a good article to follow on it, and there's plent of tutorials on google for FBOs. 来自之前海报之一的文章是一篇很好的文章,并且有很多关于FBO的谷歌教程。

In my 2d Engine (Phoenix), we decided we would go with just the back buffer method. 在我的2d引擎(Phoenix)中,我们决定只使用后缓冲方法。 Our class was fairly simple and you can view the header and source here: 我们的课很简单,你可以在这里查看标题和来源:

http://code.google.com/p/phoenixgl/source/browse/branches/0.3/libPhoenixGL/PhRenderTexture.h http://code.google.com/p/phoenixgl/source/browse/branches/0.3/libPhoenixGL/PhRenderTexture.cpp http://code.google.com/p/phoenixgl/source/browse/branches/0.3/libPhoenixGL/PhRenderTexture.h http://code.google.com/p/phoenixgl/source/browse/branches/0.3/libPhoenixGL /PhRenderTexture.cpp

Hope that helps! 希望有所帮助!

Look into FBOs - framebuffer objects. 查看FBO - 帧缓冲对象。 It's an extension that lets you render to arbitrary rendertargets, including textures. 它是一个扩展,可以渲染到任意渲染,包括纹理。 This extension should be available on most recent hardware. 此扩展应该可以在最新的硬件上使用。 This is a fairly good primer on FBOs: OpenGL Frame Buffer Object 101 这是一个关于FBO的相当好的入门: OpenGL帧缓冲对象101

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM