Browse Source

fixed memory leaks; begin mtl parser; begin obj material support

develop
Robin Thoni 7 years ago
parent
commit
77b7440b8e

+ 6
- 6
TheGame/openglrenderdevice.cpp View File

@@ -44,16 +44,16 @@ void OpenGLRenderDevice::loadTexture(const QVariant &id, const QImage &texture)
44 44
     OpenGLTextureData data;
45 45
     data.id = 0;
46 46
     data.image = texture;
47
-    data.rawData = new char[texture.width() * texture.height() * 4];
47
+    char rawData[texture.width() * texture.height() * 4];
48 48
 
49 49
     for (int y = 0; y < texture.height(); ++y) {
50 50
         for(int x = 0; x < texture.width(); ++x) {
51 51
             int p = (y * texture.height() * 4) + x * 4;
52 52
             QColor px = QColor(texture.pixel(x, y));
53
-            data.rawData[p] = px.red();
54
-            data.rawData[p + 1] = px.green();
55
-            data.rawData[p + 2] = px.blue();
56
-            data.rawData[p + 3] = 255;
53
+            rawData[p] = px.red();
54
+            rawData[p + 1] = px.green();
55
+            rawData[p + 2] = px.blue();
56
+            rawData[p + 3] = 255;
57 57
         }
58 58
     }
59 59
 
@@ -61,7 +61,7 @@ void OpenGLRenderDevice::loadTexture(const QVariant &id, const QImage &texture)
61 61
     glGenTextures(1, &data.id);
62 62
     glBindTexture(GL_TEXTURE_2D, data.id);
63 63
 
64
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width(), texture.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data.rawData);
64
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width(), texture.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, rawData);
65 65
 
66 66
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
67 67
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

+ 0
- 1
TheGame/openglrenderdevice.h View File

@@ -7,7 +7,6 @@ struct OpenGLTextureData
7 7
 {
8 8
     unsigned id;
9 9
     QImage image;
10
-    char* rawData;
11 10
 };
12 11
 
13 12
 class OpenGLRenderDevice : public AbstractRenderDevice

+ 7
- 8
TheGame/renderwidget.cpp View File

@@ -12,29 +12,28 @@ RenderWidget::RenderWidget(QWidget *parent) :
12 12
   , _radius(5.0)
13 13
   , _phi(45.0)
14 14
   , _theta(45.0)
15
-  , _angle(0.0)
16 15
 {
16
+    setMouseTracking(true);
17
+    setFocusPolicy(Qt::StrongFocus);
18
+
17 19
     _device = new OpenGLRenderDevice(this);
18 20
     _engine = new UGameEngine(_device);
19 21
 
22
+    _engine->addEntity(new UGEEntityAxes(_engine));
23
+
20 24
     UGEEntityCube* cube = new UGEEntityCube(_engine);
21 25
     cube->setTextureId("test");
22 26
     cube->rotate(Vector3D(0.0, 45.0, 45.0));
23 27
     cube->move(Vector3D(0, 1, 0));
24 28
     cube->setScale(Vector3D(1.0, 2.0, 1.0));
25
-//    cube->hide();
29
+    cube->hide();
26 30
     _engine->addEntity(cube);
27
-    _engine->addEntity(new UGEEntityAxes(_engine));
28
-    setMouseTracking(true);
29
-    setFocusPolicy(Qt::StrongFocus);
30 31
 
31 32
     WaveFrontObj* wavefrontObj = new WaveFrontObj(this);
32 33
     wavefrontObj->openFile("/home/robin/Downloads/enterprise/obj/USSEnterprise.obj");
33
-
34 34
     UGEEntityWaveFrontObj* obj = new UGEEntityWaveFrontObj(wavefrontObj, this);
35 35
     _engine->addEntity(obj);
36
-    obj->hide();
37
-
36
+//    obj->hide();
38 37
     _entity = cube;
39 38
 //    animate();
40 39
 }

+ 0
- 2
TheGame/renderwidget.h View File

@@ -48,8 +48,6 @@ private:
48 48
 
49 49
     Vector3D pos;
50 50
 
51
-    double _angle;
52
-
53 51
     UGEEntity* _entity;
54 52
 };
55 53
 

+ 4
- 2
UGameEngine/UGameEngine.pro View File

@@ -51,8 +51,10 @@ HEADERS += engine/ugameengine.h\
51 51
 
52 52
 LIBS += -lfl -ly
53 53
 
