+-
程序的主要目标是画N条线段。
创建一个数组来收纳N条线段,
N是可变的,button每点击一次就扩容一次,
扩容后把随机生成的线段放到数组里面,
定时器不断地驱动着另一个函数来访问这个数组,
依据数组里面的数据,在OPENGL里画出直线。
//1个点由X,Y,Z(空间点)来描述。
struct Point3D {
unsigned int x, y, z;
Point3D(unsigned int _x, unsigned int _y, unsigned int _z) : x(_x), y(_y), z(_z) {}
};
//1条线段由2个端点来描述,
struct Line3D
{
Point3D start,end;
Line3D(Point3D _s, Point3D _e) :start(_s), end(_e) {};
};
unsigned int Line3D_Num = 0;//记录线段总数
unsigned int pos = -1;//扩容时用到
Line3D ** pLine3DArr ;//收纳线段的数组
下面是画线函数,
//画1条线段,输入参数是线段的两个点。
void DrawLine(Point3D start,Point3D end)
{
//之所以定义XYZABC,出于好辩认的目的
GLfloat x, y, z;
GLfloat a, b, c;
x = (GLfloat)start.x / 225;
y = (GLfloat)start.y / 225;
z = (GLfloat)start.z / 225;
a = (GLfloat)end.x / 225;
b = (GLfloat)end.y / 225;
c = (GLfloat)end.z / 225;
debug(("DrawLine >>\n"));
debug((" [%d,%d,%d],[%d,%d,%d]\n", start.x, start.y, start.z, end.x, end.y, end.z));
debug((" [%.3f,%.3f,%.3f],[%.3f,%.3f,%.3f]\n", x, y, z, a, b, c));
glBegin(GL_LINES);
{
glColor3ub(255, 0, 0);
glVertex3f(x, y, z); glVertex3f(a, b, c);
}
glEnd();
}
下面程序是把数组里面线段全画出来
void DrawLine3D(Line3D ** arr)
{
for (unsigned int i = 0; i < Line3D_Num; i++)
{
debug(("i:%d\n", i));
Line3D * ptr = arr[i];
Point3D p1 = ptr->start;
Point3D p2 = ptr->end;
DrawLine(p1, p2);
}
}
下面程序由button点击时触发
bool debug = 1;
Line3D_Num ++;
//数组扩容
Line3D ** pnew = (Line3D **)realloc(pLine3DArr, sizeof(Line3D *)*Line3D_Num);
if (!pnew)
{
debug(("485 >> realloc error\n"));
break;
}
pLine3DArr = pnew;
//增量扩容,
pos++;
for (int i = pos; i < Line3D_Num; i++)
{
Point3D p1(rnd(30, 255), rnd(30, 255), 30);
Point3D p2(rnd(30, 255), rnd(30, 255), 30);
Line3D L1(p1, p2);
pLine3DArr[i] = (Line3D *)malloc(sizeof(Line3D *));
pLine3DArr[i] = &L1;
}
if (debug)
{
debug(("Line3D_Num:%d\n", Line3D_Num));
DrawLine3D(pLine3DArr);
debug(("________________________\n"));
}
还有个随机数函数,随机数函数是有效的,四个随机都不相同
unsigned int rnd(unsigned int a, unsigned int b)
{
LARGE_INTEGER seed;
QueryPerformanceFrequency(&seed);
QueryPerformanceCounter(&seed);
srand(seed.QuadPart);//初始化一个以微秒为单位的时间种子
unsigned int number = rand() % (b - a + 1) + a;
debug(("rnd>>%d\n", number));
return number;
}
最后是调用画线的函数
//渲染一帧
void DrawGLScene(GLfloat rotx, GLfloat roty, GLfloat rotz)
{
//glViewport(0, 0, 2 * LOWORD(lParam), 2 * HIWORD(lParam));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除旧画面及景深缓存
glLoadIdentity(); // 重置模型观察矩阵
glTranslatef(0.0f,0.0f,rotz); // 顺着Z轴偏移rotz
glRotatef(roty,1.0f,0.0f,0.0f); // 绕X轴旋转roty
glRotatef(rotx,0.0f,1.0f,0.0f); // 绕Y轴旋转rotx
//画正方体
glBegin(GL_QUADS);
{
glColor3ub(255,0,0);glVertex3f(-0.051f,+0.051f,-0.051f);glVertex3f(+0.051f,+0.051f,-0.051f);glVertex3f(+0.051f,-0.051f,-0.051f);glVertex3f(-0.051f,-0.051f,-0.051f);
glColor3ub(0,255,0);glVertex3f(-0.051f,+0.051f,+0.051f);glVertex3f(-0.051f,-0.051f,+0.051f);glVertex3f(+0.051f,-0.051f,+0.051f);glVertex3f(+0.051f,+0.051f,+0.051f);
glColor3ub(0,0,255);glVertex3f(+0.051f,+0.051f,+0.051f);glVertex3f(+0.051f,-0.051f,+0.051f);glVertex3f(+0.051f,-0.051f,-0.051f);glVertex3f(+0.051f,+0.051f,-0.051f);
glColor3ub(255,255,0);glVertex3f(-0.051f,+0.051f,+0.051f);glVertex3f(-0.051f,+0.051f,-0.051f);glVertex3f(-0.051f,-0.051f,-0.051f);glVertex3f(-0.051f,-0.051f,+0.051f);
glColor3ub(255,0,255);glVertex3f(-0.051f,+0.051f,+0.051f);glVertex3f(+0.051f,+0.051f,+0.051f);glVertex3f(+0.051f,+0.051f,-0.051f);glVertex3f(-0.051f,+0.051f,-0.051f);
glColor3ub(0,255,255);glVertex3f(-0.051f,-0.051f,+0.051f);glVertex3f(-0.051f,-0.051f,-0.051f);glVertex3f(+0.051f,-0.051f,-0.051f);glVertex3f(+0.051f,-0.051f,+0.051f);
}
glEnd();
//画坐标轴
glLineWidth (1.0);
glBegin(GL_LINES);
{
//X
glColor3ub(255, 0, 0);
glVertex3f(-1,0,0);glVertex3f(1,0,0);
glVertex3f(1,0,0);glVertex3f(1-0.05f,0.05f,0);
glVertex3f(1,0,0);glVertex3f(1-0.05f,-0.05f,0);
glVertex3f(1,0,0);glVertex3f(1-0.05f,0,0.05f);
glVertex3f(1,0,0);glVertex3f(1-0.05f,0,-0.05f);
//Y
glColor3ub(0, 255, 0);
glVertex3f(0,-1,0);glVertex3f(0,1,0);
glVertex3f(0,1,0);glVertex3f(0.05f,1-0.05f,0);
glVertex3f(0,1,0);glVertex3f(-0.05f,1-0.05f,0);
glVertex3f(0,1,0);glVertex3f(0,1-0.05f,0.05f);
glVertex3f(0,1,0);glVertex3f(0,1-0.05f,-0.05f);
//Z
glColor3ub(0, 0, 255);
glVertex3f(0,0,-1);glVertex3f(0,0,1);
glVertex3f(0,0,1);glVertex3f(0.05f,0,1-0.05f);
glVertex3f(0,0,1);glVertex3f(-0.05f,0,1-0.05f);
glVertex3f(0,0,1);glVertex3f(0,0.05f,1-0.05f);
glVertex3f(0,0,1);glVertex3f(0,-0.05f,1-0.05f);
}
glEnd();
//红线
display(px1, py1, px2, py2);
//出问题的地方
DrawLine3D(pLine3DArr);
glFlush();
SwapBuffers(hDC);
};
出问题的地方是
DrawLine3D(pLine3DArr);
//把这个函数放在扩容的时候,出来的数据是正常的,完全符合期待(短红框)
//但,如果把这个函数放到DrawGLScene(),出来的数据完全乱了,(长红框)
//数组是公共变量,同一个函数,同一个数组,出来的结果完全不同。
你的代码有一个比较初级的错误
...
Line3D L1(p1, p2);
pLine3DArr[i] = (Line3D *)malloc(sizeof(Line3D *));
pLine3DArr[i] = &L1;
L1 是在循环体内的一个局部变量,然后你malloc了一个指针的空间(4/8个字节),然后让这个指针指向了 L1,但循环结束后,L1就被释放了,你记录的L1指针就成了野指针。
正确的代码应该是:
...
Line3D L1(p1, p2);
pLine3DArr[i] = (Line3D *)malloc(sizeof(Line3D));
memcpy(pLine3DArr[i], &L1, sizeof(Line3D));