简体   繁体   English

OpenGL中的缩放窗口

[英]Zoom window in OpenGL

I've implemented Game of Life using OpenGL buffers (as specified here: http://www.glprogramming.com/red/chapter14.html#name20 ). 我已经使用OpenGL缓冲区(如此处指定: http : //www.glprogramming.com/red/chapter14.html#name20 )实现了《人生游戏》。 In this implementation each pixel is a cell in the game. 在此实现中,每个像素都是游戏中的一个单元。

My program receives the initial state of the game (2d array). 我的程序接收到游戏的初始状态(二维数组)。 The size array ,in my implementation, is the size of the window. 在我的实现中,size数组是窗口的大小。 This of course makes it "unplayable" if the array is 5x5 or some other small values. 如果数组是5x5或其他一些小值,这当然会使它“无法播放”。

At each iteration I'm reading the content of the framebuffer into a 2D array (its size is the window size): 在每次迭代中,我都将帧缓冲区的内容读入2D数组(其大小是窗口大小):

glReadPixels(0, 0, win_x, win_y, GL_RGB, GL_UNSIGNED_BYTE, image);

Then, I'm doing the necessary steps to calculate the living and dead cells, and then draw a rectangle which covers the whole window, using: 然后,我正在执行必要的步骤来计算活细胞和死细胞,然后使用以下方法绘制一个覆盖整个窗口的矩形:

glRectf(0, 0, win_x, win_y);

I want to zoom (or enlarge) the window without affecting the correctness of my code. 我想在不影响代码正确性的情况下缩放(或放大)窗口。 If I resize the window, then the framebuffer content won't fit inside image(the array). 如果我调整窗口大小,则帧缓冲区内容将不适合image(数组)。 Is there a way of zooming the window(so that each pixel be drawn as several pixels) without affecting the framebuffer? 有没有一种在不影响帧缓冲区的情况下缩放窗口(以便将每个像素绘制为几个像素)的方法?

First, you seem to be learning opengl 2, I would suggest instead learning a newer version, as it is more powerful and efficient. 首先,您似乎正在学习opengl 2,我建议改为学习一个新版本,因为它更强大,更高效。 A good tutorial can be found here http://www.opengl-tutorial.org/ 一个很好的教程可以在这里找到http://www.opengl-tutorial.org/

If i understand this correctly, you read in an initial state and draw it, then continuously read in the pixels on the screen, update the array based on the game of life logic then draw it back? 如果我正确地理解了这一点,那么您将在初始状态下读取并绘制它,然后连续读取屏幕上的像素,根据生命游戏逻辑更新数组,然后将其绘制回来? this seems overly complicated. 这似乎过于复杂。 The reading of the pixels on the screen is unnecessary, and will cause complications if you try to enlarge the rects to more than a pixel. 无需读取屏幕上的像素,如果尝试将矩形放大到一个像素以上,则会导致复杂化。 I would say a good solution would be to keep a bit array (1 is a organism, 0 is not), possibly as a 2d array in memory, updating the logic every say 30 iterations (for 30 fps), then drawing all the rects to the screen, black for 1, white for 0 using glColor(r,g,b,a) tied to an in statement in a nested for loop. 我想说一个好的解决方案是保留一个位数组(1是一个有机体,0不是),在内存中作为一个2d数组,每说30次迭代就更新一次逻辑(对于30 fps),然后绘制所有矩形屏幕上,使用glColor(r,g,b,a)绑定到嵌套的for循环中的in语句,将黑色表示为1,白色表示为0。 Then, if you give your rects a negative z coord, you can "zoom in" using glTranslate(x,y,z) triggered by a keyboard button. 然后,如果您给矩形赋予z负坐标,则可以使用由键盘按钮触发的glTranslate(x,y,z)来“放大”。

Of course in a newer version of opengl, vertex buffers would make the code much cleaner and efficient. 当然,在较新版本的opengl中,顶点缓冲区将使代码更加整洁和高效。

You can't store your game state directly the window framebuffer and then resize it for rendering, since what is stored in the framebuffer is by definition what is about to be rendered. 您不能将游戏状态直接存储在窗口帧缓冲区中,然后再调整其大小以进行渲染,因为根据定义,帧缓冲区中存储的内容就是要渲染的内容。 (You could overwrite it, but then you lose your game state...) The simplest solution would just to store the game state in an array (on the client side) and then update a texture based on that. (您可以覆盖它,但是然后您会丢失游戏状态...)最简单的解决方案是将游戏状态存储在一个数组中(在客户端),然后根据该纹理更新纹理。 Thus for each block that was set, you could set a pixel in a texture to be the appropriate color. 因此,对于每个已设置的块,您可以将纹理中的像素设置为适当的颜色。 Each frame, you then render a full screen quad with that texture (with GL_NEAREST filtering). 然后,在每一帧中,使用该纹理渲染全屏四边形(使用GL_NEAREST过滤)。

However, if you want to take advantage of your GPU there are some tricks that could massively speed up the simulation by using a fragment shader to generate the texture. 但是,如果您想利用GPU,可以使用一些技巧,通过使用片段着色器生成纹理来极大地加快仿真速度。 In this case you would actually have two textures that you ping-pong between: one containing the current game state, and the other containing the next game state. 在这种情况下,您实际上会在两个纹理之间进行乒乓球切换:一个包含当前游戏状态,另一个包含下一个游戏状态。 Each frame you would use your fragment shader (along with a FBO) to generate the next state texture from the current state texture. 每帧都将使用片段着色器(以及FBO)从当前状态纹理生成下一个 状态纹理。 Afterwards, the two textures are swapped, making the next state become the current state . 之后,将两个纹理交换,使下一个状态成为当前状态 The current state texture would then be rendered to the screen the same way as above. 然后,将以与上述相同的方式将当前状态纹理渲染到屏幕上。

I tried to give an overview of how you might be able to offload the computation onto the GPU, but if I was unclear anywhere just ask! 我试图概述如何将计算卸载到GPU上,但是如果我不清楚在任何地方都可以问一下! For a more detailed explanation feel free to ask another question. 有关更详细的解释,请随时提出其他问题。

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

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