在OpenGL中绘制模型时出现错误。

huangapple go评论82阅读模式
英文:

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()

然而,当我运行这段代码时,结果并不完全正确。

在OpenGL中绘制模型时出现错误。

我尝试在互联网上找到的其他一些文件上运行它,结果也类似。似乎三角形的顶点有些偏移或其他问题。

英文:

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

在OpenGL中绘制模型时出现错误。

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]}
}

huangapple
  • 本文由 发表于 2016年3月3日 22:15:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/35774594.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定