c++ - glDrawElements() draw my .obj models wrong -
i'm having problem "gldrawelements" function in opengl. when drawing model function i'm seeing artifacts:
i didn't add light or texture.
i wrote class c++:
//the obj-catcher.h //just ignore chinese in code.... #include <gl\glut.h> #include <gl\glaux.h> #include"stdlib.h" #include"string.h" #include"cstdio" #include"math.h" #include"time.h" #define max_line_length 1024 //å符串å¤å¶æ大é¿åº¦ aux_rgbimagerec *loadbmp(char *filename) // loads bitmap image { file *file=null; // file handle if (!filename) // make sure filename given { return null; // if not return null } file=fopen(filename,"r"); // check see if file exists if (file) // file exist? { fclose(file); // close handle return auxdibimageload(filename); // load bitmap , return pointer } return null; // if load failed return null } int loadgltextures(int num,char *dir,unsigned int * texture) // load bitmaps , convert textures å è½½çå¾ååªè½æ¯2çå¹ { int status=false; // status indicator aux_rgbimagerec *textureimage[1]; // create storage space texture memset(textureimage,0,sizeof(textureimage)); // set pointer null // load bitmap, check errors, if bitmap's not found quit if (textureimage[0]=loadbmp(dir)) { status=true; // set status true glgentextures(1, &texture[num]); // create texture // typical texture generation using data bitmap glbindtexture(gl_texture_2d, texture[num]); glteximage2d(gl_texture_2d, 0, 3, textureimage[0]->sizex, textureimage[0]->sizey, 0, gl_rgb, gl_unsigned_byte, textureimage[0]->data); gltexparameteri(gl_texture_2d,gl_texture_min_filter,gl_linear); gltexparameteri(gl_texture_2d,gl_texture_mag_filter,gl_nearest); } if (textureimage[0]) // if texture exists { if (textureimage[0]->data) // if texture image exists free(textureimage[0]->data); // free texture image memory free(textureimage[0]); // free image structure } return status; // return status } typedef struct vertex { glfloat pos[3];//ä¾æ¬¡æ¯x,y,z }vertex; typedef struct vertexnormals { glfloat io[3]; }vertexnormals; typedef struct texturecoords { glfloat io[3]; }texturecoords; typedef struct vertexindex { unsigned int vertex[3]; }vertexindex; bool fco(file *file) { if(fclose(file)!=0) { perror("fclose"); exit(exit_failure); } return true; } bool getsurface(char *src,vertexindex &vindex)//get surface { if(src[0]!='f'||src[1]!=' ') return false; int i; int result=0; for(i=1;i==' ';i++);i++; for(;;i++) { if(src[i]==' ') break; if(src[i]=='/') break; else { result*=10; result+=src[i]-48; } } vindex.vertex[0]=result-1; for(;;i++) if(src[i]==' ') break; for(;i==' ';i++);i++; result=0; for(;;i++) { if(src[i]==' ') break; if(src[i]=='/') break; else { result*=10; result+=src[i]-48; } } vindex.vertex[1]=result-1; for(;;i++) if(src[i]==' ') break; for(;i==' ';i++);i++; result=0; for(;;i++) { if(src[i]==' '||src[i]=='\0'||src[i]=='\n') break; if(src[i]=='/') break; else { result*=10; result+=src[i]-48; } } vindex.vertex[2]=result-1; return true; } bool getvertex(char *src,vertex &dir)//some shit in here|add:->the shit done { int i; bool flag[3]; bool pc[3]; double result=0; int db=0; bool floa; memset(flag,0,sizeof(flag));//æ¥åç¹åæ å®æ度å¤æ memset(pc,0,sizeof(pc));//æ£è´å¤æ if(src[0]!='v'||src[1]!=' ') return false; else { floa=false; for(i=1;src[i+1]==' ';i++);i++;//æ¾å°vä¹å第ä¸ä¸ªæ°æ®ä½ç½® for(;;i++) { if(src[i]=='\n'||src[i]=='\0') return false; if(src[i]==' ') break; if(src[i]=='-') pc[0]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[0]) result=-result; dir.pos[0]=result; for(;src[i+1]==' ';i++);i++;//æ¾å°ç¬¬ä¸ä¸ªæ°æ®ä¹å第äºä¸ªæ°æ®ä½ç½® floa=false; db=0; result=0; for(;;i++) { if(src[i]=='\n'||src[i]=='\0') return false; if(src[i]==' ') break; if(src[i]=='-') pc[1]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[1]) result=-result; dir.pos[1]=result; for(;src[i+1]==' ';i++);i++;//æ¾å°ç¬¬ä¸ä¸ªæ°æ®ä¹å第äºä¸ªæ°æ®ä½ç½® floa=false; db=0; result=0; for(;;i++) { if(src[i]=='\n'||src[i]=='\0') break; if(src[i]==' ') break; if(src[i]=='-') pc[2]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[2]) result=-result; dir.pos[2]=result; return true; } } bool getvertexnormals(char *src,vertexnormals &dir) { int i; bool flag[2]; bool pc[3]; double result=0; int db=0; bool floa; memset(flag,0,sizeof(flag)); memset(pc,0,sizeof(pc)); if(!(src[0]=='v'&&src[1]=='n'&&src[2]==' ')) { return false; } else { floa=false; for(i=1;src[i+1]==' ';i++);i++;//æ¾å°vä¹å第ä¸ä¸ªæ°æ®ä½ç½® for(;;i++) { if(src[i]=='\n'||src[i]=='\0') return false; if(src[i]==' ') break; if(src[i]=='-') pc[0]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[0]) result=-result; dir.io[0]=result; for(;src[i+1]==' ';i++);i++;//æ¾å°ç¬¬ä¸ä¸ªæ°æ®ä¹å第äºä¸ªæ°æ®ä½ç½® floa=false; db=0; result=0; for(;;i++) { if(src[i]=='\n'||src[i]=='\0') return false; if(src[i]==' ') break; if(src[i]=='-') pc[1]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[1]) result=-result; dir.io[1]=result; for(;src[i+1]==' ';i++);i++;//æ¾å°ç¬¬ä¸ä¸ªæ°æ®ä¹å第äºä¸ªæ°æ®ä½ç½® floa=false; db=0; result=0; for(;;i++) { if(src[i]=='\n'||src[i]=='\0') break; if(src[i]==' ') break; if(src[i]=='-') pc[2]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[2]) result=-result; dir.io[2]=result; return true; } } bool gettexturecoords(char *src,texturecoords &dir) { int i; bool flag[2]; bool pc[3]; double result=0; int db=0; bool floa; memset(flag,0,sizeof(flag)); memset(pc,0,sizeof(pc)); if(!(src[0]=='v'&&src[1]=='t'&&src[2]==' ')) { return false; } else { floa=false; for(i=1;src[i+1]==' ';i++);i++;//æ¾å°vä¹å第ä¸ä¸ªæ°æ®ä½ç½® for(;;i++) { if(src[i]=='\n'||src[i]=='\0') return false; if(src[i]==' ') break; if(src[i]=='-') pc[0]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[0]) result=-result; dir.io[0]=result; for(;src[i+1]==' ';i++);i++;//æ¾å°ç¬¬ä¸ä¸ªæ°æ®ä¹å第äºä¸ªæ°æ®ä½ç½® floa=false; db=0; result=0; for(;;i++) { if(src[i]=='\n'||src[i]=='\0') return false; if(src[i]==' ') break; if(src[i]=='-') pc[1]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[1]) result=-result; dir.io[1]=result; for(;src[i+1]==' ';i++);i++;//æ¾å°ç¬¬ä¸ä¸ªæ°æ®ä¹å第äºä¸ªæ°æ®ä½ç½® floa=false; db=0; result=0; for(;;i++) { if(src[i]=='\n'||src[i]=='\0') break; if(src[i]==' ') break; if(src[i]=='-') pc[2]=true; if(src[i]<=57&&src[i]>=48) { if(!floa) { result*=10; result+=src[i]-48; } else { result+=(src[i]-48)*pow(10.0,--db); } } else { if(src[i]=='.') floa=true; } } if(pc[2]) result=-result; dir.io[2]=result; return true; } } bool getdir(char * dir,char * tem) { int i,m=strlen(tem),num=0,j; for(i=0;i<m;i++) { if(dir[i]=='\\') num++; } for(i=0,j=0;i<m;i++) { tem[i]=dir[i]; if(dir[i]=='\\') j++; if(j==num) break; } tem[i+1]='\0'; return true; } bool getmtl(char *src,file *fp,char * dir) { int i,m=strlen(src),n; char temp[100]; if(m<6) return false; if(!(src[0]=='m'&&src[1]=='t'&&src[2]=='l'&&src[3]=='l'&&src[4]=='i'&&src[5]=='b'&&src[6]==' ')) return false; src[m-1]='\0'; getdir(dir,temp); n=strlen(temp); for(i=n;i<m;i++) temp[i]=src[i-n+7]; fp=fopen(temp,"r"); if(fp==null) { perror(temp); return false; } else printf("导å¥æè´¨åºæå :%s\n",temp); return true; } class container { public: container(char *fp)//使ç¨æ¶å¿é¡»ä¿è¯objä¸æ¯è¡åªæä¸æ¡æ令 { int t1,t2; t1=clock(); int cur=0; int i[8]={0,0,0,0,0,0,0,0}; int vcur=0; int tcur=0; mtlfnum=0; vertexnumber=0; trianglenumber=0; vertexnormals=0; texturecoords=0; if((file=fopen(fp,"r"))==null) { perror(fp); exit(1); } printf("第ä¸æ¬¡éåæ件é¢å¤çä¸...\n"); while(fgets(buffer,max_line_length,file)!=null) { cur++; if(buffer[0]=='#') continue; if(buffer[0]=='m'&&buffer[1]=='t'&&buffer[2]=='l'&&buffer[3]=='l'&&buffer[4]=='i'&&buffer[5]=='b'&&buffer[6]==' ')//ç±äº&&符å·ççè·¯æåºæ以ä¸ä¼éæ³è®¿é®åå mtlfnum++; if(buffer[0]=='v'&&buffer[1]==' ') vertexnumber++; if(buffer[0]=='f') trianglenumber++; if(buffer[0]=='v'&&buffer[1]=='n') vertexnormals++; if(buffer[0]=='v'&&buffer[1]=='t') texturecoords++; } printf("第ä¸æ¬¡é¢å¤çå·²ç»æ\nåå¾ä¿¡æ¯:æè´¨åºæ°:%d 顶ç¹æ°ï¼%d é¢æ°:%d æ³çº¿æ°ï¼%d 纹çåæ æ°:%d\n",mtlfnum,vertexnumber,trianglenumber,vertexnormals,texturecoords); v=new vertex [vertexnumber]; vn=new vertexnormals[vertexnormals]; vt=new texturecoords[texturecoords]; vindex=new vertexindex[trianglenumber]; mtl=new file * [mtlfnum]; fco(file); if((file=fopen(fp,"r"))==null) { perror(fp); exit(1); } cur=0; printf("æ£å¨è¯»å¥æ¨¡åæ°æ®...\n"); while(fgets(buffer,max_line_length,file)!=null) { cur++; if(i[0]<=vertexnumber) if(getvertex(buffer,v[i[0]])) i[0]++; if(i[1]<=trianglenumber) if(getsurface(buffer,vindex[i[1]])) i[1]++; if(i[2]<=vertexnormals) if(getvertexnormals(buffer,vn[i[2]])) i[2]++; if(i[3]<=texturecoords) if(gettexturecoords(buffer,vt[i[3]])) i[3]++; if(i[4]<=mtlfnum) if(getmtl(buffer,mtl[i[4]],fp)) i[4]++; } t2=clock(); printf("读å¥æ¨¡åæåï¼\nç¨æ¶%5d(ms)\n",t2-t1); } ~container() { fco(file); if(v) { delete(v); v=null; } if(vt) { delete(vt); vt=null; } if(vn) { delete(vn); vn=null; } if(mtl) { for(int i=0;i<mtlfnum;i++) fco(mtl[i]); delete mtl; mtl=null; } } inline int get_tnum(){return trianglenumber;} inline int get_vnum(){return vertexnumber;} inline int get_vnnum(){return vertexnormals;} inline int get_vtnum(){return texturecoords;} inline vertex * get_v() {return v; } inline vertexnormals* get_vn(){return vn; } inline texturecoords* get_vt(){return vt; } inline vertexindex* get_vi(){return vindex; } private: file *file; int vertexnumber; int trianglenumber; int vertexnormals; int mtlfnum; int texturecoords; char buffer[max_line_length]; file **mtl; vertexindex *vindex; vertex *v; texturecoords *vt; vertexnormals *vn; };
and
#include <gl\glut.h> #include <math.h> #include"obj-catcher.h" #include"stdlib.h" container a("models\\scar.obj"); #define gl_pi 3.1415926f #define bcull 1 #define bdepth 1 #define boutline 1 double xrot=0.0f,yrot=0.0f,x=0.0f,y=0.0f,dx=0.8f,dy=1.0f; glfloat nrange=50.0f; static glfloat aspe; unsigned int te[37]; gluint sample=1; void setuprc() { glclearcolor(0.0f,0.0f,0.0f,1.0f); glcolor3f(0.0f,1.0f,0.0f); glshademodel(gl_flat);//单调着色 glenableclientstate(gl_vertex_array); glvertexpointer(3,gl_float,0,(float *)a.get_v()); glnewlist(sample,gl_compile); gldrawelements(gl_triangles,a.get_tnum()*3,gl_unsigned_int,a.get_vi()); glendlist(); } void changesize(glsizei w,glsizei h) { if(h==0) h=1; glviewport(0,0,w,h); glmatrixmode(gl_projection); glloadidentity(); if(w<=h) { aspe=h/w; glortho(-nrange,nrange,-nrange*h/w,nrange*h/w,-nrange,nrange); } else { aspe=w/h; glortho(-nrange*w/h,nrange*w/h,-nrange,nrange,-nrange,nrange); } glmatrixmode(gl_modelview); glloadidentity(); glutswapbuffers(); } void renderscene(void) { glclear(gl_color_buffer_bit|gl_depth_buffer_bit); glcolor3f(1.0,1.0,1.0); glpushmatrix(); // yrot++; if(yrot>360) yrot=0; glrotatef(xrot,1.0f,0.0f,0.0f); glrotatef(yrot,0.0f,1.0f,0.0f); glcalllist(sample); glpopmatrix(); glutswapbuffers(); } void processspecialkeys(int key,int x,int y)//键位控制 { if(key==glut_key_up) xrot--; if(key==glut_key_down) xrot++; if(key==glut_key_right) yrot++; if(key==glut_key_left) yrot--; if(key==27) exit(1); } void timerfunction(int value) { glutpostredisplay(); gluttimerfunc(1,timerfunction,1); } int main(int argc,char*argv[]) { glutinit( &argc , argv ); glutinitdisplaymode(glut_double|glut_rgb); glutinitwindowsize(400,400); glutcreatewindow("caption"); glutreshapefunc(changesize); glutdisplayfunc(renderscene); glutspecialfunc(processspecialkeys); gluttimerfunc(1,timerfunction,1); setuprc(); glutmainloop(); return 0; }
can give me advise solve problem?
looks either elements data or vertex data not correct or miss-aligned between them. have seen similar problems when don't specify correctly stride or offset on vertex data. post code here how setup elements , vertex arrays before calling gldrawelements.
tip: start small, example quad o cube, move complex mesh, add texturing , lighting.
Comments
Post a Comment