54
-FLEXSOURCES = utils/lexer-wavefront-obj.l
55
-BISONSOURCES = utils/parser-wavefront-obj.y
54
+FLEXSOURCES = utils/lexer-wavefront-obj.l \
55
+    utils/lexer-wavefront-mtl.l
56
+BISONSOURCES = utils/parser-wavefront-obj.y \
57
+    utils/parser-wavefront-mtl.y
56 58
 
57 59
 OTHER_FILES +=  \
58 60
     $$FLEXSOURCES \

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

@@ -8,13 +8,13 @@ UGEEntityWaveFrontObj::UGEEntityWaveFrontObj(WaveFrontObj *obj, QObject *parent)
8 8
 
9 9
 void UGEEntityWaveFrontObj::draw(AbstractRenderDevice *device)
10 10
 {
11
-    QList<QList<int> > faces = _obj->getFaces();
11
+    QList<QList<WaveFrontObjFaceVertex> > faces = _obj->getFaces();
12 12
     QList<Vector3D> vertexes = _obj->getVertexes();
13 13
     for (int i = 0; i < faces.size(); ++i) {
14
-        QList<int> face = faces[i];
14
+        QList<WaveFrontObjFaceVertex> face = faces[i];
15 15
         QList<ColorVector3D> poly;
16 16
         for (int j = 0; j < face.size(); ++j) {
17
-            poly.append(ColorVector3D(Qt::black, vertexes[face[j] - 1]));
17
+            poly.append(ColorVector3D(Qt::black, vertexes[face[j].vertexPosition - 1]));
18 18
         }
19 19
         drawPolygon(device, poly);
20 20
     }

+ 69
- 0
UGameEngine/utils/lexer-wavefront-mtl.l View File

@@ -0,0 +1,69 @@
1
+%{
2
+// In this section we can add all needed headers, from Qt or another libraries.
3
+//#include <QtScript>
4
+#include <QVariant>
5
+#include <QDebug>
6
+
7
+// Also, we must add the parser's header where are defined the tokens.
8
+#include "utils/vector3d.h"
9
+#include "utils/wavefrontobj.h"
10
+#include "parser-wavefront-mtl.h"
11
+
12
+#define TOKEN(type) \
13
+  TOK_WFMTL_##type
14
+
15
+%}
16
+
17
+%option noyywrap
18
+%option nounput
19
+%option prefix="wavefront_mtl"
20
+
21
+%%
22
+
23
+ /* Whitespace */
24
+[ \t]+       {                           }
25
+
26
+ /* Newline */
27
+\n|\n\r      { ++wavefront_mtllineno;    }
28
+
29
+ /* Comment */
30
+"#"[^\n\r]*  {                        }
31
+
32
+ /* Material library */
33
+"mtllib"     { return TOKEN(MTLLIB);  }
34
+
35
+ /* Use material */
36
+"usemtl"     { return TOKEN(USEMTL);  }
37
+
38
+ /* Named object */
39
+"o"     { return TOKEN(O);  }
40
+
41
+ /* Vertex */
42
+"v"     { return TOKEN(V);  }
43
+
44
+ /* Texture coordinate */
45
+"vt"     { return TOKEN(VT);  }
46
+
47
+ /* Vertex normal */
48
+"vn"     { return TOKEN(VN);  }
49
+
50
+ /* Parameter space vertices */
51
+"vp"     { return TOKEN(VP);  }
52
+
53
+ /* Face */
54
+"f"     { return TOKEN(F);  }
55
+
56
+ /* Smooth */
57
+"s"     { return TOKEN(S);  }
58
+
59
+ /* Slash */
60
+"/"     { return TOKEN(SLASH);  }
61
+
62
+ /* Number */
63
+-?[0-9]+(.[0-9]+)?     { wavefront_mtllval.number=atof(yytext); return TOKEN(NUMBER); }
64
+
65
+ /* String */
66
+[^\n\r\t ]+  { wavefront_mtllval.string = strcpy((char*)malloc(strlen(yytext) + 1), yytext); return TOKEN(STRING);  }
67
+
68
+
69
+%%

+ 4
- 2
UGameEngine/utils/lexer-wavefront-obj.l View File

@@ -6,14 +6,16 @@
6 6
 
7 7
 // Also, we must add the parser's header where are defined the tokens.
8 8
 #include "utils/vector3d.h"
9
+#include "utils/wavefrontobj.h"
9 10
 #include "parser-wavefront-obj.h"
10 11
 
11 12
 #define TOKEN(type) \
12
-  TOK_##type
13
+  TOK_WFOBJ_##type
13 14
 
14 15
 %}
15 16
 
16 17
 %option noyywrap
18
+%option nounput
17 19
 %option prefix="wavefront_obj"
18 20
 
19 21
 %%
