2 kimikimi4869 kimikimi4869 于 2014.10.25 19:32 提问

代码正常运行一会后出现 0xC0000005: 读取位置 0x00000010 时发生访问冲突

#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef struct V
{
GLdouble x;
GLdouble y;
GLdouble z;
GLdouble X;
GLdouble Y;
GLdouble Z;

GLdouble XN;
GLdouble YN;
GLdouble ZN;
}V;//记录每个顶点窗口坐标、三维坐标以及法向量

V *vertex;

int v_num[2]={0,0}; //记录点的数量
int vn_num[2]={0,0};//记录法线的数量
int f_num[2]={0,0}; //记录面的数量

GLdouble **vArr; //存放点的二维数组
GLdouble **vnArr;//存放法线的二维数组
int **fvArr; //存放面顶点的二维数组
int **fnArr; //存放面法线的二维数组
char s1[100];//读取行的数组
GLfloat f2,f3,f4;//读取每行内容的变量
int a=0;
char showv[25]="";
char showf[25]="";
char space[5]=" ";
char showv1[25]="";
char showvn[25]="";
char vx[25]="";
char vy[25]="";
char vz[25]="";
char vnx[25]="";
char vny[25]="";
char vnz[25]="";//输出字符组

const int SIZE=256;

float movex=0;
float movey=0;
float len=4;
int x=0,y=0,z=0;
int xRange=0;
int yRange=0;
//运动变量

GLfloat LightAmbient[]= { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 8.0f, 10.0f };
GLfloat LightPosition[]= { 1.0f, 1.0f, 1.0f, 1.0f };
//灯光属性

int startx;
int starty;//鼠标点击坐标记录

int getLineNum(string addrstr)//读取文件的顶点数和面数
{
v_num[a]=0;
vn_num[a]=0;
f_num[a]=0;
ifstream infile(addrstr.c_str());
char sline[100];
while(infile.getline(sline,100))
{
if(sline[0]=='v')
{
if(sline[1]=='n')
vn_num[a]++;
else
v_num[a]++;
}
else if (sline[0]=='f')
f_num[a]++;
}
itoa(v_num[a],showv,10);
itoa(f_num[a],showf,10);
return 0;
}

int readfile(string addrstr) //将文件内容读到数组中去
{
vertex=new V[v_num[a]];
vArr=new GLdouble*[v_num[a]];
for (int i=0;i<v_num[a];i++)
{
vArr[i]=new GLdouble[3];
}
vnArr=new GLdouble*[vn_num[a]];
for (int i=0;i<vn_num[a];i++)
{
vnArr[i]=new GLdouble[3];
}
fvArr=new int*[f_num[a]];
fnArr=new int*[f_num[a]];
for (int i=0;i<f_num[a];i++)
{
fvArr[i]=new int[3];
fnArr[i]=new int[3];
}
ifstream infile(addrstr.c_str());
int ii=0,jj=0,kk=0;

char sline[100];
while(infile.getline(sline,100))

{
if(sline[0]=='v')
{
if(sline[1]=='n')//vn
{
istringstream sin(sline);
sin>>s1>>f2>>f3>>f4;
vnArr[ii][0]=f2;
vnArr[ii][1]=f3;
vnArr[ii][2]=f4;
vertex[ii].XN=f2;
vertex[ii].YN=f3;
vertex[ii].ZN=f4;
ii++;
}
else//v
{
istringstream sin(sline);
sin>>s1>>f2>>f3>>f4;
vArr[jj][0]=f2;
vArr[jj][1]=f3;
vArr[jj][2]=f4;
vertex[jj].X=f2;
vertex[jj].Y=f3;
vertex[jj].Z=f4;
jj++;
}
}

if (sline[0]=='f') //读取面
{
istringstream in(sline);
GLfloat a;

in>>s1;//去掉前缀f
int i,k;

for(i=0;i {
in>>s1;
//取得顶点索引和法线索引
a=0;
for(k=0;s1[k]!='/';k++)
{
a=a*10+(s1[k]-48);
}
fvArr[kk][i]=a;

a=0;
for(k=k+2;s1[k];k++)
{
  a=a*10+(s1[k]-48);;
}
fnArr[kk][i]=a;

}
kk++;
}
}
return 0;
}

void drawbunny()
{

glBegin(GL_TRIANGLES);
for (int i=0;i<f_num[a];i++)
{
glNormal3f(vnArr[fnArr[i][0]-1][0], vnArr[fnArr[i][0]-1][1],
vnArr[fnArr[i][0]-1][2]);
glVertex3f(vArr[fvArr[i][0]-1][0], vArr[fvArr[i][0]-1][1],
vArr[fvArr[i][0]-1][2]);
glNormal3f(vnArr[fnArr[i][1]-1][0], vnArr[fnArr[i][1]-1][1],
vnArr[fnArr[i][1]-1][2]);
glVertex3f(vArr[fvArr[i][1]-1][0], vArr[fvArr[i][1]-1][1],
vArr[fvArr[i][1]-1][2]);
glNormal3f(vnArr[fnArr[i][2]-1][0], vnArr[fnArr[i][2]-1][1],
vnArr[fnArr[i][2]-1][2]);
glVertex3f(vArr[fvArr[i][2]-1][0], vArr[fvArr[i][2]-1][1],
vArr[fvArr[i][2]-1][2]);
}

glEnd();

GLuint base;/*显示顶点数,面数,以及鼠标点击顶点坐标,顶点法向量*/
base=glGenLists(256);
for(int i=0;i<256;++i)
{
    glNewList(base+i,GL_COMPILE);
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,i);
    glEndList();
}
glColor3f(1.0,1.0,1.0);
glRasterPos2f(0.0,-0.1);
glListBase(base);
glCallLists((GLint)strlen("V"),GL_UNSIGNED_BYTE,"V");
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(showv),GL_UNSIGNED_BYTE,showv);
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen("F"),GL_UNSIGNED_BYTE,"F");
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(showf),GL_UNSIGNED_BYTE,showf);

