Browse Source

Performance boost by storing data in GL buffers directly

Thomas Buck 9 years ago
parent
commit
63e5a0b55f

+ 2
- 0
ChangeLog.md View File

@@ -6,6 +6,8 @@
6 6
     * Fixed bug in WindowSDL where resizing only worked after calling it two times.
7 7
     * Fixed bug in Console that caused its window to get bigger after each launch.
8 8
     * Added ShaderBuffer class.
9
+    * Level geometry now stored in GL buffers at level load.
10
+        * Greatly improved level load times, more FPS.
9 11
 
10 12
     [ 20141231 ]
11 13
     * No longer using Exceptions.

+ 0
- 1
include/Camera.h View File

@@ -51,7 +51,6 @@ class Camera {
51 51
     static void calculateFrustumPlanes();
52 52
 
53 53
     static glm::vec3 pos;
54
-    static glm::vec3 drawPos;
55 54
     static glm::quat quaternion;
56 55
     static glm::vec3 posSpeed;
57 56
     static glm::vec2 rotSpeed;

+ 10
- 45
include/Mesh.h View File

@@ -8,12 +8,13 @@
8 8
 #ifndef _MESH_H_
9 9
 #define _MESH_H_
10 10
 
11
-#include <map>
12 11
 #include <vector>
13 12
 #include <glm/mat4x4.hpp>
14 13
 #include <glm/vec2.hpp>
15 14
 #include <glm/vec3.hpp>
16 15
 
16
+#include "system/Shader.h"
17
+
17 18
 struct IndexedRectangle {
18 19
     unsigned int v1, v2, v3, v4; // Vertex list indices
19 20
     unsigned int texture; // Index into object-texture list
@@ -46,53 +47,17 @@ class Mesh {
46 47
     void display(glm::mat4 MVP);
47 48
 
48 49
   private:
49
-    std::vector<unsigned short> indices;
50
-    std::vector<glm::vec3> vertices;
51
-    std::vector<glm::vec2> uvs;
52
-    std::vector<unsigned int> textures;
53
-
54
-    std::vector<unsigned short> indicesColor;
55
-    std::vector<glm::vec3> verticesColor;
56
-    std::vector<glm::vec3> colors;
57
-};
58
-
59
-// --------------------------------------
60
-
61
-struct PackedVertex {
62
-    glm::vec3 pos;
63
-    glm::vec2 uv;
64
-    unsigned int tex;
50
+    std::vector<unsigned short> indicesBuff;
51
+    std::vector<glm::vec3> verticesBuff;
52
+    std::vector<unsigned int> texturesBuff;
65 53
 
66
-    PackedVertex(glm::vec3 p, glm::vec2 u, unsigned int t) : pos(p), uv(u), tex(t) { }
54
+    std::vector<unsigned short> indicesColorBuff;
55
+    std::vector<glm::vec3> verticesColorBuff;
56
+    std::vector<glm::vec3> colorsBuff;
67 57
 
68
-    bool operator<(const PackedVertex& v) const {
69
-        return memcmp(this, &v, sizeof(PackedVertex)) > 0;
70
-    }
58
+    ShaderBuffer indices, vertices, uvs;
59
+    ShaderBuffer indicesColor, verticesColor, colors;
71 60
 };
72 61
 
73
-struct PackedColoredVertex {
74
-    glm::vec3 pos;
75
-    glm::vec3 col;
76
-
77
-    PackedColoredVertex(glm::vec3 p, glm::vec3 c) : pos(p), col(c) { }
78
-
79
-    bool operator<(const PackedColoredVertex& v) const {
80
-        return memcmp(this, &v, sizeof(PackedColoredVertex)) > 0;
81
-    }
82
-};
83
-
84
-template <typename T>
85
-bool findSimilarVertex(T& v,
86
-                       std::map<T, unsigned short> m,
87
-                       unsigned short& s) {
88
-    auto it = m.find(v);
89
-    if (it == m.end())
90
-        return false;
91
-    else {
92
-        s = it->second;
93
-        return true;
94
-    }
95
-}
96
-
97 62
 #endif
98 63
 

+ 5
- 4
include/RoomMesh.h View File

@@ -14,6 +14,7 @@
14 14
 #include <glm/vec3.hpp>
15 15
 
16 16
 #include "Mesh.h"
17
+#include "system/Shader.h"
17 18
 
18 19
 struct RoomVertexTR2 {
19 20
     int x, y, z; // Vertex coordinates, relative to x/zOffset
@@ -36,10 +37,10 @@ class RoomMesh {
36 37
     void display(glm::mat4 MVP);
37 38
 
38 39
   private:
39
-    std::vector<unsigned short> indices;
40
-    std::vector<glm::vec3> vertices;
41
-    std::vector<glm::vec2> uvs;
42
-    std::vector<unsigned int> textures;
40
+    std::vector<unsigned short> indicesBuff;
41
+    std::vector<glm::vec3> verticesBuff;
42
+    std::vector<unsigned int> texturesBuff;
43
+    ShaderBuffer indices, vertices, uvs;
43 44
 };
44 45
 
45 46
 #endif

+ 13
- 5
include/TextureManager.h View File

@@ -59,6 +59,7 @@ class TextureManager {
59 59
         SYSTEM
60 60
     };
61 61
 
62
+    TextureManager() : nextFreeTextureUnit(0) { }
62 63
     ~TextureManager();
63 64
 
64 65
     int initialize();
@@ -69,12 +70,12 @@ class TextureManager {
69 70
     int numTextures(TextureStorage s = TextureStorage::GAME);
70 71
 
71 72
     /*!
72
-     * \brief Binds the texture for use in GL
73
-     * \param n valid texture index
74
-     * \param s Which TextureStorage should be accessed
75
-     * \param unit Which GL texture unit should be used
73
+     * \brief Bind texture to next free texture unit.
74
+     * \param n ID of texture to bind
75
+     * \param s Place where texture is stored
76
+     * \returns ID of GL texture unit to which this texture is bound.
76 77
      */
77
-    void bindTextureId(unsigned int n, TextureStorage s = TextureStorage::GAME, unsigned int unit = 0);
78
+    int bindTexture(unsigned int n, TextureStorage s);
78 79
 
79 80
     /*!
80 81
      * \brief Loads Buffer as texture
@@ -107,6 +108,9 @@ class TextureManager {
107 108
 
108 109
   private:
109 110
     std::vector<unsigned int>& getIds(TextureStorage s);
111
+    std::vector<int>& getUnits(TextureStorage s);
112
+
113
+    void bindTextureId(unsigned int n, TextureStorage s, unsigned int unit);
110 114
     int loadPCX(std::string filename, TextureStorage s, int slot);
111 115
 
112 116
     std::vector<unsigned int> mTextureIdsGame;
@@ -114,6 +118,10 @@ class TextureManager {
114 118
 
115 119
     std::vector<TextureTile*> tiles;
116 120
     std::vector<std::vector<int>> animations;
121
+
122
+    std::vector<int> gameUnits;
123
+    std::vector<int> systemUnits;
124
+    unsigned int nextFreeTextureUnit;
117 125
 };
118 126
 
119 127
 TextureManager& getTextureManager();

+ 2
- 0
include/system/FontSDL.h View File

@@ -33,6 +33,8 @@ class FontSDL {
33 33
     static bool mFontInit;
34 34
     static TTF_Font* mFont;
35 35
     static unsigned int mFontTexture;
36
+    static ShaderBuffer vertexBuffer;
37
+    static ShaderBuffer uvBuffer;
36 38
 };
37 39
 
38 40
 #endif

+ 5
- 0
include/system/FontTRLE.h View File

@@ -11,6 +11,8 @@
11 11
 #include <vector>
12 12
 #include <glm/vec2.hpp>
13 13
 
14
+#include "system/Shader.h"
15
+
14 16
 /*!
15 17
  * \brief Tomb Raider Level Editor Font loader
16 18
  */
@@ -42,6 +44,9 @@ class FontTRLE {
42 44
     // 106 entries: (x, y, w, h, offset)
43 45
     static int offsets[106][5];
44 46
     static int defaultOffsets[106][5];
47
+
48
+    static ShaderBuffer vertexBuffer;
49
+    static ShaderBuffer uvBuffer;
45 50
 };
46 51
 
47 52
 #endif

+ 17
- 23
include/system/Shader.h View File

@@ -17,7 +17,7 @@
17 17
 
18 18
 class ShaderBuffer {
19 19
   public:
20
-    ShaderBuffer();
20
+    ShaderBuffer() : created(false), buffer(0), boundSize(0) { }
21 21
     ~ShaderBuffer();
22 22
 
23 23
     void bufferData(int elem, int size, void* data);
@@ -30,8 +30,12 @@ class ShaderBuffer {
30 30
     void bindBuffer(int location, int size);
31 31
     void unbind(int location);
32 32
 
33
+    int getSize() { return boundSize; }
34
+
33 35
   private:
36
+    bool created;
34 37
     unsigned int buffer;
38
+    int boundSize;
35 39
 };
36 40
 
37 41
 class Shader {
@@ -45,41 +49,31 @@ class Shader {
45 49
     int addUniform(const char* name);
46 50
     unsigned int getUniform(int n);
47 51
 
48
-    void addBuffer(int n = 1);
49
-    unsigned int getBuffer(int n);
50
-
51
-    template<typename T>
52
-    void bufferData(int buff, std::vector<T> v)
53
-        { bufferData(buff, v.size(), sizeof(T), &v[0]); }
54
-    void bufferData(int buff, int elem, int size, void* d);
55
-
56 52
     void loadUniform(int uni, glm::vec2 vec);
57 53
     void loadUniform(int uni, glm::vec4 vec);
58 54
     void loadUniform(int uni, glm::mat4 mat);
59
-    void loadUniform(int uni, int texture, TextureManager::TextureStorage store, int slot = 0);
60
-
61
-    void bindBuffer(int buff);
62
-    void bindBuffer(int buff, int location, int size);
63
-
64
-    void disableAttribs();
55
+    void loadUniform(int uni, int texture, TextureManager::TextureStorage store);
65 56
 
66 57
     static int initialize();
67 58
     static void shutdown();
68 59
 
69
-    static void drawGL(std::vector<glm::vec2>& vertices, std::vector<glm::vec2>& uvs,
70
-                       glm::vec4 color, unsigned int texture);
60
+    static void drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, glm::vec4 color, unsigned int texture,
61
+                       TextureManager::TextureStorage store = TextureManager::TextureStorage::SYSTEM);
71 62
 
72
-    static void drawGL(std::vector<glm::vec3>& vertices, std::vector<glm::vec2>& uvs,
73
-                       std::vector<unsigned short>& indices, glm::mat4 MVP, unsigned int texture);
63
+    static void drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, unsigned int texture, glm::mat4 MVP,
64
+                       TextureManager::TextureStorage store = TextureManager::TextureStorage::GAME);
65
+    static void drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, ShaderBuffer& indices,
66
+                       unsigned int texture, glm::mat4 MVP,
67
+                       TextureManager::TextureStorage store = TextureManager::TextureStorage::GAME);
74 68
 
75
-    static void drawGL(std::vector<glm::vec3>& vertices, std::vector<glm::vec3>& colors,
76
-                       std::vector<unsigned short>& indices, glm::mat4 MVP, int mode = GL_TRIANGLES);
69
+    static void drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, glm::mat4 MVP,
70
+                       unsigned int mode = GL_TRIANGLES);
71
+    static void drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, ShaderBuffer& indices,
72
+                       glm::mat4 MVP, unsigned int mode = GL_TRIANGLES);
77 73
 
78 74
   private:
79 75
     int programID;
80 76
     std::vector<unsigned int> uniforms;
81
-    std::vector<unsigned int> buffers;
82
-    std::vector<bool> attribs;
83 77
 
84 78
     static Shader textShader;
85 79
     static const char* textShaderVertex;

+ 57
- 45
src/Camera.cpp View File

@@ -43,7 +43,6 @@ const static glm::vec3 upUnit(0.0f, 1.0f, 0.0f);
43 43
 const static glm::vec3 dirUnit(0.0f, 0.0f, -1.0f);
44 44
 
45 45
 glm::vec3 Camera::pos(0.0f, 0.0f, 0.0f);
46
-glm::vec3 Camera::drawPos(0.0f, 0.0f, 0.0f);
47 46
 glm::quat Camera::quaternion(glm::vec3(0.0f, 0.0f, 0.0f));
48 47
 glm::vec3 Camera::posSpeed(0.0f, 0.0f, 0.0f);
49 48
 glm::vec2 Camera::rotSpeed(0.0f, 0.0f);
@@ -56,7 +55,6 @@ bool Camera::dirty = true;
56 55
 
57 56
 void Camera::reset() {
58 57
     pos = glm::vec3(0.0f, 0.0f, 0.0f);
59
-    drawPos = glm::vec3(0.0f, 0.0f, 0.0f);
60 58
     quaternion = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
61 59
     posSpeed = glm::vec3(0.0f, 0.0f, 0.0f);
62 60
     rotSpeed = glm::vec2(0.0f, 0.0f);
@@ -233,6 +231,12 @@ static glm::vec3 frustumColors[6] = {
233 231
 };
234 232
 static glm::vec3 frustumVertices[8];
235 233
 
234
+static ShaderBuffer vertexBuffer;
235
+static ShaderBuffer colorBuffer;
236
+static ShaderBuffer indexBuffer;
237
+static ShaderBuffer vertexPointBuffer;
238
+static ShaderBuffer colorPointBuffer;
239
+
236 240
 void Camera::calculateFrustumPlanes() {
237 241
     glm::mat4 combo = projection * view;
238 242
 
@@ -260,30 +264,7 @@ void Camera::calculateFrustumPlanes() {
260 264
     planes[NEAR].set(frustumVertices[NTL], frustumVertices[NTR], frustumVertices[NBR]);
261 265
     planes[FAR].set(frustumVertices[FTR], frustumVertices[FTL], frustumVertices[FBL]);
262 266
 
263
-    drawPos = getPosition();
264
-}
265
-
266
-bool Camera::boxInFrustum(BoundingBox b) {
267
-    for (int i = 0; i < 6; i++) {
268
-        int out = 0, in = 0;
269
-        for (int c = 0; (c < 8) && ((in == 0) || (out == 0)); c++) {
270
-            if (planes[i].distance(b.getCorner(c)) < 0)
271
-                out++;
272
-            else
273
-                in++;
274
-        }
275
-
276
-        if (in == 0)
277
-            return false;
278
-    }
279
-
280
-    return true;
281
-}
282
-
283
-void Camera::displayFrustum(glm::mat4 MVP) {
284 267
     std::vector<glm::vec3> verts;
285
-    std::vector<glm::vec3> cols;
286
-    std::vector<unsigned short> inds;
287 268
 
288 269
     // Near
289 270
     verts.push_back(frustumVertices[NTL]);
@@ -321,29 +302,60 @@ void Camera::displayFrustum(glm::mat4 MVP) {
321 302
     verts.push_back(frustumVertices[FTR]);
322 303
     verts.push_back(frustumVertices[FBR]);
323 304
 
324
-    for (int i = 0; i < 6; i++) {
325
-        cols.push_back(frustumColors[i]);
326
-        cols.push_back(frustumColors[i]);
327
-        cols.push_back(frustumColors[i]);
328
-        cols.push_back(frustumColors[i]);
329
-
330
-        inds.push_back(4 * i);
331
-        inds.push_back((4 * i) + 1);
332
-        inds.push_back((4 * i) + 2);
333
-        inds.push_back((4 * i) + 3);
334
-        inds.push_back((4 * i) + 2);
335
-        inds.push_back(4 * i);
336
-    }
337
-
338
-    Shader::drawGL(verts, cols, inds, MVP);
305
+    vertexBuffer.bufferData(verts);
339 306
 
340 307
     verts.clear();
341
-    cols.clear();
342
-    inds.clear();
308
+    std::vector<glm::vec3> cols;
343 309
 
344
-    verts.push_back(drawPos);
310
+    verts.push_back(getPosition());
345 311
     cols.push_back(glm::vec3(1.0f, 1.0f, 1.0f));
346
-    inds.push_back(0);
347
-    Shader::drawGL(verts, cols, inds, MVP, GL_POINTS);
312
+
313
+    vertexPointBuffer.bufferData(verts);
314
+    colorPointBuffer.bufferData(cols);
315
+
316
+    if (colorBuffer.getSize() == 0) {
317
+        cols.clear();
318
+        for (int i = 0; i < 6; i++) {
319
+            for (int j = 0; j < 4; j++) {
320
+                cols.push_back(frustumColors[i]);
321
+            }
322
+        }
323
+        colorBuffer.bufferData(cols);
324
+    }
325
+
326
+    if (indexBuffer.getSize() == 0) {
327
+        std::vector<unsigned short> inds;
328
+        for (int i = 0; i < 6; i++) {
329
+            inds.push_back(4 * i);
330
+            inds.push_back((4 * i) + 1);
331
+            inds.push_back((4 * i) + 2);
332
+            inds.push_back((4 * i) + 3);
333
+            inds.push_back((4 * i) + 2);
334
+            inds.push_back(4 * i);
335
+        }
336
+        indexBuffer.bufferData(inds);
337
+    }
338
+}
339
+
340
+bool Camera::boxInFrustum(BoundingBox b) {
341
+    for (int i = 0; i < 6; i++) {
342
+        int out = 0, in = 0;
343
+        for (int c = 0; (c < 8) && ((in == 0) || (out == 0)); c++) {
344
+            if (planes[i].distance(b.getCorner(c)) < 0)
345
+                out++;
346
+            else
347
+                in++;
348
+        }
349
+
350
+        if (in == 0)
351
+            return false;
352
+    }
353
+
354
+    return true;
355
+}
356
+
357
+void Camera::displayFrustum(glm::mat4 MVP) {
358
+    Shader::drawGL(vertexBuffer, colorBuffer, indexBuffer, MVP);
359
+    Shader::drawGL(vertexPointBuffer, colorPointBuffer, MVP, GL_POINTS);
348 360
 }
349 361
 

+ 79
- 79
src/Mesh.cpp View File

@@ -16,132 +16,132 @@ Mesh::Mesh(const std::vector<glm::vec3>& vert,
16 16
            const std::vector<IndexedColoredRectangle>& coloredRect,
17 17
            const std::vector<IndexedColoredRectangle>& coloredTri) {
18 18
     for (auto& t : rect) {
19
-        indices.push_back(0);
20
-        vertices.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
21
-        vertices.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
22
-        vertices.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
23
-        vertices.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
24
-        textures.push_back(t.texture);
19
+        indicesBuff.push_back(0);
20
+        verticesBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
21
+        verticesBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
22
+        verticesBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
23
+        verticesBuff.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
24
+        texturesBuff.push_back(t.texture);
25 25
     }
26 26
 
27 27
     for (auto& t : tri) {
28
-        indices.push_back(1);
29
-        vertices.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
30
-        vertices.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
31
-        vertices.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
32
-        textures.push_back(t.texture);
28
+        indicesBuff.push_back(1);
29
+        verticesBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
30
+        verticesBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
31
+        verticesBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
32
+        texturesBuff.push_back(t.texture);
33 33
     }
34 34
 
35 35
     for (auto& t : coloredRect) {
36
-        indicesColor.push_back(0);
37
-        verticesColor.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
38
-        verticesColor.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
39
-        verticesColor.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
40
-        verticesColor.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
41
-        colors.push_back(glm::vec3(t.r, t.g, t.b));
36
+        indicesColorBuff.push_back(0);
37
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
38
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
39
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
40
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
41
+        colorsBuff.push_back(glm::vec3(t.r, t.g, t.b));
42 42
     }
43 43
 
44 44
     for (auto& t : coloredTri) {
45
-        indicesColor.push_back(1);
46
-        verticesColor.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
47
-        verticesColor.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
48
-        verticesColor.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
49
-        colors.push_back(glm::vec3(t.r, t.g, t.b));
45
+        indicesColorBuff.push_back(1);
46
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
47
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
48
+        verticesColorBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
49
+        colorsBuff.push_back(glm::vec3(t.r, t.g, t.b));
50 50
     }
51 51
 }
52 52
 
53 53
 void Mesh::prepare() {
54 54
     std::vector<unsigned short> ind;
55 55
     std::vector<glm::vec3> vert;
56
+    std::vector<glm::vec2> uvBuff;
56 57
     std::vector<unsigned int> tex;
57
-    std::map<PackedVertex, unsigned short> vertexMap;
58
+
58 59
     int vertIndex = 0;
59
-    for (int i = 0; i < indices.size(); i++) {
60
-        unsigned int texture = getTextureManager().getTile(textures.at(i)).getTexture();
61
-        for (int v = 0; v < ((indices.at(i) == 0) ? 4 : 3); v++) {
62
-            glm::vec2 uv = getTextureManager().getTile(textures.at(i)).getUV(v);
63
-            PackedVertex p(vertices.at(vertIndex + v), uv, texture);
64
-            unsigned short s;
65
-            if (findSimilarVertex(p, vertexMap, s)) {
66
-                ind.push_back(s); // Vertex already cached
67
-            } else {
68
-                vertexMap[p] = vert.size();
69
-                ind.push_back(vert.size());
70
-                vert.push_back(p.pos);
71
-                uvs.push_back(p.uv);
72
-                tex.push_back(p.tex);
73
-            }
60
+    for (int i = 0; i < indicesBuff.size(); i++) {
61
+        unsigned int texture = getTextureManager().getTile(texturesBuff.at(i)).getTexture();
62
+        for (int v = 0; v < ((indicesBuff.at(i) == 0) ? 4 : 3); v++) {
63
+            ind.push_back(vert.size());
64
+            vert.push_back(verticesBuff.at(vertIndex + v));
65
+            uvBuff.push_back(getTextureManager().getTile(texturesBuff.at(i)).getUV(v));
66
+            tex.push_back(texture);
74 67
         }
75 68
 
76
-        if (indices.at(i) == 0) {
69
+        if (indicesBuff.at(i) == 0) {
77 70
             ind.push_back(ind.at(ind.size() - 2));
78 71
             ind.push_back(ind.at(ind.size() - 5));
79 72
         }
80 73
 
81
-        vertIndex += (indices.at(i) == 0) ? 4 : 3;
74
+        vertIndex += (indicesBuff.at(i) == 0) ? 4 : 3;
82 75
     }
76
+
83 77
     assert((ind.size() % 3) == 0);
84 78
     assert(vert.size() == tex.size());
85
-    assert(vert.size() == uvs.size());
86
-    indices = std::move(ind);
87
-    vertices = std::move(vert);
88
-    textures = std::move(tex);
89
-
90
-    std::vector<unsigned short> indC;
91
-    std::vector<glm::vec3> vertC;
92
-    std::vector<glm::vec3> col;
93
-    std::map<PackedColoredVertex, unsigned short> vertexMapC;
79
+    assert(vert.size() == uvBuff.size());
80
+
81
+    indicesBuff = std::move(ind);
82
+    vertices.bufferData(vert);
83
+    uvs.bufferData(uvBuff);
84
+    texturesBuff = std::move(tex);
85
+
86
+    std::vector<unsigned short> indCol;
87
+    std::vector<glm::vec3> vertCol;
88
+    std::vector<glm::vec3> cols;
89
+
94 90
     vertIndex = 0;
95
-    for (int i = 0; i < indicesColor.size(); i++) {
96
-        for (int v = 0; v < ((indicesColor.at(i) == 0) ? 4 : 3); v++) {
97
-            PackedColoredVertex p(verticesColor.at(vertIndex + v), colors.at(i));
98
-            unsigned short s;
99
-            if (findSimilarVertex(p, vertexMapC, s)) {
100
-                indC.push_back(s); // Vertex already cached
101
-            } else {
102
-                vertexMapC[p] = vertC.size();
103
-                indC.push_back(vertC.size());
104
-                vertC.push_back(p.pos);
105
-                col.push_back(p.col);
106
-            }
91
+    for (int i = 0; i < indicesColorBuff.size(); i++) {
92
+        for (int v = 0; v < ((indicesColorBuff.at(i) == 0) ? 4 : 3); v++) {
93
+            indCol.push_back(vertCol.size());
94
+            vertCol.push_back(verticesColorBuff.at(vertIndex + v));
95
+            cols.push_back(colorsBuff.at(i));
107 96
         }
108 97
 
109
-        if (indicesColor.at(i) == 0) {
110
-            indC.push_back(indC.at(indC.size() - 2));
111
-            indC.push_back(indC.at(indC.size() - 5));
98
+        if (indicesColorBuff.at(i) == 0) {
99
+            indCol.push_back(indCol.at(indCol.size() - 2));
100
+            indCol.push_back(indCol.at(indCol.size() - 5));
112 101
         }
113 102
 
114
-        vertIndex += (indicesColor.at(i) == 0) ? 4 : 3;
103
+        vertIndex += (indicesColorBuff.at(i) == 0) ? 4 : 3;
115 104
     }
116
-    assert((indC.size() % 3) == 0);
117
-    assert(vertC.size() == col.size());
118
-    indicesColor = std::move(indC);
119
-    verticesColor = std::move(vertC);
120
-    colors = std::move(col);
105
+
106
+    assert((indCol.size() % 3) == 0);
107
+    assert(vertCol.size() == cols.size());
108
+
109
+    indicesColor.bufferData(indCol);
110
+    verticesColor.bufferData(vertCol);
111
+    colors.bufferData(cols);
112
+
113
+    verticesBuff.clear();
114
+    indicesColorBuff.clear();
115
+    verticesColorBuff.clear();
116
+    colorsBuff.clear();
121 117
 }
122 118
 
123 119
 void Mesh::display(glm::mat4 MVP) {
124
-    if (indices.size() > 0) {
120
+    if (indicesBuff.size() > 0) {
125 121
         unsigned int indexStart = 0;
126 122
         unsigned int indexPos = 1;
127
-        unsigned int texture = textures.at(indices.at(0));
123
+        unsigned int texture = texturesBuff.at(indicesBuff.at(0));
128 124
 
129
-        while ((indexStart != indexPos) && (indexPos < indices.size())) {
130
-            while ((indexPos < indices.size()) && (textures.at(indices.at(indexPos)) == texture))
125
+        while ((indexStart != indexPos) && (indexPos < indicesBuff.size())) {
126
+            while ((indexPos < indicesBuff.size())
127
+                    && (texturesBuff.at(indicesBuff.at(indexPos)) == texture)) {
131 128
                 indexPos++;
129
+            }
132 130
 
133
-            std::vector<unsigned short> ind(indices.begin() + indexStart, indices.begin() + indexPos);
134
-            Shader::drawGL(vertices, uvs, ind, MVP, texture);
131
+            std::vector<unsigned short> ind(indicesBuff.begin() + indexStart,
132
+                                            indicesBuff.begin() + indexPos);
133
+            indices.bufferData(ind);
134
+            Shader::drawGL(vertices, uvs, indices, texture, MVP);
135 135
 
136
-            if (indexPos < indices.size()) {
136
+            if (indexPos < indicesBuff.size()) {
137 137
                 indexStart = indexPos;
138 138
                 indexPos += 1;
139
-                texture = textures.at(indices.at(indexStart));
139
+                texture = texturesBuff.at(indicesBuff.at(indexStart));
140 140
             }
141 141
         }
142 142
     }
143 143
 
144
-    if (indicesColor.size() > 0)
144
+    if (indicesColor.getSize() > 0)
145 145
         Shader::drawGL(verticesColor, colors, indicesColor, MVP);
146 146
 }
147 147
 

+ 4
- 3
src/Render.cpp View File

@@ -185,10 +185,11 @@ void Render::drawTexture(float x, float y, float w, float h, glm::vec4 color,
185 185
     uvs.push_back(glm::vec2(1.0f, 1.0f));
186 186
     uvs.push_back(glm::vec2(0.0f, 0.0f));
187 187
 
188
-    //! \fixme This drawGL only uses SYSTEM textures!
189
-    assert(s == TextureManager::TextureStorage::SYSTEM);
188
+    static ShaderBuffer vert, uv;
189
+    vert.bufferData(vertices);
190
+    uv.bufferData(uvs);
190 191
 
191
-    Shader::drawGL(vertices, uvs, color, texture);
192
+    Shader::drawGL(vert, uv, color, texture, s);
192 193
 }
193 194
 
194 195
 static const int modeStringCount = 4;

+ 10
- 2
src/RoomData.cpp View File

@@ -40,7 +40,11 @@ void BoundingBox::display(glm::mat4 VP, glm::vec3 colorLine, glm::vec3 colorDot)
40 40
     inds.push_back(5);
41 41
     inds.push_back(2);
42 42
 
43
-    Shader::drawGL(verts, cols, inds, VP, GL_LINE_STRIP);
43
+    static ShaderBuffer vert, col, ind;
44
+    vert.bufferData(verts);
45
+    col.bufferData(cols);
46
+    ind.bufferData(inds);
47
+    Shader::drawGL(vert, col, ind, VP, GL_LINE_STRIP);
44 48
 
45 49
     cols.clear();
46 50
     inds.clear();
@@ -50,7 +54,11 @@ void BoundingBox::display(glm::mat4 VP, glm::vec3 colorLine, glm::vec3 colorDot)
50 54
         inds.push_back(i);
51 55
     }
52 56
 
53
-    Shader::drawGL(verts, cols, inds, VP, GL_POINTS);
57
+    static ShaderBuffer vert2, col2, ind2;
58
+    vert2.bufferData(verts);
59
+    col2.bufferData(cols);
60
+    ind2.bufferData(inds);
61
+    Shader::drawGL(vert2, col2, ind2, VP, GL_POINTS);
54 62
 }
55 63
 
56 64
 // ----------------------------------------------------------------------------

+ 39
- 43
src/RoomMesh.cpp View File

@@ -6,89 +6,85 @@
6 6
  */
7 7
 
8 8
 #include "global.h"
9
-#include "Mesh.h"
10 9
 #include "TextureManager.h"
11
-#include "system/Shader.h"
12 10
 #include "RoomMesh.h"
13 11
 
14 12
 RoomMesh::RoomMesh(const std::vector<RoomVertexTR2>& vert,
15 13
                    const std::vector<IndexedRectangle>& rect,
16 14
                    const std::vector<IndexedRectangle>& tri) {
17 15
     for (auto& t : rect) {
18
-        indices.push_back(0);
19
-        vertices.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
20
-        vertices.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
21
-        vertices.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
22
-        vertices.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
23
-        textures.push_back(t.texture);
16
+        indicesBuff.push_back(0);
17
+        verticesBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
18
+        verticesBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
19
+        verticesBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
20
+        verticesBuff.push_back(glm::vec3(vert.at(t.v4).x, vert.at(t.v4).y, vert.at(t.v4).z));
21
+        texturesBuff.push_back(t.texture);
24 22
     }
25 23
 
26 24
     for (auto& t : tri) {
27
-        indices.push_back(1);
28
-        vertices.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
29
-        vertices.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
30
-        vertices.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
31
-        textures.push_back(t.texture);
25
+        indicesBuff.push_back(1);
26
+        verticesBuff.push_back(glm::vec3(vert.at(t.v1).x, vert.at(t.v1).y, vert.at(t.v1).z));
27
+        verticesBuff.push_back(glm::vec3(vert.at(t.v2).x, vert.at(t.v2).y, vert.at(t.v2).z));
28
+        verticesBuff.push_back(glm::vec3(vert.at(t.v3).x, vert.at(t.v3).y, vert.at(t.v3).z));
29
+        texturesBuff.push_back(t.texture);
32 30
     }
33 31
 }
34 32
 
35 33
 void RoomMesh::prepare() {
36 34
     std::vector<unsigned short> ind;
37 35
     std::vector<glm::vec3> vert;
36
+    std::vector<glm::vec2> uvBuff;
38 37
     std::vector<unsigned int> tex;
39 38
 
40
-    std::map<PackedVertex, unsigned short> vertexMap;
41
-
42 39
     int vertIndex = 0;
43
-    for (int i = 0; i < indices.size(); i++) {
44
-        unsigned int texture = getTextureManager().getTile(textures.at(i)).getTexture();
45
-        for (int v = 0; v < ((indices.at(i) == 0) ? 4 : 3); v++) {
46
-            glm::vec2 uv = getTextureManager().getTile(textures.at(i)).getUV(v);
47
-            PackedVertex p(vertices.at(vertIndex + v), uv, texture);
48
-            unsigned short s;
49
-            if (findSimilarVertex(p, vertexMap, s)) {
50
-                ind.push_back(s); // Vertex already cached
51
-            } else {
52
-                vertexMap[p] = vert.size();
53
-                ind.push_back(vert.size());
54
-                vert.push_back(p.pos);
55
-                uvs.push_back(p.uv);
56
-                tex.push_back(p.tex);
57
-            }
40
+    for (int i = 0; i < indicesBuff.size(); i++) {
41
+        unsigned int texture = getTextureManager().getTile(texturesBuff.at(i)).getTexture();
42
+        for (int v = 0; v < ((indicesBuff.at(i) == 0) ? 4 : 3); v++) {
43
+            ind.push_back(vert.size());
44
+            vert.push_back(verticesBuff.at(vertIndex + v));
45
+            uvBuff.push_back(getTextureManager().getTile(texturesBuff.at(i)).getUV(v));
46
+            tex.push_back(texture);
58 47
         }
59 48
 
60
-        if (indices.at(i) == 0) {
49
+        if (indicesBuff.at(i) == 0) {
61 50
             ind.push_back(ind.at(ind.size() - 2));
62 51
             ind.push_back(ind.at(ind.size() - 5));
63 52
         }
64 53
 
65
-        vertIndex += (indices.at(i) == 0) ? 4 : 3;
54
+        vertIndex += (indicesBuff.at(i) == 0) ? 4 : 3;
66 55
     }
67 56
 
68 57
     assert((ind.size() % 3) == 0);
58
+    assert(vert.size() == tex.size());
59
+    assert(vert.size() == uvBuff.size());
69 60
 
70
-    indices = std::move(ind);
71
-    vertices = std::move(vert);
72
-    textures = std::move(tex);
61
+    indicesBuff = std::move(ind);
62
+    vertices.bufferData(vert);
63
+    uvs.bufferData(uvBuff);
64
+    texturesBuff = std::move(tex);
73 65
 }
74 66
 
75 67
 void RoomMesh::display(glm::mat4 MVP) {
76
-    if (indices.size() > 0) {
68
+    if (indicesBuff.size() > 0) {
77 69
         unsigned int indexStart = 0;
78 70
         unsigned int indexPos = 1;
79
-        unsigned int texture = textures.at(indices.at(0));
71
+        unsigned int texture = texturesBuff.at(indicesBuff.at(0));
80 72
 
81
-        while ((indexStart != indexPos) && (indexPos < indices.size())) {
82
-            while ((indexPos < indices.size()) && (textures.at(indices.at(indexPos)) == texture))
73
+        while ((indexStart != indexPos) && (indexPos < indicesBuff.size())) {
74
+            while ((indexPos < indicesBuff.size())
75
+                    && (texturesBuff.at(indicesBuff.at(indexPos)) == texture)) {
83 76
                 indexPos++;
77
+            }
84 78
 
85
-            std::vector<unsigned short> ind(indices.begin() + indexStart, indices.begin() + indexPos);
86
-            Shader::drawGL(vertices, uvs, ind, MVP, texture);
79
+            std::vector<unsigned short> ind(indicesBuff.begin() + indexStart,
80
+                                            indicesBuff.begin() + indexPos);
81
+            indices.bufferData(ind);
82
+            Shader::drawGL(vertices, uvs, indices, texture, MVP);
87 83
 
88
-            if (indexPos < indices.size()) {
84
+            if (indexPos < indicesBuff.size()) {
89 85
                 indexStart = indexPos;
90 86
                 indexPos += 1;
91
-                texture = textures.at(indices.at(indexStart));
87
+                texture = texturesBuff.at(indicesBuff.at(indexStart));
92 88
             }
93 89
         }
94 90
     }

+ 29
- 5
src/TextureManager.cpp View File

@@ -69,8 +69,11 @@ void TextureManager::clear() {
69 69
         tiles.pop_back();
70 70
     }
71 71
 
72
-    while (!animations.empty())
73
-        animations.pop_back();
72
+    animations.clear();
73
+
74
+    gameUnits.clear();
75
+    systemUnits.clear();
76
+    nextFreeTextureUnit = 0;
74 77
 }
75 78
 
76 79
 void TextureManager::addTile(TextureTile* t) {
@@ -125,6 +128,13 @@ std::vector<unsigned int>& TextureManager::getIds(TextureStorage s) {
125 128
         return mTextureIdsSystem;
126 129
 }
127 130
 
131
+std::vector<int>& TextureManager::getUnits(TextureStorage s) {
132
+    if (s == TextureStorage::GAME)
133
+        return gameUnits;
134
+    else
135
+        return systemUnits;
136
+}
137
+
128 138
 int TextureManager::initialize() {
129 139
     assert(mTextureIdsGame.size() == 0);
130 140
     assert(mTextureIdsSystem.size() == 0);
@@ -216,7 +226,7 @@ int TextureManager::loadBufferSlot(unsigned char* image,
216 226
     }
217 227
 
218 228
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
219
-    glBindTexture(GL_TEXTURE_2D, getIds(s).at(slot));
229
+    bindTexture(slot, s);
220 230
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, glcMode, GL_UNSIGNED_BYTE, image);
221 231
 
222 232
     if (filter) {
@@ -246,9 +256,23 @@ void TextureManager::bindTextureId(unsigned int n, TextureStorage s, unsigned in
246 256
     glBindTexture(GL_TEXTURE_2D, getIds(s).at(n));
247 257
 }
248 258
 
249
-int TextureManager::loadImage(std::string filename, TextureStorage s, int slot) {
250
-    //! \todo case insensitive compare
259
+int TextureManager::bindTexture(unsigned int n, TextureStorage s) {
260
+    assert(n < getIds(s).size());
261
+
262
+    if ((n < getUnits(s).size()) && (getUnits(s).at(n) >= 0)) {
263
+        bindTextureId(n, s, getUnits(s).at(n));
264
+        return getUnits(s).at(n);
265
+    } else {
266
+        while (getUnits(s).size() <= n)
267
+            getUnits(s).push_back(-1);
268
+        getUnits(s).at(n) = nextFreeTextureUnit;
269
+        bindTextureId(n, s, nextFreeTextureUnit);
270
+        nextFreeTextureUnit++;
271
+        return nextFreeTextureUnit - 1;
272
+    }
273
+}
251 274
 
275
+int TextureManager::loadImage(std::string filename, TextureStorage s, int slot) {
252 276
     if (stringEndsWith(filename, ".pcx")) {
253 277
         return loadPCX(filename, s, slot);
254 278
     } else {

+ 15
- 16
src/UI.cpp View File

@@ -52,7 +52,6 @@ int UI::initialize() {
52 52
         return -2;
53 53
     if (imguiShader.addUniform("textureSampler") < 0)
54 54
         return -3;
55
-    imguiShader.addBuffer(3);
56 55
 
57 56
     iniFilename = RunTime::getBaseDir() + "/imgui.ini";
58 57
     logFilename = RunTime::getBaseDir() + "/imgui_log.txt";
@@ -531,19 +530,17 @@ void UI::renderImGui(ImDrawList** const cmd_lists, int cmd_lists_count) {
531 530
     if (cmd_lists_count == 0)
532 531
         return;
533 532
 
533
+    static ShaderBuffer vert, uv, col;
534
+
534 535
     glEnable(GL_SCISSOR_TEST);
535 536
     glDisable(GL_DEPTH_TEST);
536 537
 
537 538
     imguiShader.use();
538 539
     imguiShader.loadUniform(0, Window::getSize());
539 540
     imguiShader.loadUniform(1, fontTex, TextureManager::TextureStorage::SYSTEM);
540
-    imguiShader.bindBuffer(0, 0, 2);
541
-    imguiShader.bindBuffer(1, 1, 2);
542
-    imguiShader.bindBuffer(2, 2, 4);
543
-
544
-    std::vector<glm::vec2> vertices;
545
-    std::vector<glm::vec2> uvs;
546
-    std::vector<glm::vec4> colors;
541
+    vert.bindBuffer(0, 2);
542
+    uv.bindBuffer(1, 2);
543
+    col.bindBuffer(2, 4);
547 544
 
548 545
     /*! \fixme Don't copy data
549 546
      * The GL calls and the shaders can probably be slightly altered
@@ -556,6 +553,10 @@ void UI::renderImGui(ImDrawList** const cmd_lists, int cmd_lists_count) {
556 553
 
557 554
         int offset = 0;
558 555
         for (int n = 0; n < commands.size(); n++) {
556
+            std::vector<glm::vec2> vertices;
557
+            std::vector<glm::vec2> uvs;
558
+            std::vector<glm::vec4> colors;
559
+
559 560
             for (int v = 0; v < commands[n].vtx_count; v++) {
560 561
                 vertices.push_back(glm::vec2(buffer[offset + v].pos.x, buffer[offset + v].pos.y));
561 562
                 uvs.push_back(glm::vec2(buffer[offset + v].uv.x, buffer[offset + v].uv.y));
@@ -570,9 +571,9 @@ void UI::renderImGui(ImDrawList** const cmd_lists, int cmd_lists_count) {
570 571
 
571 572
             offset += commands[n].vtx_count;
572 573
 
573
-            imguiShader.bufferData(0, vertices);
574
-            imguiShader.bufferData(1, uvs);
575
-            imguiShader.bufferData(2, colors);
574
+            vert.bufferData(vertices);
575
+            uv.bufferData(uvs);
576
+            col.bufferData(colors);
576 577
 
577 578
             glScissor(commands[n].clip_rect.x,
578 579
                       Window::getSize().y - commands[n].clip_rect.w,
@@ -580,14 +581,12 @@ void UI::renderImGui(ImDrawList** const cmd_lists, int cmd_lists_count) {
580 581
                       commands[n].clip_rect.w - commands[n].clip_rect.y);
581 582
 
582 583
             glDrawArrays(GL_TRIANGLES, 0, vertices.size());
583
-
584
-            vertices.clear();
585
-            uvs.clear();
586
-            colors.clear();
587 584
         }
588 585
     }
589 586
 
590
-    imguiShader.disableAttribs();
587
+    vert.unbind(0);
588
+    uv.unbind(1);
589
+    col.unbind(2);
591 590
 
592 591
     glEnable(GL_DEPTH_TEST);
593 592
     glDisable(GL_SCISSOR_TEST);

+ 10
- 2
src/system/FontSDL.cpp View File

@@ -15,6 +15,8 @@
15 15
 bool FontSDL::mFontInit = false;
16 16
 TTF_Font* FontSDL::mFont = nullptr;
17 17
 unsigned int FontSDL::mFontTexture = -1;
18
+ShaderBuffer FontSDL::vertexBuffer;
19
+ShaderBuffer FontSDL::uvBuffer;
18 20
 
19 21
 void FontSDL::shutdown() {
20 22
     if (mFont != nullptr)
@@ -126,7 +128,10 @@ void FontSDL::drawText(unsigned int x, unsigned int y, float scale,
126 128
     uvs.push_back(glm::vec2(1.0f, 1.0f));
127 129
     uvs.push_back(glm::vec2(0.0f, 0.0f));
128 130
 
129
-    Shader::drawGL(vertices, uvs, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), mFontTexture);
131
+    vertexBuffer.bufferData(vertices);
132
+    uvBuffer.bufferData(uvs);
133
+    Shader::drawGL(vertexBuffer, uvBuffer, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
134
+                   mFontTexture, TextureManager::TextureStorage::SYSTEM);
130 135
 }
131 136
 
132 137
 unsigned int FontSDL::heightText(float scale, unsigned int maxWidth, std::string s) {
@@ -208,6 +213,9 @@ void FontSDL::drawTextWrapped(unsigned int x, unsigned int y, float scale,
208 213
     uvs.push_back(glm::vec2(1.0f, 1.0f));
209 214
     uvs.push_back(glm::vec2(0.0f, 0.0f));
210 215
 
211
-    Shader::drawGL(vertices, uvs, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f), mFontTexture);
216
+    vertexBuffer.bufferData(vertices);
217
+    uvBuffer.bufferData(uvs);
218
+    Shader::drawGL(vertexBuffer, uvBuffer, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
219
+                   mFontTexture, TextureManager::TextureStorage::SYSTEM);
212 220
 }
213 221
 

+ 8
- 2
src/system/FontTRLE.cpp View File

@@ -21,6 +21,8 @@
21 21
 bool FontTRLE::mFontInit = false;
22 22
 unsigned int FontTRLE::mFontTexture = 0;
23 23
 int FontTRLE::offsets[106][5];
24
+ShaderBuffer FontTRLE::vertexBuffer;
25
+ShaderBuffer FontTRLE::uvBuffer;
24 26
 
25 27
 void FontTRLE::shutdown() {
26 28
 }
@@ -166,8 +168,10 @@ void FontTRLE::drawText(unsigned int x, unsigned int y, float scale,
166 168
         x += (int)((float)(offsets[index][2] + 1) * scale * SCALING); // width
167 169
     }
168 170
 
171
+    vertexBuffer.bufferData(vertices);
172
+    uvBuffer.bufferData(uvs);
169 173
     glm::vec4 col(color[0] / 256.0f, color[1] / 256.0f, color[2] / 256.0f, color[3] / 256.0f);
170
-    Shader::drawGL(vertices, uvs, col, mFontTexture);
174
+    Shader::drawGL(vertexBuffer, uvBuffer, col, mFontTexture);
171 175
 }
172 176
 
173 177
 unsigned int FontTRLE::heightText(float scale, unsigned int maxWidth, std::string s) {
@@ -240,8 +244,10 @@ void FontTRLE::drawTextWrapped(unsigned int x, unsigned int y, float scale,
240 244
         x += (int)((float)(offsets[index][2] + 1) * scale * SCALING); // width
241 245
     }
242 246
 
247
+    vertexBuffer.bufferData(vertices);
248
+    uvBuffer.bufferData(uvs);
243 249
     glm::vec4 col(color[0] / 256.0f, color[1] / 256.0f, color[2] / 256.0f, color[3] / 256.0f);
244
-    Shader::drawGL(vertices, uvs, col, mFontTexture);
250
+    Shader::drawGL(vertexBuffer, uvBuffer, col, mFontTexture);
245 251
 }
246 252
 
247 253
 int FontTRLE::defaultOffsets[106][5] = {

+ 81
- 93
src/system/Shader.cpp View File

@@ -11,30 +11,44 @@
11 11
 #include "system/Window.h"
12 12
 #include "system/Shader.h"
13 13
 
14
-ShaderBuffer::ShaderBuffer() : buffer(0) {
15
-    glGenBuffers(1, &buffer);
16
-}
17
-
18 14
 ShaderBuffer::~ShaderBuffer() {
19
-    glDeleteBuffers(1, &buffer);
15
+    if (created)
16
+        glDeleteBuffers(1, &buffer);
20 17
 }
21 18
 
22 19
 void ShaderBuffer::bufferData(int elem, int size, void* data) {
20
+    if (!created) {
21
+        glGenBuffers(1, &buffer);
22
+        created = true;
23
+    }
24
+
25
+    boundSize = elem;
23 26
     glBindBuffer(GL_ARRAY_BUFFER, buffer);
24 27
     glBufferData(GL_ARRAY_BUFFER, elem * size, data, GL_STATIC_DRAW);
25 28
 }
26 29
 
27 30
 void ShaderBuffer::bindBuffer() {
31
+    if (!created) {
32
+        glGenBuffers(1, &buffer);
33
+        created = true;
34
+    }
35
+
28 36
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
29 37
 }
30 38
 
31 39
 void ShaderBuffer::bindBuffer(int location, int size) {
40
+    if (!created) {
41
+        glGenBuffers(1, &buffer);
42
+        created = true;
43
+    }
44
+
32 45
     glEnableVertexAttribArray(location);
33 46
     glBindBuffer(GL_ARRAY_BUFFER, buffer);
34 47
     glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, 0, nullptr);
35 48
 }
36 49
 
37 50
 void ShaderBuffer::unbind(int location) {
51
+    assert(created == true);
38 52
     glDisableVertexAttribArray(location);
39 53
 }
40 54
 
@@ -43,9 +57,6 @@ void ShaderBuffer::unbind(int location) {
43 57
 Shader::~Shader() {
44 58
     if (programID >= 0)
45 59
         glDeleteProgram(programID);
46
-
47
-    if (!buffers.empty())
48
-        glDeleteBuffers(buffers.size(), &buffers[0]);
49 60
 }
50 61
 
51 62
 int Shader::addUniform(const char* name) {
@@ -65,24 +76,6 @@ unsigned int Shader::getUniform(int n) {
65 76
     return uniforms.at(n);
66 77
 }
67 78
 
68
-void Shader::addBuffer(int n) {
69
-    int s = buffers.size();
70
-    for (int i = 0; i < n; i++)
71
-        buffers.push_back(0);
72
-    glGenBuffers(n, &buffers[s]);
73
-}
74
-
75
-unsigned int Shader::getBuffer(int n) {
76
-    assert(n >= 0);
77
-    assert(n < buffers.size());
78
-    return buffers.at(n);
79
-}
80
-
81
-void Shader::bufferData(int buff, int elem, int size, void* d) {
82
-    glBindBuffer(GL_ARRAY_BUFFER, getBuffer(buff));
83
-    glBufferData(GL_ARRAY_BUFFER, elem * size, d, GL_STREAM_DRAW);
84
-}
85
-
86 79
 void Shader::loadUniform(int uni, glm::vec2 vec) {
87 80
     glUniform2f(getUniform(uni), vec.x, vec.y);
88 81
 }
@@ -95,32 +88,8 @@ void Shader::loadUniform(int uni, glm::mat4 mat) {
95 88
     glUniformMatrix4fv(getUniform(uni), 1, GL_FALSE, &mat[0][0]);
96 89
 }
97 90
 
98
-void Shader::loadUniform(int uni, int texture, TextureManager::TextureStorage store, int slot) {
99
-    getTextureManager().bindTextureId(texture, store, slot);
100
-    glUniform1i(getUniform(uni), slot);
101
-}
102
-
103
-void Shader::bindBuffer(int buff) {
104
-    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBuffer(buff));
105
-}
106
-
107
-void Shader::bindBuffer(int buff, int location, int size) {
108
-    glEnableVertexAttribArray(location);
109
-    glBindBuffer(GL_ARRAY_BUFFER, getBuffer(buff));
110
-    glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, 0, nullptr);
111
-
112
-    while (attribs.size() <= location)
113
-        attribs.push_back(false);
114
-    attribs.at(location) = true;
115
-}
116
-
117
-void Shader::disableAttribs() {
118
-    for (int i = 0; i < attribs.size(); i++) {
119
-        if (attribs.at(i)) {
120
-            glDisableVertexAttribArray(i);
121
-            attribs.at(i) = false;
122
-        }
123
-    }
91
+void Shader::loadUniform(int uni, int texture, TextureManager::TextureStorage store) {
92
+    glUniform1i(getUniform(uni), getTextureManager().bindTexture(texture, store));
124 93
 }
125 94
 
126 95
 void Shader::use() {
@@ -225,6 +194,9 @@ int Shader::initialize() {
225 194
     // Accept fragment if closer to camera
226 195
     glDepthFunc(GL_LESS);
227 196
 
197
+    glEnable(GL_BLEND);
198
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
199
+
228 200
     // Set up culling
229 201
     //glEnable(GL_CULL_FACE); //! \todo Transparency?
230 202
 
@@ -238,7 +210,6 @@ int Shader::initialize() {
238 210
         return -3;
239 211
     if (textShader.addUniform("colorVar") < 0)
240 212
         return -4;
241
-    textShader.addBuffer(2);
242 213
 
243 214
     if (textureShader.compile(textureShaderVertex, textureShaderFragment) < 0)
244 215
         return -5;
@@ -246,16 +217,11 @@ int Shader::initialize() {
246 217
         return -6;
247 218
     if (textureShader.addUniform("textureSampler") < 0)
248 219
         return -7;
249
-    textureShader.addBuffer(3);
250 220
 
251 221
     if (colorShader.compile(colorShaderVertex, colorShaderFragment) < 0)
252 222
         return -8;
253 223
     if (colorShader.addUniform("MVP") < 0)
254 224
         return -9;
255
-    colorShader.addBuffer(3);
256
-
257
-    glEnable(GL_BLEND);
258
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
259 225
 
260 226
     return 0;
261 227
 }
@@ -264,59 +230,81 @@ void Shader::shutdown() {
264 230
     glDeleteVertexArrays(1, &vertexArrayID);
265 231
 }
266 232
 
267
-void Shader::drawGL(std::vector<glm::vec2>& vertices, std::vector<glm::vec2>& uvs,
268
-                    glm::vec4 color, unsigned int texture) {
269
-    assert(vertices.size() == uvs.size());
270
-    assert((vertices.size() % 3) == 0);
233
+void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, glm::vec4 color,
234
+                    unsigned int texture, TextureManager::TextureStorage store) {
235
+    assert(vertices.getSize() == uvs.getSize());
236
+    assert((vertices.getSize() % 3) == 0);
271 237
 
272
-    textShader.bufferData(0, vertices);
273
-    textShader.bufferData(1, uvs);
274 238
     textShader.use();
275 239
     textShader.loadUniform(0, Window::getSize());
276
-    textShader.loadUniform(1, texture, TextureManager::TextureStorage::SYSTEM);
240
+    textShader.loadUniform(1, texture, store);
277 241
     textShader.loadUniform(2, color);
278
-    textShader.bindBuffer(0, 0, 2);
279
-    textShader.bindBuffer(1, 1, 2);
242
+    vertices.bindBuffer(0, 2);
243
+    uvs.bindBuffer(1, 2);
280 244
 
281 245
     glDisable(GL_DEPTH_TEST);
282
-    glDrawArrays(GL_TRIANGLES, 0, vertices.size());
246
+    glDrawArrays(GL_TRIANGLES, 0, vertices.getSize());
283 247
     glEnable(GL_DEPTH_TEST);
284 248
 
285
-    textShader.disableAttribs();
249
+    vertices.unbind(0);
250
+    uvs.unbind(1);
286 251
 }
287 252
 
288
-void Shader::drawGL(std::vector<glm::vec3>& vertices, std::vector<glm::vec2>& uvs,
289
-                    std::vector<unsigned short>& indices, glm::mat4 MVP, unsigned int texture) {
290
-    assert(vertices.size() == uvs.size());
291
-    assert((indices.size() % 3) == 0);
253
+void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, unsigned int texture,
254
+                    glm::mat4 MVP, TextureManager::TextureStorage store) {
255
+    assert(vertices.getSize() == uvs.getSize());
256
+    assert((vertices.getSize() % 3) == 0);
292 257
 
293
-    textureShader.bufferData(0, vertices);
294
-    textureShader.bufferData(1, uvs);
295
-    textureShader.bufferData(2, indices);
296 258
     textureShader.use();
297 259
     textureShader.loadUniform(0, MVP);
298
-    textureShader.loadUniform(1, texture, TextureManager::TextureStorage::GAME);
299
-    textureShader.bindBuffer(0, 0, 3);
300
-    textureShader.bindBuffer(1, 1, 2);
301
-    textureShader.bindBuffer(2);
302
-    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, nullptr);
303
-    textureShader.disableAttribs();
260
+    textureShader.loadUniform(1, texture, store);
261
+    vertices.bindBuffer(0, 3);
262
+    uvs.bindBuffer(1, 2);
263
+    glDrawArrays(GL_TRIANGLES, 0, vertices.getSize());
264
+    vertices.unbind(0);
265
+    uvs.unbind(1);
266
+}
267
+
268
+void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, ShaderBuffer& indices,
269
+                    unsigned int texture, glm::mat4 MVP, TextureManager::TextureStorage store) {
270
+    assert(vertices.getSize() == uvs.getSize());
271
+    assert((indices.getSize() % 3) == 0);
272
+
273
+    textureShader.use();
274
+    textureShader.loadUniform(0, MVP);
275
+    textureShader.loadUniform(1, texture, store);
276
+    vertices.bindBuffer(0, 3);
277
+    uvs.bindBuffer(1, 2);
278
+    indices.bindBuffer();
279
+    glDrawElements(GL_TRIANGLES, indices.getSize(), GL_UNSIGNED_SHORT, nullptr);
280
+    vertices.unbind(0);
281
+    uvs.unbind(1);
282
+}
283
+
284
+void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, glm::mat4 MVP, unsigned int mode) {
285
+    assert(vertices.getSize() == colors.getSize());
286
+
287
+    colorShader.use();
288
+    colorShader.loadUniform(0, MVP);
289
+    vertices.bindBuffer(0, 3);
290
+    colors.bindBuffer(1, 3);
291
+    glDrawArrays(mode, 0, vertices.getSize());
292
+    vertices.unbind(0);
293
+    colors.unbind(1);
304 294
 }
305 295
 
306
-void Shader::drawGL(std::vector<glm::vec3>& vertices, std::vector<glm::vec3>& colors,
307
-                    std::vector<unsigned short>& indices, glm::mat4 MVP, int mode) {
308
-    assert(vertices.size() == colors.size());
296
+void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, ShaderBuffer& indices,
297
+                    glm::mat4 MVP, unsigned int mode) {
298
+    assert(vertices.getSize() == colors.getSize());
309 299
 
310
-    colorShader.bufferData(0, vertices);
311
-    colorShader.bufferData(1, colors);
312
-    colorShader.bufferData(2, indices);
313 300
     colorShader.use();
314 301
     colorShader.loadUniform(0, MVP);
315
-    colorShader.bindBuffer(0, 0, 3);
316
-    colorShader.bindBuffer(1, 1, 3);
317
-    colorShader.bindBuffer(2);
318
-    glDrawElements(mode, indices.size(), GL_UNSIGNED_SHORT, nullptr);
319
-    colorShader.disableAttribs();
302
+    vertices.bindBuffer(0, 3);
303
+    colors.bindBuffer(1, 3);
304
+    indices.bindBuffer();
305
+    glDrawElements(mode, indices.getSize(), GL_UNSIGNED_SHORT, nullptr);
306
+    vertices.unbind(0);
307
+    colors.unbind(1);
320 308
 }
321 309
 
322 310
 // --------------------------------------

Loading…
Cancel
Save