Hello, I'm trying to make a raycasting engine with pyglet but i'm having ~15fps right now and i think i need more advanced opengl knowledge. If i understand well, batchs are a way to reduce the number of calls but since everything graphically changes at every movement i'm not sure if i will benefit from it. I'm wondering what i could do to improve performances.
I'm not focusing on the raycasting algorithm right now but maybe i should use something simpler : I'm using the tutorial from permadi.com on raycasting but i know there's a popular algorithm called B******** (I can't remember the name and google is not helping me) This is the piece of code i'm using : glBegin(GL_QUADS) glVertex2f(x, y - h) glVertex2f(x + self.wall_width, y - h) glVertex2f(x + self.wall_width, y + h) glVertex2f(x, y + h) glEnd() Sorry i'm never sure if i should paste so much code here but i don't like to put links so here is the whole source (i've commented the texture mapping part so it should work just by pasting it) : If you want a more readable version > http://paste2.org/p/1886941 from math import cos, sin, tan, radians, sqrt, pow import pyglet from pyglet.gl import * from pyglet.window import key bmap = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], ] BLOCK_SIZE = 32 WINDOW_WIDTH = 640 WINDOW_HEIGHT = 480 def rotate(v, angle): vx = v[0] * cos(radians(-angle)) - v[1] * sin(radians(-angle)) vy = v[0] * sin(radians(-angle)) + v[1] * cos(radians(-angle)) return vx, vy class Game(pyglet.event.EventDispatcher): def __init__(self): self.window = pyglet.window.Window( vsync=False, width=WINDOW_WIDTH, height=WINDOW_HEIGHT) self.keys = pyglet.window.key.KeyStateHandler() self.window.push_handlers(self.keys) self.window.push_handlers(self) self.myplayer = Player(self, 100, 200) self.fps = pyglet.clock.ClockDisplay() self.fps.label.x = 200 pyglet.clock.schedule_interval(self.update, 1 / 60.) self.Ax = self.Ay = self.Cx = self.Cy = 0 self.Bx = self.By = 0 self.H = self.V = self.C = None self.collision_points = {} self.map_active = False self.rays_angles = [] angle_range = 60. rays = 640 angle_step = angle_range / rays angle = -angle_range / 2 while angle < angle_range / 2: angle += angle_step self.rays_angles.append(angle) # self.img = pyglet.image.load('stonetest.png') self.wall_width = WINDOW_WIDTH / rays print "wall width", self.wall_width # self.wall_tex = self.img.get_texture().id ### Blocks instanciation for x, row in enumerate(bmap): for y, kind in enumerate(row): Block(self, x, y, kind) print "Game Started" def on_key_press(self, symbol, modifiers): if symbol == key.F12: if self.map_active == False: self.map_active = True else: self.map_active = False def update(self, dt): self.myplayer.update(dt) ### RAAAAYCAAASTIIING self.collision_points = {} for col, angle in enumerate(self.rays_angles): self.collision_points[col] = self.get_collision_point(col, angle) def get_collision_point(self, col, angle): v = rotate(self.myplayer.v, angle) x, y = self.myplayer.x, self.myplayer.y dV = dH = 999999 # dummy C = None angle = radians(90 + angle + self.myplayer.rotation) ### A if v[1] > 0: Ay = (y // BLOCK_SIZE) * BLOCK_SIZE + BLOCK_SIZE else: Ay = (y // BLOCK_SIZE) * BLOCK_SIZE - 0.1 try: Ax = x + (y - Ay) / tan(angle) except ZeroDivisionError: Ax = x ### Xa / Ya if v[1] > 0: try: Xa = BLOCK_SIZE / tan(-angle) except ZeroDivisionError: Xa = 9999 Ya = BLOCK_SIZE else: try: Xa = BLOCK_SIZE / tan(angle) except ZeroDivisionError: Xa = 9999 Ya = -BLOCK_SIZE Px = Ax Py = Ay ### Horizontal Collisions while True: self.H = None posx = int(Px // BLOCK_SIZE) posy = int(Py // BLOCK_SIZE) try: if Block._registry[(posx, posy)].kind == 1: self.H = (Px, Py) dH = sqrt(pow(self.H[0] - x, 2) + pow(self.H[1] - y, 2)) break else: Px += Xa Py += Ya except KeyError: break ######################################################## ### B if v[0] > 0: Bx = (x // BLOCK_SIZE) * BLOCK_SIZE + BLOCK_SIZE else: Bx = (x // BLOCK_SIZE) * BLOCK_SIZE - 0.1 By = y + (x - Bx) * tan(angle) ### Xa / Ya if v[0] > 0: Ya = BLOCK_SIZE * tan(-angle) Xa = BLOCK_SIZE else: Ya = BLOCK_SIZE * tan(angle) Xa = -BLOCK_SIZE Px = Bx Py = By ### Vertical Collisions while True: self.V = None posx = int(Px // BLOCK_SIZE) posy = int(Py // BLOCK_SIZE) try: if Block._registry[(posx, posy)].kind == 1: self.V = (Px, Py) dV = sqrt(pow(self.V[0] - x, 2) + pow(self.V[1] - y, 2)) break else: Px += Xa Py += Ya except KeyError: break if dV < dH: C = self.V d = dV coltype = "V" else: C = self.H d = dH coltype = "H" offset = x = y = h = sx = sx2 = None # Ugly but whatever if C is not None: if coltype == "V": offset = C[1] % BLOCK_SIZE else: offset = C[0] % BLOCK_SIZE x = col * self.wall_width y = WINDOW_HEIGHT / 2 h = (BLOCK_SIZE / d) * 277 k = 1. / BLOCK_SIZE sx = offset * k sx2 = (offset + self.wall_width) * k return C, d, offset, x, y, h, sx, sx2 def on_draw(self): self.window.clear() pyglet.gl.glColor3f(0.3, 0.3, 0.3) pyglet.gl.glRectf(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT / 2) for block in Block._registry.values(): block.draw() self.myplayer.draw() if self.map_active: # H point if self.H is not None: pyglet.gl.glColor3f(1, 1, 0.3) pyglet.gl.glRectf(self.H[0], self.H[1], self.H[0] + 2, self.H[1] + 2) # V point if self.V is not None: pyglet.gl.glColor3f(1, 0.3, 1) pyglet.gl.glRectf(self.V[0], self.V[1], self.V[0] + 2, self.V[1] + 2) for col, (point, d, offset, x, y, h, sx, sx2) \ in self.collision_points.items(): if point is not None: if self.map_active: # RAY pyglet.gl.glColor3f(0.6, 0.6, 0.6) pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.myplayer.x, self.myplayer.y, point[0], point[1]))) # POINT pyglet.gl.glColor3f(1, 0.1, 0.1) pyglet.gl.glRectf(point[0], point[1], point[0] + 2, point[1] + 2) # WALL, here is the interesting part pyglet.gl.glColor3f(0.6, 1, 0.3) # glEnable(GL_TEXTURE_2D) # glBindTexture(GL_TEXTURE_2D, self.wall_tex) glBegin(GL_QUADS) # glTexCoord2f(sx, 0.0) glVertex2f(x, y - h) # glTexCoord2f(sx2, 0.0) glVertex2f(x + self.wall_width, y - h) # glTexCoord2f(sx2, 1.0) glVertex2f(x + self.wall_width, y + h) # glTexCoord2f(sx, 1.0) glVertex2f(x, y + h) glEnd() # glDisable(GL_TEXTURE_2D) self.fps.draw() class Block: _registry = {} def __init__(self, game, posx, posy, kind): self.game = game self._registry[(posx, posy)] = self self.x = posx * BLOCK_SIZE self.y = posy * BLOCK_SIZE self.posx = posx self.posy = posy self.kind = kind def draw(self): if self.game.map_active: if self.kind == 0: pyglet.gl.glColor3f(0.5, 0.5, 0.5) else: pyglet.gl.glColor3f(0.5, 0.5, 1) pyglet.gl.glRectf(self.x, self.y, self.x + BLOCK_SIZE, self.y + BLOCK_SIZE) pyglet.gl.glColor3f(0.4, 0.4, 0.4) pyglet.graphics.draw(8, pyglet.gl.GL_LINES, ('v2f', (self.x, self.y, self.x, self.y + BLOCK_SIZE, self.x, self.y + BLOCK_SIZE, self.x + BLOCK_SIZE, self.y + BLOCK_SIZE, self.x + BLOCK_SIZE, self.y + BLOCK_SIZE, self.x + BLOCK_SIZE, self.y, self.x + BLOCK_SIZE, self.y, self.x, self.y) )) class Player: SPEED = 400 def __init__(self, game, x, y): self.game = game self.x, self.y = x, y self.rotation = 0 self.v = self.vo = (0, 1) def update(self, dt): if self.game.keys[key.W]: self.x += self.v[0] * self.SPEED * dt self.y += self.v[1] * self.SPEED * dt if self.game.keys[key.S]: self.x -= self.v[0] * self.SPEED * dt self.y -= self.v[1] * self.SPEED * dt if self.game.keys[key.A]: self.rotation -= 5 self.v = rotate(self.vo, self.rotation) if self.game.keys[key.D]: self.rotation += 5 self.v = rotate(self.vo, self.rotation) def draw(self): if self.game.map_active: # Char pyglet.gl.glColor3f(1, 0.5, 0.5) pyglet.gl.glRectf(self.x - 2, self.y - 2, self.x + 2, self.y + 2) # View ray pyglet.gl.glColor3f(0.6, 1, 0.6) pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.x, self.y, self.x + 100 * self.v[0], self.y + 100 * self.v[1]))) # View pyglet.gl.glColor3f(1, 0.5, 0.5) pyglet.graphics.draw(2, pyglet.gl.GL_LINES, ('v2f', (self.x, self.y, self.x + 10 * self.v[0], self.y + 10 * self.v[1]))) if __name__ == '__main__': app = Game() pyglet.app.run() -- You received this message because you are subscribed to the Google Groups "pyglet-users" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/pyglet-users?hl=en.
