diff --git a/renders/rename_png_to_bmp.py b/renders/rename_png_to_bmp.py
index a97bea928afa419b81584e7ce36e1e2deb1149a6..617b1925e626bb38533643f88353bd1b76f96b2f 100755
--- a/renders/rename_png_to_bmp.py
+++ b/renders/rename_png_to_bmp.py
@@ -11,5 +11,5 @@ for path in pathlib.Path(".").iterdir():
         old_extension = path.suffix
         directory = path.parent
         new_name = old_name + ".bmp"
-        
+
         path.rename(pathlib.Path(directory, new_name))
diff --git a/src/geometries/Geometry.h b/src/geometries/Geometry.h
index 7ff995b01c5740a9b012ebdaccf1b704c64ca3cf..be4a452b7f07c2d7aa7e708d202225785b3971bb 100644
--- a/src/geometries/Geometry.h
+++ b/src/geometries/Geometry.h
@@ -16,7 +16,7 @@ public:
 
     virtual void Draw() = 0;
 
-    virtual VertexData GetVertexDataByUV(float u, float v) {throw std::bad_exception();};
+    virtual VertexData GetVertexDataByUV(float u, float v) { throw std::bad_exception(); };
 
     ~Geometry();
 };
diff --git a/src/geometries/ObjGeometry.cpp b/src/geometries/ObjGeometry.cpp
index 0ca8111565bfc0777f779c78529d0f361823aa28..c48fbe30c641f014072cc4fe81da5d27c195b3c4 100644
--- a/src/geometries/ObjGeometry.cpp
+++ b/src/geometries/ObjGeometry.cpp
@@ -1,5 +1,24 @@
-//
-// Created by bobarna on 2020. 11. 29..
-//
-
 #include "ObjGeometry.h"
+
+ObjGeometry::ObjGeometry(const std::string &objPath) :
+        Geometry(),
+        objReader(objPath, vtxData) {
+    Initialize();
+}
+
+void ObjGeometry::Initialize() {
+    glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData)*vtxData.size(), &vtxData[0], GL_STATIC_DRAW);
+    // Enable the vertex attribute arrays
+    glEnableVertexAttribArray(0);  // attribute array 0 = POSITION
+    glEnableVertexAttribArray(1);  // attribute array 1 = NORMAL
+    glEnableVertexAttribArray(2);  // attribute array 2 = TEXCOORD0
+    // attribute array, components/attribute, component type, normalize?, stride, offset
+    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void *) offsetof(VertexData, position));
+    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void *) offsetof(VertexData, normal));
+    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void *) offsetof(VertexData, texcoord));
+}
+
+void ObjGeometry::Draw() {
+    glBindVertexArray(vao);
+    glDrawArrays(GL_TRIANGLES, 0, vtxData.size());
+}
\ No newline at end of file
diff --git a/src/geometries/ObjGeometry.h b/src/geometries/ObjGeometry.h
index e65024762d860c27792eb42d24af632651025e9d..c34b803f5508c2e3c06ac9a34db201e01672b0f3 100644
--- a/src/geometries/ObjGeometry.h
+++ b/src/geometries/ObjGeometry.h
@@ -2,8 +2,20 @@
 #define BRAVE2_OBJGEOMETRY_H
 
 
