英文:
Error drawing model in opengl
问题
所以我正在尝试编写一个基本的OpenGL程序,它可以读取一个.obj
文件并渲染它(该obj文件包含以v 1.000000 2.000000, 3.00000
格式表示的三角形顶点)。
以下是我用来实现这个功能的代码(我使用了GLFW和其对应的Golang绑定库)(目前忽略了法线)。
gl.Begin(gl.TRIANGLES)
for scanner.Scan() {
var v0, v1, v2 float32
t := strings.Split(scanner.Text(), " ")
line := scanner.Text()
fmt.Sscanf(line, "v %f %f %f", &v0, &v1, &v2)
if t[0] == "v" {
gl.Vertex3f(v0, v1, v2)
}
}
gl.End()
然而,当我运行这段代码时,结果并不完全正确。
我尝试在互联网上找到的其他一些文件上运行它,结果也类似。似乎三角形的顶点有些偏移或其他问题。
英文:
So i'm trying to a basic opengl program that reads in an .obj
file and then renders it (the obj file contains triangle vertices in the format
v 1.000000 2.000000, 3.00000
.
So here's my code to do that (im using GLFW and a Golang binding library for it) (also im currently ignoring normals).
gl.Begin(gl.TRIANGLES)
for scanner.Scan() {
var v0, v1, v2 float32
t := strings.Split(scanner.Text(), " ")
line := scanner.Text()
fmt.Sscanf(line, "v %f %f %f", &v0, &v1, &v2)
if t[0] == "v" {
gl.Vertex3f(v0, v1, v2)
}
}
gl.End()
However when I go to run this the result isnt quite right
I tried it on a few other files I found around the internet and I get similar results. It almost seems like the triangles vertices are offset or something.
答案1
得分: 3
你应该将所有顶点数据读入数组中。Obj文件包含有关三角形和顶点索引的信息。以f
开头的行包含描述三角形的3个数字。所以你的代码应该像这样(我不知道go语言):
var vertices [1000*3] float32
for scanner.Scan() {
var i=0
var v0, v1, v2 float32
var vv byte
t := strings.Split(scanner.Text(), " ")
line := scanner.Text()
fmt.Sscanf(line, "%c %f %f %f", &vv, &v0, &v1, &v2)
if vv == "v" {
vertices[i] = v0
vertices[i+1] = v1
vertices[i+2] = v2
}
i = i+3
}
gl.Begin(gl.TRIANGLES)
for scanner.Scan() {
var v0, v1, v2 int
var vv byte
t := strings.Split(scanner.Text(), " ")
line := scanner.Text()
fmt.Sscanf(line, "%c %d %d %d", &vv, &v0, &v1, &v2)
if vv == "f" {
gl.Vertex3f(vertices[v0], vertices[v1], vertices[v2])
}
}
gl.End()
请注意,这只是一个示例代码,具体实现可能需要根据你的需求进行调整。
英文:
You should read all vertices data into array. Obj file contains information about triangles, and how vertices should be indexed. Lines starting with f
contains 3 numbers which describes triangles. So your code should look like this (I don't know go):
var vertices [1000*3] float32
for scanner.Scan() {
var i=0
var v0, v1, v2 float32
var vv byte
t := strings.Split(scanner.Text(), " ")
line := scanner.Text()
fmt.Sscanf(line, "%c %f %f %f", &vv, &v0, &v1, &v2)
if vv == "v" {
vertices[i] = v0
vertices[i+1] = v1
vertices[i+2] = v2
}
i = i+3
}
gl.Begin(gl.TRIANGLES)
for scanner.Scan() {
var v0, v1, v2 int
var vv byte
t := strings.Split(scanner.Text(), " ")
line := scanner.Text()
fmt.Sscanf(line, "%c %d %d %d", &vv, &v0, &v1, &v2)
if vv == "f" {
gl.Vertex3f(vertices[v0], vertices[v1], vertices[v2])
}
}
gl.End()
答案2
得分: 1
Obj文件除了存储顶点(v行)之外,还存储了如何将它们组合成面(f行)。顶点本身没有特定的顺序存储,这意味着第一个三角形不一定由顶点0-2组成。
您需要将所有顶点读入一个向量/列表/数组中,然后解析面条目,根据额外存储的信息(法线、纹理坐标)可以以四种不同的方式组合(根据此处):
f v1 v2 v3 ...
f v1/vt1 v2/vt2 v3/vt3 ...
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ....
f v1//vn1 v2//vn2 v3//vn3 ...
其中
v ... 索引指向v条目列表
vt ... 索引指向vt条目列表(纹理坐标)
vn ... 索引指向vn条目列表(法线)
对于您的示例,您需要执行类似于以下伪代码的操作(假设所有面已经三角化):
v-list vertices[];
将每个v行解析到v-list中
对于每个f行
{
解析v索引 -> {v0, v1, v2}
绘制三角形 {vertices[v0], vertices[v1], vertices[v2]}
}
英文:
Obj files store in addition to the vertices (v-lines) also how they have to be combined into faces (f-lines). The vertices themself are stored without a particular ordering, which means that the first triangle is not necessarily composed of the vertices 0-2.
You will have to read all of the vertices into a vector/list/array and then parse the face entries which can be composed (according to here) in four different ways depending on which additional information (normals, texture coordinates) are additionally stored:
f v1 v2 v3 ...
f v1/vt1 v2/vt2 v3/vt3 ...
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ....
f v1//vn1 v2//vn2 v3//vn3 ...
where
v ... index into the list of v-entries
vt ... index into the list of vt-entries (texture coordinates)
vn ... index into the list of vn-entries (normals)
For your example, you will have to do something similar to this pseudocode (assuming that all faces are already triangulated)
v-list vertices[];
parse each v-line into v-list
foreach (f-line)
{
parse v-indices -> {v0, v1, v2}
draw triangle {vertices[v0], vertices[v1], vertices[v2]}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论