Browse Source

Support for Room Sprites

Thomas Buck 9 years ago
parent
commit
0d31c3b41a
17 changed files with 264 additions and 329 deletions
  1. 7
    0
      ChangeLog.md
  2. 1
    1
      include/Log.h
  3. 19
    18
      include/Room.h
  4. 12
    0
      include/RoomData.h
  5. 9
    17
      include/Sprite.h
  6. 8
    3
      include/World.h
  7. 1
    1
      src/Console.cpp
  8. 25
    2
      src/Render.cpp
  9. 15
    70
      src/Room.cpp
  10. 11
    0
      src/RoomData.cpp
  11. 25
    138
      src/Sprite.cpp
  12. 4
    4
      src/TextureManager.cpp
  13. 16
    3
      src/World.cpp
  14. 87
    57
      src/deps/imgui/imgui.cpp
  15. 9
    5
      src/deps/imgui/imgui.h
  16. 11
    10
      src/loader/LoaderTR2.cpp
  17. 4
    0
      src/system/Shader.cpp

+ 7
- 0
ChangeLog.md View File

@@ -2,6 +2,13 @@
2 2
 
3 3
 ## OpenRaider (0.1.3) xythobuz <xythobuz@xythobuz.de>
4 4
 
5
+    [ 20140117 ]
6
+    * Updated imgui, fix for Logging to Clipboard included.
7
+    * Sprites and SpriteSequences are now stored independently in World.
8
+    * Added support for Room Sprites displaying.
9
+    * Can now toggle display of Room geometry, models and sprites.
10
+    * Room list is now displayed in reverse. This _fixes_ some transparency issues.
11
+
5 12
     [ 20140111 ]
6 13
     * Enabled back face culling --> triangles now oriented correctly
7 14
     * Game is now completely static

+ 1
- 1
include/Log.h View File