-class ObjGeometry {
+#include "../utils/math.h"
+#include "../utils/OBJReader.h"
+#include "../objects/Object.h"
 
+class ObjGeometry : public Geometry {
+    std::string objPath;
+    OBJReader objReader;
+public:
+    //TODO read every data from OBJ file
+    ObjGeometry(const std::string &objPath);
+
+    void Initialize();
+
+    void Draw() override;
 };
 
 
diff --git a/src/geometries/PBDSimulation.cpp b/src/geometries/PBDSimulation.cpp
index 8e6dd78d0a53cdb24cc31cfa6448a05121eb4304..1ce44f6bac5e2ad50ca2977e73fd1f9bef3ab392 100644
--- a/src/geometries/PBDSimulation.cpp
+++ b/src/geometries/PBDSimulation.cpp
@@ -33,7 +33,7 @@ void PBDSimulation::propagateHead() {
         float currU = dis(gen);
         float currV = dis(gen);
         VertexData currPos = head->GetVertexDataByUV(currU, currV);
-        while(currPos.normal.y < .0f){
+        while (currPos.normal.y < .0f) {
             currU = dis(gen);
             currV = dis(gen);
             currPos = head->GetVertexDataByUV(currU, currV);
@@ -44,7 +44,7 @@ void PBDSimulation::propagateHead() {
 #endif
 
         vec3 color = util::getRandomRGBColorAround(vec3(222.0f, 101.0f, 32.0f), vec3(40.0f, 20.0f, 20.0f));
-        strands.emplace_back(CreateStrand(nrSegments, lSeg, currPos.position * vec3(1,-1,1), color));
+        strands.emplace_back(CreateStrand(nrSegments, lSeg, currPos.position * vec3(1, -1, 1), color));
     }
 }
 
diff --git a/src/geometries/VertexData.cpp b/src/geometries/VertexData.cpp
index da8b2097c8b336d35e0d80b937a14523462abb15..9f8afeca148dc6b78385aa6e06f5f087ffe40075 100644
--- a/src/geometries/VertexData.cpp
+++ b/src/geometries/VertexData.cpp
@@ -3,3 +3,11 @@
 std::ostream &operator<<(std::ostream &out, const VertexData &vD) {
     return out << vD.texcoord << " -> P: " << vD.position << " N: " << vD.normal;
 }
+
+VertexData::VertexData(vec3 p, vec3 n, vec2 uv) :
+        position(p), normal(n), texcoord(uv) {
+
+}
+
+VertexData::VertexData() {
+}
diff --git a/src/geometries/VertexData.h b/src/geometries/VertexData.h
index 8bdfc9fed2d296f046ffeb5718df79c22ad1b578..e808702321d5527e2d4a57c62979550a7ba9e251 100644
--- a/src/geometries/VertexData.h
+++ b/src/geometries/VertexData.h
@@ -6,6 +6,8 @@
 struct VertexData {
     vec3 position, normal;
     vec2 texcoord;
+    VertexData();
+    VertexData(vec3 p, vec3 n, vec2 uv);
 };
 
 std::ostream &operator<<(std::ostream &out, const VertexData &vD);
diff --git a/src/objects/HeadObject.h b/src/objects/HeadObject.h
index e5f901b777b89f38b38a6d1f200524469e905a2b..f5a22ac3ff8549cf0b9051893d75b3a9e0f1bfef 100644
--- a/src/objects/HeadObject.h
+++ b/src/objects/HeadObject.h
@@ -6,6 +6,7 @@
 class HeadObject : public Object {
 public:
     HeadObject(Shader *_shader, Geometry *_geometry, Material *_material, Texture *_texture);
+
     VertexData GetVertexDataByUV(float u, float v);
 };
 
diff --git a/src/rendering/Camera.cpp b/src/rendering/Camera.cpp
index 9c3677d926cf503e0320fddf9e56567a87857f51..ea2f1ce0ff799b16882f3e8ff438298cc1624070 100644
--- a/src/rendering/Camera.cpp
+++ b/src/rendering/Camera.cpp
@@ -31,7 +31,7 @@ mat4 Camera::P() const {
 }
 
 void Camera::Translate(vec3 dir) {
-    vec3 forward = dir * vec3(0,0,1.f);
+    vec3 forward = dir * vec3(0, 0, 1.f);
 
     wEye = normalize(wEye + dir) * length(wEye) + forward;
 }
diff --git a/src/rendering/Scene.cpp b/src/rendering/Scene.cpp
index d09d161bae58b13abe297fc06d66be39f4690776..d6d5bca004bf820871f0ca9560dd6c76a0db1f27 100644
--- a/src/rendering/Scene.cpp
+++ b/src/rendering/Scene.cpp
@@ -3,6 +3,7 @@
 #include "../geometries/ParamSurface.h"
 #include "shaders/PhongShader.h"
 #include "../utils/OBJReader.h"
+#include "../geometries/ObjGeometry.h"
 
 Scene::Scene(int w, int h) : camera(vec3(0, -.15f, .5), // Camera position (wEye)
                                     vec3(0, -.15f, 0), // wLookat
@@ -11,19 +12,11 @@ Scene::Scene(int w, int h) : camera(vec3(0, -.15f, .5), // Camera position (wEye
 }
 
 
-
 void Scene::Build() {
     size_t nrSims = 200;
     size_t nrSegments = 30;
     float lSeg = 0.025f;
 
-    std::vector<vec3> objVertices;
-    std::vector<vec2> objUvs;
-    std::vector<vec3> objNormals;
-    std::string objPath = "data/sphere.obj";
-    OBJReader objReader(objPath, objVertices, objUvs, objNormals);
-
-
 
     Shader *basicShader = new BasicShader();
     basicShader->Bind(camera.getState());
@@ -42,11 +35,19 @@ void Scene::Build() {
     auto headObject = new HeadObject(phongShader, sphere, headMaterial, headTexture);
 
     headObject->Scale(vec3(.15, .1, .1));
-    objects.push_back(headObject);
+//    objects.push_back(headObject);
 
     auto PBDSim = new PBDSimulation(headObject, nrSims, nrSegments, lSeg);
     auto simulationObject = new HairSimObject(headObject, basicShader, PBDSim);
-    sims.push_back(simulationObject);
+//    sims.push_back(simulationObject);
+
+    auto testObject =
+            new Object(phongShader,
+                       new ObjGeometry("../data/test.obj"),
+                       headMaterial,
+                       headTexture);
+
+    objects.push_back(testObject);
 
     // Lights
     lights.resize(3);
diff --git a/src/utils/OBJReader.cpp b/src/utils/OBJReader.cpp
index 680ea6fab0bd81a1a3be46da2c355ff16ec4abbf..e102360509ab30fdd240ceca0a1a9a52453c9e26 100644
--- a/src/utils/OBJReader.cpp
+++ b/src/utils/OBJReader.cpp
@@ -1,7 +1,6 @@
 #include "OBJReader.h"
 
-OBJReader::OBJReader(const std::string &filePath, std::vector<vec3> &out_vertices, std::vector<vec2> &out_uvs,
-                     std::vector<vec3> &out_normals) : is(filePath) {
+OBJReader::OBJReader(const std::string &filePath, std::vector<VertexData> &out_vtxData) : is(filePath) {
 
     if (!is) {
         std::cerr << "Can't open OBJ file: " << filePath << std::endl;
@@ -9,17 +8,12 @@ OBJReader::OBJReader(const std::string &filePath, std::vector<vec3> &out_vertice
     }
 
     readData();
-    if (is.fail())
-        std::cerr << filePath << std::endl;
 
+    for (auto curr: out_vtxData)
+        std::cout << curr << std::endl;
     for (unsigned int i : vertexIndices)
-        out_vertices.push_back(temp_vertices[i - 1]);
+        out_vtxData.emplace_back(temp_vertices[i - 1], temp_normals[i - 1], temp_uvs[i - 1]);
 
-    for (unsigned int i : uvIndices)
-        out_uvs.push_back(temp_uvs[i - 1]);
-
-    for (unsigned int i : normalIndices)
-        out_normals.push_back(temp_normals[i - 1]);
 
 }
 
@@ -48,7 +42,6 @@ void OBJReader::readData() {
             std::getline(is, lineType);
             // output rest of the line
             std::cerr << " " << lineType << std::endl;
-            is.setstate(std::iostream::failbit);
         }
     }
 }
diff --git a/src/utils/OBJReader.h b/src/utils/OBJReader.h
index 702774300cc42d2207f92b2170938331291db5a9..73b66eac0135c4de1ae82a6d2a24195a13d2ea4f 100644
--- a/src/utils/OBJReader.h
+++ b/src/utils/OBJReader.h
@@ -5,6 +5,7 @@
 #include <vector>
 #include <fstream>
 #include "math.h"
+#include "../geometries/VertexData.h"
 
 class OBJReader {
     std::vector<unsigned int> vertexIndices, uvIndices, normalIndices;
@@ -15,8 +16,7 @@ class OBJReader {
     std::ifstream is;
 
 public:
-    OBJReader(const std::string &filePath, std::vector<vec3> &vertices, std::vector<vec2> &uvs,
-              std::vector<vec3> &normals);
+    OBJReader(const std::string &filePath, std::vector<VertexData>& out_vtxData);
 
     void readData();