@@ -61,7 +63,7 @@
61 63
 -?[0-9]+(.[0-9]+)?     { wavefront_objlval.number=atof(yytext); return TOKEN(NUMBER); }
62 64
 
63 65
  /* String */
64
-[^\n\r\t ]+  { wavefront_objlval.string = strcpy((char*)malloc(strlen(yytext)), yytext); return TOKEN(STRING);  }
66
+[^\n\r\t ]+  { wavefront_objlval.string = strcpy((char*)malloc(strlen(yytext) + 1), yytext); return TOKEN(STRING);  }
65 67
 
66 68
 
67 69
 %%

+ 114
- 0
UGameEngine/utils/parser-wavefront-mtl.y View File

@@ -0,0 +1,114 @@
1
+%{
2
+#include <QVariant>
3
+#include <QDebug>
4
+#include "utils/vector3d.h"
5
+#include "utils/wavefrontobj.h"
6
+#include "lexer-wavefront-mtl.h"
7
+
8
+
9
+
10
+// yylex is a function generated by Flex and we must tell to Bison that it is
11
+// defined in other place.
12
+extern int wavefront_mtllex(void);
13
+
14
+// Bison uses the yyerror function for informing us when a parsing error has
15
+// occurred.
16
+void wavefront_mtlerror(WaveFrontObj* data, const char *s);
17
+%}
18
+
19
+%define api.prefix {wavefront_mtl}
20
+%define api.token.prefix {TOK_WFMTL_}
21
+
22
+%parse-param {struct WaveFrontObj* wavefrontData}
23
+
24
+// Here we define our custom variable types.
25
+// Custom types must be of fixed size.
26
+%union {
27
+    double number;
28
+    int integer;
29
+    char* string;
30
+    Vector3D* vector3d;
31
+    QList<int>* integers;
32
+    WaveFrontObjFaceVertex faceVertex;
33
+    QList<WaveFrontObjFaceVertex>* face;
34
+}
35
+
36
+// Define the terminal expression types.
37
+%token <number> NUMBER
38
+%token <string> STRING
39
+%token SLASH
40
+%token MTLLIB
41
+%token USEMTL
42
+%token O
43
+%token V
44
+%token VT
45
+%token VN
46
+%token VP
47
+%token F
48
+%token S
49
+
50
+%destructor { free($$); } <string>
51
+%destructor { delete $$; } <vector3d>
52
+%destructor { delete $$; } <integers>
53
+%destructor { delete $$; } <face>
54
+
55
+// Define the non-terminal expression types.
56
+%type <vector3d> vertex
57
+%type <faceVertex>   face_vertex
58
+%type <face>  face_vertex_list
59
+%type <face>  face
60
+
61
+
62
+%%
63
+
64
+wavefront_mtl: stmt_list {};
65
+
66
+
67
+stmt_list: {}
68
+            | stmt_list stmt {};
69
+
70
+stmt: mtllib {}
71
+            | usemtl {}
72
+            | named_object {}
73
+            | vertex { wavefrontData->addVertex(*$1); delete $1; }
74
+            | texture_coordinate {}
75
+            | vertex_normal {}
76
+            | vertex_space {}
77
+            | face { wavefrontData->addFace(*$1); delete $1; }
78
+            | smooth {};
79
+
80
+mtllib: MTLLIB STRING { free($2); };
81
+
82
+usemtl: USEMTL STRING { free($2); };
83
+
84
+named_object: O STRING { free($2); };
85
+
86
+vertex: V NUMBER NUMBER NUMBER { $$ = new Vector3D($2, $3, $4); }
87
+            | V NUMBER NUMBER NUMBER NUMBER { $$ = new Vector3D($2, $3, $4); };
88
+
89
+texture_coordinate: VT NUMBER NUMBER {}
90
+            | VT NUMBER NUMBER NUMBER {};
91
+
92
+vertex_normal: VN NUMBER NUMBER NUMBER {};
93
+
94
+vertex_space: VP NUMBER NUMBER NUMBER {};
95
+
96
+face: F face_vertex_list { $$ = $2; };
97
+
98
+face_vertex_list: { $$ = new QList<WaveFrontObjFaceVertex>(); }
99
+            | face_vertex_list face_vertex { $1->append($2); $$ = $1;};
100
+
101
+face_vertex: NUMBER { $$.vertexPosition = $1; }
102
+            | NUMBER SLASH NUMBER { $$.vertexPosition = $1; $$.textureCoordPosition = $3; }
103
+            | NUMBER SLASH NUMBER SLASH NUMBER { $$.vertexPosition = $1; $$.textureCoordPosition = $3; }
104
+            | NUMBER SLASH SLASH NUMBER { $$.vertexPosition = $1; };
105
+
106
+smooth: S NUMBER {}
107
+            | S STRING { free($2); };
108
+
109
+%%
110
+
111
+void wavefront_mtlerror(WaveFrontObj* data, const char *s)
112
+{
113
+    data->setError("Parse error: " + QString(s) + " at line " + QString::number(wavefront_mtllineno) + " at " + QString(wavefront_mtltext));
114
+}

