我正在尝试使用libobj
来解析从Blender导出的.obj
文件。
网站http://people.cs.kuleuven.be/~ares.lagae/libobj/index.html
是libobj
来自http://en.wikipedia.org/wiki/Wavefront_Object_file_format的地方
描述了.obj
文件格式的细节。 libobj
网站
有一个关于如何解析顶点的例子,我在其中详细阐述过
以下代码。
但是我不确定如何解析面和渲染 他们在OpenGL中。我是否必须使用顶点列表或服务器端缓冲区对象? 如何扩展下面的代码以使其正确渲染面部?
#include <GL/glut.h>
#include <obj.hpp>
#include <iostream>
void geometric_vertex_callback(obj::float_type x, obj::float_type y, obj::float_type z)
{
std::cout << "v " << x << " " << y << " " << z << "\n";
glVertex3f(x, y, z);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
obj::obj_parser obj_parser;
obj_parser.geometric_vertex_callback(geometric_vertex_callback);
std::cout << std::endl;
glLoadIdentity();
gluLookAt(1.0f, 1.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_POINTS);
obj_parser.parse("./cube.obj");
glEnd();
glFlush();
}
void reshape(int h, int w) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-8.0f, 8.0f, -8.0f, 8.0f, -10.0f, 10.0f);
glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutCreateWindow("cube");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
编译:{{1}}
答案 0 :(得分:3)
检查参考文献(http://people.cs.kuleuven.be/~ares.lagae/libobj/obj-0.1/doc/html/classobj_1_1obj__parser.html)。您可以使用多个回调来渲染几何体。
.OBJ是一种非常简单直接的格式。我认为编写解析器并不困难,这可能是一种有趣的学习体验。
答案 1 :(得分:2)
我知道这不是你要问的问题,因为你想使用libobj,但我发现自己学习如何做一些事情比使用预制的库要好得多。我实际上刚刚为我的程序完成了一个简单的.obj阅读器。我会在这里发布它以帮助你入门。
请注意,它包含一些特定于我的实现的代码(即我如何处理我的顶点缓冲区等),它仍然只处理包含单个对象的目标文件。但是希望这会让你走上正轨。
另外,我按照我在网上发现的一个教程(不记得哪个),所以我不能全力以赴。
private class Face{
public int[] v;
public int[] vt;
public int[] vn;
public Face(){
v = new int[3];
vt = new int[3];
vn = new int[3];
for(int i = 0; i < 3; i++){
v[i] = vt[i] = vn[i] = -1;
}
}
}
public void readObjFile(String fileName){
Reader r;
try{
r = new FileReader(fileName);
BufferedReader reader = new BufferedReader(r);
String line = null;
int lineNo = 0;
float[] floatTemp = new float[3];
int[] intTemp = new int[3];
ArrayList<Face> faces = new ArrayList<Face>();
ArrayList<Vector3> v = new ArrayList<Vector3>();
ArrayList<Vector2> vt = new ArrayList<Vector2>();
ArrayList<Vector3> vn = new ArrayList<Vector3>();
while((line = reader.readLine()) != null){
++lineNo;
String[] elements = line.split("\\s+");
if(elements.length > 0){
if(elements[0].equals("v")){
if(elements.length < 4){
System.out.println("Something is wrong with the obj loading");
}
else{
//mVertexBuffer.addVertex(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
v.add(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
}
}
else if(elements[0].equals("vt")){
if(elements.length < 3){
System.out.println("Something is wrong with the obj loading");
}
else{
//mVertexBuffer.addTextureCoord(new Vector2(Float.parseFloat(elements[1]), Float.parseFloat(elements[2])));
vt.add(new Vector2(Float.parseFloat(elements[1]), 1.0f - Float.parseFloat(elements[2])));
}
}
else if(elements[0].equals("vn"))
{
if(elements.length < 4){
System.out.println("Something is wrong with the obj loading");
}
else{
//mVertexBuffer.addVertex(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
vn.add(new Vector3(Float.parseFloat(elements[1]), Float.parseFloat(elements[2]),Float.parseFloat(elements[3])));
}
}
else if(elements[0].equals("f")){
if(elements.length != 4){
System.out.println("Something is wrong with the obj loading");
}
else{
//if(mIndexBuffer == null){
// mIndexBuffer = new IndexBuffer(mGl);
//}
Face newFace = new Face();
for (int i = 1; i < 4; i++) {
String seg = elements[i];
if(seg.indexOf("/") > 0)
{
String[] faceOrder = seg.split("/");
if (faceOrder.length > 0) {
//mIndexBuffer.addIndex(Integer.valueOf(faceOrder[0]) - 1);
newFace.v[i - 1] = Integer.valueOf(faceOrder[0]) - 1;
}
if (faceOrder.length > 1) {
if(faceOrder[1].length() > 0){
//f.uvIndices.add(Integer.valueOf(faceOrder[1]));
newFace.vt[i - 1] = Integer.valueOf(faceOrder[1]) - 1;
}
}
if (faceOrder.length > 2) {
//f.normalIndices.add(Integer.valueOf(faceOrder[2]));
newFace.vn[i - 1] = Integer.valueOf(faceOrder[2]) - 1;
}
}
else
{
if (seg.length() > 0) {
//mIndexBuffer.addIndex(Integer.valueOf(seg) - 1);
newFace.v[i - 1] = Integer.valueOf(seg) - 1;
}
}
}
faces.add(newFace);
}
}
}
}
// Now do post process
for(int i = 0; i < faces.size(); i++){
mVertexBuffer.addVertex(v.get(faces.get(i).v[0]));
mVertexBuffer.addVertex(v.get(faces.get(i).v[1]));
mVertexBuffer.addVertex(v.get(faces.get(i).v[2]));
if(vt.size() > 0){
mVertexBuffer.addTextureCoord(vt.get(faces.get(i).vt[0]));
mVertexBuffer.addTextureCoord(vt.get(faces.get(i).vt[1]));
mVertexBuffer.addTextureCoord(vt.get(faces.get(i).vt[2]));
}
}
}
catch(IOException e){
e.printStackTrace();
}
}