对象加载器 [英] object loader in opengl
问题描述
我已经创建了一个程序在C + +也包含opengl和我想创建一个obj加载器为了加载一个obj文件我有!我已经创建了两个函数:
void ReadFile(model * md)
{
/ /打开读取文件OBJINFO.TXT
ifstream obj_file(tree.obj);
if(obj_file.fail())
exit(1);
//获取顶点数量
obj_file>> md->顶点;
//获取面数量
obj_file>> md-面;
//获取顶点坐标
for(int i = 0; i {
obj_file> md-> obj_points [i] .x;
obj_file>> md-> obj_points [i] .y;
obj_file>> md-> obj_points [i] .z;
}
//获取面结构
for(int i = 0; i {
obj_file>> md-> obj_faces [i] .vn [0];
obj_file>> md-> obj_faces [i] .vn [1];
obj_file>> md-> obj_faces [i] .vn [2];
obj_file>> md-> obj_faces [i] .vn [3];
}
obj_file.close();
}
void DisplayModel(model md)
{
glPushMatrix();
glBegin(GL_TRIANGLES);
for(int i = 0; i {
glVertex3f(md.obj_points [md.obj_faces [i] .vn [0] -1] .x,md.obj_points [md.obj_faces [i] .vn [0] -1] .y,md.obj_points [md.obj_faces [i] .vn [0] -1] .z);
glVertex3f(md.obj_points [md.obj_faces [i] .vn [1] -1] .x,md.obj_points [md.obj_faces [i] .vn [1] -1] .y,md。 obj_points [md.obj_faces [i] .vn [1] -1] .z);
glVertex3f(md.obj_points [md.obj_faces [i] .vn [2] -1] .x,md.obj_points [md.obj_faces [i] .vn [2] -1] .y,md。 obj_points [md.obj_faces [i] .vn [2] -1] .z);
glVertex3f(md.obj_points [md.obj_faces [i] .vn [2] -1] .x,md.obj_points [md.obj_faces [i] .vn [2] -1] .y,md。 obj_points [md.obj_faces [i] .vn [3] -1] .z);
}
glEnd();
glPopMatrix();
}
主要的问题是当我编译项目并运行它时,在视口。我增加了视口的尺寸,以防它小为了出现对象,但情况保持不变!所以我达到的结果,我做了一些错误在这些功能!有人可以帮助我吗?
此外,我还提供了一些obj文件的值:
v 0.158000 0.975000 0.151491 1.000000
v 0.188743 0.025000 0.173826 1.000000
v 0.196000 0.025000 0.151491 1.000000
v 0.158000 0.025000 0.151491 1.000000
v 0.169743 0.025000 0.187631 1.000000
v 0.146257 0.025000 0.187631 1.000000
v 0.127257 0.025000 0.173826 1.000000
vn 0.950370 0.038015 0.308791
vn 0.950370 0.038015 0.308791
vn 0.950370 0.038015 0.308791
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 -0.000000
vn 0.587380 0.038015 0.808418
f 1 // 1 2 // 2 3 // 3
f 4 // 4 3 // 5 2 // 6
f 1 / / 7 5 // 8 2 // 9
f 4 // 10 2 // 11 5 // 12
f 1 // 13 6 // 14 5 // 15
f 4 // 16 5 // 17 6 // 18
f 1 // 19 7 // 20 6 // 21
//获取顶点数量
obj_file>> md->顶点;
//获取面数量
obj_file>> md-面;
阅读规范。这不是OBJs如何工作。你必须解析出顶点/纹理坐标/法线/面,你一起去。
尝试这样:
// g ++ main.cpp -o main -lglut -lGL -lGLU&& ./main
#include< GL / glut.h>
#include< glm / glm.hpp>
#include< glm / gtx / component_wise.hpp>
#include< vector>
#include< fstream>
#include< sstream>
using namespace std;
using namespace glm;
struct Vertex
{
vec3 position;
vec2 texcoord;
vec3 normal;
};
struct VertRef
{
VertRef(int v,int vt,int vn)
:v(v),vt(vt),vn b $ b {}
int v,vt,vn;
};
vector<顶点> LoadOBJ(istream& in)
{
vector<顶点> ;
vector< vec4>位置(1,vec4(0,0,0,0));
vector< vec3> texcoords(1,vec3(0,0,0));
vector< vec3>法线(1,vec3(0,0,0));
string stringStr;
while(getline(in,lineStr))
{
istringstream lineSS(lineStr);
string lineType;
lineSS>> lineType;
// vertex
if(lineType ==v)
{
float x = 0,y = 0,z = 0,w = 1;
lineSS>> x>> y>> z>> w;
positions.push_back(vec4(x,y,z,w));
}
// texture
if(lineType ==vt)
{
float u = 0,v = 0,w = 0 ;
lineSS>> u> v>> w;
texcoords.push_back(vec3(u,v,w));
}
// normal
if(lineType ==vn)
{
float i = 0,j = 0,k = 0 ;
lineSS>> i>> j>> k;
normals.push_back(normalize(vec3(i,j,k)));
}
// polygon
if(lineType ==f)
{
vector< VertRef>参考;
string refStr;
while(lineSS>> refStr)
{
istringstream ref(refStr);
string vStr,vtStr,vnStr;
getline(ref,vStr,'/');
getline(ref,vtStr,'/');
getline(ref,vnStr,'/');
int v = atoi(vStr.c_str());
int vt = atoi(vtStr.c_str());
int vn = atoi(vnStr.c_str());
v =(v> = 0?v:positions.size()+ v);
vt =(vt> = 0?vt:texcoords.size()+ vt);
vn =(vn> = 0?vn:normals.size()+ vn);
refs.push_back(VertRef(v,vt,vn));
}
if(refs.size()< 3)
{
//错误,跳过
continue;
}
//三角形,假设n> 3-gons是凸的和共面的
VertRef * p [3] = {& refs [0],NULL, ;
for(size_t i = 1; i + 1< refs.size(); ++ i)
{
p [1] =& refs [i + 0];
p [2] =& refs [i + 1];
// http://www.opengl.org/wiki/Calculating_a_Surface_Normal
vec3 U(positions [p [1] - > v] - positions [p [0] - > ; v]);
vec3 V(positions [p [2] - > v] - positions [p [0] - > v]);
vec3 faceNormal = normalize(cross(U,V));
for(size_t j = 0; j <3; ++ j)
{
顶点vert;
vert.position = vec3(positions [p [j] - > v]);
vert.texcoord = vec2(texcoords [p [j] - > vt]);
vert.normal =(p [j] - > vn!= 0?normals [p [j] - > vn]:faceNormal);
verts.push_back(vert);
}
}
}
}
return verts;
}
int btn;
ivec2 startMouse;
ivec2 startRot,curRot;
ivec2 startTrans,curTrans;
void mouse(int button,int state,int x,int y)
{
if(button == GLUT_LEFT_BUTTON&& state == GLUT_DOWN)
{
btn = button;
startMouse = ivec2(x,glutGet(GLUT_WINDOW_HEIGHT) - y);
startRot = curRot;
}
if(button == GLUT_RIGHT_BUTTON&& state == GLUT_DOWN)
{
btn = button;
startMouse = ivec2(x,glutGet(GLUT_WINDOW_HEIGHT) - y);
startTrans = curTrans;
}
}
void motion(int x,int y)
{
ivec2 curMouse(x,glutGet(GLUT_WINDOW_HEIGHT) - y);
if(btn == GLUT_LEFT_BUTTON)
{
curRot = startRot +(curMouse - startMouse);
}
else if(btn == GLUT_RIGHT_BUTTON)
{
curTrans = startTrans +(curMouse - startMouse);
}
glutPostRedisplay();
}
vector<顶点>模型;
void display()
{
glClearColor(0.2f,0.2f,0.2f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet(GLUT_WINDOW_WIDTH);
double h = glutGet(GLUT_WINDOW_HEIGHT);
double ar = w / h;
glTranslatef(curTrans.x / w * 2,curTrans.y / h * 2,0);
gluPerspective(60,ar,0.1,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0,0,-10);
glPushMatrix();
{
glRotatef(curRot.x%360,0,1,0);
glRotatef(-curRot.y%360,1,0,0);
// object
glColor3ub(255,0,0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3,GL_FLOAT,sizeof(Vertex),& model [0] .position);
glTexCoordPointer(2,GL_FLOAT,sizeof(Vertex),& model [0] .texcoord);
glNormalPointer(GL_FLOAT,sizeof(Vertex),& model [0] .normal);
glDrawArrays(GL_TRIANGLES,0,model.size());
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
// bounding cube
glDisable(GL_LIGHTING);
glColor3ub(255,255,255);
glutWireCube(7);
glEnable(GL_LIGHTING);
}
glPopMatrix();
glutSwapBuffers();
}
//返回pts的最小/最大点
template< typename Vec>
pair< Vec,Vec> GetExtents(const Vec * pts,size_t stride,size_t count)
{
unsigned char * base =(unsigned char *)pts;
Vec pmin(*(Vec *)base);
Vec pmax(*(Vec *)base);
for(size_t i = 0; i {
const Vec& pt = *(Vec *)base;
pmin = glm :: min(pmin,pt);
pmax = glm :: max(pmax,pt);
}
return make_pair(pmin,pmax);
}
//围绕原点
//居中几何,并缩放到适合尺寸^ 3盒
模板< typename Vec>
void CenterAndScale(Vec * pts,size_t stride,size_t count,const typename Vec :: value_type& size)
{
typedef typename Vec :: value_type Scalar;
//获取最小/最大范围
pair< Vec,Vec> exts = GetExtents(pts,stride,count);
//中心和缩放
const Vec center =(exts.first * Scalar(0.5))+(exts.second * Scalar(0.5f));
const标量因子= size / glm :: compMax(exts.second - exts.first);
unsigned char * base =(unsigned char *)pts;
for(size_t i = 0; i {
Vec& pt = *(Vec *)base;
pt =((pt - center)* factor);
}
}
int main(int argc,char ** argv)
{
ifstream ifile(test.obj);
model = LoadOBJ(ifile);
CenterAndScale(& model [0] .position,sizeof(Vertex),model.size(),7);
glutInit(& argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(640,480);
glutCreateWindow(OBJ);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glEnable(GL_DEPTH_TEST);
//设置headlamplike light
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat position [] = {0,0,1,0};
glLightfv(GL_LIGHT0,GL_POSITION,position);
glPolygonMode(GL_FRONT,GL_FILL);
glPolygonMode(GL_BACK,GL_LINE);
glutMainLoop();
return 0;
}
LMB-拖动旋转,人民币拖动平底锅
并使用:
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
f -4 -3 -2 -1
v 2.000000 2.000000 0.000000
v 2.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 2000000 0.000000
f -4 -3 -2 -1
v 2.000000 2.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
f -4 -3 -2 -1
v 0.000000 2.000000 0.000000
v 0.000000 2.000000 2.000000
v 2.000000 2.000000 2.000000
v 2.000000 2.000000 0.000000
f -4 -3 -2 -1
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 2.000000
v 0.000000 2.000000 2.000000
f -4 -3 -2 -1
v 0.000000 0.000000 2.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 0.000000 2.000000
f -4 -3 -2 -1
或:
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
v 4.000000 0.000000 -1.255298
v 4.000000 2.000000 -1.255298
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.276597 0.000000 0.960986
vn 0.276597 0.000000 0.960986
vn 0.531611 0.000000 0.846988
vn 0.531611 0.000000 0.846988
#6 vertices
#6 normals
g all
s 1
f 1 // 1 2 // 2 3 // 3 4 // 4
f 4 // 4 3 // 3 5 // 5 6 // 6
#2 elements
test.obj
。
glm.hpp
GLM库。
I have create a program in C++ that contains also opengl and I want to create also an obj loader in order to load an obj file I have ! I have already created two functions which are :
void ReadFile(model *md)
{
// Open the file for reading OBJINFO.TXT
ifstream obj_file("tree.obj");
if (obj_file.fail())
exit(1);
// Get the number of vertices
obj_file >> md->vertices;
// Get the number of faces
obj_file >> md->faces;
// Get the vertex coordinates
for (int i = 0; i < md->vertices; i++)
{
obj_file >> md->obj_points[i].x;
obj_file >> md->obj_points[i].y;
obj_file >> md->obj_points[i].z;
}
// Get the face structure
for (int i = 0; i < md->faces; i++)
{
obj_file >> md->obj_faces[i].vn[0];
obj_file >> md->obj_faces[i].vn[1];
obj_file >> md->obj_faces[i].vn[2];
obj_file >> md->obj_faces[i].vn[3];
}
obj_file.close();
}
void DisplayModel(model md)
{
glPushMatrix();
glBegin(GL_TRIANGLES);
for (int i = 0; i < md.faces; i++)
{
glVertex3f(md.obj_points[md.obj_faces[i].vn[0]-1].x, md.obj_points[md.obj_faces[i].vn[0]-1].y, md.obj_points[md.obj_faces[i].vn[0]-1].z);
glVertex3f(md.obj_points[md.obj_faces[i].vn[1]-1].x, md.obj_points[md.obj_faces[i].vn[1]-1].y, md.obj_points[md.obj_faces[i].vn[1]-1].z);
glVertex3f(md.obj_points[md.obj_faces[i].vn[2]-1].x, md.obj_points[md.obj_faces[i].vn[2]-1].y, md.obj_points[md.obj_faces[i].vn[2]-1].z);
glVertex3f(md.obj_points[md.obj_faces[i].vn[2]-1].x, md.obj_points[md.obj_faces[i].vn[2]-1].y, md.obj_points[md.obj_faces[i].vn[3]-1].z);
}
glEnd();
glPopMatrix();
}
The main problem is that when I compile the project and run it , nothing appears in viewport . I increased also the dimensions of viewport in case it is small in order to appear the object , but the situation remains the same ! So I reach the result that I have done something wrong in these functions ! Could anyone help me ?!
Also I give some values of my obj file :
v 0.158000 0.975000 0.151491 1.000000
v 0.188743 0.025000 0.173826 1.000000
v 0.196000 0.025000 0.151491 1.000000
v 0.158000 0.025000 0.151491 1.000000
v 0.169743 0.025000 0.187631 1.000000
v 0.146257 0.025000 0.187631 1.000000
v 0.127257 0.025000 0.173826 1.000000
vn 0.950370 0.038015 0.308791
vn 0.950370 0.038015 0.308791
vn 0.950370 0.038015 0.308791
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 -0.000000
vn 0.587380 0.038015 0.808418
f 1//1 2//2 3//3
f 4//4 3//5 2//6
f 1//7 5//8 2//9
f 4//10 2//11 5//12
f 1//13 6//14 5//15
f 4//16 5//17 6//18
f 1//19 7//20 6//21
// Get the number of vertices
obj_file >> md->vertices;
// Get the number of faces
obj_file >> md->faces;
Read the spec again. That's not how OBJs work. You have to parse out the vertexes/texture coordinates/normals/faces as you go along.
Try something like this:
// g++ main.cpp -o main -lglut -lGL -lGLU && ./main
#include <GL/glut.h>
#include <glm/glm.hpp>
#include <glm/gtx/component_wise.hpp>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
using namespace glm;
struct Vertex
{
vec3 position;
vec2 texcoord;
vec3 normal;
};
struct VertRef
{
VertRef( int v, int vt, int vn )
: v(v), vt(vt), vn(vn)
{ }
int v, vt, vn;
};
vector< Vertex > LoadOBJ( istream& in )
{
vector< Vertex > verts;
vector< vec4 > positions( 1, vec4( 0, 0, 0, 0 ) );
vector< vec3 > texcoords( 1, vec3( 0, 0, 0 ) );
vector< vec3 > normals( 1, vec3( 0, 0, 0 ) );
string lineStr;
while( getline( in, lineStr ) )
{
istringstream lineSS( lineStr );
string lineType;
lineSS >> lineType;
// vertex
if( lineType == "v" )
{
float x = 0, y = 0, z = 0, w = 1;
lineSS >> x >> y >> z >> w;
positions.push_back( vec4( x, y, z, w ) );
}
// texture
if( lineType == "vt" )
{
float u = 0, v = 0, w = 0;
lineSS >> u >> v >> w;
texcoords.push_back( vec3( u, v, w ) );
}
// normal
if( lineType == "vn" )
{
float i = 0, j = 0, k = 0;
lineSS >> i >> j >> k;
normals.push_back( normalize( vec3( i, j, k ) ) );
}
// polygon
if( lineType == "f" )
{
vector< VertRef > refs;
string refStr;
while( lineSS >> refStr )
{
istringstream ref( refStr );
string vStr, vtStr, vnStr;
getline( ref, vStr, '/' );
getline( ref, vtStr, '/' );
getline( ref, vnStr, '/' );
int v = atoi( vStr.c_str() );
int vt = atoi( vtStr.c_str() );
int vn = atoi( vnStr.c_str() );
v = ( v >= 0 ? v : positions.size() + v );
vt = ( vt >= 0 ? vt : texcoords.size() + vt );
vn = ( vn >= 0 ? vn : normals.size() + vn );
refs.push_back( VertRef( v, vt, vn ) );
}
if( refs.size() < 3 )
{
// error, skip
continue;
}
// triangulate, assuming n>3-gons are convex and coplanar
VertRef* p[3] = { &refs[0], NULL, NULL };
for( size_t i = 1; i+1 < refs.size(); ++i )
{
p[1] = &refs[i+0];
p[2] = &refs[i+1];
// http://www.opengl.org/wiki/Calculating_a_Surface_Normal
vec3 U( positions[ p[1]->v ] - positions[ p[0]->v ] );
vec3 V( positions[ p[2]->v ] - positions[ p[0]->v ] );
vec3 faceNormal = normalize( cross( U, V ) );
for( size_t j = 0; j < 3; ++j )
{
Vertex vert;
vert.position = vec3( positions[ p[j]->v ] );
vert.texcoord = vec2( texcoords[ p[j]->vt ] );
vert.normal = ( p[j]->vn != 0 ? normals[ p[j]->vn ] : faceNormal );
verts.push_back( vert );
}
}
}
}
return verts;
}
int btn;
ivec2 startMouse;
ivec2 startRot, curRot;
ivec2 startTrans, curTrans;
void mouse(int button, int state, int x, int y )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
btn = button;
startMouse = ivec2( x, glutGet( GLUT_WINDOW_HEIGHT ) - y );
startRot = curRot;
}
if( button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN )
{
btn = button;
startMouse = ivec2( x, glutGet( GLUT_WINDOW_HEIGHT ) - y );
startTrans = curTrans;
}
}
void motion( int x, int y )
{
ivec2 curMouse( x, glutGet( GLUT_WINDOW_HEIGHT ) - y );
if( btn == GLUT_LEFT_BUTTON )
{
curRot = startRot + ( curMouse - startMouse );
}
else if( btn == GLUT_RIGHT_BUTTON )
{
curTrans = startTrans + ( curMouse - startMouse );
}
glutPostRedisplay();
}
vector< Vertex > model;
void display()
{
glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double ar = w / h;
glTranslatef( curTrans.x / w * 2, curTrans.y / h * 2, 0 );
gluPerspective( 60, ar, 0.1, 100 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0, 0, -10 );
glPushMatrix();
{
glRotatef( curRot.x % 360, 0, 1, 0 );
glRotatef( -curRot.y % 360, 1, 0, 0 );
// object
glColor3ub( 255, 0, 0 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), &model[0].position );
glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), &model[0].texcoord );
glNormalPointer( GL_FLOAT, sizeof(Vertex), &model[0].normal );
glDrawArrays( GL_TRIANGLES, 0, model.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
// bounding cube
glDisable( GL_LIGHTING );
glColor3ub( 255, 255, 255 );
glutWireCube( 7 );
glEnable( GL_LIGHTING );
}
glPopMatrix();
glutSwapBuffers();
}
// return the min/max points of pts
template< typename Vec >
pair< Vec, Vec > GetExtents( const Vec* pts, size_t stride, size_t count )
{
unsigned char* base = (unsigned char*)pts;
Vec pmin( *(Vec*)base );
Vec pmax( *(Vec*)base );
for( size_t i = 0; i < count; ++i, base += stride )
{
const Vec& pt = *(Vec*)base;
pmin = glm::min( pmin, pt );
pmax = glm::max( pmax, pt );
}
return make_pair( pmin, pmax );
}
// centers geometry around the origin
// and scales it to fit in a size^3 box
template< typename Vec >
void CenterAndScale( Vec* pts, size_t stride, size_t count, const typename Vec::value_type& size )
{
typedef typename Vec::value_type Scalar;
// get min/max extents
pair< Vec, Vec > exts = GetExtents( pts, stride, count );
// center and scale
const Vec center = ( exts.first * Scalar( 0.5 ) ) + ( exts.second * Scalar( 0.5f ) );
const Scalar factor = size / glm::compMax( exts.second - exts.first );
unsigned char* base = (unsigned char*)pts;
for( size_t i = 0; i < count; ++i, base += stride )
{
Vec& pt = *(Vec*)base;
pt = ( ( pt - center ) * factor );
}
}
int main( int argc, char **argv )
{
ifstream ifile( "test.obj" );
model = LoadOBJ( ifile );
CenterAndScale( &model[0].position, sizeof( Vertex ), model.size(), 7 );
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "OBJ" );
glutDisplayFunc( display );
glutMouseFunc( mouse );
glutMotionFunc( motion );
glEnable( GL_DEPTH_TEST );
// set up "headlamp"-like light
glShadeModel( GL_SMOOTH );
glEnable( GL_COLOR_MATERIAL );
glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
GLfloat position[] = { 0, 0, 1, 0 };
glLightfv( GL_LIGHT0, GL_POSITION, position );
glPolygonMode( GL_FRONT, GL_FILL );
glPolygonMode( GL_BACK, GL_LINE );
glutMainLoop();
return 0;
}
LMB-drag rotates, RMB-drag "pans".
And use this:
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
f -4 -3 -2 -1
v 2.000000 2.000000 0.000000
v 2.000000 0.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 2.000000 0.000000
f -4 -3 -2 -1
v 2.000000 2.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
f -4 -3 -2 -1
v 0.000000 2.000000 0.000000
v 0.000000 2.000000 2.000000
v 2.000000 2.000000 2.000000
v 2.000000 2.000000 0.000000
f -4 -3 -2 -1
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 0.000000 0.000000 2.000000
v 0.000000 2.000000 2.000000
f -4 -3 -2 -1
v 0.000000 0.000000 2.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 0.000000 2.000000
f -4 -3 -2 -1
Or this:
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
v 4.000000 0.000000 -1.255298
v 4.000000 2.000000 -1.255298
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.276597 0.000000 0.960986
vn 0.276597 0.000000 0.960986
vn 0.531611 0.000000 0.846988
vn 0.531611 0.000000 0.846988
# 6 vertices
# 6 normals
g all
s 1
f 1//1 2//2 3//3 4//4
f 4//4 3//3 5//5 6//6
# 2 elements
for test.obj
.
glm.hpp
is from the GLM library.
这篇关于对象加载器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!