RenderInterfaceSFML.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * This source file is part of libRocket, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://www.librocket.com
  5. *
  6. * Copyright (c) 2008-2010 Nuno Silva
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. *
  26. */
  27. #include <Rocket/Core/Core.h>
  28. #include "RenderInterfaceSFML.h"
  29. #include <GL/gl.h>
  30. #define GL_CLAMP_TO_EDGE 0x812F
  31. // If built with the GL Easy Extension library we can compile geometry to VBO's
  32. // http://www.opengl.org/sdk/libs/GLee/
  33. #ifdef ENABLE_GLEE
  34. #include <GL/glee.h>
  35. class RocketSFMLRendererGeometryHandler
  36. {
  37. public:
  38. GLuint VertexID, IndexID;
  39. int NumVertices;
  40. Rocket::Core::TextureHandle Texture;
  41. RocketSFMLRendererGeometryHandler() : VertexID(0), IndexID(0), Texture(0), NumVertices(0)
  42. {
  43. };
  44. ~RocketSFMLRendererGeometryHandler()
  45. {
  46. if(VertexID)
  47. glDeleteBuffers(1, &VertexID);
  48. if(IndexID)
  49. glDeleteBuffers(1, &IndexID);
  50. VertexID = IndexID = 0;
  51. };
  52. };
  53. #endif
  54. struct RocketSFMLRendererVertex
  55. {
  56. sf::Vector2f Position, TexCoord;
  57. sf::Color Color;
  58. };
  59. RocketSFMLRenderer::RocketSFMLRenderer()
  60. {
  61. }
  62. void RocketSFMLRenderer::SetWindow(sf::RenderWindow *Window)
  63. {
  64. MyWindow = Window;
  65. Resize();
  66. };
  67. sf::RenderWindow *RocketSFMLRenderer::GetWindow()
  68. {
  69. return MyWindow;
  70. };
  71. void RocketSFMLRenderer::Resize()
  72. {
  73. MyWindow->SetActive(true);
  74. MyWindow->PreserveOpenGLStates(true);
  75. static sf::View View;
  76. View.SetFromRect(sf::FloatRect(0, (float)MyWindow->GetWidth(), (float)MyWindow->GetHeight(), 0));
  77. MyWindow->SetView(View);
  78. glMatrixMode(GL_PROJECTION);
  79. glLoadIdentity();
  80. glOrtho(0, MyWindow->GetWidth(), MyWindow->GetHeight(), 0, -1, 1);
  81. glMatrixMode(GL_MODELVIEW);
  82. glViewport(0, 0, MyWindow->GetWidth(), MyWindow->GetHeight());
  83. };
  84. // Called by Rocket when it wants to render geometry that it does not wish to optimise.
  85. void RocketSFMLRenderer::RenderGeometry(Rocket::Core::Vertex* vertices, int num_vertices, int* indices, int num_indices, const Rocket::Core::TextureHandle texture, const Rocket::Core::Vector2f& translation)
  86. {
  87. MyWindow->SetActive();
  88. glPushMatrix();
  89. glTranslatef(translation.x, translation.y, 0);
  90. std::vector<Rocket::Core::Vector2f> Positions(num_vertices);
  91. std::vector<Rocket::Core::Colourb> Colors(num_vertices);
  92. std::vector<Rocket::Core::Vector2f> TexCoords(num_vertices);
  93. for(int i = 0; i < num_vertices; i++)
  94. {
  95. Positions[i] = vertices[i].position;
  96. Colors[i] = vertices[i].colour;
  97. TexCoords[i] = vertices[i].tex_coord;
  98. };
  99. glEnableClientState(GL_VERTEX_ARRAY);
  100. glEnableClientState(GL_COLOR_ARRAY);
  101. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  102. glVertexPointer(2, GL_FLOAT, 0, &Positions[0]);
  103. glColorPointer(4, GL_UNSIGNED_BYTE, 0, &Colors[0]);
  104. glTexCoordPointer(2, GL_FLOAT, 0, &TexCoords[0]);
  105. glEnable(GL_BLEND);
  106. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  107. sf::Image *image = (sf::Image *)texture;
  108. if(image)
  109. {
  110. image->Bind();
  111. }
  112. else
  113. {
  114. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  115. glBindTexture(GL_TEXTURE_2D, 0);
  116. };
  117. glDrawElements(GL_TRIANGLES, num_indices, GL_UNSIGNED_INT, indices);
  118. glDisableClientState(GL_VERTEX_ARRAY);
  119. glDisableClientState(GL_COLOR_ARRAY);
  120. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  121. glColor4f(1, 1, 1, 1);
  122. glPopMatrix();
  123. }
  124. // Called by Rocket when it wants to compile geometry it believes will be static for the forseeable future.
  125. Rocket::Core::CompiledGeometryHandle RocketSFMLRenderer::CompileGeometry(Rocket::Core::Vertex* vertices,
  126. int num_vertices, int* indices,
  127. int num_indices,
  128. const Rocket::Core::TextureHandle texture)
  129. {
  130. #ifdef ENABLE_GLEE
  131. MyWindow->SetActive();
  132. if(!GLEE_VERSION_2_0)
  133. return (Rocket::Core::CompiledGeometryHandle) NULL;
  134. std::vector<RocketSFMLRendererVertex> Data(num_vertices);
  135. for(unsigned long i = 0; i < Data.size(); i++)
  136. {
  137. Data[i].Position = *(sf::Vector2f*)&vertices[i].position;
  138. Data[i].TexCoord = *(sf::Vector2f*)&vertices[i].tex_coord;
  139. Data[i].Color = sf::Color(vertices[i].colour.red, vertices[i].colour.green,
  140. vertices[i].colour.blue, vertices[i].colour.alpha);
  141. };
  142. RocketSFMLRendererGeometryHandler *Geometry = new RocketSFMLRendererGeometryHandler();
  143. Geometry->NumVertices = num_indices;
  144. glGenBuffers(1, &Geometry->VertexID);
  145. glBindBuffer(GL_ARRAY_BUFFER, Geometry->VertexID);
  146. glBufferData(GL_ARRAY_BUFFER, sizeof(RocketSFMLRendererVertex) * num_vertices, &Data[0],
  147. GL_STATIC_DRAW);
  148. glGenBuffers(1, &Geometry->IndexID);
  149. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Geometry->IndexID);
  150. glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * num_indices, indices, GL_STATIC_DRAW);
  151. glBindBuffer(GL_ARRAY_BUFFER, 0);
  152. Geometry->Texture = texture;
  153. return (Rocket::Core::CompiledGeometryHandle)Geometry;
  154. #else
  155. return NULL;
  156. #endif
  157. }
  158. // Called by Rocket when it wants to render application-compiled geometry.
  159. void RocketSFMLRenderer::RenderCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry, const Rocket::Core::Vector2f& translation)
  160. {
  161. #ifdef ENABLE_GLEE
  162. MyWindow->SetActive();
  163. RocketSFMLRendererGeometryHandler *RealGeometry = (RocketSFMLRendererGeometryHandler *)geometry;
  164. glPushMatrix();
  165. glTranslatef(translation.x, translation.y, 0);
  166. glEnable(GL_BLEND);
  167. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  168. sf::Image *image = (sf::Image *)RealGeometry->Texture;
  169. if(image)
  170. {
  171. image->Bind();
  172. }
  173. else
  174. {
  175. glBindTexture(GL_TEXTURE_2D, 0);
  176. };
  177. glEnable(GL_VERTEX_ARRAY);
  178. glEnable(GL_TEXTURE_COORD_ARRAY);
  179. glEnable(GL_COLOR_ARRAY);
  180. #define BUFFER_OFFSET(x) ((char*)0 + x)
  181. glBindBuffer(GL_ARRAY_BUFFER, RealGeometry->VertexID);
  182. glVertexPointer(2, GL_FLOAT, sizeof(RocketSFMLRendererVertex), BUFFER_OFFSET(0));
  183. glTexCoordPointer(2, GL_FLOAT, sizeof(RocketSFMLRendererVertex), BUFFER_OFFSET(sizeof(sf::Vector2f)));
  184. glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(RocketSFMLRendererVertex), BUFFER_OFFSET(sizeof(sf::Vector2f[2])));
  185. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, RealGeometry->IndexID);
  186. glDrawElements(GL_TRIANGLES, RealGeometry->NumVertices, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
  187. glBindBuffer(GL_ARRAY_BUFFER, 0);
  188. glDisable(GL_COLOR_ARRAY);
  189. glDisable(GL_TEXTURE_COORD_ARRAY);
  190. glDisable(GL_VERTEX_ARRAY);
  191. glColor4f(1, 1, 1, 1);
  192. glPopMatrix();
  193. #else
  194. ROCKET_ASSERT(false & "Not Implemented");
  195. #endif
  196. }
  197. // Called by Rocket when it wants to release application-compiled geometry.
  198. void RocketSFMLRenderer::ReleaseCompiledGeometry(Rocket::Core::CompiledGeometryHandle geometry)
  199. {
  200. #ifdef ENABLE_GLEE
  201. MyWindow->SetActive();
  202. delete (RocketSFMLRendererGeometryHandler *)geometry;
  203. #else
  204. ROCKET_ASSERT(false & "Not Implemented");
  205. #endif
  206. }
  207. // Called by Rocket when it wants to enable or disable scissoring to clip content.
  208. void RocketSFMLRenderer::EnableScissorRegion(bool enable)
  209. {
  210. MyWindow->SetActive();
  211. if (enable)
  212. glEnable(GL_SCISSOR_TEST);
  213. else
  214. glDisable(GL_SCISSOR_TEST);
  215. }
  216. // Called by Rocket when it wants to change the scissor region.
  217. void RocketSFMLRenderer::SetScissorRegion(int x, int y, int width, int height)
  218. {
  219. MyWindow->SetActive();
  220. glScissor(x, MyWindow->GetHeight() - (y + height), width, height);
  221. }
  222. // Called by Rocket when a texture is required by the library.
  223. bool RocketSFMLRenderer::LoadTexture(Rocket::Core::TextureHandle& texture_handle, Rocket::Core::Vector2i& texture_dimensions, const Rocket::Core::String& source)
  224. {
  225. MyWindow->SetActive();
  226. Rocket::Core::FileInterface* file_interface = Rocket::Core::GetFileInterface();
  227. Rocket::Core::FileHandle file_handle = file_interface->Open(source);
  228. if (file_handle == NULL)
  229. return false;
  230. file_interface->Seek(file_handle, 0, SEEK_END);
  231. size_t buffer_size = file_interface->Tell(file_handle);
  232. file_interface->Seek(file_handle, 0, SEEK_SET);
  233. char* buffer = new char[buffer_size];
  234. file_interface->Read(buffer, buffer_size, file_handle);
  235. file_interface->Close(file_handle);
  236. sf::Image *image = new sf::Image();
  237. if(!image->LoadFromMemory(buffer, buffer_size))
  238. {
  239. delete buffer;
  240. delete image;
  241. return false;
  242. };
  243. delete buffer;
  244. texture_handle = (Rocket::Core::TextureHandle) image;
  245. texture_dimensions = Rocket::Core::Vector2i(image->GetWidth(), image->GetHeight());
  246. return true;
  247. }
  248. // Called by Rocket when a texture is required to be built from an internally-generated sequence of pixels.
  249. bool RocketSFMLRenderer::GenerateTexture(Rocket::Core::TextureHandle& texture_handle, const Rocket::Core::byte* source, const Rocket::Core::Vector2i& source_dimensions)
  250. {
  251. MyWindow->SetActive();
  252. sf::Image *image = new sf::Image();
  253. if(!image->LoadFromPixels(source_dimensions.x, source_dimensions.y, source))
  254. {
  255. delete image;
  256. return false;
  257. };
  258. texture_handle = (Rocket::Core::TextureHandle)image;
  259. return true;
  260. }
  261. // Called by Rocket when a loaded texture is no longer required.
  262. void RocketSFMLRenderer::ReleaseTexture(Rocket::Core::TextureHandle texture_handle)
  263. {
  264. MyWindow->SetActive();
  265. delete (sf::Image *)texture_handle;
  266. }