glRasterPos2f(-0.2,-0.2);
glCallLists((GLint)strlen("v"),GL_UNSIGNED_BYTE,"v");
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(vx),GL_UNSIGNED_BYTE,vx);
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(vy),GL_UNSIGNED_BYTE,vy);
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(vz),GL_UNSIGNED_BYTE,vz);


glRasterPos2f(-0.2,-0.15);
glCallLists((GLint)strlen("vn"),GL_UNSIGNED_BYTE,"vn");
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(vnx),GL_UNSIGNED_BYTE,vnx);
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(vny),GL_UNSIGNED_BYTE,vny);
glCallLists((GLint)strlen(space),GL_UNSIGNED_BYTE,space);
glCallLists((GLint)strlen(vnz),GL_UNSIGNED_BYTE,vnz);

glFlush();
glutSwapBuffers();

}

void myDisplay()
{

}

void IdleDisplay()
{
glEnable(GL_DEPTH_TEST);

glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫射光
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // 设置光源位置
glEnable(GL_LIGHT1);



glClearColor(0.0, 0.0, 0.0, 0.0);

glViewport(0,0,800,800);

GLint viewport[4]; 
glGetIntegerv( GL_VIEWPORT , viewport ); 

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -10, 10);  

GLdouble projectionMatrix[16]; 
glGetDoublev( GL_PROJECTION_MATRIX , projectionMatrix ); 


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(movex,movey,0);
glScalef(len,len,len);
glRotatef(xRange, 1, 0, 0);
glRotatef(yRange, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);

GLdouble modelMatrix[16]; 
glGetDoublev( GL_MODELVIEW_MATRIX , modelMatrix ); 

for(int i=0;i<v_num[a];i++)
    gluProject(vertex[i].X,vertex[i].Y,vertex[i].Z,modelMatrix,projectionMatrix,viewport,&vertex[i].x,&vertex[i].y,&vertex[i].z);//计算每个顶点的窗口坐标

drawbunny();

}

//控制
void moveright()

{ movex+=0.2;

if (movex>5.0)

movex=0.0;

glutPostRedisplay();

}

void moveleft()

{ movex-=0.2;

if (movex<-5.0)

movex=0.0;

glutPostRedisplay();

}

void moveup()
{

movey+=0.2;

if (movey>5.0)

movey=0.0;

glutPostRedisplay();

}

void movedown()
{

movey-=0.2;

if (movey<-5.0)

movey=0.0;

glutPostRedisplay();
}

void shrink()
{
len-=0.1;
if(len<-10)
len=-10;
glutPostRedisplay();
}

void zoom()
{
len+=0.1;
if(len>10)
len=10;
glutPostRedisplay();
}

