Bläddra i källkod

optimize tilemap memory ._.

Ethosa 3 år sedan
förälder
incheckning
5cac73d1df

+ 0 - 4
src/nodesnim/core/tileset.nim

@@ -52,8 +52,6 @@ proc draw*(self: TileSetObj, tilex, tiley, x, y: float) =
       texx2 = self.grid.x*(tilex+1f) / self.size.x
       texy2 = self.grid.y*(tiley+1f) / self.size.y
     glBindTexture(GL_TEXTURE_2D, self.texture)
-    glEnable(GL_TEXTURE_2D)
-    glEnable(GL_DEPTH_TEST)
     glBegin(GL_QUADS)
     glTexCoord2f(texx1, texy1)
     glVertex2f(x, y)
@@ -64,6 +62,4 @@ proc draw*(self: TileSetObj, tilex, tiley, x, y: float) =
     glTexCoord2f(texx2, texy1)
     glVertex2f(x + self.grid.x, y)
     glEnd()
-    glDisable(GL_DEPTH_TEST)
-    glDisable(GL_TEXTURE_2D)
     glBindTexture(GL_TEXTURE_2D, 0)

+ 14 - 0
src/nodesnim/core/vector2.nim

@@ -6,6 +6,7 @@ import math
 type
   Vector2Obj* = object
     x*, y*: float
+  Vector2Ref* = ref Vector2Obj
 
 
 proc Vector2*(x, y: float): Vector2Obj {.inline.} =
@@ -21,6 +22,19 @@ proc Vector2*(): Vector2Obj {.inline.} =
   Vector2Obj(x: 0, y: 0)
 
 
+proc newVector2*(x, y: float): Vector2Ref {.inline.} =
+  Vector2Ref(x: x, y: y)
+
+proc newVector2*(o: Vector2Obj): Vector2Ref {.inline.} =
+  Vector2Ref(x: o.x, y: o.y)
+
+proc newVector2*(o: float): Vector2Ref {.inline.} =
+  Vector2Ref(x: o, y: o)
+
+proc newVector2*(): Vector2Ref {.inline.} =
+  Vector2Ref(x: 0f, y: 0f)
+
+
 
 proc abs*(a: Vector2Obj): Vector2Obj =
   Vector2(abs(a.x), abs(a.y))

+ 24 - 10
src/nodesnim/nodes2d/tilemap.nim

@@ -16,7 +16,7 @@ type
   TileMapObj* = object of Node2DObj
     map_size*: tuple[x, y: int]
     tileset*: TileSetObj
-    map*: seq[seq[tuple[x, y: float]]]
+    map*: seq[seq[Vector2Ref]]
   TileMapRef = ref TileMapObj
 
 
@@ -48,22 +48,35 @@ method draw*(self: TileMapRef, w, h: GLfloat) =
   if viewport[3] >= self.map_size.y:
     viewport[3] = self.map_size.y-1
 
+  glEnable(GL_TEXTURE_2D)
+  glEnable(GL_DEPTH_TEST)
   for x1 in viewport[0]..viewport[2]:
     for y1 in viewport[1]..viewport[3]:
-      let
-        posx = x + self.tileset.grid.x*x1.float
-        posy = y - self.tileset.grid.y*y1.float
-      self.tileset.draw(self.map[x1][y1].x, self.map[x1][y1].y, posx, posy)
+      if not self.map[x1][y1].isNil():
+        let
+          posx = x + self.tileset.grid.x*x1.float
+          posy = y - self.tileset.grid.y*y1.float
+        self.tileset.draw(self.map[x1][y1].x, self.map[x1][y1].y, posx, posy)
+  glDisable(GL_DEPTH_TEST)
+  glDisable(GL_TEXTURE_2D)
 
-method drawTile*(self: TileMapRef, x, y: int, tile_pos: Vector2Obj) {.base.} =
-  self.map[x][y] = (x: tile_pos.x, y: tile_pos.y)
+method drawTile*(self: TileMapRef, x, y: int, tile_pos: Vector2Ref) {.base.} =
+  ## Changes map tile at `x`,`y` point to tile from tileset at `tile_pos` point.
+  self.map[x][y] = tile_pos
 
-method fillTile*(self: TileMapRef, tile_pos: Vector2Obj) {.base.} =
+method drawRect*(self: TileMapRef, x, y, w, h: int, tile_pos: Vector2Ref) {.base.} =
+  for x1 in x..x+w:
+    for y1 in y..y+h:
+      self.map[x1][y1] = tile_pos
+
+method fill*(self: TileMapRef, tile_pos: Vector2Ref) {.base.} =
+  ## Fills the map with a tile at `tile_pos` position.
   for x in 0..<self.map_size.x.int:
     for y in 0..<self.map_size.y.int:
-      self.map[x][y] = (x: tile_pos.x, y: tile_pos.y)
+      self.map[x][y] = tile_pos
 
-method resizeMap*(self: TileMapRef, size: Vector2Obj) {.base.} =
+method resizeMap*(self: TileMapRef, size: Vector2Ref) {.base.} =
+  ## Changes map size to `size`.
   self.map_size = (x: size.x.int, y: size.y.int)
   self.map = @[]
   self.map.setLen(self.map_size.x)
@@ -71,4 +84,5 @@ method resizeMap*(self: TileMapRef, size: Vector2Obj) {.base.} =
     self.map[x].setLen(self.map_size.x)
 
 method setTileSet*(self: TileMapRef, tileset: TileSetObj) {.base.} =
+  ## Changes current tileset.
   self.tileset = tileset

+ 1 - 1
src/nodesnim/nodescontrol/popup.nim

@@ -14,7 +14,7 @@ import
 
 
 type
-  PopupObj* = object of ControlRef
+  PopupObj* = object of ControlObj
   PopupRef* = ref PopupObj
 
 

+ 7 - 6
tests/test46.nim

@@ -10,12 +10,13 @@ build:
   - Scene main:
     - TileMap map:
       call setTileSet(tileset)
-      call resizeMap(Vector2(10000, 10000))
-      call fillTile(Vector2(1, 0))
-      call drawTile(0, 0, Vector2(3, 0))
-      call drawTile(1, 0, Vector2(7, 4.5))
-      call drawTile(0, 1, Vector2(6.5, 5))
-      call drawTile(1, 1, Vector2(7, 5))
+      call resizeMap(newVector2(8096, 512))
+      call fill(newVector2(1, 0))
+      call drawRect(3, 3, 10, 5, newVector2(9, 7))
+      call drawTile(0, 0, newVector2(3, 0))
+      call drawTile(1, 0, newVector2(7, 4.5))
+      call drawTile(0, 1, newVector2(6.5, 5))
+      call drawTile(1, 1, newVector2(7, 5))
 
 addMainScene(main)
 windowLaunch()