+ 16
- 14
UGameEngine/utils/parser-wavefront-obj.y View File

@@ -1,5 +1,4 @@
1 1
 %{
2
-/*#include <QtGui>*/
3 2
 #include <QVariant>
4 3
 #include <QDebug>
5 4
 #include "utils/vector3d.h"
@@ -18,7 +17,7 @@ void wavefront_objerror(WaveFrontObj* data, const char *s);
18 17
 %}
19 18
 
20 19
 %define api.prefix {wavefront_obj}
21
-%define api.token.prefix {TOK_}
20
+%define api.token.prefix {TOK_WFOBJ_}
22 21
 
23 22
 %parse-param {struct WaveFrontObj* wavefrontData}
24 23
 
@@ -30,6 +29,8 @@ void wavefront_objerror(WaveFrontObj* data, const char *s);
30 29
     char* string;
31 30
     Vector3D* vector3d;
32 31
     QList<int>* integers;
32
+    WaveFrontObjFaceVertex faceVertex;
33
+    QList<WaveFrontObjFaceVertex>* face;
33 34
 }
34 35
 
35 36
 // Define the terminal expression types.
@@ -49,12 +50,13 @@ void wavefront_objerror(WaveFrontObj* data, const char *s);
49 50
 %destructor { free($$); } <string>
50 51
 %destructor { delete $$; } <vector3d>
51 52
 %destructor { delete $$; } <integers>
53
+%destructor { delete $$; } <face>
52 54
 
53 55
 // Define the non-terminal expression types.
54 56
 %type <vector3d> vertex
55
-%type <integer>   face_vertex
56
-%type <integers>  face_vertex_list
57
-%type <integers>  face
57
+%type <faceVertex>   face_vertex
58
+%type <face>  face_vertex_list
59
+%type <face>  face
58 60
 
59 61
 
60 62
 %%
@@ -75,11 +77,11 @@ stmt: mtllib {}
75 77
             | face { wavefrontData->addFace(*$1); delete $1; }
76 78
             | smooth {};
77 79
 
78
-mtllib: MTLLIB STRING {};
80
+mtllib: MTLLIB STRING { free($2); };
79 81
 
80
-usemtl: USEMTL STRING {};
82
+usemtl: USEMTL STRING { free($2); };
81 83
 
82
-named_object: O STRING {};
84
+named_object: O STRING { free($2); };
83 85
 
84 86
 vertex: V NUMBER NUMBER NUMBER { $$ = new Vector3D($2, $3, $4); }
85 87
             | V NUMBER NUMBER NUMBER NUMBER { $$ = new Vector3D($2, $3, $4); };
@@ -93,16 +95,16 @@ vertex_space: VP NUMBER NUMBER NUMBER {};
93 95
 
94 96
 face: F face_vertex_list { $$ = $2; };
95 97
 
96
-face_vertex_list: { $$ = new QList<int>(); }
98
+face_vertex_list: { $$ = new QList<WaveFrontObjFaceVertex>(); }
97 99
             | face_vertex_list face_vertex { $1->append($2); $$ = $1;};
98 100
 
99
-face_vertex: NUMBER { $$ = $1; }
100
-            | NUMBER SLASH NUMBER { $$ = $1; }
101
-            | NUMBER SLASH NUMBER SLASH NUMBER { $$ = $1; }
102
-            | NUMBER SLASH SLASH NUMBER { $$ = $1; };
101
+face_vertex: NUMBER { $$.vertexPosition = $1; }
102
+            | NUMBER SLASH NUMBER { $$.vertexPosition = $1; $$.textureCoordPosition = $3; }
103
+            | NUMBER SLASH NUMBER SLASH NUMBER { $$.vertexPosition = $1; $$.textureCoordPosition = $3; }
104
+            | NUMBER SLASH SLASH NUMBER { $$.vertexPosition = $1; };
103 105
 
104 106
 smooth: S NUMBER {}
105
-            | S STRING {};
107
+            | S STRING { free($2); };
106 108
 
107 109
 %%
108 110
 

+ 6
- 5
UGameEngine/utils/wavefrontobj.cpp View File

@@ -3,13 +3,15 @@
3 3
 #include <QDebug>
4 4
 #include "lexer-wavefront-obj.h"
