我试图用openGl编写C++代码来渲染Sierpinski_gasket。我已经使用typedef定义了两个新数据类型,然后创建了一个指向这些新数据类型之一的指针:

typedef GLfloat point2[2];
typedef point2 myTriangle[3];
myTriangle *triangle;

我编写了一个函数init,该函数需要三点,然后创建一个新的myTriangle,然后将其分配给*triangle
void init(point2 p1, point2 p2, point2 p3){
    myTriangle t;
    t[0][0] = p1[0];
    t[0][1] = p1[1];

    t[1][0] = p2[0];
    t[1][1] = p2[1];

    t[2][0] = p3[0];
    t[2][1] = p3[1];

    triangle = &t;
}

这是我的diplay函数:
void display(void){
    static point2 p = {1,1};
    int i;
    //pick a random vertex
    i = rand() % 3;  //i in the range 0 to 2

    p[0] = (p[0] + *triangle[i][0])/2;
    p[1] = (p[1] + *triangle[i][1])/2;
    cout << p[0] << ' , ' << p[1] << endl;
    //display new points
    glBegin(GL_POINTS);
        glVertex2fv(p);
    glEnd();
}

问题是每次调用*triangle后,display的值都会更改。
谁能告诉我原因以及如何解决?

完整的代码如下
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cstdlib>
#include <iostream>
using namespace std;

typedef GLfloat point2[2];
typedef point2 myTriangle[3];

myTriangle *triangle;
void init(point2 p1, point2 p2, point2 p3);
void display(void);
int main(int argc, char** argv) {
    //initialize the GLUT library
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("OpenGL");

    //openGL Code
    glClearColor(0.0, 1.0, 0.0, 0.0 );
    glClear(GL_COLOR_BUFFER_BIT);
    glOrtho(-5.0, 15.0, -5, 15.0, -1.0, 1.0);
    glColor3f(1.0, 0.0, 0.0);
    glEnable(GL_POINT_SMOOTH);
    glPointSize(5);
    //triangle points
    point2 p1, p2, p3;

    p1[0] = 5.0;
    p1[1] = 0.0;

    p2[0] = 10.0;
    p2[1] = 0.0;

    p3[0] = 7.5;
    p3[1] = 10.0;

    init(p1,p2,p3);
//    glBegin(GL_TRIANGLES);
//        glVertex2fv(p1);
//        glVertex2fv(p2);
//        glVertex2fv(p3);
//    glEnd();
    for(int j=0 ; j< 10000; j++){
        display();
    }

    glFlush();
    glutSwapBuffers();
    glutMainLoop();
    return 0;
}

void init(point2 p1, point2 p2, point2 p3){
    myTriangle t;
    t[0][0] = p1[0];
    t[0][1] = p1[1];

    t[1][0] = p2[0];
    t[1][1] = p2[1];

    t[2][0] = p3[0];
    t[2][1] = p3[1];

    triangle = &t;
}

void display(void){
    static point2 p = {1,1};
    int i;

    //pick a random vertex
    i = rand() % 3;  //i in the range 0 to 2

    p[0] = (p[0] + *triangle[i][0])/2;
    p[1] = (p[1] + *triangle[i][1])/2;
    cout << p[0] << ' , ' << p[1] << endl;
    //display new points
    glBegin(GL_POINTS);
        glVertex2fv(p);
    glEnd();


}

最佳答案

您正在init函数中分配局部变量的地址。当init返回时,您分配的地址不再有效,因为绑定(bind)到该地址的变量是本地的。

void init(point2 p1, point2 p2, point2 p3)
{
    myTriangle t;
    t[0][0] = p1[0];
    t[0][1] = p1[1];

    t[1][0] = p2[0];
    t[1][1] = p2[1];

    t[2][0] = p3[0];
    t[2][1] = p3[1];

    triangle = &t;    // <-- assigning address of local variable.  No good.
}

代码的问题在于,您没有活着的myTriangle可以分配给triangle指针。

您当前的代码将triangle设置为myTriangle,一旦init函数返回,该代码将消失,并且您的代码中没有任何内容指示triangle指向的“ Activity ”对象的位置将存在。

因此,实际上,您正在寻求一个只有您才能真正想到的解决方案。我们可以建议诸如分配全局myTriangle(地址不会无效)之类的事情,或者使用函数内的new myTriangle动态分配一个地址(这会导致其他问题),或类似的其他答案。但是,这是您必须做出的设计决定。

08-17 08:40