I'm working on a small 3D engine to learn more of OpenGL. I'm using Scala and lwjgl for the task.
Loading "hand-made" (all vertices, texture coordinates and indices - arrays specified by hand) models works like a charm, so I wanted to move on to loading .obj files. Turns out, it's not that easy, or, well, I'm somehow misunderstanding something.
Let's look into my parsing-method:
private def parseObj(path: String): Model =
{
val objSource: List[String] = Source.fromFile(path).getLines.toList
val positions: List[Vector4] = objSource.filter(_.startsWith("v ")).map(_.split(" ")).map(v => new Vector4(v(1).toFloat,v(2).toFloat,v(3).toFloat, 1.0f))
// val normals: List[Vector4] = objSource.filter(_.startsWith("vn ")).map(_.split(" ")).map(v => new Vector4(v(1)toFloat,v(2).toFloat, v(3).toFloat, 0.0f))
val textureCoordinates: List[Vector2] = objSource.filter(_.startsWith("vt ")).map(_.split(" ")).map(v => new Vector2(v(1).toDouble.toFloat,v(2).toDouble.toFloat))
val faces: List[(Int, Int, Int)] = objSource.filter(_.startsWith("f ")).map(_.split(" ")).flatten.filterNot(_ == "f").map(_.split("/")).map(a => ((a(0).toInt, a(1).toInt, a(2).toInt)))
val indices: List[Int] = faces.map(f => f._1-1) // Wrong?
/*
println(positions.map{p => s"v ${p.x} ${p.y} ${p.z}"}.mkString("\n"))
println(textureCoordinates.map {t => s"vt ${t.x} ${t.y}"}.mkString("\n"))
println(indices)
*/
//println(faces.length)
val vertices: List[Vertex] = for(face <- faces) yield(new Vertex(positions(face._1-1), textureCoordinates(face._2-1)))
println(vertices.mkString("\n"))
new Model(vertices.toArray, indices.toArray)
}
Now, what am I doing? An .obj-file looks like this:
v 0.000000 -1.000000 0.000000
v 0.723607 -0.447220 0.525725
v -0.276388 -0.447220 0.850649
v -0.894426 -0.447216 0.000000
v -0.276388 -0.447220 -0.850649
v 0.723607 -0.447220 -0.525725
v 0.276388 0.447220 0.850649
v -0.723607 0.447220 0.525725
v -0.723607 0.447220 -0.525725
v 0.276388 0.447220 -0.850649
v 0.894426 0.447216 0.000000
v 0.000000 1.000000 0.000000
v -0.162456 -0.850654 0.499995
v 0.425323 -0.850654 0.309011
v 0.262869 -0.525738 0.809012
v 0.850648 -0.525736 0.000000
v 0.425323 -0.850654 -0.309011
v -0.525730 -0.850652 0.000000
v -0.688189 -0.525736 0.499997
v -0.162456 -0.850654 -0.499995
v -0.688189 -0.525736 -0.499997
v 0.262869 -0.525738 -0.809012
v 0.951058 0.000000 0.309013
v 0.951058 0.000000 -0.309013
v 0.000000 0.000000 1.000000
v 0.587786 0.000000 0.809017
v -0.951058 0.000000 0.309013
v -0.587786 0.000000 0.809017
v -0.587786 0.000000 -0.809017
v -0.951058 0.000000 -0.309013
v 0.587786 0.000000 -0.809017
v 0.000000 0.000000 -1.000000
v 0.688189 0.525736 0.499997
v -0.262869 0.525738 0.809012
v -0.850648 0.525736 0.000000
v -0.262869 0.525738 -0.809012
v 0.688189 0.525736 -0.499997
v 0.162456 0.850654 0.499995
v 0.525730 0.850652 0.000000
v -0.425323 0.850654 0.309011
v -0.425323 0.850654 -0.309011
v 0.162456 0.850654 -0.499995
vt 0.534208 0.190162
vt 0.439232 0.259166
vt 0.570486 0.301814
vt 0.995860 0.190574
vt 0.999792 0.292763
vt 0.903537 0.265179
vt 0.651606 0.190162
vt 0.570486 0.078511
vt 0.439232 0.121159
vt 0.903535 0.129002
vt 0.092743 0.471488
vt 0.212444 0.449586
vt 0.158053 0.569043
vt 0.737562 0.458199
vt 0.632422 0.499661
vt 0.728679 0.579260
vt 0.408849 0.471488
vt 0.316315 0.457312
vt 0.342992 0.573818
vt 0.632005 0.463365
vt 0.528550 0.449586
vt 0.605329 0.564268
vt 0.999792 0.072423
vt 0.026885 0.573818
vt 0.847656 0.509327
vt 0.474160 0.569043
vt 0.793444 0.309553
vt 0.688302 0.255514
vt 0.784558 0.198935
vt 0.251881 0.000208
vt 0.343838 0.078511
vt 0.226439 0.078511
vt 0.028577 0.072765
vt 0.131462 0.009506
vt 0.095186 0.121159
vt 0.939981 0.570899
vt 0.847658 0.645504
vt 0.943912 0.673088
vt 0.539471 0.666598
vt 0.419770 0.688500
vt 0.517323 0.757552
vt 0.793441 0.077875
vt 0.688301 0.119336
vt 0.747790 0.000208
vt 0.307560 0.190162
vt 0.226439 0.301814
vt 0.190162 0.190162
vt 0.343838 0.301814
vt 0.251881 0.380116
vt 0.095186 0.259166
vt 0.131462 0.370818
vt 0.028577 0.307559
vt 0.000208 0.190162
vt 0.737565 0.689877
vt 0.824936 0.743021
vt 0.103663 0.688500
vt 0.223364 0.666598
vt 0.201217 0.757552
vt 0.880811 0.006181
vt 0.632005 0.680774
vt 0.316315 0.674721
vt 0.000208 0.674721
vt 0.289222 0.564268
vt 0.315898 0.680774
vt 0.943912 0.452748
vt 0.824932 0.386505
vt 0.632423 0.635839
vt 0.000208 0.457312
vt 0.315898 0.463365
vt 0.475509 0.009506
vt 0.372624 0.072765
vt 0.430997 0.380533
vt 0.687884 0.078511
vt 0.595927 0.000208
vt 0.691911 0.380533
vt 0.687884 0.301814
vt 0.595927 0.380116
vt 0.880815 0.362696
vt 0.344255 0.190162
vt 0.114890 0.380533
vt 0.475509 0.370818
vt 0.372624 0.307559
vn 0.102400 -0.943500 0.315100
vn 0.700200 -0.661700 0.268000
vn -0.268000 -0.943500 0.194700
vn -0.268000 -0.943500 -0.194700
vn 0.102400 -0.943500 -0.315100
vn 0.905000 -0.330400 0.268000
vn 0.024700 -0.330400 0.943500
vn -0.889700 -0.330400 0.315100
vn -0.574600 -0.330400 -0.748800
vn 0.534600 -0.330400 -0.777900
vn 0.802600 -0.125600 0.583100
vn -0.306600 -0.125600 0.943500
vn -0.992100 -0.125600 0.000000
vn -0.306600 -0.125600 -0.943500
vn 0.802600 -0.125600 -0.583100
vn 0.408900 0.661700 0.628400
vn -0.471300 0.661700 0.583100
vn -0.700200 0.661700 -0.268000
vn 0.038500 0.661700 -0.748800
vn 0.724000 0.661700 -0.194700
vn 0.268000 0.943500 -0.194700
vn 0.491100 0.794700 -0.356800
vn 0.408900 0.661700 -0.628400
vn -0.102400 0.943500 -0.315100
vn -0.187600 0.794700 -0.577300
vn -0.471300 0.661700 -0.583100
vn -0.331300 0.943500 0.000000
vn -0.607100 0.794700 0.000000
vn -0.700200 0.661700 0.268000
vn -0.102400 0.943500 0.315100
vn -0.187600 0.794700 0.577300
vn 0.038500 0.661700 0.748800
vn 0.268000 0.943500 0.194700
vn 0.491100 0.794700 0.356800
vn 0.724000 0.661700 0.194700
vn 0.889700 0.330400 -0.315100
vn 0.794700 0.187600 -0.577300
vn 0.574600 0.330400 -0.748800
vn -0.024700 0.330400 -0.943500
vn -0.303500 0.187600 -0.934200
vn -0.534600 0.330400 -0.777900
vn -0.905000 0.330400 -0.268000
vn -0.982200 0.187600 0.000000
vn -0.905000 0.330400 0.268000
vn -0.534600 0.330400 0.777900
vn -0.303500 0.187600 0.934200
vn -0.024700 0.330400 0.943500
vn 0.574600 0.330400 0.748800
vn 0.794700 0.187600 0.577300
vn 0.889700 0.330400 0.315100
vn 0.306600 0.125600 -0.943500
vn 0.303500 -0.187600 -0.934200
vn 0.024700 -0.330400 -0.943500
vn -0.802600 0.125600 -0.583100
vn -0.794700 -0.187600 -0.577300
vn -0.889700 -0.330400 -0.315100
vn -0.802600 0.125600 0.583100
vn -0.794700 -0.187600 0.577300
vn -0.574600 -0.330400 0.748800
vn 0.306600 0.125600 0.943500
vn 0.303500 -0.187600 0.934200
vn 0.534600 -0.330400 0.777900
vn 0.992100 0.125600 0.000000
vn 0.982200 -0.187600 0.000000
vn 0.905000 -0.330400 -0.268000
vn 0.471300 -0.661700 -0.583100
vn 0.187600 -0.794700 -0.577300
vn -0.038500 -0.661700 -0.748800
vn -0.408900 -0.661700 -0.628400
vn -0.491100 -0.794700 -0.356800
vn -0.724000 -0.661700 -0.194700
vn -0.724000 -0.661700 0.194700
vn -0.491100 -0.794700 0.356800
vn -0.408900 -0.661700 0.628400
vn 0.700200 -0.661700 -0.268000
vn 0.607100 -0.794700 0.000000
vn 0.331300 -0.943500 0.000000
vn -0.038500 -0.661700 0.748800
vn 0.187600 -0.794700 0.577300
vn 0.471300 -0.661700 0.583100
usemtl Material.001
s off
f 1/1/1 14/2/1 13/3/1
f 2/4/2 14/5/2 16/6/2
f 1/1/3 13/3/3 18/7/3
f 1/1/4 18/7/4 20/8/4
f 1/1/5 20/8/5 17/9/5
f 2/4/6 16/6/6 23/10/6
f 3/11/7 15/12/7 25/13/7
f 4/14/8 19/15/8 27/16/8
f 5/17/9 21/18/9 29/19/9
f 6/20/10 22/21/10 31/22/10
f 2/4/11 23/10/11 26/23/11
f 3/11/12 25/13/12 28/24/12
f 4/14/13 27/16/13 30/25/13
f 5/17/14 29/19/14 32/26/14
f 6/27/15 31/28/15 24/29/15
f 7/30/16 33/31/16 38/32/16
f 8/33/17 34/34/17 40/35/17
f 9/36/18 35/37/18 41/38/18
f 10/39/19 36/40/19 42/41/19
f 11/42/20 37/43/20 39/44/20
f 39/45/21 42/46/21 12/47/21
f 39/45/22 37/48/22 42/46/22
f 37/48/23 10/49/23 42/46/23
f 42/46/24 41/50/24 12/47/24
f 42/46/25 36/51/25 41/50/25
f 36/51/26 9/52/26 41/50/26
f 41/50/27 40/35/27 12/47/27
f 41/50/28 35/53/28 40/35/28
f 35/37/29 8/54/29 40/55/29
f 40/35/30 38/32/30 12/47/30
f 40/35/31 34/34/31 38/32/31
f 34/56/32 7/57/32 38/58/32
f 38/32/33 39/45/33 12/47/33
f 38/32/34 33/31/34 39/45/34
f 33/59/35 11/42/35 39/44/35
f 24/29/36 37/43/36 11/42/36
f 24/29/37 31/28/37 37/43/37
f 31/22/38 10/39/38 37/60/38
f 32/26/39 36/40/39 10/39/39
f 32/26/40 29/19/40 36/40/40
f 29/19/41 9/61/41 36/40/41
f 30/25/42 35/37/42 9/36/42
f 30/25/43 27/16/43 35/37/43
f 27/16/44 8/54/44 35/37/44
f 28/24/45 34/56/45 8/62/45
f 28/24/46 25/13/46 34/56/46
f 25/13/47 7/57/47 34/56/47
f 26/63/48 33/64/48 7/57/48
f 26/23/49 23/10/49 33/59/49
f 23/10/50 11/42/50 33/59/50
f 31/22/51 32/26/51 10/39/51
f 31/22/52 22/21/52 32/26/52
f 22/21/53 5/17/53 32/26/53
f 29/65/54 30/25/54 9/36/54
f 29/65/55 21/66/55 30/25/55
f 21/66/56 4/14/56 30/25/56
f 27/16/57 28/67/57 8/54/57
f 27/16/58 19/15/58 28/67/58
f 19/68/59 3/11/59 28/24/59
f 25/13/60 26/63/60 7/57/60
f 25/13/61 15/12/61 26/63/61
f 15/12/62 2/69/62 26/63/62
f 23/10/63 24/29/63 11/42/63
f 23/10/64 16/6/64 24/29/64
f 16/6/65 6/27/65 24/29/65
f 17/9/66 22/70/66 6/71/66
f 17/9/67 20/8/67 22/70/67
f 20/72/68 5/17/68 22/21/68
f 20/8/69 21/73/69 5/74/69
f 20/8/70 18/7/70 21/73/70
f 18/75/71 4/14/71 21/66/71
f 18/75/72 19/15/72 4/14/72
f 18/7/73 13/3/73 19/76/73
f 13/3/74 3/77/74 19/76/74
f 16/6/75 17/78/75 6/27/75
f 16/79/76 14/2/76 17/9/76
f 14/2/77 1/1/77 17/9/77
f 13/80/78 15/12/78 3/11/78
f 13/3/79 14/2/79 15/81/79
f 14/2/80 2/82/80 15/81/80
v 0.000000 -1.000000 0.000000
v 0.723607 -0.447220 0.525725
v -0.276388 -0.447220 0.850649
v -0.894426 -0.447216 0.000000
v -0.276388 -0.447220 -0.850649
v 0.723607 -0.447220 -0.525725
v 0.276388 0.447220 0.850649
v -0.723607 0.447220 0.525725
v -0.723607 0.447220 -0.525725
v 0.276388 0.447220 -0.850649
v 0.894426 0.447216 0.000000
v 0.000000 1.000000 0.000000
v -0.162456 -0.850654 0.499995
v 0.425323 -0.850654 0.309011
v 0.262869 -0.525738 0.809012
v 0.850648 -0.525736 0.000000
v 0.425323 -0.850654 -0.309011
v -0.525730 -0.850652 0.000000
v -0.688189 -0.525736 0.499997
v -0.162456 -0.850654 -0.499995
v -0.688189 -0.525736 -0.499997
v 0.262869 -0.525738 -0.809012
v 0.951058 0.000000 0.309013
v 0.951058 0.000000 -0.309013
v 0.000000 0.000000 1.000000
v 0.587786 0.000000 0.809017
v -0.951058 0.000000 0.309013
v -0.587786 0.000000 0.809017
v -0.587786 0.000000 -0.809017
v -0.951058 0.000000 -0.309013
v 0.587786 0.000000 -0.809017
v 0.000000 0.000000 -1.000000
v 0.688189 0.525736 0.499997
v -0.262869 0.525738 0.809012
v -0.850648 0.525736 0.000000
v -0.262869 0.525738 -0.809012
v 0.688189 0.525736 -0.499997
v 0.162456 0.850654 0.499995
v 0.525730 0.850652 0.000000
v -0.425323 0.850654 0.309011
v -0.425323 0.850654 -0.309011
v 0.162456 0.850654 -0.499995
vt 0.534208 0.190162
vt 0.439232 0.259166
vt 0.570486 0.301814
vt 0.995860 0.190574
vt 0.999792 0.292763
vt 0.903537 0.265179
vt 0.651606 0.190162
vt 0.570486 0.078511
vt 0.439232 0.121159
vt 0.903535 0.129002
vt 0.092743 0.471488
vt 0.212444 0.449586
vt 0.158053 0.569043
vt 0.737562 0.458199
vt 0.632422 0.499661
vt 0.728679 0.579260
vt 0.408849 0.471488
vt 0.316315 0.457312
vt 0.342992 0.573818
vt 0.632005 0.463365
vt 0.528550 0.449586
vt 0.605329 0.564268
vt 0.999792 0.072423
vt 0.026885 0.573818
vt 0.847656 0.509327
vt 0.474160 0.569043
vt 0.793444 0.309553
vt 0.688302 0.255514
vt 0.784558 0.198935
vt 0.251881 0.000208
vt 0.343838 0.078511
vt 0.226439 0.078511
vt 0.028577 0.072765
vt 0.131462 0.009506
vt 0.095186 0.121159
vt 0.939981 0.570899
vt 0.847658 0.645504
vt 0.943912 0.673088
vt 0.539471 0.666598
vt 0.419770 0.688500
vt 0.517323 0.757552
vt 0.793441 0.077875
vt 0.688301 0.119336
vt 0.747790 0.000208
vt 0.307560 0.190162
vt 0.226439 0.301814
vt 0.190162 0.190162
vt 0.343838 0.301814
vt 0.251881 0.380116
vt 0.095186 0.259166
vt 0.131462 0.370818
vt 0.028577 0.307559
vt 0.000208 0.190162
vt 0.737565 0.689877
vt 0.824936 0.743021
vt 0.103663 0.688500
vt 0.223364 0.666598
vt 0.201217 0.757552
vt 0.880811 0.006181
vt 0.632005 0.680774
vt 0.316315 0.674721
vt 0.000208 0.674721
vt 0.289222 0.564268
vt 0.315898 0.680774
vt 0.943912 0.452748
vt 0.824932 0.386505
vt 0.632423 0.635839
vt 0.000208 0.457312
vt 0.315898 0.463365
vt 0.475509 0.009506
vt 0.372624 0.072765
vt 0.430997 0.380533
vt 0.687884 0.078511
vt 0.595927 0.000208
vt 0.691911 0.380533
vt 0.687884 0.301814
vt 0.595927 0.380116
vt 0.880815 0.362696
vt 0.344255 0.190162
vt 0.114890 0.380533
vt 0.475509 0.370818
vt 0.372624 0.307559
vn 0.102400 -0.943500 0.315100
vn 0.700200 -0.661700 0.268000
vn -0.268000 -0.943500 0.194700
vn -0.268000 -0.943500 -0.194700
vn 0.102400 -0.943500 -0.315100
vn 0.905000 -0.330400 0.268000
vn 0.024700 -0.330400 0.943500
vn -0.889700 -0.330400 0.315100
vn -0.574600 -0.330400 -0.748800
vn 0.534600 -0.330400 -0.777900
vn 0.802600 -0.125600 0.583100
vn -0.306600 -0.125600 0.943500
vn -0.992100 -0.125600 0.000000
vn -0.306600 -0.125600 -0.943500
vn 0.802600 -0.125600 -0.583100
vn 0.408900 0.661700 0.628400
vn -0.471300 0.661700 0.583100
vn -0.700200 0.661700 -0.268000
vn 0.038500 0.661700 -0.748800
vn 0.724000 0.661700 -0.194700
vn 0.268000 0.943500 -0.194700
vn 0.491100 0.794700 -0.356800
vn 0.408900 0.661700 -0.628400
vn -0.102400 0.943500 -0.315100
vn -0.187600 0.794700 -0.577300
vn -0.471300 0.661700 -0.583100
vn -0.331300 0.943500 0.000000
vn -0.607100 0.794700 0.000000
vn -0.700200 0.661700 0.268000
vn -0.102400 0.943500 0.315100
vn -0.187600 0.794700 0.577300
vn 0.038500 0.661700 0.748800
vn 0.268000 0.943500 0.194700
vn 0.491100 0.794700 0.356800
vn 0.724000 0.661700 0.194700
vn 0.889700 0.330400 -0.315100
vn 0.794700 0.187600 -0.577300
vn 0.574600 0.330400 -0.748800
vn -0.024700 0.330400 -0.943500
vn -0.303500 0.187600 -0.934200
vn -0.534600 0.330400 -0.777900
vn -0.905000 0.330400 -0.268000
vn -0.982200 0.187600 0.000000
vn -0.905000 0.330400 0.268000
vn -0.534600 0.330400 0.777900
vn -0.303500 0.187600 0.934200
vn -0.024700 0.330400 0.943500
vn 0.574600 0.330400 0.748800
vn 0.794700 0.187600 0.577300
vn 0.889700 0.330400 0.315100
vn 0.306600 0.125600 -0.943500
vn 0.303500 -0.187600 -0.934200
vn 0.024700 -0.330400 -0.943500
vn -0.802600 0.125600 -0.583100
vn -0.794700 -0.187600 -0.577300
vn -0.889700 -0.330400 -0.315100
vn -0.802600 0.125600 0.583100
vn -0.794700 -0.187600 0.577300
vn -0.574600 -0.330400 0.748800
vn 0.306600 0.125600 0.943500
vn 0.303500 -0.187600 0.934200
vn 0.534600 -0.330400 0.777900
vn 0.992100 0.125600 0.000000
vn 0.982200 -0.187600 0.000000
vn 0.905000 -0.330400 -0.268000
vn 0.471300 -0.661700 -0.583100
vn 0.187600 -0.794700 -0.577300
vn -0.038500 -0.661700 -0.748800
vn -0.408900 -0.661700 -0.628400
vn -0.491100 -0.794700 -0.356800
vn -0.724000 -0.661700 -0.194700
vn -0.724000 -0.661700 0.194700
vn -0.491100 -0.794700 0.356800
vn -0.408900 -0.661700 0.628400
vn 0.700200 -0.661700 -0.268000
vn 0.607100 -0.794700 0.000000
vn 0.331300 -0.943500 0.000000
vn -0.038500 -0.661700 0.748800
vn 0.187600 -0.794700 0.577300
vn 0.471300 -0.661700 0.583100
usemtl Material.001
s off
f 1/1/1 14/2/1 13/3/1
f 2/4/2 14/5/2 16/6/2
f 1/1/3 13/3/3 18/7/3
f 1/1/4 18/7/4 20/8/4
f 1/1/5 20/8/5 17/9/5
f 2/4/6 16/6/6 23/10/6
f 3/11/7 15/12/7 25/13/7
f 4/14/8 19/15/8 27/16/8
f 5/17/9 21/18/9 29/19/9
f 6/20/10 22/21/10 31/22/10
f 2/4/11 23/10/11 26/23/11
f 3/11/12 25/13/12 28/24/12
f 4/14/13 27/16/13 30/25/13
f 5/17/14 29/19/14 32/26/14
f 6/27/15 31/28/15 24/29/15
f 7/30/16 33/31/16 38/32/16
f 8/33/17 34/34/17 40/35/17
f 9/36/18 35/37/18 41/38/18
f 10/39/19 36/40/19 42/41/19
f 11/42/20 37/43/20 39/44/20
f 39/45/21 42/46/21 12/47/21
f 39/45/22 37/48/22 42/46/22
f 37/48/23 10/49/23 42/46/23
f 42/46/24 41/50/24 12/47/24
f 42/46/25 36/51/25 41/50/25
f 36/51/26 9/52/26 41/50/26
f 41/50/27 40/35/27 12/47/27
f 41/50/28 35/53/28 40/35/28
f 35/37/29 8/54/29 40/55/29
f 40/35/30 38/32/30 12/47/30
f 40/35/31 34/34/31 38/32/31
f 34/56/32 7/57/32 38/58/32
f 38/32/33 39/45/33 12/47/33
f 38/32/34 33/31/34 39/45/34
f 33/59/35 11/42/35 39/44/35
f 24/29/36 37/43/36 11/42/36
f 24/29/37 31/28/37 37/43/37
f 31/22/38 10/39/38 37/60/38
f 32/26/39 36/40/39 10/39/39
f 32/26/40 29/19/40 36/40/40
f 29/19/41 9/61/41 36/40/41
f 30/25/42 35/37/42 9/36/42
f 30/25/43 27/16/43 35/37/43
f 27/16/44 8/54/44 35/37/44
f 28/24/45 34/56/45 8/62/45
f 28/24/46 25/13/46 34/56/46
f 25/13/47 7/57/47 34/56/47
f 26/63/48 33/64/48 7/57/48
f 26/23/49 23/10/49 33/59/49
f 23/10/50 11/42/50 33/59/50
f 31/22/51 32/26/51 10/39/51
f 31/22/52 22/21/52 32/26/52
f 22/21/53 5/17/53 32/26/53
f 29/65/54 30/25/54 9/36/54
f 29/65/55 21/66/55 30/25/55
f 21/66/56 4/14/56 30/25/56
f 27/16/57 28/67/57 8/54/57
f 27/16/58 19/15/58 28/67/58
f 19/68/59 3/11/59 28/24/59
f 25/13/60 26/63/60 7/57/60
f 25/13/61 15/12/61 26/63/61
f 15/12/62 2/69/62 26/63/62
f 23/10/63 24/29/63 11/42/63
f 23/10/64 16/6/64 24/29/64
f 16/6/65 6/27/65 24/29/65
f 17/9/66 22/70/66 6/71/66
f 17/9/67 20/8/67 22/70/67
f 20/72/68 5/17/68 22/21/68
f 20/8/69 21/73/69 5/74/69
f 20/8/70 18/7/70 21/73/70
f 18/75/71 4/14/71 21/66/71
f 18/75/72 19/15/72 4/14/72
f 18/7/73 13/3/73 19/76/73
f 13/3/74 3/77/74 19/76/74
f 16/6/75 17/78/75 6/27/75
f 16/79/76 14/2/76 17/9/76
f 14/2/77 1/1/77 17/9/77
f 13/80/78 15/12/78 3/11/78
f 13/3/79 14/2/79 15/81/79
f 14/2/80 2/82/80 15/81/80
each line starting with v defines a vertex' position in 3D-space. So I'm reading all these in and create new Vector4 to get homogeneous coordinates.
I ignore vn for now, these would be the normals.
For vt - specifying texture coordinates - I do the same as for the positions.
Now f is prepending the really interesting lines. These are faces, triangles defined as triples of (vertexposition/texturecoordinates/normals). Each of these define which index of positions and texturecoordinates maps together.
So, for example in f 1/1/1 14/2/1 13/3/1
1/1/1
would mean that positions(1) has the texture coordinates(1) (and the last 1 in the first triple would stand for the normal in normals(1))
14/2/1
would mean that positions(14) and texturecoordinates(2) map together.
The whole line would connect these 3 vertices, like (1,14,13)
would build up a triangle.
Am I understanding this correctly until here?
val faces: List[(Int, Int, Int)] = objSource.filter(_.startsWith("f ")).map(_.split(" ")).flatten.filterNot(_ == "f").map(_.split("/")).map(a => ((a(0).toInt, a(1).toInt, a(2).toInt)))
Would give me a List of these triples. For each of the entries I would then create a Vertex:
val vertices: List[Vertex] = for(face <- faces) yield(new Vertex(positions(face._1-1), textureCoordinates(face._2-1)))
Vertex is defined like so:
case class Vertex(position: Vector4,/* normal: Vector4,*/ textureCoordinates: Vector2)
I need to do "-1" on each face to avoid off-by-one and IndexOutOfBoundsExceptions, as the index of a List starts with 0 while the indices are starting with 1.
The last thing are the indices: In OpenGL you may use an ELEMENT_ARRAY_BUFFER
to specify which vertices are connected and to save (possibly a lot) of data.
As I said earlier, each face f 1/1/1 14/2/1 13/3/1
is built up like this v1/t1/n1 v2/t2/n2 v3/t3/n3
(for each line) so I only need to extract v1,v2,v3
, pack it into one long List and let OpenGL do the rest.
v1/v2/v3/v4/v5/v6/.../vn
would then be my indices
Am I right or is something wrong until here?
Last but not least I would create a new model:
class Model(vertices: Array[Vertex], indices: Array[Int]/*, textures: Array[Texture]*/)
{
// Create VAO, VBO and a buffer for the indices
val vao: Int = glGenVertexArrays
val vbo: Int = glGenBuffers
val ibo: Int = glGenBuffers
setup
private def setup(): Unit =
{
val interleavedBuffer: FloatBuffer = prepareVertexBuffer(vertices)
val indicesBuffer: IntBuffer = prepareIntBuffer(indices)
// One VAO to bind them all!
glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
// Fill buffers with data
glBufferData(GL_ARRAY_BUFFER, interleavedBuffer, GL_STATIC_DRAW)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW)
// Set vertex attribute pointers
glVertexAttribPointer(0, 4, GL_FLOAT, false, 4*6, 0) // 0 = Position = Vector4(x,y,z,w)
glVertexAttribPointer(1, 2, GL_FLOAT, false, 4*6, 4*4) // 1 = Texture Coordinates = Vector2(x,y) -> 2 (coordinates) * 4 (byte-size of float) => stride = 4 (position) + 2 (texture coordinates) = 6 * 4 (byte-size of float); offset = 4 (position) * 4 (byte-size of float)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
}
private def prepareIntBuffer(data: Array[Int]): IntBuffer =
{
val buffer: IntBuffer = BufferUtils.createIntBuffer(data.length)
buffer.put(data)
buffer.flip // Make the buffer readable
buffer
}
private def prepareVertexBuffer(vertices: Array[Vertex]): FloatBuffer =
{
val positions: Array[Float] = vertices.map(v => v.position).map(_.toArray).flatten
val textureCoordinates: Array[Float] = vertices.map(v => v.textureCoordinates).map(_.toArray).flatten
// TODO remove hardcoded sizes for grouping
val zipped: Array[Float] = (positions.grouped(4) zip textureCoordinates.grouped(2)).toArray.flatMap {case (x,y) => x ++ y}
val buffer: FloatBuffer = BufferUtils.createFloatBuffer(zipped.size)
buffer.put(zipped)
buffer.flip
buffer
}
The problem is, the output looks like this:
While actually it should be an Ico-Sphere from Blender. So, something is really off with my implementation or understanding of the .obj-file-format.
I assume it has to do with the indices, but no idea. I've debugged a lot, manually compared the different Lists with the actual .obj-file but to no avail. Everything looks okay, so I assume it's really my understanding.
edit: I'm not yet sure what exactly I am misunderstanding but, instead of going through the faces to create a List of Vertices (my own class) I gave the model all the positions and texture coordinates and voilà, the meshes appearance looks right (apart from wrong texturing).
So what I did:
class Model(positions: Array[Vector3], texcoords: Array[Vector2], indices: Array[Int])
private def prepareVertexBuffer(positions: Array[Vector3], texcoords: Array[Vector2]): FloatBuffer =
{
val pos: Array[Float] = positions.map(_.toArray).flatten
val textureCoordinates: Array[Float] = texcoords.map(_.toArray).flatten
// TODO remove hardcoded sizes for grouping
val zipped: Array[Float] = (pos.grouped(3) zip textureCoordinates.grouped(2)).toArray.flatMap {case (x,y) => x ++ y}
println(zipped.toList.grouped(5).mkString("\n"))
val buffer: FloatBuffer = BufferUtils.createFloatBuffer(zipped.size)
buffer.put(zipped)
buffer.flip
buffer
}
(Note: I've also switched back to Vector3 instead of Vector4 for now. Thought there might be a problem with it)
val indices: List[Int] = faces.map(f => f._1-1) // Wrong?
new Model(vertices.toArray, indices.toArray)
The rest is the same. So I guess my texturing problem results from this.
I now have only 42 vertices instead of 240 (coming from the faces), so I lose a lot of combinations.
edit
The problem boils down to the difference between .obj and opengl. OpenGL may only use one index-buffer while in .obj there is one for each attribute.
So I need to manually merge these in an appropriate way. I've found C++ functions for that and although I know C++ quite a bit, I'm not sure why it's not working on my end with Scala.
I simply do not find any duplicates...
val indices: List[Int] = faces.map(f => f._1-1)
So for each triple I get the first value and reduce it by one (as it represents an index starting by 1 - we need one starting by 0 - same list else) Am I thinking it through wrongly? – Heilner