使用GLSL进行纹理处理(在PyOpenGL和Pygame中)

2024-05-19 22:25:43 发布

您现在位置:Python中文网/ 问答频道 /正文

在对Python中固定函数管道运行缓慢感到沮丧之后,我开始研究着色器来绘制游戏的视差背景。但是,我找不到任何简单的方法来纹理绘制的顶点。在

我现在有一个PyOpenGL顶点缓冲区对象,其中每个顶点都是这样的:[x,y,z,texX,texY,texID]

我将这些传递给具有getAttriblLocation/GlenableVertexAttributeArray的着色器。我不确定它是否有效,因为着色器目前还没有编译,但在我添加我可能很糟糕的纹理代码之前,彩色顶点的工作情况还不错。在

我想要的是用一个着色器绘制一个有纹理的模型,有多个纹理,但是这个模型是一个平面背景。这是一个大的(1600x800左右)图像,它被分成256x256纹理和四边形多边形。(附带问题:是有更多的小多边形,这样屏幕上就少了一点多边形,还是大多边形这样就少了纹理绑定?)在

因为它是多个相关的纹理,我想在着色器中完成所有操作,而不必为CPU上的每个块绑定纹理,所以我认为用顶点数据发送纹理数据是最好的,但我无法使其工作。在

有人能给我一个简单的例子,顶点和碎片着色器相互作用,使多个多边形具有不同的纹理?在

编辑:着色器、vbo和此处的内容:http://pastebin.com/3LaYiyvh着色器现在可以编译,但是三角形是不可见的。在

编辑:到了!不知道最终是什么破解了它,但程序如下:http://pastebin.com/k87sfiEf 我认为这就像,只要你在开始时绑定所有的纹理,着色器就可以在它们之间交换。但我不确定。 另外要注意的是,将大背景分割成更小的块来绘制不是一个好主意,因为绘制时会交换纹理。大的纹理和浪费的空间是好的,地图册更好!在


Tags: 数据函数模型comhttp游戏编辑管道
3条回答

Could someone please give me a simple example of the vertex and fragment shaders interacting to make multiple polys with different textures?

谷歌GLSL教程。例子是以前写过的,没有理由只为你再写一次。或者下载NVidia OpenGL SDK,并对其进行检查。OpenGL.org网站同时推荐书籍。”橙书“涵盖着色器。在

which is split into 256x256

传统上,我们建议做相反的-采取所有的纹理,并将它们组合成一个“阿特拉斯”纹理,最好是类似16384x16384的纹理-以尽量减少状态切换。在

What I want is to draw a textured model with a shader, with multiple textures, but the model is a flat background. It's a large (1600x800 or so) image

1600x800将完全适合几乎所有硬件的纹理,因为Riva TNT 2 pro。如果你关心“浪费”纹理内存,那么很多卡片支持非2次幂的纹理。然而,非二次幂纹理通常有局限性,在使用这种纹理的某些硬件(某些ati卡+驱动程序)上,会导致fps急剧下降。一、 从200..400到40。这不值得。在配备256MB VRam的硬件上,未使用的40%纹理是微优化。如果你对vram的使用感到吝啬的话,你可以使用纹理图集,用有用的东西填充“浪费”的空间。另外,请记住,您永远不知道驱动程序使用视频内存的效率如何。在

I want to do it all in the shader without having to bind the texture for each chunk on the CPU,

你不能那样做。着色器不绑定纹理。它们使用已经绑定的纹理。在

I'm not sure if it works, since the shaders don't currently compile,

好吧,让他们编译后再问一次。在没有看到着色器或错误消息的情况下,无法帮助您。你知道着色器编译器produces error messages,对吧?在

After getting frustrated with the fixed-function pipeline being slow in Python

请考虑切换到C语言或C++语言。你可以轻松地得到200…400帧每秒的原始固定函数OpenGL在C/C++应用程序(“地牢爬虫”)中,不使用缓冲区或显示列表-<强>如果你使用正确的算法来消除隐藏表面(和VSYNC被禁用)<强>和< /强>你的纹理是MIP映射。众所周知的“固定功能”应用程序包括地震1..3,半衰期1,立方体和许多其他游戏都是非常快的。也就是说,如果进展缓慢,那是你的错。在

不同于C/C++,Python具有较大的函数调用开销——执行字节码,从列表/元组中提取未知类型的值(可以包含任何“设计”),然后将其作为浮点(如GLVTEX3F)倾倒,而最后将其转发到本机API调用将比没有中间步骤的类似C/C++调用要慢。您可以通过使用显示列表或缓冲区对象来抵消这一点,但对于我来说,这样做是不值得的。然而,在特定的任务中使用特定的语言是个人偏好的问题。在

编辑

However, if shaders can't bind textures, how does multitexturing work?

有N个纹理阶段(至少2个-se glGet/GL_MAX_texture_COORDS/GL_MAX_texture_UNITS),可以一次设置多个纹理。见glActiveTexture。如果没有着色器(固定函数),则使用glTexEnv为每个阶段指定颜色操作。{4中使用多个纹理采样器来指定纹理,然后使用相同的纹理集来读取纹理。着色器无法切换纹理。它可以使用已经由程序设置的纹理。着色器不了解着色器之外的任何纹理。技术上,着色器甚至不知道“纹理”,它有“采样器”用来读取数据。在

Or texture sampling? Shaders must be able to do some work with selecting/changing textures...

着色器根本不切换或选择纹理。这部分由你的程序完成。有关更多信息,请阅读OpenGL规范和您的OpenGL/GLSL版本的GLSL规范。这两个版本都可以从opengl.org网站网站,“文档”菜单。在

正如我已经说过的,此时您需要GLSL教程或书籍。两者都很容易找到。找一个,一直读到你“明白”为止。目前它看起来不像你做了你的家庭作业,并试图做一个简单的着色器使用书籍或教程。如果你找不到一本书,那么NVIDIA OpenGL SDK有很多例子(C/C++,但转换它们并不难)。在

After getting frustrated with the fixed-function pipeline being slow in Python, I started looking into shaders to draw my game's parallax backgrounds.

如果fixed函数对您来说很慢,那么使用着色器不会使它更快。在

可能你只是做了一些根本性的错误,比如使用即时模式,或者根本没有硬件加速(由于缺乏正确安装的驱动程序或类似的驱动程序)。在

也许你可以在我的Minecraft mapping blog posts中找到有用的东西。所有示例都使用Python、Pygame和PyOpenGL。他们在碎片着色器中做了很多事情。它们只使用简单的几何体:只有一个四边形。在

从你的描述来看,一个大的纹理比多个小的纹理要好得多。但是,在某些情况下,有很多小纹理并在着色器中进行选择确实有意义。Array textures 在这种情况下很有用,因为它们不会遇到与使用纹理图集时相同的过滤和钳制问题。(事实上,我博客中的例子使用了纹理图集,当缩小到远处时,mip映射会遇到一些问题。我最近一直在使用数组纹理来解决这个问题。)

相关问题 更多 >