@@ -36,7 +36,7 @@ class Log {
36 36
 
37 37
     static LogLevel& get(int level);
38 38
     static unsigned long size() { return wholeLog.size(); }
39
-    static LogEntry getEntry(unsigned long i) { return wholeLog.at(i); }
39
+    static LogEntry& getEntry(unsigned long i) { return wholeLog.at(i); }
40 40
 
41 41
   private:
42 42
     static LogLevel logs[LOG_COUNT];

+ 19
- 18
include/Room.h View File

@@ -42,28 +42,26 @@ class Room {
42 42
 
43 43
     unsigned int getFlags() { return flags; }
44 44
 
45
-    unsigned long sizePortals();
46
-    Portal& getPortal(unsigned long index);
47
-    void addPortal(Portal* p);
45
+    void addSprite(RoomSprite* s) { sprites.emplace_back(s); }
46
+    void addModel(StaticModel* s) { models.emplace_back(s); }
47
+    void addSector(Sector* s) { sectors.emplace_back(s); }
48
+    void addLight(Light* l) { lights.emplace_back(l); }
48 49
 
49
-    unsigned long sizeSectors();
50
-    Sector& getSector(unsigned long index);
51
-    void addSector(Sector* s);
50
+    void addPortal(Portal* p) { portals.emplace_back(p); }
51
+    unsigned long sizePortals() { return portals.size(); }
52
+    Portal& getPortal(unsigned long index) { return *portals.at(index); }
52 53
 
53
-    unsigned long sizeModels();
54
-    StaticModel& getModel(unsigned long index);
55
-    void addModel(StaticModel* s);
54
+    static void setShowBoundingBox(bool s) { showBoundingBox = s; }
55
+    static bool getShowBoundingBox() { return showBoundingBox; }
56 56
 
57
-    unsigned long sizeLights();
58
-    Light& getLight(unsigned long index);
59
-    void addLight(Light* l);
57
+    static void setShowRoomModels(bool s) { showRoomModels = s; }
58
+    static bool getShowRoomModels() { return showRoomModels; }
60 59
 
61
-    unsigned long sizeSprites();
62
-    Sprite& getSprite(unsigned long index);
63
-    void addSprite(Sprite* s);
60
+    static void setShowRoomSprites(bool s) { showRoomSprites = s; }
61
+    static bool getShowRoomSprites() { return showRoomSprites; }
64 62
 
65
-    static void setShowBoundingBox(bool s) { showBoundingBox = s; }
66
-    static bool getShowBoundingBox() { return showBoundingBox; }
63
+    static void setShowRoomGeometry(bool s) { showRoomGeometry = s; }
64
+    static bool getShowRoomGeometry() { return showRoomGeometry; }
67 65
 
68 66
   private:
69 67
     glm::vec3 pos;
@@ -76,13 +74,16 @@ class Room {
76 74
     int numXSectors;
77 75
     int numZSectors;
78 76
 
79
-    std::vector<std::unique_ptr<Sprite>> sprites;
77
+    std::vector<std::unique_ptr<RoomSprite>> sprites;
80 78
     std::vector<std::unique_ptr<StaticModel>> models;
81 79
     std::vector<std::unique_ptr<Portal>> portals;
82 80
     std::vector<std::unique_ptr<Sector>> sectors;
83 81
     std::vector<std::unique_ptr<Light>> lights;
84 82
 
85 83
     static bool showBoundingBox;
84
+    static bool showRoomModels;
85
+    static bool showRoomSprites;
86
+    static bool showRoomGeometry;
86 87
 };
87 88
 
88 89
 #endif

+ 12
- 0
include/RoomData.h View File

@@ -60,6 +60,18 @@ class StaticModel {
60 60
 
61 61
 // --------------------------------------
62 62
 
63
+class RoomSprite {
64
+  public:
65
+    RoomSprite(glm::vec3 p, int s) : pos(p), sprite(s) { }
66
+    void display(glm::mat4 VP);
67
+
68
+  private:
69
+    glm::vec3 pos;
70
+    int sprite;
71
+};
72
+
73
+// --------------------------------------
74
+
63 75
 class Portal {
64 76
   public:
65 77
     Portal(int adj, glm::vec3 n, glm::vec3 v1, glm::vec3 v2, glm::vec3 v3,

+ 9
- 17
include/Sprite.h View File

@@ -8,35 +8,27 @@
8 8
 #ifndef _SPRITE_H_
9 9
 #define _SPRITE_H_
10 10
 
11
-#include <cstdint>
12
-
13
-#include "loader/Loader.h"
11
+#include "system/Shader.h"
14 12
 
15 13
 class Sprite {
16 14
   public:
17
-    Sprite(uint16_t tile, uint8_t x, uint8_t y, uint16_t width, uint16_t height);
18
-    void display();
19
-    void display(float x, float y, float w, float h);
15
+    Sprite(int tile, int x, int y, int width, int height);
16
+    void display(glm::mat4 MVP);
20 17
 
21 18
   private:
22
-    float vertex[4][3];
23
-    float texel[4][2];
24
-    //float pos[3];
25
-    //float radius; //!< \fixme yeah, I know (I don't? --xythobuz)
26 19
     int texture;
20
+    ShaderBuffer vertices, uvs;
27 21
 };
28 22
 
29 23
 class SpriteSequence {
30 24
   public:
31
-    SpriteSequence(int32_t objectID);
32
-    void add(Sprite s);
33
-
34
-    unsigned long size();
35
-    Sprite& get(unsigned long index);
25
+    SpriteSequence(int objectID, int offset, int size)
26
+        : id(objectID), start(offset), length(size) { }
36 27
 
37 28
   private:
38
-    int32_t id;
39
-    std::vector<Sprite> sprites;
29
+    int id;
30
+    int start;
31
+    int length;
40 32
 };
41 33
 
42 34
 #endif

+ 8
- 3
include/World.h View File

@@ -39,9 +39,13 @@ class World {
39 39
     unsigned long sizeRoom();
40 40
     Room& getRoom(unsigned long index);
41 41
 
42
-    void addSprite(SpriteSequence* sprite);
42
+    void addSprite(Sprite* sprite);
43 43
     unsigned long sizeSprite();
44
-    SpriteSequence& getSprite(unsigned long index);
44
+    Sprite& getSprite(unsigned long index);
45
+
46
+    void addSpriteSequence(SpriteSequence* sprite);
47
+    unsigned long sizeSpriteSequence();
48
+    SpriteSequence& getSpriteSequence(unsigned long index);
45 49
 
46 50
     void addEntity(Entity* entity);
47 51
     unsigned long sizeEntity();
@@ -61,7 +65,8 @@ class World {
61 65
 
62 66
   private:
63 67
     std::vector<std::unique_ptr<Room>> mRooms;
64
-    std::vector<std::unique_ptr<SpriteSequence>> mSprites;
68
+    std::vector<std::unique_ptr<Sprite>> mSprites;
69
+    std::vector<std::unique_ptr<SpriteSequence>> mSpriteSequences;
65 70
     std::vector<std::unique_ptr<Entity>> mEntities;
66 71
     std::vector<std::unique_ptr<SkeletalModel>> mModels;
67 72
     std::vector<std::unique_ptr<StaticMesh>> mStaticMeshes;

+ 1
- 1
src/Console.cpp View File

@@ -106,7 +106,7 @@ void Console::display() {
106 106
         else if (logToFile)
107 107
             ImGui::LogToFile();
108 108
         for (unsigned long i = 0; i < Log::size(); i++) {
109
-            auto entry = Log::getEntry(i);
109
+            auto& entry = Log::getEntry(i);
110 110
 
111 111
             assert(entry.level < LOG_COUNT);
112 112
             if (!visibleLogs[entry.level]) {

+ 25
- 2
src/Render.cpp View File

@@ -6,6 +6,7 @@
6 6
  * \author xythobuz
7 7
  */
8 8
 
9
+#include <fstream>
9 10
 #include <sstream>
10 11
 
11 12
 #include "global.h"
@@ -51,8 +52,8 @@ void Render::display() {
51 52
     glm::mat4 view = Camera::getViewMatrix();
52 53
     glm::mat4 VP = projection * view;
53 54
 
54
-    for (auto r : roomList) {
55
-        r->display(VP);
55
+    for (int r = roomList.size() - 1; r >= 0; r--) {
56
+        roomList.at(r)->display(VP);
56 57
     }
57 58
 
58 59
     if (displayViewFrustum)
@@ -212,6 +213,28 @@ void Render::displayUI() {
212 213
         if (ImGui::Checkbox("StaticMesh##bbox", &showBoundingBox2)) {
213 214
             StaticMesh::setShowBoundingBox(showBoundingBox2);
214 215
         }
216
+
217
+        ImGui::Separator();
218
+        ImGui::Text("Renderable Objects:");
219
+        bool showRoomGeometry = Room::getShowRoomGeometry();
220
+        if (ImGui::Checkbox("Room Geometry##render", &showRoomGeometry)) {
221
+            Room::setShowRoomGeometry(showRoomGeometry);
222
+        }
223
+        ImGui::SameLine();
224
+        bool showRoomModels = Room::getShowRoomModels();
225
+        if (ImGui::Checkbox("Room Models##render", &showRoomModels)) {
226
+            Room::setShowRoomModels(showRoomModels);
227
+        }
228
+        ImGui::SameLine();
229
+        bool showRoomSprites = Room::getShowRoomSprites();
230
+        if (ImGui::Checkbox("Room Sprites##render", &showRoomSprites)) {
231
+            Room::setShowRoomSprites(showRoomSprites);
232
+        }
233
+
234
+        ImGui::Separator();
235
+        if (ImGui::Button("New Splash##render")) {
236
+            TextureManager::initializeSplash();
237
+        }
215 238
     }
216 239
 }
217 240
 

+ 15
- 70
src/Room.cpp View File

@@ -13,6 +13,9 @@
13 13
 #include <glm/gtx/intersect.hpp>
14 14
 
15 15
 bool Room::showBoundingBox = false;
16
+bool Room::showRoomModels = true;
17
+bool Room::showRoomSprites = true;
18
+bool Room::showRoomGeometry = true;
16 19
 
17 20
 Room::Room(glm::vec3 _pos, BoundingBox* _bbox, RoomMesh* _mesh, unsigned int f,
18 21
            int a, int x, int z) : pos(_pos), bbox(_bbox), mesh(_mesh), flags(f),
@@ -23,10 +26,19 @@ Room::Room(glm::vec3 _pos, BoundingBox* _bbox, RoomMesh* _mesh, unsigned int f,
23 26
 void Room::display(glm::mat4 VP) {
24 27
     glm::mat4 MVP = VP * model;
25 28
 
26
-    mesh->display(MVP);
29
+    if (showRoomGeometry)
30
+        mesh->display(MVP);
27 31
 
28
-    for (auto& m : models) {
29
-        m->display(VP);
32
+    if (showRoomModels) {
33
+        for (auto& m : models) {
34
+            m->display(VP);
35
+        }
36
+    }
37
+
38
+    if (showRoomSprites) {
39
+        for (auto& s : sprites) {
40
+            s->display(VP);
41
+        }
30 42
     }
31 43
 
32 44
     if (showBoundingBox)
@@ -89,70 +101,3 @@ int Room::getAdjoiningRoom(float x, float y, float z,
89 101
     return -1;
90 102
 }
91 103
 
92
-// --------------------------------------
93
-
94
-unsigned long Room::sizePortals() {
95
-    return portals.size();
96
-}
97
-
98
-Portal& Room::getPortal(unsigned long index) {
99
-    assert(index < portals.size());
100
-    return *portals.at(index);
101
-}
102
-
103
-void Room::addPortal(Portal* p) {
104
-    portals.emplace_back(p);
105
-}
106
-
107
-unsigned long Room::sizeSectors() {
108
-    return sectors.size();
109
-}
110
-
111
-Sector& Room::getSector(unsigned long index) {
112
-    assert(index < sectors.size());
113
-    return *sectors.at(index);
114
-}
115
-
116
-void Room::addSector(Sector* s) {
117
-    sectors.emplace_back(s);
118
-}
119
-
120
-unsigned long Room::sizeModels() {
121
-    return models.size();
122
-}
123
-
124
-StaticModel& Room::getModel(unsigned long index) {
125
-    assert(index < models.size());
126
-    return *models.at(index);
127
-}
128
-
129
-void Room::addModel(StaticModel* s) {
130
-    models.emplace_back(s);
131
-}
132
-
133
-unsigned long Room::sizeLights() {
134
-    return lights.size();
135
-}
136
-
137
-Light& Room::getLight(unsigned long index) {
138
-    assert(index < lights.size());
139
-    return *lights.at(index);
140
-}
141
-
142
-void Room::addLight(Light* l) {
143
-    lights.emplace_back(l);
144
-}
145
-
146
-unsigned long Room::sizeSprites() {
147
-    return sprites.size();
148
-}
149
-
150
-Sprite& Room::getSprite(unsigned long index) {
151
-    assert(index < sprites.size());
152
-    return *sprites.at(index);
153
-}
154
-
155
-void Room::addSprite(Sprite* s) {
156
-    sprites.emplace_back(s);
157
-}
158
-

+ 11
- 0
src/RoomData.cpp View File

@@ -6,6 +6,7 @@
6 6
  */
7 7
 
8 8
 #include "global.h"
9
+#include "Camera.h"
9 10
 #include "World.h"
10 11
 #include "system/Shader.h"
11 12
 #include "RoomData.h"
@@ -83,6 +84,16 @@ void StaticModel::display(glm::mat4 VP) {
83 84
 
84 85
 // ----------------------------------------------------------------------------
85 86
 
87
+void RoomSprite::display(glm::mat4 VP) {
88
+    glm::mat4 translate = glm::translate(glm::mat4(1.0f), glm::vec3(pos.x, -pos.y, pos.z));
89
+    glm::mat4 rotate = glm::rotate(glm::mat4(1.0f), Camera::getRotation().x, glm::vec3(0.0f, 1.0f, 0.0f));
90
+    glm::mat4 model = translate * rotate;
91
+
92
+    getWorld().getSprite(sprite).display(VP * model);
93
+}
94
+
95
+// ----------------------------------------------------------------------------
96
+
86 97
 void Light::getPos(float p[4]) {
87 98
     p[0] = pos[0];
88 99
     p[1] = pos[1];

+ 25
- 138
src/Sprite.cpp View File

@@ -11,151 +11,38 @@
11 11
 #include "TextureManager.h"
12 12
 #include "Sprite.h"
13 13
 
14
-SpriteSequence::SpriteSequence(int32_t objectID) {
15
-    id = objectID;
16
-}
17
-
18
-void SpriteSequence::add(Sprite s) {
19
-    sprites.push_back(s);
20
-}
21
-
22
-unsigned long SpriteSequence::size() {
23
-    return sprites.size();
24
-}
25
-
26
-Sprite& SpriteSequence::get(unsigned long index) {
27
-    assert(index < sprites.size());
28
-    return sprites.at(index);
29
-}
30
-
31
-// ----------------------------------------------------------------------------
32
-
33
-Sprite::Sprite(uint16_t tile, uint8_t x, uint8_t y, uint16_t width, uint16_t height) {
34
-    /*!
35
-     * \fixme TODO Can't do translation/visibility-check when rendering here.
36
-     * We don't know xyz of this Sprite because it could be used by
37
-     * different items at other coordinates in the world.
38
-     * Do translation/visibility-check at item/room level.
39
-     */
40
-
41
-    const float scale = 4.0f;
42
-    const float texelScale = 256.0f;
14
+const static float scale = 4.0f;
15
+const static float texelScale = 256.0f;
16
+const static int texelOffset = 2;
43 17
 
18
+Sprite::Sprite(int tile, int x, int y, int width, int height) : texture(tile) {
44 19
     width >>= 8;
45 20
     height >>= 8;
21
+
46 22
     int width2 = (int)(width * scale);
47 23
     int height2 = (int)(height * scale);
48 24
 
49
-    vertex[0][0] = -width2 / 2.0f;
50
-    vertex[1][0] = -width2 / 2.0f;
51
-    vertex[2][0] = width2 / 2.0f;
52
-    vertex[3][0] = width2 / 2.0f;
53
-
54
-    vertex[0][1] = 0;
55
-    vertex[1][1] = -height2;
56
-    vertex[2][1] = -height2;
57
-    vertex[3][1] = 0;
58
-
59
-    vertex[0][2] = 0;
60
-    vertex[1][2] = 0;
61
-    vertex[2][2] = 0;
62
-    vertex[3][2] = 0;
63
-
64
-    texel[3][0] = (float)(x + width) / texelScale;
65
-    texel[3][1] = (float)(y + height) / texelScale;
66
-
67
-    texel[2][0] = (float)(x + width) / texelScale;
68
-    texel[2][1] = (float)(y) / texelScale;
69
-
70
-    texel[1][0] = (float)(x) / texelScale;
71
-    texel[1][1] = (float)(y) / texelScale;
72
-
73
-    texel[0][0] = (float)(x) / texelScale;
74
-    texel[0][1] = (float)(y + height) / texelScale;
75
-
76
-    texture = tile;
77
-    //radius = width2 / 2.0f;
25
+    std::vector<glm::vec2> uv;
26
+    uv.emplace_back(float(x + texelOffset) / texelScale, float(y + height) / texelScale);
27
+    uv.emplace_back(float(x + texelOffset) / texelScale, float(y + texelOffset) / texelScale);
28
+    uv.emplace_back(float(x + width) / texelScale, float(y + texelOffset) / texelScale);
29
+    uv.emplace_back(float(x + width) / texelScale, float(y + height) / texelScale);
30
+    uv.emplace_back(uv.at(0));
31
+    uv.emplace_back(uv.at(2));
32
+
33
+    std::vector<glm::vec3> vert;
34
+    vert.emplace_back(float(-width2) / 2.0f, 0.0f, 0.0f);
35
+    vert.emplace_back(float(-width2) / 2.0f, float(-height2), 0.0f);
36
+    vert.emplace_back(float(width2) / 2.0f, float(-height2), 0.0f);
37
+    vert.emplace_back(float(width2) / 2.0f, 0.0f, 0.0f);
38
+    vert.emplace_back(vert.at(0));
39
+    vert.emplace_back(vert.at(2));
40
+
41
+    vertices.bufferData(vert);
42
+    uvs.bufferData(uv);
78 43
 }
79 44
 
80
-void Sprite::display() {
81
-    /*
82
-    //if (!Render::isVisible(pos[0], pos[1], pos[2], radius))
83
-    //    return;
84
-
85
-    glPushMatrix();
86
-    //glTranslated(pos[0], pos[1], pos[2]);
87
-
88
-    // Sprites must always face camera, because they have no depth =)
89
-    glRotated(glm::degrees(Camera::getRadianYaw()), 0, 1, 0);
90
-
91
-    switch (Render::getMode()) {
92
-        // No vertex lighting on sprites, as far as I see in specs
93
-        // So just draw normal texture, no case 2
94
-        case RenderMode::Solid:
95
-            glBegin(GL_TRIANGLE_STRIP);
96
-            glColor3f(texel[0][0], texel[0][1], 0.5);
97
-            glVertex3fv(vertex[0]);
98
-
99
-            glColor3f(texel[1][0], texel[1][1], 0.5);
100
-            glVertex3fv(vertex[1]);
101
-
102
-            glColor3f(texel[3][0], texel[3][1], 0.5);
103
-            glVertex3fv(vertex[3]);
104
-
105
-            glColor3f(texel[2][0], texel[2][1], 0.5);
106
-            glVertex3fv(vertex[2]);
107
-            glEnd();
108
-            break;
109
-        case RenderMode::Wireframe:
110
-            glColor3ubv(CYAN);
111
-            glBegin(GL_LINE_LOOP);
112
-            glVertex3fv(vertex[0]);
113
-            glVertex3fv(vertex[1]);
114
-            glVertex3fv(vertex[2]);
115
-            glVertex3fv(vertex[3]);
116
-            glEnd();
117
-            glColor3ubv(WHITE);
118
-            break;
119
-        default:
120
-            getTextureManager().bindTextureId(texture);
121
-
122
-            glBegin(GL_TRIANGLE_STRIP);
123
-            glTexCoord2fv(texel[0]);
124
-            glVertex3fv(vertex[0]);
125
-            glTexCoord2fv(texel[1]);
126
-            glVertex3fv(vertex[1]);
127
-            glTexCoord2fv(texel[3]);
128
-            glVertex3fv(vertex[3]);
129
-            glTexCoord2fv(texel[2]);
130
-            glVertex3fv(vertex[2]);
131
-            glEnd();
132
-    }
133
-
134
-    glPopMatrix();
135
-    */
136
-}
137
-
138
-void Sprite::display(float x, float y, float w, float h) {
139
-    /*
140
-    float z = 0.0f;
141
-
142
-    getTextureManager().bindTextureId(texture);
143
-
144
-    glBegin(GL_QUADS);
145
-
146
-    glTexCoord2fv(texel[1]);
147
-    glVertex3f(x, y, z);
148
-
149
-    glTexCoord2fv(texel[2]);
150
-    glVertex3f(x + w, y, z);
151
-
152
-    glTexCoord2fv(texel[3]);
153
-    glVertex3f(x + w, y + h, z);
154
-
155
-    glTexCoord2fv(texel[0]);
156
-    glVertex3f(x, y + h, z);
157
-
158
-    glEnd();
159
-    */
45
+void Sprite::display(glm::mat4 MVP) {
46
+    Shader::drawGL(vertices, uvs, texture, MVP);
160 47
 }
161 48
 

+ 4
- 4
src/TextureManager.cpp View File

@@ -36,10 +36,6 @@ int TextureManager::initialize() {
36 36
         mTextureIdsSystem.push_back(id);
37 37
     }
38 38
 
39
-    return 0;
40
-}
41
-
42
-int TextureManager::initializeSplash() {
43 39
     unsigned char* image = generateColorTexture(WHITE, 32, 32, 32);
44 40
     int res = loadBufferSlot(image, 32, 32, ColorMode::RGBA, 32, TextureStorage::SYSTEM, TEXTURE_WHITE,
45 41
                              false);
@@ -48,6 +44,10 @@ int TextureManager::initializeSplash() {
48 44
         return -1;
49 45
     }
50 46
 
47
+    return 0;
48
+}
49
+
50
+int TextureManager::initializeSplash() {
51 51
     Folder f(RunTime::getPakDir());
52 52
     std::vector<File> files;
53 53
     f.findRecursiveFilesEndingWith(files, ".pcx");

+ 16
- 3
src/World.cpp View File

@@ -34,19 +34,32 @@ Room& World::getRoom(unsigned long index) {
34 34
     return *mRooms.at(index);
35 35
 }
36 36
 
37
-void World::addSprite(SpriteSequence* sprite) {
38
-    mSprites.emplace_back(std::unique_ptr<SpriteSequence>(sprite));
37
+void World::addSprite(Sprite* sprite) {
38
+    mSprites.emplace_back(std::unique_ptr<Sprite>(sprite));
39 39
 }
40 40
 
41 41
 unsigned long World::sizeSprite() {
42 42
     return mSprites.size();
43 43
 }
44 44
 
45
-SpriteSequence& World::getSprite(unsigned long index) {
45
+Sprite& World::getSprite(unsigned long index) {
46 46
     assert(index < mSprites.size());
47 47
     return *mSprites.at(index);
48 48
 }
49 49
 
50
+void World::addSpriteSequence(SpriteSequence* sprite) {
51
+    mSpriteSequences.emplace_back(std::unique_ptr<SpriteSequence>(sprite));
52
+}
53
+
54
+unsigned long World::sizeSpriteSequence() {
55
+    return mSpriteSequences.size();
56
+}
57
+
58
+SpriteSequence& World::getSpriteSequence(unsigned long index) {
59
+    assert(index < mSpriteSequences.size());
60
+    return *mSpriteSequences.at(index);
61
+}
62
+
50 63
 void World::addEntity(Entity* entity) {
51 64
     mEntities.emplace_back(std::unique_ptr<Entity>(entity));
52 65
 }

+ 87
- 57
src/deps/imgui/imgui.cpp View File

@@ -1,4 +1,4 @@
1
-// ImGui library v1.20
1
+// ImGui library v1.21 wip
2 2
 // See ImGui::ShowTestWindow() for sample code.
3 3
 // Read 'Programmer guide' below for notes on how to setup ImGui in your codebase.
4 4
 // Get latest version at https://github.com/ocornut/imgui
@@ -197,11 +197,13 @@
197 197
  - window: fix resize grip rendering scaling along with Rounding style setting
198 198
  - window: autofit feedback loop when user relies on any dynamic layout (window width multiplier, column). maybe just clearly drop manual autofit?
199 199
  - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. 
200
+ - window: allow resizing of child windows (possibly given min/max for each axis?)
201
+ - window: resizing from any sides? + mouse cursor directives for app.
200 202
  - widgets: switching from "widget-label" to "label-widget" would make it more convenient to integrate widgets in trees
201 203
  - widgets: clip text? hover clipped text shows it in a tooltip or in-place overlay
202
- - widgets: IsItemHovered() returns true even if mouse is active on another widget (e.g. dragging outside of sliders). Maybe not a sensible default? Add parameter or alternate function?
203
- - main: make IsHovered() more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
204
- - main: make IsHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
204
+ - main: IsItemHovered() returns true even if mouse is active on another widget (e.g. dragging outside of sliders). Maybe not a sensible default? Add parameter or alternate function?
205
+ - main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
206
+ - main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
205 207
  - scrollbar: use relative mouse movement when first-clicking inside of scroll grab box.
206 208
  - scrollbar: make the grab visible and a minimum size for long scroll regions
207 209
 !- input number: very large int not reliably supported because of int<>float conversions.
@@ -210,7 +212,7 @@
210 212
  - input number: use mouse wheel to step up/down
211 213
  - input number: non-decimal input.
212 214
  - layout: horizontal layout helper (github issue #97)
213
- - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 horrible layout code. item width should include frame padding.
215
+ - layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding.
214 216
  - columns: separator function or parameter that works within the column (currently Separator() bypass all columns)
215 217
  - columns: declare column set (each column: fixed size, %, fill, distribute default size among fills)
216 218
  - columns: columns header to act as button (~sort op) and allow resize/reorder
@@ -224,13 +226,15 @@
224 226
  - file selection widget -> build the tool in our codebase to improve model-dialog idioms (may or not lead to ImGui changes)
225 227
  - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
226 228
  - slider: initial absolute click is imprecise. change to relative movement slider? hide mouse cursor, allow more precise input using less screen-space.
227
- - text edit: clean up the horrible mess caused by converting UTF-8 <> wchar
229
+ - text edit: clean up the mess caused by converting UTF-8 <> wchar
228 230
  - text edit: centered text for slider or input text to it matches typical positioning.
229 231
  - text edit: flag to disable live update of the user buffer. 
230 232
  - text edit: field resize behavior - field could stretch when being edited? hover tooltip shows more text?
231 233
  - text edit: add multi-line text edit
232 234
  - settings: write more decent code to allow saving/loading new fields
233 235
  - settings: api for per-tool simple persistent data (bool,int,float) in .ini file
236
+ - style: checkbox: padding for "active" color should be a multiplier of the 
237
+ - style: colorbox not always square?
234 238
  - log: LogButtons() options for specifying depth and/orhiding depth slider
235 239
  - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
236 240
  - log: be able to right-click and log a window or tree-node into tty/file/clipboard / generalized context menu?
@@ -244,14 +248,13 @@
244 248
  - tooltip: move to fit within screen (e.g. when mouse cursor is right of the screen).
245 249
  - clipboard: automatically transform \n into \n\r or equivalent for higher compatibility on windows
246 250
  - portability: big-endian test/support (github issue #81)
247
- - examples: add History support in the demo console application (pertinent to github issue #68).
251
+ - misc: rounded triangle fail to draw correctly on OpenGL3 example.
248 252
  - misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
249 253
  - misc: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
250
- - style editor: add a button to output C code.
254
+ - style editor: color child window height expressed in multiple of line height.
251 255
  - optimization/render: use indexed rendering to reduce vertex data cost (for remote/networked imgui)
252 256
  - optimization/render: move clip-rect to vertex data? would allow merging all commands
253 257
  - optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
254
- - optimization/render: font exported by bmfont is not tight fit on vertical axis, incur unneeded pixel-shading cost.
255 258
  - optimization: turn some the various stack vectors into statically-sized arrays
256 259
  - optimization: better clipping for multi-component widgets
257 260
  - optimization: specialize for height based clipping first (assume widgets never go up + height tests before width tests?)
@@ -346,9 +349,10 @@ ImGuiStyle::ImGuiStyle()
346 349
 {
347 350
     Alpha                   = 1.0f;             // Global alpha applies to everything in ImGui
348 351
     WindowPadding           = ImVec2(8,8);      // Padding within a window
349
-    WindowMinSize           = ImVec2(48,48);    // Minimum window size
352
+    WindowMinSize           = ImVec2(32,32);    // Minimum window size
350 353
     WindowRounding          = 9.0f;             // Radius of window corners rounding. Set to 0.0f to have rectangular windows
351 354
     FramePadding            = ImVec2(4,3);      // Padding within a framed rectangle (used by most widgets)
355
+    FrameRounding           = 0.0f;             // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets).
352 356
     ItemSpacing             = ImVec2(8,4);      // Horizontal and vertical spacing between widgets/lines
353 357
     ItemInnerSpacing        = ImVec2(4,4);      // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
354 358
     TouchExtraPadding       = ImVec2(0,0);      // Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much!
@@ -1180,18 +1184,32 @@ bool ImGuiTextFilter::PassFilter(const char* val) const
1180 1184
 
1181 1185
 //-----------------------------------------------------------------------------
1182 1186
 
1187
+// On some platform vsnprintf() takes va_list by reference and modifies it. 
1188
+// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it.
1189
+#ifndef va_copy
1190
+#define va_copy(dest, src) (dest = src)
1191
+#endif
1192
+
1183 1193
 // Helper: Text buffer for logging/accumulating text
1184 1194
 void ImGuiTextBuffer::appendv(const char* fmt, va_list args)
1185 1195
 {
1196
+    va_list args_copy;
1197
+    va_copy(args_copy, args);
1198
+
1186 1199
     int len = vsnprintf(NULL, 0, fmt, args);         // FIXME-OPT: could do a first pass write attempt, likely successful on first pass.
1187 1200
     if (len <= 0)
1188 1201
         return;
1202
+
1189 1203
     const size_t write_off = Buf.size();
1204
+    const size_t needed_sz = write_off + (size_t)len;
1190 1205
     if (write_off + (size_t)len >= Buf.capacity())
1191
-        Buf.reserve(Buf.capacity() * 2);
1206
+    {
1207
+        const size_t double_capacity = Buf.capacity() * 2;
1208
+        Buf.reserve(needed_sz > double_capacity ? needed_sz : double_capacity);
1209
+    }
1192 1210
 
1193
-    Buf.resize(write_off + (size_t)len);
1194
-    ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args);
1211
+    Buf.resize(needed_sz);
1212
+    ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args_copy);
1195 1213
 }
1196 1214
 
1197 1215
 void ImGuiTextBuffer::append(const char* fmt, ...)
@@ -1835,6 +1853,7 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* text_en
1835 1853
     const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth);
1836 1854
     while (true)
1837 1855
     {
1856
+        // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry.
1838 1857
         const char* line_end = text_remaining;
1839 1858
         while (line_end < text_end)
1840 1859
             if (*line_end == '\n')
@@ -2141,7 +2160,9 @@ int ImGui::GetFrameCount()
2141 2160
 
2142 2161
 void ImGui::BeginTooltip()
2143 2162
 {
2144
-    ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), 0.9f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_Tooltip);
2163
+    ImGuiState& g = GImGui;
2164
+    ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_Tooltip;
2165
+    ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), g.Style.Colors[ImGuiCol_TooltipBg].w, window_flags);
2145 2166
 }
2146 2167
 
2147 2168
 void ImGui::EndTooltip()
@@ -2291,11 +2312,13 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2291 2312
     g.CurrentWindow = window;
2292 2313
 
2293 2314
     // Process SetNextWindow***() calls
2315
+    bool window_pos_set_by_api = false;
2294 2316
     if (g.SetNextWindowPosCond)
2295 2317
     {
2296 2318
         const ImVec2 backup_cursor_pos = window->DC.CursorPos;
2297 2319
         ImGui::SetWindowPos(g.SetNextWindowPosVal, g.SetNextWindowPosCond);
2298 2320
         window->DC.CursorPos = backup_cursor_pos;
2321
+        window_pos_set_by_api = true;
2299 2322
         g.SetNextWindowPosCond = 0;
2300 2323
     }
2301 2324
     if (g.SetNextWindowSizeCond)
@@ -2333,16 +2356,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2333 2356
 
2334 2357
         // New windows appears in front
2335 2358
         if (window->LastFrameDrawn < current_frame - 1)
2336
-        {
2337 2359
             FocusWindow(window);
2338
-            if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
2339
-            {
2340
-                // Hide for 1 frame while resizing
2341
-                window->AutoFitFrames = 2;
2342
-                window->AutoFitOnlyGrows = false;
2343
-                window->Visible = false;
2344
-            }
2345
-        }
2346 2360
 
2347 2361
         window->LastFrameDrawn = current_frame;
2348 2362
         window->ClipRectStack.resize(0);
@@ -2386,26 +2400,26 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2386 2400
             }
2387 2401
         }
2388 2402
 
2389
-        // Tooltips always follow mouse
2390
-        if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
2403
+        // Tooltips always follows mouse
2404
+        if (!window_pos_set_by_api && (window->Flags & ImGuiWindowFlags_Tooltip) != 0)
2391 2405
         {
2392 2406
             window->PosFloat = g.IO.MousePos + ImVec2(32,16) - style.FramePadding*2;
2393 2407
         }
2394 2408
 
2395 2409
         // Clamp into view
2396
-        if (!(window->Flags & ImGuiWindowFlags_ChildWindow))
2410
+        if (!(window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Tooltip))
2397 2411
         {
2398
-            const ImVec2 pad = ImVec2(window->FontSize()*2.0f, window->FontSize()*2.0f);
2412
+            const ImVec2 pad = ImVec2(window->FontSize()*2.0f, window->FontSize()*2.0f); // FIXME: Parametrize of clarify this behavior.
2399 2413
             if (g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
2400 2414
             {
2401 2415
                 window->PosFloat = ImMax(window->PosFloat + window->Size, pad) - window->Size;
2402 2416
                 window->PosFloat = ImMin(window->PosFloat, ImVec2(g.IO.DisplaySize.x, g.IO.DisplaySize.y) - pad);
2403 2417
             }
2404
-            window->SizeFull = ImMax(window->SizeFull, pad);
2418
+            window->SizeFull = ImMax(window->SizeFull, style.WindowMinSize);
2405 2419
         }
2406 2420
         window->Pos = ImVec2((float)(int)window->PosFloat.x, (float)(int)window->PosFloat.y);
2407 2421
 
2408
-        // Default item width
2422
+        // Default item width. Make it proportional to window size if window manually resizes
2409 2423
         if (window->Size.x > 0.0f && !(window->Flags & ImGuiWindowFlags_Tooltip) && !(window->Flags & ImGuiWindowFlags_AlwaysAutoResize))
2410 2424
             window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f);
2411 2425
         else
@@ -2467,11 +2481,9 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2467 2481
             ImU32 resize_col = 0;
2468 2482
             if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
2469 2483
             {
2470
-                // Tooltip always resize
2471
-                if (window->AutoFitFrames > 0)
2472
-                {
2473
-                    window->SizeFull = window->SizeContentsFit + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y);
2474
-                }
2484
+                // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose.
2485
+                const ImVec2 size_auto_fit = window->SizeContentsFit + style.WindowPadding - ImVec2(0.0f, style.ItemSpacing.y);
2486
+                window->SizeFull = size_auto_fit;
2475 2487
             }
2476 2488
             else
2477 2489
             {
@@ -2493,7 +2505,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2493 2505
                 }
2494 2506
                 else if (!(window->Flags & ImGuiWindowFlags_NoResize))
2495 2507
                 {
2496
-                    // Resize grip
2508
+                    // Manual resize grip
2497 2509
                     const ImGuiAabb resize_aabb(window->Aabb().GetBR()-ImVec2(18,18), window->Aabb().GetBR());
2498 2510
                     const ImGuiID resize_id = window->GetID("##RESIZE");
2499 2511
                     bool hovered, held;
@@ -2502,7 +2514,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2502 2514
 
2503 2515
                     if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0])
2504 2516
                     {
2505
-                        // Manual auto-fit
2517
+                        // Manual auto-fit when double-clicking
2506 2518
                         window->SizeFull = size_auto_fit;
2507 2519
                         window->Size = window->SizeFull;
2508 2520
                         if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
@@ -2518,7 +2530,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2518 2530
                     }
2519 2531
                 }
2520 2532
 
2521
-                // Update aabb immediately so that the rendering below isn't one frame late
2533
+                // Update aabb immediately so that rendering right below us isn't one frame late
2522 2534
                 title_bar_aabb = window->TitleBarAabb();
2523 2535
             }
2524 2536
 
@@ -2527,6 +2539,8 @@ bool ImGui::Begin(const char* name, bool* p_opened, ImVec2 size, float fill_alph
2527 2539
             {
2528 2540
                 if ((window->Flags & ImGuiWindowFlags_ComboBox) != 0)
2529 2541
                     window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_ComboBg, fill_alpha), 0);
2542
+                else if ((window->Flags & ImGuiWindowFlags_Tooltip) != 0)
2543
+                    window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_TooltipBg, fill_alpha), style.WindowRounding);
2530 2544
                 else
2531 2545
                     window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, window->Color(ImGuiCol_WindowBg, fill_alpha), style.WindowRounding);
2532 2546
             }
@@ -2810,6 +2824,7 @@ static float* GetStyleVarFloatAddr(ImGuiStyleVar idx)
2810 2824
     {
2811 2825
     case ImGuiStyleVar_Alpha: return &g.Style.Alpha;
2812 2826
     case ImGuiStyleVar_WindowRounding: return &g.Style.WindowRounding;
2827
+    case ImGuiStyleVar_FrameRounding: return &g.Style.FrameRounding;
2813 2828
     case ImGuiStyleVar_TreeNodeSpacing: return &g.Style.TreeNodeSpacing;
2814 2829
     }
2815 2830
     return NULL;
@@ -2888,9 +2903,9 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
2888 2903
     case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
2889 2904
     case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
2890 2905
     case ImGuiCol_ComboBg: return "ComboBg";
2891
-    case ImGuiCol_CheckHovered: return "CheckBgHovered";
2892
-    case ImGuiCol_CheckActive: return "CheckBgActive";
2893
-    case ImGuiCol_CheckMark: return "CheckSelected";
2906
+    case ImGuiCol_CheckHovered: return "CheckHovered";
2907
+    case ImGuiCol_CheckActive: return "CheckActive";
2908
+    case ImGuiCol_CheckMark: return "CheckMark";
2894 2909
     case ImGuiCol_SliderGrab: return "SliderGrab";
2895 2910
     case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
2896 2911
     case ImGuiCol_Button: return "Button";
@@ -3088,6 +3103,8 @@ void ImGui::SetWindowFontScale(float scale)
3088 3103
     window->FontWindowScale = scale;
3089 3104
 }
3090 3105
 
3106
+// NB: internally we store CursorPos in absolute screen coordinates because it is more convenient.
3107
+// Conversion happens as we pass the value to user, but it makes our naming convention dodgy. May want to rename 'DC.CursorPos'.
3091 3108
 ImVec2 ImGui::GetCursorPos()
3092 3109
 {
3093 3110
     ImGuiWindow* window = GetCurrentWindow();
@@ -3118,6 +3135,12 @@ ImVec2 ImGui::GetCursorScreenPos()
3118 3135
     return window->DC.CursorPos;
3119 3136
 }
3120 3137
 
3138
+void ImGui::SetCursorScreenPos(const ImVec2& screen_pos)
3139
+{
3140
+    ImGuiWindow* window = GetCurrentWindow();
3141
+    window->DC.CursorPos = screen_pos;
3142
+}
3143
+
3121 3144
 void ImGui::SetScrollPosHere()
3122 3145
 {
3123 3146
     ImGuiWindow* window = GetCurrentWindow();
@@ -3426,7 +3449,7 @@ bool ImGui::Button(const char* label, ImVec2 size, bool repeat_when_held)
3426 3449
 
3427 3450
     // Render
3428 3451
     const ImU32 col = window->Color((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
3429
-    RenderFrame(bb.Min, bb.Max, col);
3452
+    RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
3430 3453
 
3431 3454
     if (size.x < text_size.x || size.y < text_size.y)
3432 3455
         PushClipRect(ImVec4(bb.Min.x+style.FramePadding.x, bb.Min.y+style.FramePadding.y, bb.Max.x, bb.Max.y-style.FramePadding.y));        // Allow extra to draw over the horizontal padding to make it visible that text doesn't fit
@@ -3670,7 +3693,7 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, const bool d
3670 3693
     if (display_frame)
3671 3694
     {
3672 3695
         // Framed type
3673
-        RenderFrame(bb.Min, bb.Max, col, true);
3696
+        RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
3674 3697
         RenderCollapseTriangle(bb.Min + style.FramePadding, opened, 1.0f, true);
3675 3698
         if (g.LogEnabled)
3676 3699
         {
@@ -4012,7 +4035,7 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c
4012 4035
     }
4013 4036
 
4014 4037
     ItemSize(bb);
4015
-    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));
4038
+    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
4016 4039
 
4017 4040
     // Process clicking on the slider
4018 4041
     if (g.ActiveId == id)
@@ -4270,7 +4293,7 @@ static void Plot(ImGuiPlotType plot_type, const char* label, float (*values_gett
4270 4293
             scale_max = v_max;
4271 4294
     }
4272 4295
 
4273
-    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));
4296
+    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
4274 4297
 
4275 4298
     int res_w = ImMin((int)graph_size.x, values_count);
4276 4299
     if (plot_type == ImGuiPlotType_Lines)
@@ -4396,12 +4419,12 @@ bool ImGui::Checkbox(const char* label, bool* v)
4396 4419
     if (pressed)
4397 4420
         *v = !(*v);
4398 4421
 
4399
-    RenderFrame(check_bb.Min, check_bb.Max, window->Color((held && hovered) ? ImGuiCol_CheckActive : hovered ? ImGuiCol_CheckHovered : ImGuiCol_FrameBg));
4422
+    RenderFrame(check_bb.Min, check_bb.Max, window->Color((held && hovered) ? ImGuiCol_CheckActive : hovered ? ImGuiCol_CheckHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
4400 4423
     if (*v)
4401 4424
     {
4402 4425
         const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight());
4403 4426
         const float pad = check_sz < 8.0f ? 1.0f : check_sz < 13.0f ? 2.0f : 3.0f;
4404
-        window->DrawList->AddRectFilled(check_bb.Min+ImVec2(pad,pad), check_bb.Max-ImVec2(pad,pad), window->Color(ImGuiCol_CheckMark));
4427
+        window->DrawList->AddRectFilled(check_bb.Min+ImVec2(pad,pad), check_bb.Max-ImVec2(pad,pad), window->Color(ImGuiCol_CheckMark), style.FrameRounding);
4405 4428
     }
4406 4429
 
4407 4430
     if (g.LogEnabled)
@@ -5000,7 +5023,7 @@ bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputT
5000 5023
         }
5001 5024
     }
5002 5025
     
5003
-    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true);
5026
+    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
5004 5027
 
5005 5028
     const ImVec2 font_off_up = ImVec2(0.0f,window->FontSize()+1.0f);    // FIXME: those offsets are part of the style or font API
5006 5029
     const ImVec2 font_off_dn = ImVec2(0.0f,2.0f);
@@ -5167,8 +5190,8 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
5167 5190
     const bool hovered = IsHovered(frame_bb, id);
5168 5191
 
5169 5192
     bool value_changed = false;
5170
-    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg));
5171
-    RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button));
5193
+    RenderFrame(frame_bb.Min, frame_bb.Max, window->Color(ImGuiCol_FrameBg), true, style.FrameRounding);
5194
+    RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, window->Color(hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding);	// FIXME-ROUNDING
5172 5195
     RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true);
5173 5196
 
5174 5197
     if (*current_item >= 0 && *current_item < items_count)
@@ -5275,6 +5298,7 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde
5275 5298
         return false;
5276 5299
 
5277 5300
     const ImGuiStyle& style = g.Style;
5301
+    const ImGuiID id = window->GetID("##colorbutton");
5278 5302
     const float square_size = window->FontSize();
5279 5303
     const ImGuiAabb bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(square_size + style.FramePadding.x*2, square_size + (small_height ? 0 : style.FramePadding.y*2)));
