texture_rect.nim 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # author: Ethosa
  2. ## It provides a primitive display image.
  3. import
  4. ../thirdparty/opengl,
  5. ../core/vector2,
  6. ../core/rect2,
  7. ../core/anchor,
  8. ../core/input,
  9. ../core/image,
  10. ../core/enums,
  11. ../core/color,
  12. ../nodes/node,
  13. control
  14. type
  15. TextureRectObj* = object of ControlPtr
  16. texture*: Gluint
  17. texture_mode*: TextureMode
  18. texture_size*: Vector2Ref
  19. texture_anchor*: AnchorRef
  20. texture_filter*: ColorRef
  21. TextureRectPtr* = ptr TextureRectObj
  22. proc TextureRect*(name: string, variable: var TextureRectObj): TextureRectPtr =
  23. ## Creates a new TextureRect pointer.
  24. ##
  25. ## Arguments:
  26. ## - `name` is a node name.
  27. ## - `variable` is a TextureRectObj variable.
  28. runnableExamples:
  29. var
  30. textureobj: TextureRectObj
  31. texture = TextureRect("TextureRect", textureobj)
  32. nodepattern(TextureRectObj)
  33. controlpattern()
  34. variable.rect_size.x = 40
  35. variable.rect_size.y = 40
  36. variable.texture = 0
  37. variable.texture_mode = TEXTURE_FILL_XY
  38. variable.texture_size = Vector2()
  39. variable.texture_anchor = Anchor(0, 0, 0, 0)
  40. variable.texture_filter = Color(1f, 1f, 1f)
  41. variable.kind = TEXTURE_RECT_NODE
  42. proc TextureRect*(obj: var TextureRectObj): TextureRectPtr {.inline.} =
  43. ## Creates a new TextureRect pointer with default name "TextureRect".
  44. ##
  45. ## Arguments:
  46. ## - `variable` is a TextureRectObj variable.
  47. runnableExamples:
  48. var
  49. textureobj: TextureRectObj
  50. texture = TextureRect(textureobj)
  51. TextureRect("TextureRect", obj)
  52. method draw*(self: TextureRectPtr, w, h: GLfloat) =
  53. ## This uses in the `window.nim`.
  54. let
  55. x = -w/2 + self.global_position.x
  56. y = h/2 - self.global_position.y
  57. glColor4f(self.background_color.r, self.background_color.g, self.background_color.b, self.background_color.a)
  58. glRectf(x, y, x+self.rect_size.x, y-self.rect_size.y)
  59. glColor4f(self.texture_filter.r, self.texture_filter.g, self.texture_filter.b, self.texture_filter.a)
  60. if self.texture > 0:
  61. glEnable(GL_TEXTURE_2D)
  62. glBindTexture(GL_TEXTURE_2D, self.texture)
  63. glBegin(GL_QUADS)
  64. if self.texture_mode == TEXTURE_FILL_XY:
  65. glTexCoord2f(0, 0)
  66. glVertex2f(x, y)
  67. glTexCoord2f(0, 1)
  68. glVertex2f(x, y - self.rect_size.y)
  69. glTexCoord2f(1, 1)
  70. glVertex2f(x + self.rect_size.x, y - self.rect_size.y)
  71. glTexCoord2f(1, 0)
  72. glVertex2f(x + self.rect_size.x, y)
  73. elif self.texture_mode == TEXTURE_KEEP_ASPECT_RATIO:
  74. let
  75. w = self.rect_size.x / self.texture_size.x
  76. h = self.rect_size.y / self.texture_size.y
  77. q = if w < h: w else: h
  78. x1 = x + (self.rect_size.x*self.texture_anchor.x1) - (self.texture_size.x*q)*self.texture_anchor.x2
  79. y1 = y - (self.rect_size.y*self.texture_anchor.y1) + (self.texture_size.y*q)*self.texture_anchor.y2
  80. x2 = x1 + self.texture_size.x*q
  81. y2 = y1 - self.texture_size.y*q
  82. glTexCoord2f(0, 0)
  83. glVertex2f(x1, y1)
  84. glTexCoord2f(0, 1)
  85. glVertex2f(x1, y2)
  86. glTexCoord2f(1, 1)
  87. glVertex2f(x2, y2)
  88. glTexCoord2f(1, 0)
  89. glVertex2f(x2, y1)
  90. elif self.texture_mode == TEXTURE_CROP:
  91. if self.texture_size.x < self.rect_size.x:
  92. let q = self.rect_size.x / self.texture_size.x
  93. self.texture_size.x *= q
  94. self.texture_size.y *= q
  95. if self.texture_size.y < self.rect_size.y:
  96. let q = self.rect_size.y / self.texture_size.y
  97. self.texture_size.x *= q
  98. self.texture_size.y *= q
  99. let
  100. x1 = self.rect_size.x / self.texture_size.x
  101. y1 = self.rect_size.y / self.texture_size.y
  102. x2 = normalize(self.texture_anchor.x1 - x1*self.texture_anchor.x2, 0, 1)
  103. y2 = normalize(self.texture_anchor.y1 - y1*self.texture_anchor.y2, 0, 1)
  104. x3 = normalize(x2 + x1, 0, 1)
  105. y3 = normalize(y2 + y1, 0, 1)
  106. glTexCoord2f(x2, y2)
  107. glVertex2f(x, y)
  108. glTexCoord2f(x2, y3)
  109. glVertex2f(x, y - self.rect_size.y)
  110. glTexCoord2f(x3, y3)
  111. glVertex2f(x + self.rect_size.x, y - self.rect_size.y)
  112. glTexCoord2f(x3, y2)
  113. glVertex2f(x + self.rect_size.x, y)
  114. glEnd()
  115. glDisable(GL_TEXTURE_2D)
  116. # Press
  117. if self.pressed:
  118. self.on_press(self, last_event.x, last_event.y)
  119. method duplicate*(self: TextureRectPtr, obj: var TextureRectObj): TextureRectPtr {.base.} =
  120. ## Duplicates TextureRect and create a new TextureRect pointer.
  121. obj = self[]
  122. obj.addr
  123. method loadTexture*(self: TextureRectPtr, file: cstring) {.base.} =
  124. ## Loads texture from file.
  125. ##
  126. ## Arguments:
  127. ## - `file` is an image file path.
  128. var
  129. x: float = 0f
  130. y: float = 0f
  131. self.texture = load(file, x, y)
  132. self.texture_size = Vector2(x, y)
  133. method setTexture*(self: TextureRectPtr, gltexture: GlTextureObj) {.base.} =
  134. ## Changes texture.
  135. ##
  136. ## Arguments:
  137. ## - `gltexture` is a texture, loaded via load(file, mode=GL_RGB).
  138. self.texture = gltexture.texture
  139. self.texture_size = gltexture.size
  140. method setTextureFilter*(self: TextureRectPtr, color: ColorRef) {.base.} =
  141. ## Changes texture filter color.
  142. self.texture_filter = color
  143. method setTextureAnchor*(self: TextureRectPtr, anchor: AnchorRef) {.base.} =
  144. ## Changes texture anchor.
  145. self.texture_anchor = anchor
  146. method setTextureAnchor*(self: TextureRectPtr, x1, y1, x2, y2: float) {.base.} =
  147. ## Changes texture anchor.
  148. ##
  149. ## ARguments:
  150. ## - `x1` and `y1` is an anchor relative to TextureRect size.
  151. ## - `x2` and `y2` is an anchor relative to texture size.
  152. self.texture_anchor = Anchor(x1, y1, x2, y2)