glrectangle.cpp 10KB

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