Browse Source

optimized draw: time/2; multithread entities update

develop
Robin Thoni 7 years ago
parent
commit
601cb60e81

+ 4
- 3
TheGame/openglrenderdevice.cpp View File

@@ -170,7 +170,7 @@ void OpenGLRenderDevice::drawLine(const ColorVector3D &begin, const ColorVector3
170 170
 void OpenGLRenderDevice::drawPolygon(const QList<ColorVector3D> &points)
171 171
 {
172 172
     glBegin(GL_POLYGON);
173
-    Vector3D p1 = points[0];
173
+//    Vector3D p1 = points[0];
174 174
 //    Vector3D p2 = points[1];
175 175
 //    Vector3D n = p1.crossProduct(p2);
176 176
 //    Vector3D n2 = p2.crossProduct(p1);
@@ -188,8 +188,9 @@ void OpenGLRenderDevice::drawPolygonTexture(const QList<TextureVector3D> &points
188 188
     glBindTexture(GL_TEXTURE_2D, data.id);
189 189
     glBegin(GL_POLYGON);
190 190
     for (int i = 0; i < points.size(); ++i) {
191
-        TextureVector3D p = points[i];
192
-        glTexCoord2d(p.getTextureCoord().getX(), p.getTextureCoord().getY());
191
+        const TextureVector3D& p = points[i];
192
+        const Vector2D& coord = p.getTextureCoord();
193
+        glTexCoord2d(coord.getX(), coord.getY());
193 194
         drawVertex(p);
194 195
     }
195 196
     glEnd();

+ 5
- 5
TheGame/renderwidget.cpp View File

@@ -20,12 +20,12 @@ RenderWidget::RenderWidget(QWidget *parent) :
20 20
 
21 21
     _engine->addEntity(new UGEEntityAxes(_engine));
22 22
 
23
-    for (int i = 0; i < 100; ++i) {
23
+    for (int i = 0; i < 1000; ++i) {
24 24
         UGEEntityCube* cube = new UGEEntityCube(_engine);
25 25
         cube->setTextureId("test");
26 26
         cube->rotate(Vector3D(0.0, 45.0, 45.0));
27 27
         cube->move(Vector3D(0, i, i));
28
-        cube->setScale(Vector3D(1.0, 2.0, 1.0));
28
+//        cube->setScale(Vector3D(1.0, 2.0, 1.0));
29 29
         _engine->addEntity(cube);
30 30
         _entities.append(cube);
31 31
     }
@@ -103,9 +103,9 @@ void RenderWidget::keyReleaseEvent(QKeyEvent *event)
103 103
 
104 104
 void RenderWidget::animate()
105 105
 {
106
-//    for (int i = 0; i < _entities.size(); ++i) {
107
-//        _entities[i]->rotate(Vector3D(0.0, 2.0, 2.0));
108
-//    }
106
+    for (int i = 0; i < _entities.size(); ++i) {
107
+        _entities[i]->rotate(Vector3D(0.0, 2.0, 2.0));
108
+    }
109 109
     QTimer::singleShot(20, this, SLOT(animate()));
110 110
     update();
111 111
 }

+ 4
- 2
UGameEngine/UGameEngine.pro View File

@@ -30,7 +30,8 @@ SOURCES += engine/ugameengine.cpp \
30 30
     utils/tools.cpp \
31 31
     cameras/abstractcamera.cpp \
32 32
     cameras/rotationcamera.cpp \
33
-    cameras/freeflycamera.cpp
33
+    cameras/freeflycamera.cpp \
34
+    engine/entitiesupdatethread.cpp
34 35
 
35 36
 HEADERS += engine/ugameengine.h\
36 37
     engine/abstractrenderdevice.h \
@@ -54,7 +55,8 @@ HEADERS += engine/ugameengine.h\
54 55
     cameras/rotationcamera.h \
55 56
     cameras/freeflycamera.h \
56 57
     utils/matrixdebug.h \
57
-    utils/matrixdebug.hxx
58
+    utils/matrixdebug.hxx \
59
+    engine/entitiesupdatethread.h
58 60
 
59 61
 
60 62
 # FLEX && BISON

+ 25
- 0
UGameEngine/engine/entitiesupdatethread.cpp View File

@@ -0,0 +1,25 @@
1
+#include "entitiesupdatethread.h"
2
+#include "entities/ugeentity.h"
3
+
4
+EntitiesUpdateThread::EntitiesUpdateThread(UGameEngine *parent)
5
+    : QThread(parent)
6
+    , _engine(parent)
7
+{
8
+}
9
+
10
+void EntitiesUpdateThread::update(int begin, int end)
11
+{
12
+    _begin = begin;
13
+    _end = end;
14
+    start();
15
+}
16
+
17
+void EntitiesUpdateThread::run()
18
+{
19
+    for (int i = _begin; i < _end; ++i) {
20
+        UGEEntity* entity = _engine->getEntity(i);
21
+        if (entity->isVisible()) {
22
+            entity->update();
23
+        }
24
+    }
25
+}

+ 33
- 0
UGameEngine/engine/entitiesupdatethread.h View File

@@ -0,0 +1,33 @@
1
+#ifndef ENTITIESUPDATETHREAD_H
2
+#define ENTITIESUPDATETHREAD_H
3
+
4
+#include <QThread>
5
+#include "ugameengine.h"
6
+
7
+class UGameEngine;
8
+
9
+class EntitiesUpdateThread : public QThread
10
+{
11
+    Q_OBJECT
12
+public:
13
+    explicit EntitiesUpdateThread(UGameEngine *parent = 0);
14
+
15
+    void update(int begin, int end);
16
+
17
+protected:
18
+    void run();
19
+
20
+signals:
21
+
22
+public slots:
23
+
24
+private:
25
+    UGameEngine* _engine;
26
+
27
+    int _begin;
28
+
29
+    int _end;
30
+
31
+};
32
+
33
+#endif // ENTITIESUPDATETHREAD_H

+ 51
- 1
UGameEngine/engine/ugameengine.cpp View File

@@ -1,29 +1,79 @@
1 1
 #include "ugameengine.h"
2
-
2
+#include <QTime>
3 3
 
4 4
 UGameEngine::UGameEngine(AbstractRenderDevice* device)
5 5
     : _device(device)
6 6
 {
7
+    for (int i = 0; i < 8; ++i) {
8
+        _entitiesUpdateThreads.append(new EntitiesUpdateThread(this));
9
+    }
7 10
 }
8 11
 
9 12
 UGameEngine::~UGameEngine()
10 13
 {
11 14
 }
12 15
 
16
+void UGameEngine::update()
17
+{
18
+    int entitiesCount = _entitites.size();
19
+    if (entitiesCount > 1000) {
20
+        int threads = _entitiesUpdateThreads.size();
21
+        for (int t = 0; t < threads; ++t) {
22
+            EntitiesUpdateThread* thread = _entitiesUpdateThreads[t];
23
+            int begin = (entitiesCount / threads) * t;
24
+            int end = (entitiesCount / threads) * (t + 1);
25
+            if (t == threads - 1) {
26
+                end = entitiesCount;
27
+            }
28
+            thread->update(begin, end);
29
+        }
30
+        for (int t = 0; t < threads; ++t) {
31
+            EntitiesUpdateThread* thread = _entitiesUpdateThreads[t];
32
+            thread->wait();
33
+        }
34
+    }
35
+    else {
36
+        for(int i = 0; i < _entitites.size(); ++i) {
37
+            UGEEntity* entity = _entitites[i];
38
+            if (entity->isVisible()) {
39
+                entity->update();
40
+            }
41
+        }
42
+    }
43
+}
44
+
13 45
 void UGameEngine::draw()
14 46
 {
15 47
     _device->preDraw();
16 48
 
49
+    QTime time;
50
+    time.start();
51
+    update();
52
+    int update = time.elapsed();
53
+    time.restart();
54
+
17 55
     for(int i = 0; i < _entitites.size(); ++i) {
18 56
         UGEEntity* entity = _entitites[i];
19 57
         if (entity->isVisible()) {
20 58
             entity->draw(_device);
21 59
         }
22 60
     }
61
+    int draw = time.elapsed();
62
+    qDebug() << update << draw << (update + draw);
23 63
 
24 64
     _device->postDraw();
25 65
 }
26 66
 
67
+const QList<UGEEntity *> &UGameEngine::getEntities() const
68
+{
69
+    return _entitites;
70
+}
71
+
72
+UGEEntity *UGameEngine::getEntity(int i) const
73
+{
74
+    return _entitites[i];
75
+}
76
+
27 77
 void UGameEngine::addEntity(UGEEntity *entity)
28 78
 {
29 79
     _entitites.append(entity);

+ 11
- 0
UGameEngine/engine/ugameengine.h View File

@@ -3,6 +3,9 @@
3 3
 
4 4
 #include "abstractrenderdevice.h"
5 5
 #include "entities/ugeentity.h"
6
+#include "entitiesupdatethread.h"
7
+
8
+class EntitiesUpdateThread;
6 9
 
7 10
 class UGameEngine : public QObject
8 11
 {
@@ -11,8 +14,14 @@ public:
11 14
     UGameEngine(AbstractRenderDevice* device);
12 15
     virtual ~UGameEngine();
13 16
 
17
+    void update();
18
+
14 19
     void draw();
15 20
 
21
+    const QList<UGEEntity*>& getEntities() const;
22
+
23
+    UGEEntity *getEntity(int i) const;
24
+
16 25
 public slots:
17 26
     void addEntity(UGEEntity* entity);
18 27
 
@@ -30,6 +39,8 @@ protected:
30 39
     QList<UGEEntity*> _entitites;
31 40
 
32 41
     AbstractRenderDevice* _device;
42
+
43
+    QList<EntitiesUpdateThread*> _entitiesUpdateThreads;
33 44
 };
34 45
 
35 46
 #endif // UGAMEENGINE_H

+ 31
- 3
UGameEngine/entities/ugeentity.cpp View File

@@ -5,7 +5,12 @@ UGEEntity::UGEEntity(QObject *parent)
5 5
     : QObject(parent)
6 6
     , _scale(1.0, 1.0, 1.0)
7 7
     , _visible(true)
8
+    , _needUpdate(true)
8 9
 {
10
+    connect(this, SIGNAL(positionChanged()), this, SLOT(needUpdate()));
11
+    connect(this, SIGNAL(rotationChanged()), this, SLOT(needUpdate()));
12
+    connect(this, SIGNAL(scaleChanged()), this, SLOT(needUpdate()));
13
+    connect(this, SIGNAL(colorChanged()), this, SLOT(needUpdate()));
9 14
 }
10 15
 
11 16
 UGEEntity::~UGEEntity()
@@ -109,7 +114,7 @@ void UGEEntity::hide()
109 114
     emit visibilityChanged(_visible);
110 115
 }
111 116
 
112
-QColor UGEEntity::getColor() const
117
+const QColor& UGEEntity::getColor() const
113 118
 {
114 119
     return _color;
115 120
 }
@@ -123,8 +128,7 @@ void UGEEntity::setColor(const QColor &color)
123 128
 
124 129
 Vector3D UGEEntity::getRealPoint(const Vector3D &pos)
125 130
 {
126
-    Matrix3x3 trans = getTransformationMatrix();
127
-    return (trans.multMatrix(pos) + _position);
131
+    return (_tranformation.multMatrix(pos) + _position);
128 132
 }
129 133
 
130 134
 ColorVector3D UGEEntity::getRealPoint(const ColorVector3D &pos)
@@ -204,3 +208,27 @@ void UGEEntity::drawPolygonTexture(AbstractRenderDevice *device, QList<TextureVe
204 208
     }
205 209
     device->drawPolygonTexture(points, textureId);
206 210
 }
211
+
212
+void UGEEntity::draw(AbstractRenderDevice *device)
213
+{
214
+    onDraw(device);
215
+}
216
+
217
+void UGEEntity::update()
218
+{
219
+    if (_needUpdate) {
220
+        _tranformation = getTransformationMatrix();
221
+        onUpdate();
222
+        _needUpdate = false;
223
+    }
224
+}
225
+
226
+void UGEEntity::onUpdate()
227
+{
228
+
229
+}
230
+
231
+void UGEEntity::needUpdate()
232
+{
233
+    _needUpdate = true;
234
+}

+ 20
- 6
UGameEngine/entities/ugeentity.h View File

@@ -36,7 +36,7 @@ public:
36 36
     void show();
37 37
     void hide();
38 38
 
39
-    QColor getColor() const;
39
+    const QColor &getColor() const;
40 40
     void setColor(const QColor &color);
41 41
 
42 42
     Vector3D getRealPoint(const Vector3D& pos);
@@ -47,15 +47,25 @@ public:
47 47
     Matrix3x3 getScaleMatrix() const;
48 48
     Matrix3x3 getRotationMatrix() const;
49 49
 
50
-    virtual void drawPoint(AbstractRenderDevice* device, const ColorVector3D& point);
50
+    void drawPoint(AbstractRenderDevice* device, const ColorVector3D& point);
51 51
 
52
-    virtual void drawLine(AbstractRenderDevice* device, const ColorVector3D& begin, const ColorVector3D& end, double width = 1.0);
52
+    void drawLine(AbstractRenderDevice* device, const ColorVector3D& begin, const ColorVector3D& end, double width = 1.0);
53 53
 
54
-    virtual void drawPolygon(AbstractRenderDevice* device, QList<ColorVector3D> points);
54
+    void drawPolygon(AbstractRenderDevice* device, QList<ColorVector3D> points);
55 55
 
56
-    virtual void drawPolygonTexture(AbstractRenderDevice *device, QList<TextureVector3D> points, const QVariant& textureId);
56
+    void drawPolygonTexture(AbstractRenderDevice *device, QList<TextureVector3D> points, const QVariant& textureId);
57 57
 
58
-    virtual void draw(AbstractRenderDevice* device) = 0;
58
+    void draw(AbstractRenderDevice* device);
59
+
60
+    virtual void onDraw(AbstractRenderDevice* device) = 0;
61
+
62
+    void update();
63
+
64
+    virtual void onUpdate();
65
+
66
+public slots:
67
+
68
+    void needUpdate();
59 69
 
60 70
 signals:
61 71
     void positionChanged();
@@ -86,6 +96,10 @@ private:
86 96
 
87 97
     QColor _color;
88 98
 
99
+    bool _needUpdate;
100
+
101
+    Matrix3x3 _tranformation;
102
+
89 103
 };
90 104
 
91 105
 #endif // UGEENTITY_H

+ 1
- 1
UGameEngine/entities/ugeentityaxes.cpp View File

@@ -5,7 +5,7 @@ UGEEntityAxes::UGEEntityAxes(QObject *parent) :
5 5
 {
6 6
 }
7 7
 
8
-void UGEEntityAxes::draw(AbstractRenderDevice *device)
8
+void UGEEntityAxes::onDraw(AbstractRenderDevice *device)
9 9
 {
10 10
     drawLine(device, ColorVector3D(Qt::red, 0.0, 0.0, 0.0), ColorVector3D(Qt::red, 1.0, 0.0, 0.0), 2.5);
11 11
     drawLine(device, ColorVector3D(Qt::green, 0.0, 0.0, 0.0), ColorVector3D(Qt::green, 0.0, 1.0, 0.0), 2.5);

+ 1
- 1
UGameEngine/entities/ugeentityaxes.h View File

@@ -9,7 +9,7 @@ class UGEEntityAxes : public UGEEntity
9 9
 public:
10 10
     explicit UGEEntityAxes(QObject *parent = 0);
11 11
 
12
-    virtual void draw(AbstractRenderDevice* device);
12
+    virtual void onDraw(AbstractRenderDevice* device);
13 13
 
14 14
 signals:
15 15
 

+ 19
- 10
UGameEngine/entities/ugeentitycube.cpp View File

@@ -4,10 +4,8 @@ UGEEntityCube::UGEEntityCube(QObject *parent)
4 4
     : UGEEntity(parent)
5 5
     , _size(1.0)
6 6
 {
7
-    updateFaces();
8
-    connect(this, SIGNAL(colorChanged()), this, SLOT(updateFaces()));
9
-    connect(this, SIGNAL(sizeChanged()), this, SLOT(updateFaces()));
10
-    connect(this, SIGNAL(textureChanged()), this, SLOT(updateFaces()));
7
+    connect(this, SIGNAL(sizeChanged()), this, SLOT(needUpdate()));
8
+    connect(this, SIGNAL(textureChanged()), this, SLOT(needUpdate()));
11 9
 }
12 10
 
13 11
 double UGEEntityCube::getSize() const
@@ -15,16 +13,18 @@ double UGEEntityCube::getSize() const
15 13
     return _size;
16 14
 }
17 15
 
18
-void UGEEntityCube::draw(AbstractRenderDevice *device)
16
+void UGEEntityCube::onDraw(AbstractRenderDevice *device)
19 17
 {
20 18
     if (!_facesColor.empty()) {
21 19
         for (int i = 0; i < _facesColor.size(); ++i) {
22
-            drawPolygon(device, _facesColor[i]);
20
+//            drawPolygon(device, _facesColor[i]);
21
+            device->drawPolygon(_facesColor[i]);
23 22
         }
24 23
     }
25 24
     else {
26 25
         for (int i = 0; i < _facesTexture.size(); ++i) {
27
-            drawPolygonTexture(device, _facesTexture[i], _textureId);
26
+//            drawPolygonTexture(device, _facesTexture[i], _textureId);
27
+            device->drawPolygonTexture(_facesTexture[i], _textureId);
28 28
         }
29 29
     }
30 30
 }
@@ -56,17 +56,19 @@ void UGEEntityCube::setTextureId(const QVariant &textureId)
56 56
     emit textureChanged(_textureId);
57 57
 }
58 58
 
59
-void UGEEntityCube::updateFaces()
59
+void UGEEntityCube::onUpdate()
60 60
 {
61
-    _facesColor.clear();
62
-    _facesTexture.clear();
63 61
     double r = _size / 2;
64 62
     if (_textureId.isNull()) {
63
+        _facesColor.clear();
65 64
         QList<ColorVector3D> points;
66 65
         points << ColorVector3D(getColor(), -r, -r, r)  << ColorVector3D(getColor(), -r, r, r)
67 66
                << ColorVector3D(getColor(), r, r, r)    << ColorVector3D(getColor(), r, -r, r)
68 67
                << ColorVector3D(getColor(), -r, -r, -r) << ColorVector3D(getColor(), -r, r, -r)
69 68
                << ColorVector3D(getColor(), r, r, -r)   << ColorVector3D(getColor(), r, -r, -r);
69
+        for (int i = 0; i < points.size(); ++i) {
70
+            points[i] = getRealPoint(points[i]);
71
+        }
70 72
         _facesColor.append(QList<ColorVector3D>() << points[3] << points[2] << points[1] << points[0]);
71 73
         _facesColor.append(QList<ColorVector3D>() << points[2] << points[3] << points[7] << points[6]);
72 74
         _facesColor.append(QList<ColorVector3D>() << points[6] << points[7] << points[4] << points[5]);
@@ -75,6 +77,7 @@ void UGEEntityCube::updateFaces()
75 77
         _facesColor.append(QList<ColorVector3D>() << points[4] << points[7] << points[3] << points[0]);
76 78
     }
77 79
     else {
80
+        _facesTexture.clear();
78 81
         _facesTexture.append(QList<TextureVector3D>() << TextureVector3D(Vector2D(0.25, 0.50), getColor(), r, -r, r)
79 82
                              << TextureVector3D(Vector2D(0.25, 0.25), getColor(), r, r, r)
80 83
                              << TextureVector3D(Vector2D(0.00, 0.25), getColor(), -r, r, r)
@@ -99,5 +102,11 @@ void UGEEntityCube::updateFaces()
99 102
                              << TextureVector3D(Vector2D(0.50, 0.50), getColor(), r, -r, -r)
100 103
                              << TextureVector3D(Vector2D(0.25, 0.5), getColor(), r, -r, r)
101 104
                              << TextureVector3D(Vector2D(0.25, 0.75), getColor(), -r, -r, r));
105
+        for (int i = 0; i < _facesTexture.size(); ++i) {
106
+            QList<TextureVector3D>& face = _facesTexture[i];
107
+            for (int j = 0; j < face.size(); ++j) {
108
+                face[j] = getRealPoint(face[j]);
109
+            }
110
+        }
102 111
     }
103 112
 }

+ 2
- 4
UGameEngine/entities/ugeentitycube.h View File

@@ -13,7 +13,8 @@ public:
13 13
 
14 14
     QVariant getTextureId() const;
15 15
 
16
-    virtual void draw(AbstractRenderDevice* device);
16
+    virtual void onDraw(AbstractRenderDevice* device);
17
+    void onUpdate();
17 18
 
18 19
 signals:
19 20
     void sizeChanged();
@@ -28,9 +29,6 @@ public slots:
28 29
 
29 30
     void setTextureId(const QVariant &textureId);
30 31
 
31
-private slots:
32
-    void updateFaces();
33
-
34 32
 private:
35 33
     double _size;
36 34
 

+ 1
- 1
UGameEngine/entities/ugeentitywavefrontobj.cpp View File

@@ -6,7 +6,7 @@ UGEEntityWaveFrontObj::UGEEntityWaveFrontObj(WaveFrontObj *obj, QObject *parent)
6 6
 {
7 7
 }
8 8
 
9
-void UGEEntityWaveFrontObj::draw(AbstractRenderDevice *device)
9
+void UGEEntityWaveFrontObj::onDraw(AbstractRenderDevice *device)
10 10
 {
11 11
     QList<QList<WaveFrontObjFaceVertex> > faces = _obj->getFaces();
12 12
     QList<Vector3D> vertexes = _obj->getVertexes();

+ 1
- 1
UGameEngine/entities/ugeentitywavefrontobj.h View File

@@ -10,7 +10,7 @@ class UGEEntityWaveFrontObj : public UGEEntity
10 10
 public:
11 11
     explicit UGEEntityWaveFrontObj(WaveFrontObj* obj, QObject *parent = 0);
12 12
 
13
-    virtual void draw(AbstractRenderDevice* device);
13
+    virtual void onDraw(AbstractRenderDevice* device);
14 14
 
15 15
 signals:
16 16
 

+ 1
- 1
UGameEngine/utils/texturevector3d.cpp View File

@@ -46,7 +46,7 @@ TextureVector3D::~TextureVector3D()
46 46
 {
47 47
 }
48 48
 
49
-Vector2D TextureVector3D::getTextureCoord() const
49
+const Vector2D &TextureVector3D::getTextureCoord() const
50 50
 {
51 51
     return _textureCoord;
52 52
 }

+ 1
- 1
UGameEngine/utils/texturevector3d.h View File

@@ -16,7 +16,7 @@ public:
16 16
     TextureVector3D(const TextureVector3D& other);
17 17
     virtual ~TextureVector3D();
18 18
 
19
-    Vector2D getTextureCoord() const;
19
+    const Vector2D& getTextureCoord() const;
20 20
     void setTextureCoord(const Vector2D &textureCoord);
21 21
 
22 22
 private:

Loading…
Cancel
Save