rectangle.cpp 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. #include "rectangle.hpp"
  2. Rectangle::Rectangle( glm::vec2 p1, glm::vec2 p2, float border, float padding, glm::vec4 color, bool highlight ) {
  3. this->color = color;
  4. this->border = border;
  5. this->padding = padding;
  6. this->highlight = highlight;
  7. // Find each corner of the rectangle
  8. ul = glm::vec2( glm::min( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
  9. bl = glm::vec2( glm::min( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
  10. ur = glm::vec2( glm::max( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
  11. br = glm::vec2( glm::max( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
  12. // Offset the inner corners by the padding.
  13. ul = ul + glm::vec2(-padding,padding);
  14. bl = bl + glm::vec2(-padding,-padding);
  15. ur = ur + glm::vec2(padding,padding);
  16. br = br + glm::vec2(padding,-padding);
  17. // Create the outer corners by offsetting the inner by the bordersize
  18. oul = ul + glm::vec2(-border,border);
  19. obl = bl + glm::vec2(-border,-border);
  20. our = ur + glm::vec2(border,border);
  21. obr = br + glm::vec2(border,-border);
  22. generateBuffers();
  23. shader = new Shader( "simple.vert", "simple.frag" );
  24. }
  25. void Rectangle::setPoints( glm::vec2 p1, glm::vec2 p2 ) {
  26. // Find each corner of the rectangle
  27. ul = glm::vec2( glm::min( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
  28. bl = glm::vec2( glm::min( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
  29. ur = glm::vec2( glm::max( p1.x, p2.x ), glm::max( p1.y, p2.y ) ) ;
  30. br = glm::vec2( glm::max( p1.x, p2.x ), glm::min( p1.y, p2.y ) ) ;
  31. // Offset the inner corners by the padding.
  32. ul = ul + glm::vec2(-padding,padding);
  33. bl = bl + glm::vec2(-padding,-padding);
  34. ur = ur + glm::vec2(padding,padding);
  35. br = br + glm::vec2(padding,-padding);
  36. // Create the outer corners by offsetting the inner by the bordersize
  37. oul = ul + glm::vec2(-border,border);
  38. obl = bl + glm::vec2(-border,-border);
  39. our = ur + glm::vec2(border,border);
  40. obr = br + glm::vec2(border,-border);
  41. generateBuffers();
  42. }
  43. void Rectangle::generateBuffers() {
  44. std::vector<glm::vec2> rectangle_verts;
  45. std::vector<glm::vec2> rectangle_uvs;
  46. std::vector<glm::vec2> corner_verts;
  47. std::vector<glm::vec2> corner_uvs;
  48. std::vector<glm::vec2> center_verts;
  49. std::vector<glm::vec2> center_uvs;
  50. // Top left corner
  51. corner_verts.push_back( oul );
  52. corner_uvs.push_back( glm::vec2(0, 1) );
  53. corner_verts.push_back( ul );
  54. corner_uvs.push_back( glm::vec2(1, 0) );
  55. corner_verts.push_back( ul + glm::vec2( -border, 0 ) );
  56. corner_uvs.push_back( glm::vec2(0, 0) );
  57. corner_verts.push_back( oul );
  58. corner_uvs.push_back( glm::vec2(0, 1) );
  59. corner_verts.push_back( ul + glm::vec2( 0, border ) );
  60. corner_uvs.push_back( glm::vec2(1, 1) );
  61. corner_verts.push_back( ul );
  62. corner_uvs.push_back( glm::vec2(1, 0) );
  63. // Top right corner
  64. corner_verts.push_back( ur + glm::vec2( 0, border ) );
  65. corner_uvs.push_back( glm::vec2(0, 1) );
  66. corner_verts.push_back( ur + glm::vec2( border, 0 ) );
  67. corner_uvs.push_back( glm::vec2(1, 0) );
  68. corner_verts.push_back( ur );
  69. corner_uvs.push_back( glm::vec2(0, 0) );
  70. corner_verts.push_back( ur + glm::vec2( 0, border ) );
  71. corner_uvs.push_back( glm::vec2(0, 1) );
  72. corner_verts.push_back( our );
  73. corner_uvs.push_back( glm::vec2(1, 1) );
  74. corner_verts.push_back( ur + glm::vec2( border, 0 ) );
  75. corner_uvs.push_back( glm::vec2(1, 0) );
  76. // Bottom left corner
  77. corner_verts.push_back( bl + glm::vec2( -border, 0 ) );
  78. corner_uvs.push_back( glm::vec2(0, 1) );
  79. corner_verts.push_back( obl + glm::vec2( border, 0 ) );
  80. corner_uvs.push_back( glm::vec2(1, 0) );
  81. corner_verts.push_back( obl );
  82. corner_uvs.push_back( glm::vec2(0, 0) );
  83. corner_verts.push_back( bl + glm::vec2( -border, 0 ) );
  84. corner_uvs.push_back( glm::vec2(0, 1) );
  85. corner_verts.push_back( bl );
  86. corner_uvs.push_back( glm::vec2(1, 1) );
  87. corner_verts.push_back( bl + glm::vec2( 0, -border ) );
  88. corner_uvs.push_back( glm::vec2(1, 0) );
  89. // Bottom right corner
  90. corner_verts.push_back( br );
  91. corner_uvs.push_back( glm::vec2(0, 1) );
  92. corner_verts.push_back( obr );
  93. corner_uvs.push_back( glm::vec2(1, 0) );
  94. corner_verts.push_back( br + glm::vec2( 0, -border ) );
  95. corner_uvs.push_back( glm::vec2(0, 0) );
  96. corner_verts.push_back( br );
  97. corner_uvs.push_back( glm::vec2(0, 1) );
  98. corner_verts.push_back( br + glm::vec2( border, 0 ) );
  99. corner_uvs.push_back( glm::vec2(1, 1) );
  100. corner_verts.push_back( obr );
  101. corner_uvs.push_back( glm::vec2(1, 0) );
  102. // Left Rectangle
  103. rectangle_verts.push_back( ul + glm::vec2( -border, 0 ) );
  104. rectangle_uvs.push_back( glm::vec2(0, 1) );
  105. rectangle_verts.push_back( bl );
  106. rectangle_uvs.push_back( glm::vec2(1, 0) );
  107. rectangle_verts.push_back( bl + glm::vec2( -border, 0 ) );
  108. rectangle_uvs.push_back( glm::vec2(0, 0) );
  109. rectangle_verts.push_back( ul + glm::vec2( -border, 0 ) );
  110. rectangle_uvs.push_back( glm::vec2(0, 1) );
  111. rectangle_verts.push_back( ul );
  112. rectangle_uvs.push_back( glm::vec2(1, 1) );
  113. rectangle_verts.push_back( bl );
  114. rectangle_uvs.push_back( glm::vec2(1, 0) );
  115. // Right Rectangle
  116. rectangle_verts.push_back( ur );
  117. rectangle_uvs.push_back( glm::vec2(0, 1) );
  118. rectangle_verts.push_back( br + glm::vec2( border, 0 ) );
  119. rectangle_uvs.push_back( glm::vec2(1, 0) );
  120. rectangle_verts.push_back( br );
  121. rectangle_uvs.push_back( glm::vec2(0, 0) );
  122. rectangle_verts.push_back( ur );
  123. rectangle_uvs.push_back( glm::vec2(0, 1) );
  124. rectangle_verts.push_back( ur + glm::vec2( border, 0 ) );
  125. rectangle_uvs.push_back( glm::vec2(1, 1) );
  126. rectangle_verts.push_back( br + glm::vec2( border, 0 ) );
  127. rectangle_uvs.push_back( glm::vec2(1, 0) );
  128. // Top Rectangle
  129. rectangle_verts.push_back( ul + glm::vec2( 0, border ) );
  130. rectangle_uvs.push_back( glm::vec2(0, 1) );
  131. rectangle_verts.push_back( ur );
  132. rectangle_uvs.push_back( glm::vec2(1, 0) );
  133. rectangle_verts.push_back( ul );
  134. rectangle_uvs.push_back( glm::vec2(0, 0) );
  135. rectangle_verts.push_back( ul + glm::vec2( 0, border ) );
  136. rectangle_uvs.push_back( glm::vec2(0, 1) );
  137. rectangle_verts.push_back( ur + glm::vec2( 0, border ) );
  138. rectangle_uvs.push_back( glm::vec2(1, 1) );
  139. rectangle_verts.push_back( ur );
  140. rectangle_uvs.push_back( glm::vec2(1, 0) );
  141. // Bot Rectangle
  142. rectangle_verts.push_back( bl );
  143. rectangle_uvs.push_back( glm::vec2(0, 1) );
  144. rectangle_verts.push_back( br + glm::vec2( 0, -border ) );
  145. rectangle_uvs.push_back( glm::vec2(1, 0) );
  146. rectangle_verts.push_back( bl + glm::vec2( 0, -border ) );
  147. rectangle_uvs.push_back( glm::vec2(0, 0) );
  148. rectangle_verts.push_back( bl );
  149. rectangle_uvs.push_back( glm::vec2(0, 1) );
  150. rectangle_verts.push_back( br );
  151. rectangle_uvs.push_back( glm::vec2(1, 1) );
  152. rectangle_verts.push_back( br + glm::vec2( 0, -border ) );
  153. rectangle_uvs.push_back( glm::vec2(1, 0) );
  154. center_verts.push_back( ul );
  155. center_uvs.push_back( glm::vec2(0, 1) );
  156. center_verts.push_back( br );
  157. center_uvs.push_back( glm::vec2(1, 0) );
  158. center_verts.push_back( bl );
  159. center_uvs.push_back( glm::vec2(0, 0) );
  160. center_verts.push_back( ul );
  161. center_uvs.push_back( glm::vec2(0, 1) );
  162. center_verts.push_back( ur );
  163. center_uvs.push_back( glm::vec2(1, 1) );
  164. center_verts.push_back( br );
  165. center_uvs.push_back( glm::vec2(1, 0) );
  166. glGenBuffers( 6, (GLuint*)&buffer );
  167. glBindBuffer( GL_ARRAY_BUFFER, buffer.corner_verts );
  168. glBufferData( GL_ARRAY_BUFFER, corner_verts.size() * sizeof( glm::vec2 ), &corner_verts[0], GL_STATIC_DRAW );
  169. glBindBuffer( GL_ARRAY_BUFFER, buffer.corner_uvs );
  170. glBufferData( GL_ARRAY_BUFFER, corner_uvs.size() * sizeof( glm::vec2 ), &corner_uvs[0], GL_STATIC_DRAW );
  171. glBindBuffer( GL_ARRAY_BUFFER, buffer.rectangle_verts );
  172. glBufferData( GL_ARRAY_BUFFER, rectangle_verts.size() * sizeof( glm::vec2 ), &rectangle_verts[0], GL_STATIC_DRAW );
  173. glBindBuffer( GL_ARRAY_BUFFER, buffer.rectangle_uvs );
  174. glBufferData( GL_ARRAY_BUFFER, rectangle_uvs.size() * sizeof( glm::vec2 ), &rectangle_uvs[0], GL_STATIC_DRAW );
  175. glBindBuffer( GL_ARRAY_BUFFER, buffer.center_verts );
  176. glBufferData( GL_ARRAY_BUFFER, center_verts.size() * sizeof( glm::vec2 ), &center_verts[0], GL_STATIC_DRAW );
  177. glBindBuffer( GL_ARRAY_BUFFER, buffer.rectangle_uvs );
  178. glBufferData( GL_ARRAY_BUFFER, center_uvs.size() * sizeof( glm::vec2 ), &center_uvs[0], GL_STATIC_DRAW );
  179. corner_vertCount = corner_verts.size();
  180. rectangle_vertCount = rectangle_verts.size();
  181. center_vertCount = center_verts.size();
  182. }
  183. Rectangle::~Rectangle() {
  184. delete shader;
  185. glDeleteBuffers( 6, (GLuint*)&buffer );
  186. }
  187. void Rectangle::draw( glm::mat4& matrix ) {
  188. glEnable( GL_BLEND );
  189. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  190. shader->bind();
  191. shader->setParameter( "projection", matrix );
  192. if ( highlight ) {
  193. // Draw the center of the highlight
  194. shader->setParameter( "color", color );
  195. shader->setAttribute( "position", buffer.center_verts, 2 );
  196. glDrawArrays(GL_TRIANGLES, 0, center_vertCount );
  197. // Set the color to have no alpha, then draw the borders.
  198. glm::vec4 fullAlpha = glm::vec4(color.r,color.g,color.b,1);
  199. shader->setParameter( "color", fullAlpha );
  200. shader->setAttribute( "position", buffer.corner_verts, 2 );
  201. glDrawArrays(GL_TRIANGLES, 0, corner_vertCount );
  202. shader->setAttribute( "position", buffer.rectangle_verts, 2 );
  203. glDrawArrays(GL_TRIANGLES, 0, rectangle_vertCount );
  204. } else {
  205. shader->setParameter( "color", color );
  206. shader->setAttribute( "position", buffer.corner_verts, 2 );
  207. glDrawArrays(GL_TRIANGLES, 0, corner_vertCount );
  208. shader->setAttribute( "position", buffer.rectangle_verts, 2 );
  209. glDrawArrays(GL_TRIANGLES, 0, rectangle_vertCount );
  210. }
  211. shader->unbind();
  212. glDisable( GL_BLEND );
  213. }
  214. glm::vec4 Rectangle::getRect() {
  215. return glm::vec4( bl.x, bl.y, ur.x-ul.x, ul.y-bl.y );
  216. }