I've been steadily working through building a basic 2D tile framework in python.
I'm trying to use modern openGL so I have a simple shader and some vertex buffers and it's mostly doing what I want so far. I have a Scene with a method for centering the viewport on a Sprite:
def centre_viewport(self, x, y):
x = -x+self.viewport_width//2
y = y-self.viewport_height//2
if x > 0:
x = 0
if y < 0:
y = 0
if x - self.viewport_width < -self.width:
x = -self.width + self.viewport_width
if y + self.viewport_height > self.height:
y = self.height - self.viewport_height
self.viewport_x = x
self.viewport_y = y
glViewport(x, y, self.viewport_width, self.viewport_height)
self.viewport_width
and _height
are set when a scene is added to the window, so they have the same dimensions as whatever window is created.
In my test game, the scene width and height are twice the window dimensions of 704x512
. Everything works fine on my main mac development machine. On my work windows machine though, when the sprite moves and causes the scene to scroll, the previously hidden parts of the scene are not drawn:
My draw loop is very simple:
def _draw(self):
glBindBuffer(GL_ARRAY_BUFFER, self.sprite_vertex_buffer)
glVertexAttribPointer(self.vertices, 3, GL_FLOAT, GL_FALSE, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, self.sprite_texture_buffer)
glVertexAttribPointer(self.tex_coords, 2, GL_FLOAT, GL_TRUE, 0, None)
glDrawArrays(GL_TRIANGLES, 0, self.sprite_vertex_count)
glBindBuffer(GL_ARRAY_BUFFER, self.tile_vertex_buffer)
glVertexAttribPointer(self.vertices, 3, GL_FLOAT, GL_FALSE, 0, None)
glBindBuffer(GL_ARRAY_BUFFER, self.tile_texture_buffer)
glVertexAttribPointer(self.tex_coords, 2, GL_FLOAT, GL_TRUE, 0, None)
glDrawArrays(GL_TRIANGLES, 0, self.tile_vertex_count)
and as mentioned, it works fine on my mac.
Is glViewport()
the appropriate way to be doing this, and why isn't it working properly on windows?
_draw()
method. There is an_update()
method that runs through each sprite to update the positions/tex coords for each sprite (hence the separate tile/sprite buffers) and they are each loaded with new data usingglBufferSubData()
so that the buffers aren't recreated. That part was all learnt from this question :) \$\endgroup\$glGetAttribLocation
is very costy, you should only call it once and save the result somewhere \$\endgroup\$_draw()
method to take those out! \$\endgroup\$