5 5
 #include "parser-wavefront-obj.h"
6
+#include "lexer-wavefront-mtl.h"
7
+#include "parser-wavefront-mtl.h"
6 8
 
7 9
 WaveFrontObj::WaveFrontObj(QObject *parent) :
8 10
     QObject(parent)
9 11
 {
10 12
 }
11 13
 
12
-QList<QList<int> > WaveFrontObj::getFaces() const
14
+QList<QList<WaveFrontObjFaceVertex> > WaveFrontObj::getFaces() const
13 15
 {
14 16
     return _faces;
15 17
 }
@@ -42,15 +44,14 @@ bool WaveFrontObj::load(QIODevice &device)
42 44
     wavefront_obj_delete_buffer(bufferState);
43 45
     if (res) {
44 46
         qDebug() << _error;
47
+        return false;
45 48
     }
46 49
     else {
47
-        qDebug() << "faces:" << _faces.size() << "vertexes" << _vertexes.size();
50
+        return true;
48 51
     }
49
-
50
-    return res == 0;
51 52
 }
52 53
 
53
-void WaveFrontObj::addFace(QList<int> face)
54
+void WaveFrontObj::addFace(QList<WaveFrontObjFaceVertex> face)
54 55
 {
55 56
     _faces.append(face);
56 57
 }

+ 9
- 3
UGameEngine/utils/wavefrontobj.h View File

@@ -5,13 +5,19 @@
5 5
 #include <QIODevice>
6 6
 #include "utils/vector3d.h"
7 7
 
8
+struct WaveFrontObjFaceVertex
9
+{
10
+    int vertexPosition;
11
+    int textureCoordPosition;
12
+};
13
+
8 14
 class WaveFrontObj : public QObject
9 15
 {
10 16
     Q_OBJECT
11 17
 public:
12 18
     explicit WaveFrontObj(QObject *parent = 0);
13 19
 
14
-    QList<QList<int> > getFaces() const;
20
+    QList<QList<WaveFrontObjFaceVertex> > getFaces() const;
15 21
     QList<Vector3D> getVertexes() const;
16 22
 
17 23
 signals:
@@ -19,14 +25,14 @@ signals:
19 25
 public slots:
20 26
     bool openFile(const QString& filename);
21 27
     bool load(QIODevice& device);
22
-    void addFace(QList<int> face);
28
+    void addFace(QList<WaveFrontObjFaceVertex> face);
23 29
     void addVertex(const Vector3D& vertex);
24 30
     void setError(const QString& error);
25 31
 
26 32
 private:
27 33
     QString _error;
28 34
     QList<Vector3D> _vertexes;
29
-    QList<QList<int> > _faces;
35
+    QList<QList<WaveFrontObjFaceVertex> > _faces;
30 36
 
31 37
 };
32 38
 

+ 25
- 0
UGameEngine/utils/wavefrontobjfacevertex.cpp View File

@@ -0,0 +1,25 @@
1
+#include "wavefrontobjfacevertex.h"
2
+
3
+WaveFrontObjFaceVertex::WaveFrontObjFaceVertex()
4
+{
5
+}
6
+int WaveFrontObjFaceVertex::textureCoordPosition() const
7
+{
8
+    return _textureCoordPosition;
9
+}
10
+
11
+void WaveFrontObjFaceVertex::setTextureCoordPosition(int textureCoordPosition)
12
+{
13
+    _textureCoordPosition = textureCoordPosition;
14
+}
15
+int WaveFrontObjFaceVertex::vertexPosition() const
16
+{
17
+    return _vertexPosition;
18
+}
19
+
20
+void WaveFrontObjFaceVertex::setVertexPosition(int vertexPosition)
21
+{
22
+    _vertexPosition = vertexPosition;
23
+}
24
+
25
+

+ 22
- 0
UGameEngine/utils/wavefrontobjfacevertex.h View File

@@ -0,0 +1,22 @@
1
+#ifndef WAVEFRONTOBJVERTEX_H
2
+#define WAVEFRONTOBJVERTEX_H
3
+
4
+class WaveFrontObjFaceVertex
5
+{
6
+public:
7
+    WaveFrontObjFaceVertex();
8
+
9
+    int vertexPosition() const;
10
+    void setVertexPosition(int vertexPosition);
11
+
12
+    int textureCoordPosition() const;
13
+    void setTextureCoordPosition(int textureCoordPosition);
14
+
15
+private:
16
+    int _vertexPosition;
17
+
18
+    int _textureCoordPosition;
19
+
20
+};
21
+
22
+#endif // WAVEFRONTOBJVERTEX_H

Loading…
Cancel
Save