पर मैं एक .obj-file में लोड करने की कोशिश कर रहा हूं और glDrawElements
की सहायता से इसे खींच रहा हूं।एकाधिक ओबीजे-इंडेक्स-बफर ओपनजीएल के 1 इंडेक्स बफर
अब glDrawArrays
सबकुछ पूरी तरह से काम करता है, लेकिन यह निश्चित रूप से अक्षम है।
मेरे पास अभी समस्या है, कि एक .obj-file एकाधिक इंडेक्स-बफर (प्रत्येक विशेषता के लिए) का उपयोग करता है जबकि ओपनजीएल केवल एक का उपयोग कर सकता है। इसलिए मुझे उन्हें तदनुसार मानचित्र बनाना होगा।
वहां बहुत सारे छद्म-एल्गोरिदम हैं और मुझे सी ++ कार्यान्वयन भी मिला है। मुझे सी ++ का थोड़ा सा पता है लेकिन अजीब तरह से मुझे स्कैला में मेरे कार्यान्वयन में मदद नहीं मिली।
चलो देखते हैं:
private def parseObj(path: String): Model =
{
val objSource: List[String] = Source.fromFile(path).getLines.toList
val positions: List[Vector3] = objSource.filter(_.startsWith("v ")).map(_.split(" ")).map(v => new Vector3(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).toFloat, 1-v(2).toFloat)) // TODO 1-y because of blender
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 vertices: List[Vertex] = for(face <- faces) yield(new Vertex(positions(face._1-1), textureCoordinates(face._2-1)))
val f: List[(Vector3, Vector2, Vector4)] = for(face <- faces) yield((positions(face._1-1), textureCoordinates(face._2-1), normals(face._3-1)))
println(f.mkString("\n"))
val indices: List[Int] = faces.map(f => f._1-1) // Wrong!
new Model(vertices.toArray, indices.toArray)
}
val indices: List[Int]
मेरी पहली अनुभवहीन दृष्टिकोण था और निश्चित रूप से गलत है। लेकिन चलिए शीर्ष पर शुरू करें:
मैं फ़ाइल में लोड करता हूं और इसके माध्यम से जाता हूं। (मुझे लगता है कि आप जानते हैं कि एक .obj-file कैसे बनाई गई है)
मैंने शिखर, बनावट-निर्देशांक और मानदंडों में पढ़ा है। तब मैं चेहरे पर आ गया।
अब, मेरे उदाहरण में प्रत्येक चेहरे में vertexAtIndexX, textureCoordAtIndexY, normalAtIndexZ
परिभाषित 3 मान v_x, t_y, n_z
है। इसलिए इनमें से प्रत्येक एक वर्टेक्स को परिभाषित करता है जबकि इनमें से एक तिहाई (या फ़ाइल में एक पंक्ति) फेस/पॉलीगॉन/त्रिकोण को परिभाषित करता है।
val indices: List[Int] = faces.map(f => f._1-1) // Wrong!
val vertices: List[Vertex] = for(face <- faces) yield(new Vertex(positions(face._1-1), textureCoordinates(face._2-1)))
में मैं वास्तव में कोने (एक मामले वर्ग है कि वर्तमान में केवल पदों और बनावट निर्देशांक रखती है और अब के लिए normals neglects)
वास्तविक समस्या पैदा करने की कोशिश इस लाइन है
असली सूचकांक मैं मूल रूप से इस बजाय की क्या करने की जरूरत प्राप्त करने के लिए
val vertices: List[Vertex] = for(face <- faces) yield(new Vertex(positions(face._1-1), textureCoordinates(face._2-1)))
और val indices: List[Int] = faces.map(f => f._1-1) // Wrong!
छद्म कोड:
Iterate over all faces
Iterate over all vertices in a face
Check if we already have that combination of(position, texturecoordinate, normal) in our newVertices
if(true)
indices.put(indexOfCurrentVertex)
else
create a new Vertex from the face
store the new vertex in the vertex list
indices.put(indexOfNewVertex)
अभी तक मैं पूरी तरह से अटक कर रहा हूँ। मैंने अलग-अलग चीजों की कोशिश की है, लेकिन वास्तव में काम करने वाले एक अच्छे और साफ समाधान के साथ नहीं आ सकता है।
हालात की तरह:
val f: List[(Vector3, Vector2, Vector4)] = for(face <- faces) yield((positions(face._1-1), textureCoordinates(face._2-1), normals(face._3-1)))
और f.distinct
करने की कोशिश कर काम नहीं कर रहे हैं, जो पूरी तरह से समझ में आता है अगर मैं फ़ाइल को देखो और अभी तक वो क्या है अलग, सभी प्रविष्टियों अद्वितीय देखते हैं, कोई बात नहीं है क्योंकि वहाँ छद्म कोड मुझे जांचने के लिए कहता है।
तो मैं तदनुसार (अधिमानतः एक एक लाइनर में और कार्यात्मक सुंदरता का एक बहुत कुछ के साथ)
लेकिन मैं डुप्लीकेट ढूंढना का प्रयास करना चाहिए सूचकांक को भरने के लिए की आवश्यकता होगी तो ... मैं तरह कर रहा हूँ परेशान मुझे लगता है कि मैं सभी संदर्भों के साथ, विभिन्न "कोष्ठक" और "पदों" को बहुत अधिक मिलाता हूं।
तो, क्या मैं गलत सोच रहा हूं, या एल्गोरिदम/सोच सही है और मुझे इसे अच्छे, साफ (और वास्तव में काम कर रहे) स्कैला कोड में लागू करने की आवश्यकता है?
कृपया मुझे प्रबुद्ध करें!
var index: Int = 0
val map: mutable.HashMap[(Int, Int, Int), Int] = new mutable.HashMap[(Int, Int, Int), Int].empty
val combinedIndices: ListBuffer[Int] = new ListBuffer[Int]
for(face <- faces)
{
val vID: Int = face._1-1
val nID: Int = face._2-1
val tID: Int = face._3-1
var combinedIndex: Int = -1
if(map.contains((vID, nID, tID)))
{
println("We have a duplicate, wow!")
combinedIndex = map.get((vID, nID, tID)).get
}
else
{
combinedIndex = index
map.put((vID, nID, tID), combinedIndex)
index += 1
}
combinedIndices += combinedIndex
}
जहां अभी भी सामना करना पड़ता है है:
टिप्पणियों के अनुसार, मैं एक छोटे से अद्यतन किया जाता
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)))
मज़ेदार तथ्य मैं अभी भी यह स्पष्ट रूप से समझ नहीं कर रहा हूँ, क्योंकि वह जिस तरह से मुझे कभी डुप्लिकेट नहीं मिलता!
मतलब है कि combinedIndices
अंत में जैसे प्राकृतिक संख्या रखती है:
ListBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...)
मुझे स्कैला बिल्कुल नहीं पता, इसलिए मैं यह नहीं बता सकता कि यह वही है जो आप पहले से कर रहे हैं। लेकिन आपको आवश्यक महत्वपूर्ण डेटा संरचना एक नक्शा है जो स्थिति के ** इंडेक्स **, बनावट निर्देशांक और कुंजी के रूप में चेहरे रिकॉर्ड से सामान्य, और ओपनजीएल वर्टेक्स की अनुक्रमणिका के रूप में एक टुपल का उपयोग करता है। यहां मेरे पुराने जवाब में छद्म कोड है, यदि यह आपकी खोजों में पहले से मिली पोस्टों में से एक नहीं है: http://stackoverflow.com/questions/23349080/opengl-index-buffers-difficulties/23356738#23356738 । –
@RetoKoradi: तो प्रत्येक चेहरे के लिए मुझे कुंजी [पदों (face._1-1), बनावट कोऑर्डिनेट्स (फेस ._2-1), मानक (चेहरा ._2-1) के साथ एक मानचित्र-प्रविष्टि बनाने की आवश्यकता है]) मैं कैसे करूँ फिर मूल्य के लिए ओपनजीएल वर्टेक्स की अनुक्रमणिका की गणना करें? – Sorona
आप 0 से शुरू करते हैं, और प्रत्येक बार जब आपको एक नई कशेरुक की आवश्यकता होती है (यानी कुंजी पहले से ही मानचित्र में नहीं थी)। यह जुड़े छद्म कोड से काफी स्पष्ट होना चाहिए। –