5280 5304
     ItemSize(bb);
@@ -5282,9 +5306,9 @@ bool ImGui::ColorButton(const ImVec4& col, bool small_height, bool outline_borde
5282 5306
     if (ClipAdvance(bb))
5283 5307
         return false;
5284 5308
 
5285
-    const bool hovered = IsHovered(bb, 0);
5286
-    const bool pressed = hovered && g.IO.MouseClicked[0];
5287
-    RenderFrame(bb.Min, bb.Max, window->Color(col), outline_border);
5309
+    bool hovered, held;
5310
+    bool pressed = ButtonBehaviour(bb, id, &hovered, &held, true);
5311
+    RenderFrame(bb.Min, bb.Max, window->Color(col), outline_border, style.FrameRounding);
5288 5312
 
5289 5313
     if (hovered)
5290 5314
     {
@@ -5327,7 +5351,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
5327 5351
     const float square_sz = (window->FontSize() + style.FramePadding.x * 2.0f);
5328 5352
 
5329 5353
     ImGuiColorEditMode edit_mode = window->DC.ColorEditMode;
5330
-    if (edit_mode == ImGuiColorEditMode_UserSelect)
5354
+    if (edit_mode == ImGuiColorEditMode_UserSelect || edit_mode == ImGuiColorEditMode_UserSelectShowButton)
5331 5355
         edit_mode = g.ColorEditModeStorage.GetInt(id, 0) % 3;
5332 5356
 
5333 5357
     float fx = col[0];
@@ -5409,9 +5433,13 @@ bool ImGui::ColorEdit4(const char* label, float col[4], bool alpha)
5409 5433
     }
5410 5434
 
5411 5435
     ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
5412
-    ImGui::ColorButton(col_display);
5436
+    if (ImGui::ColorButton(col_display))
5437
+    {
5438
+        // Don't set local copy of 'edit_mode' right away!
5439
+        g.ColorEditModeStorage.SetInt(id, (edit_mode + 1) % 3);
5440
+    }
5413 5441
 
5414
-    if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelect)
5442
+    if (window->DC.ColorEditMode == ImGuiColorEditMode_UserSelectShowButton)
5415 5443
     {
5416 5444
         ImGui::SameLine(0, (int)style.ItemInnerSpacing.x);
5417 5445
         const char* button_titles[3] = { "RGB", "HSV", "HEX" };
@@ -6869,6 +6897,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
6869 6897
         ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
6870 6898
         ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f");
6871 6899
         ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f");
6900
+        ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 16.0f, "%.0f");
6872 6901
         ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f");
