gpt4 book ai didi

python - 在 pyglet 中使用 gl_points 滚动星空

转载 作者:行者123 更新时间:2023-11-28 22:01:53 24 4
gpt4 key购买 nike

对于我正在开发的游戏,我想实现一个滚动的星空。到目前为止,所有游戏都是从 OpenGL 基元绘制的,我想继续这个,gl_points 似乎是合适的。

我正在使用 pyglet (python),并且知道我可以实现存储一大堆位置或点更新它们并手动移动它们的目的,但我希望有一个更简洁的选择。

编辑:在回答伊恩马利特我想我想问的是,如果我生成一堆点,有没有什么方法可以将它们 blit 到某种表面或缓冲区上并在后台滚动它。

此外,关于在这个阶段我试图生成什么样的星空,我正在尝试为自上而下的游戏创建一个简单的单层,这与在小行星中的情况差不多

最佳答案


无限程序星空模式

(特色:视差滚动)

基本配方是:

  • 为随机生成器播种(每帧相同的种子)
  • 生成 N 个随机点 (X,Y) 和一个“Z”值(比如每个点 0.5 ... 2)

  • 平移每个点的位置:(X,Y) += scrollXY * Z
    这是棘手的部分。 每个点都有不同的Z值,所以它们以不同的速度滚动。这被称为“视差滚动”,效果惊人。

  • 环绕点(以屏幕尺寸为模)。

每一帧都使用相同的种子会给你一个随机的星空图案,但每一帧都是持久的(仅由滚动值改变)。

趣闻

可以很容易地修改此算法,这样您就不必在内存中实际存储所有 N 个位置。您只需要一个生成器,它可以为您提供随机基础 (X,Y) 坐标(和深度),并由一个常数值加上一些星号作为种子。

伪代码:

for (int i=0; i<1000; ++i) {

RandomGenerator rnd;
rnd.seed(SomeConstantSeed + i*10293);

// determine i-th star's position
var basePosition = vec2(rnd.next(800), rnd.next(600));
var depth = rnd.next(0.5, 2);

// parallax scrolling and wrapping
var realPosition = basePosition + scrollXY * depth;
var wrappedPosition = realPosition modulo vec2(800, 600);

// these are our coordinates! let's draw
renderStar(wrappedPosition);
}

在这里,每个星星都是按需生成的,我们不必在帧之间将其值保存在内存中。随机生成器种子保持不变就足以在每一帧生成相同(但动画)的星空。

您可以使用相同的技术为每颗星分配不同的随机(但持久)颜色。


如何使用OpenGL高效实现?

最简单和最有效的方法是在顶点着色器中动态生成位置。

  • 在 VBO 中准备星形几何体。它可以是任何你想要的:一个顶点(对于一个点 Sprite )、一个带纹理的四边形,任何东西。

  • 使用 glDrawArraysInstanced 渲染它,其中 primcount 是您想要的星星数量

  • 在您的顶点着色器中,实现上述伪代码中的循环主体,将 gl_InstanceID 替换为 i。然后通过滚动值(作为 uniform vec2 变量传递)改变每个顶点的输入 XY 屏幕位置(VS 中的一个属性变量),如上所述。

一些脚注:

  • 您将需要在顶点着色器中使用一个随机生成器。使用 1D 噪声纹理或 have a look here 实现它.
  • 如果您的星星的几何形状多于一个点(即您使用四边形,而不是点 Sprite ),您需要更加小心屏幕环绕,以避免星星的某些顶点环绕而其余顶点不环绕的情况。这有点棘手,但可行。使用点 Sprite 更简单。

关于python - 在 pyglet 中使用 gl_points 滚动星空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12470417/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com