void specialKeyFunc(int key,int x,int y)
{
switch(key)
{
case GLUT_KEY_RIGHT:
moveright();
break;
case GLUT_KEY_LEFT:
moveleft();
break;
case GLUT_KEY_DOWN:
movedown();
break;
case GLUT_KEY_UP:
moveup();
break;
case GLUT_KEY_F1:
zoom();
break;
case GLUT_KEY_F2:
shrink();
break;
default:
break;
}
}

void processmenu(int value)
{
if(value==1)
{
a=0;
getLineNum("bunny.obj");
readfile("bunny.obj");
glutIdleFunc(&IdleDisplay);
}
if(value==2)
{
a=1;
getLineNum("mycube.obj");
readfile("mycube.obj");
glutIdleFunc(&IdleDisplay);
}
}

void mouse(int button,int state,int x,int y)
{
if (button != GLUT_LEFT_BUTTON ||
state != GLUT_DOWN) return;

if(state==GLUT_DOWN)

startx=x,starty=y;

GLdouble temp;
GLdouble min=100000;
for(int i=0;i {
if(vertex[i].x>x-5&&vertex[i].x(800-y)-5&&vertex[i].y<800-y+5)//顶点的窗口坐标在鼠标点击范围内
{
temp=sqrt(pow(x-vertex[i].x,2)+pow((800-y)-vertex[i].y,2));
if(temp<min)//取距离鼠标点击位置最近的顶点
min=temp;
}
}

int flag=0;
GLdouble v[2][4];
GLdouble vn[2][4];
GLdouble zmin;

for(int i=0;i if(sqrt(pow(x-vertex[i].x,2)+pow((800-y)-vertex[i].y,2))==min)//根据获得的最小值依次查询相应顶点
{
if(flag==0)
{
flag++;
v[0][0]=vertex[i].X;
v[0][1]=vertex[i].Y;
v[0][2]=vertex[i].Z;
v[0][3]=1;
vn[0][0]=vertex[i].XN;
vn[0][1]=vertex[i].YN;
vn[0][2]=vertex[i].ZN;
zmin=vertex[i].z;
continue;
}
if(flag==1)//避免两点恰好重合的情况,如果两点恰好重合,取前点
{
v[1][0]=vertex[i].X;
v[1][1]=vertex[i].Y;
v[1][2]=vertex[i].Z;
v[1][3]=1;
vn[1][0]=vertex[i].XN;
vn[1][1]=vertex[i].YN;
vn[1][2]=vertex[i].ZN;
if(vertex[i].z>zmin)
{
v[1][3]=1;
v[0][3]=0;
}
else
{
v[0][3]=1;
v[1][3]=0;
}
}
}

    if(v[0][3]==1)
    {
        sprintf(vx,"%lf",v[0][0]);
        sprintf(vy,"%lf",v[0][1]);
        sprintf(vz,"%lf",v[0][2]);
        sprintf(vnx,"%lf",vn[0][0]);
        sprintf(vny,"%lf",vn[0][1]);
        sprintf(vnz,"%lf",vn[0][2]);
    }
    if(v[1][3]==1)
        {
        sprintf(vx,"%lf",v[1][0]);
        sprintf(vy,"%lf",v[1][1]);
        sprintf(vz,"%lf",v[1][2]);
        sprintf(vnx,"%lf",vn[1][0]);
        sprintf(vny,"%lf",vn[1][1]);
        sprintf(vnz,"%lf",vn[1][2]);
    }

glutPostRedisplay();

}

void onMouseMove(int x,int y)
{
xRange += 3.14159265 * (y - starty) / 5;
if(xRange >= 360 || xRange <= -360)
xRange = 0;

yRange += 3.14159265 * (x - startx) / 5;
if(yRange >= 360 || yRange <= -360)
    yRange = 0;

startx = x; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备
starty = y;

}

int main(int argc, char *argv[])
{

glutInit(&argc, argv);  
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowPosition(100, 100); 

   glutInitWindowSize(800, 800);  
   glutCreateWindow("OBJ"); 

   int id=glutCreateMenu(processmenu);
   glutAddMenuEntry("model1",1);
   glutAddMenuEntry("model2",2);
   glutAttachMenu(GLUT_RIGHT_BUTTON);



glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);

 glutDisplayFunc(&myDisplay); 

glutSpecialFunc(specialKeyFunc);
glutMouseFunc(mouse);
glutMotionFunc(onMouseMove);


glutMainLoop(); 

return 0; 

}

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!