6873 6902
         ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
6874 6903
         ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
@@ -6906,6 +6935,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
6906 6935
         ImGui::RadioButton("HSV", &edit_mode, ImGuiColorEditMode_HSV);
6907 6936
         ImGui::SameLine();
6908 6937
         ImGui::RadioButton("HEX", &edit_mode, ImGuiColorEditMode_HEX);
6938
+        //ImGui::Text("Tip: Click on colored square to change edit mode.");
6909 6939
 
6910 6940
         static ImGuiTextFilter filter;
6911 6941
         filter.Draw("Filter colors", 200);
@@ -7730,7 +7760,7 @@ struct ExampleAppConsole
7730 7760
                 if (data->EventKey == ImGuiKey_UpArrow)
7731 7761
                 {
7732 7762
                     if (HistoryPos == -1)
7733
-                        HistoryPos = History.size() - 1;
7763
+                        HistoryPos = (int)(History.size() - 1);
7734 7764
                     else if (HistoryPos > 0)
7735 7765
                         HistoryPos--;
7736 7766
                 }
@@ -7746,7 +7776,7 @@ struct ExampleAppConsole
7746 7776
                 {
7747 7777
                     ImFormatString(data->Buf, data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : "");
7748 7778
                     data->BufDirty = true;
7749
-                    data->CursorPos = data->SelectionStart = data->SelectionEnd = strlen(data->Buf);
7779
+                    data->CursorPos = data->SelectionStart = data->SelectionEnd = (int)strlen(data->Buf);
7750 7780
                 }
7751 7781
             }
7752 7782
         }

+ 9
- 5
src/deps/imgui/imgui.h View File

@@ -1,4 +1,4 @@
1
-// ImGui library v1.20
1
+// ImGui library v1.21 wip
2 2
 // See .cpp file for commentary.
3 3
 // See ImGui::ShowTestWindow() for sample code.
4 4
 // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@@ -206,7 +206,8 @@ namespace ImGui
206 206
     IMGUI_API void          SetCursorPos(const ImVec2& pos);                                    // "
207 207
     IMGUI_API void          SetCursorPosX(float x);                                             // "
208 208
     IMGUI_API void          SetCursorPosY(float y);                                             // "
209
-    IMGUI_API ImVec2        GetCursorScreenPos();                                               // cursor position in screen space
209
+    IMGUI_API ImVec2        GetCursorScreenPos();                                               // cursor position in absolute screen coordinates (0..io.DisplaySize)
210
+    IMGUI_API void          SetCursorScreenPos(const ImVec2& pos);                              // cursor position in absolute screen coordinates (0..io.DisplaySize)
210 211
     IMGUI_API void          AlignFirstTextHeightToWidgets();                                    // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets.
211 212
     IMGUI_API float         GetTextLineSpacing();
212 213
     IMGUI_API float         GetTextLineHeight();
@@ -422,6 +423,7 @@ enum ImGuiStyleVar_
422 423
     ImGuiStyleVar_WindowPadding,     // ImVec2
423 424
     ImGuiStyleVar_WindowRounding,    // float
424 425
     ImGuiStyleVar_FramePadding,      // ImVec2
426
+    ImGuiStyleVar_FrameRounding,     // float
425 427
     ImGuiStyleVar_ItemSpacing,       // ImVec2
426 428
     ImGuiStyleVar_ItemInnerSpacing,  // ImVec2
427 429
     ImGuiStyleVar_TreeNodeSpacing,   // float
@@ -430,7 +432,8 @@ enum ImGuiStyleVar_
430 432
 // Enumeration for ColorEditMode()
431 433
 enum ImGuiColorEditMode_
432 434
 {
433
-    ImGuiColorEditMode_UserSelect = -1,
435
+    ImGuiColorEditMode_UserSelect = -2,
436
+    ImGuiColorEditMode_UserSelectShowButton = -1,
434 437
     ImGuiColorEditMode_RGB = 0,
435 438
     ImGuiColorEditMode_HSV = 1,
436 439
     ImGuiColorEditMode_HEX = 2
@@ -452,6 +455,7 @@ struct ImGuiStyle
452 455
     ImVec2      WindowMinSize;              // Minimum window size
453 456
     float       WindowRounding;             // Radius of window corners rounding. Set to 0.0f to have rectangular windows
454 457
     ImVec2      FramePadding;               // Padding within a framed rectangle (used by most widgets)
458
+    float       FrameRounding;              // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets).
455 459
     ImVec2      ItemSpacing;                // Horizontal and vertical spacing between widgets/lines
456 460
     ImVec2      ItemInnerSpacing;           // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
457 461
     ImVec2      TouchExtraPadding;          // Expand bounding box for touch-based system where touch position is not accurate enough (unnecessary for mouse inputs). Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget running. So dont grow this too much!
@@ -604,11 +608,11 @@ struct ImGuiTextBuffer
604 608
     ImVector<char>      Buf;
605 609
 
606 610
     ImGuiTextBuffer()   { Buf.push_back(0); }
607
-    ~ImGuiTextBuffer()  { clear(); }
611
+    ~ImGuiTextBuffer()  { }
608 612
     const char*         begin() const { return &Buf.front(); }
609 613
     const char*         end() const { return &Buf.back(); }      // Buf is zero-terminated, so end() will point on the zero-terminator
610 614
     size_t              size() const { return Buf.size()-1; }
611
-    bool                empty() { return Buf.empty(); }
615
+    bool                empty() { return size() >= 1; }
612 616
     void                clear() { Buf.clear(); Buf.push_back(0); }
613 617
     IMGUI_API void      append(const char* fmt, ...);
614 618
     IMGUI_API void      appendv(const char* fmt, va_list args);

+ 11
- 10
src/loader/LoaderTR2.cpp View File

@@ -63,7 +63,7 @@ int LoaderTR2::load(std::string f) {
63 63
 
64 64
     loadExternalSoundFile(f);
65 65
 
66
-    return 0; // TODO Not finished with implementation!
66
+    return 0;
67 67
 }
68 68
 
69 69
 // ---- Textures ----
@@ -266,11 +266,13 @@ void LoaderTR2::loadRooms() {
266 266
         }
267 267
 
268 268
         uint16_t numSprites = file.readU16();
269
+        std::vector<RoomSprite*> roomSprites;
269 270
         for (unsigned int s = 0; s < numSprites; s++) {
270 271
             uint16_t vertex = file.readU16(); // Index into vertex list
271 272
             uint16_t sprite = file.readU16(); // Index into sprite list
272 273
 
273
-            // TODO store sprites somewhere
274
+            auto& v = vertices.at(vertex);
275
+            roomSprites.push_back(new RoomSprite(glm::vec3(v.x, v.y, v.z) + pos, sprite));
274 276
         }
275 277
 
276 278
         uint16_t numPortals = file.readU16();
@@ -402,6 +404,9 @@ void LoaderTR2::loadRooms() {
402 404
         for (auto m : staticModels)
403 405
             room->addModel(m);
404 406
 
407
+        for (auto s : roomSprites)
408
+            room->addSprite(s);
409
+
405 410
         getWorld().addRoom(room);
406 411
 
407 412
         // Sanity check
@@ -435,7 +440,6 @@ void LoaderTR2::loadFloorData() {
435 440
 
436 441
 void LoaderTR2::loadSprites() {
437 442
     uint32_t numSpriteTextures = file.readU32();
438
-    std::vector<Sprite> sprites;
439 443
     for (unsigned int s = 0; s < numSpriteTextures; s++) {
440 444
         uint16_t tile = file.readU16();
441 445
         uint8_t x = file.readU8();
@@ -449,7 +453,8 @@ void LoaderTR2::loadSprites() {
449 453
         int16_t rightSide = file.read16();
450 454
         int16_t bottomSide = file.read16();
451 455
 
452
-        sprites.emplace_back(tile, x, y, width, height);
456
+        Sprite* sp = new Sprite(tile, x, y, width, height);
457
+        getWorld().addSprite(sp);
453 458
     }
454 459
 
455 460
     uint32_t numSpriteSequences = file.readU32();
@@ -462,11 +467,8 @@ void LoaderTR2::loadSprites() {
462 467
         assert(offset >= 0);
463 468
         assert((offset + (negativeLength * -1)) <= numSpriteTextures);
464 469
 
465
-        SpriteSequence* ss = new SpriteSequence(objectID);
466
-        for (int i = 0; i < (negativeLength * -1); i++) {
467
-            ss->add(sprites.at(offset + i));
468
-        }
469
-        getWorld().addSprite(ss);
470
+        SpriteSequence* ss = new SpriteSequence(objectID, offset, (negativeLength * -1));
471
+        getWorld().addSpriteSequence(ss);
470 472
     }
471 473
 
472 474
     if ((numSpriteTextures > 0) || (numSpriteSequences > 0))
@@ -491,7 +493,6 @@ void LoaderTR2::loadMeshes() {
491 493
     }
492 494
 
493 495
     uint32_t numMeshPointers = file.readU32();
494
-
495 496
     for (unsigned int i = 0; i < numMeshPointers; i++) {
496 497
         uint32_t meshPointer = file.readU32();
497 498
 

+ 4
- 0
src/system/Shader.cpp View File

@@ -289,6 +289,8 @@ void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& uvs, ShaderBuffer& ind
289 289
 void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, glm::mat4 MVP,
290 290
                     unsigned int mode, Shader& shader) {
291 291
     assert(vertices.getSize() == colors.getSize());
292
+    if (mode == GL_TRIANGLES)
293
+        assert((vertices.getSize() % 3) == 0)
292 294
 
293 295
     shader.use();
294 296
     shader.loadUniform(0, MVP);
@@ -302,6 +304,8 @@ void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, glm::mat4 MVP,
302 304
 void Shader::drawGL(ShaderBuffer& vertices, ShaderBuffer& colors, ShaderBuffer& indices,
303 305
                     glm::mat4 MVP, unsigned int mode, Shader& shader) {
304 306
     assert(vertices.getSize() == colors.getSize());
307
+    if (mode == GL_TRIANGLES)
308
+        assert((indices.getSize() % 3) == 0)
305 309
 
306 310
     shader.use();
307 311
     shader.loadUniform(0, MVP);

Loading…
Cancel
Save