C++ OpenGL缩放效率

C++ OpenGL缩放效率,c++,opengl,camera,zooming,C++,Opengl,Camera,Zooming,我是OpenGL的初学者,作为我的第一个应用程序,我尝试使用三角形的重心细分方法生成分形。由于不知道OpenGL在透视变化方面的功能,我对缩放和视点变化算法的第一个想法是,每次按下一个键(箭头表示相机移动,+/-表示缩放),用不同的起点坐标和比例因子简单地重绘整个分形 考虑到重心细分的6次迭代绘制了大约56000个三角形(6^0+6^1+6^2+6^3+6^4+6^5+6^6三角形),该算法效率非常低。所以我试着用gluPerspective()进行缩放,结果很不幸是一个黑屏,而不是分形。我有两

我是OpenGL的初学者,作为我的第一个应用程序,我尝试使用三角形的重心细分方法生成分形。由于不知道OpenGL在透视变化方面的功能,我对缩放和视点变化算法的第一个想法是,每次按下一个键(箭头表示相机移动,+/-表示缩放),用不同的起点坐标和比例因子简单地重绘整个分形

考虑到重心细分的6次迭代绘制了大约56000个三角形(6^0+6^1+6^2+6^3+6^4+6^5+6^6三角形),该算法效率非常低。所以我试着用gluPerspective()进行缩放,结果很不幸是一个黑屏,而不是分形。我有两个主要问题:

  • 用于透视变化和视点(gluPerspective()、gluLookAt()、glFrustum()等)的OpenGL函数是否使用不同的坐标重新绘制整个图形,还是使用更有效的方法获得相同的结果?在我的情况下,它们的使用会更有效吗
  • 我在代码中做错了什么。为什么我会有黑屏

    #include <GL/glfw.h>
    #include <iostream>
    #include <math.h>
    
    using namespace std;
    
    struct punct{ GLdouble x, y;}; //"punct" means "point" in my native language
    punct A, B, C;
    int n=0, mode=1;
    double l=1.6, ox=0, oy=0, scale=1;
    
    punct mid (punct A, punct B);
    void initiate ();
    void line (punct A, punct B);
    void triangle (punct A, punct B, punct C);
    void divide (punct A, punct B, punct C,int i);
    
    int main ()
    {
        int     width, height;
        bool    running = true;
        char input=NULL;
    
        glfwInit();
    
        if( !glfwOpenWindow( 800, 800, 0, 0, 0, 0, 0, 0, GLFW_FULLSCREEN ) )
        {
            glfwTerminate();
            return 0;
        }
    
        glfwSetWindowTitle("Baricentric");
    
        while(running)
        {
            glfwGetWindowSize( &width, &height );
            height = height > 0 ? height : 1;
    
            glViewport( 0, 0, width, height );
    
            glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
            glClear( GL_COLOR_BUFFER_BIT );
    
            //This functions make my screen black 
            //glMatrixMode(GL_MODELVIEW);
            //glLoadIdentity();
            //gluPerspective (50*scale, width/height, 10.0, 100.0); 
    
            initiate ();
    
            if(glfwGetKey(GLFW_KEY_KP_ADD) && glfwGetKey(GLFW_KEY_LCTRL)) input='+';
            if(!glfwGetKey(GLFW_KEY_KP_ADD) && input=='+') {
            if(n<7) n++;
            input='\n';
            }
            if(glfwGetKey(GLFW_KEY_KP_SUBTRACT) && glfwGetKey(GLFW_KEY_LCTRL)) input='-';
            if(!glfwGetKey(GLFW_KEY_KP_SUBTRACT) && input=='-') {
                if(n>0)n--;
                input='\n';
            }
    
            if(glfwGetKey(GLFW_KEY_KP_1)||glfwGetKey('1')) input='1';
            if(!glfwGetKey(GLFW_KEY_KP_1) && input=='1') {
                mode=1;
                input='\n';
            }
    
            if(glfwGetKey(GLFW_KEY_KP_0)||glfwGetKey('0')) input='0';
            if(!glfwGetKey(GLFW_KEY_KP_0) && input=='0') {
                mode=0;
                input='\n';
            }
    
            if(glfwGetKey(GLFW_KEY_KP_ADD) && !glfwGetKey(GLFW_KEY_LCTRL)) l+=0.002*(n+0.5); //'l' is replaced with 'scale' when using gluPerspective()
            if(glfwGetKey(GLFW_KEY_KP_SUBTRACT) && !glfwGetKey(GLFW_KEY_LCTRL)) l-=0.002*(n+0.5); //'l' is replaced with 'scale' when using gluPerspective()
            if(glfwGetKey(GLFW_KEY_UP)) oy-=0.002*(n+0.5);
            if(glfwGetKey(GLFW_KEY_DOWN)) oy+=0.002*(n+0.5);
            if(glfwGetKey(GLFW_KEY_RIGHT)) ox+=0.002*(n+0.5);
            if(glfwGetKey(GLFW_KEY_LEFT)) ox-=0.002*(n+0.5);
    
    
            if (n) divide (A,B,C,1);
    
    
            glfwSwapBuffers();
    
            running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED);
        }
    
        glfwTerminate();
    
        return 0;
    }
    
    punct mid (punct A, punct B) {
        punct C;
        C.x=(A.x+B.x)/2;
        C.y=(A.y+B.y)/2;
        return C;
    }
    
    void initiate () {
    
        A.x = -(l/2)+ox; A.y = -(l*sqrt(3)/4)+oy;
        B.x = l/2+ox; B.y = A.y;
        C.x = 0+ox; C.y = (l*sqrt(3)/4)+oy;
    
        glBegin (GL_QUADS);
            glColor3f(0.93,0.84,0.82); glVertex3d(-1, 1, 0);
            glColor3f(0.01,0.95,0.83); glVertex3d(-1, -1, 0);
            glColor3f(0.80,0.71,0.80); glVertex3d(1, -1, 0);
            glColor3f(0.8,1,0.8); glVertex3d(1, 1, 0);
        glEnd ();
    
        glBegin (GL_TRIANGLES);
            glColor3f(0,0.6,0.88); glVertex3d(C.x, C.y, 0);
            glColor3f(0,0.77,0.73); glVertex3d(B.x, B.y, 0);
            glColor3f(0.01,0.66,0.62); glVertex3d(A.x, A.y, 0);
        glEnd ();
    
        if (mode==0) {
            glLineWidth (0.1);
            glColor3f(0,0,0.36);
            glBegin (GL_LINE_LOOP);
                glVertex3d(C.x, C.y, 0);
                glVertex3d(B.x, B.y, 0);
                glVertex3d(A.x, A.y, 0);
            glEnd ();
        }
    }
    
    
    void divide (punct A, punct B, punct C, int i) {
        if(i<=n) {
            punct a, b, c, G;
            c=mid(A,B);
            b=mid(A,C);
            a=mid(B,C);
            G.x=(A.x+B.x+C.x)/3;
            G.y=(A.y+B.y+C.y)/3;
            if(mode==1) {
                triangle(G,a,C);
                triangle(G,b,C);
                triangle(G,a,B);
                triangle(G,c,B);
                triangle(G,c,A);
                triangle(G,b,A);
            }
            line(c,C);
            line(a,A);
            line(b,B);
            divide(G,a,C,i+1);
            divide(G,b,C,i+1);
            divide(G,a,B,i+1);
            divide(G,c,B,i+1);
            divide(G,c,A,i+1);
            divide(G,b,A,i+1);
        }
    
    }
    
    void line (punct A, punct B) {
        glBegin (GL_LINE_STRIP);
            glVertex3d(A.x,A.y,0);
            glVertex3d(B.x,B.y,0);
        glEnd ();
    }
    
    void triangle (punct A, punct B, punct C) {
        glBegin (GL_TRIANGLES);
            glColor3f(0,0.6,0.88); glVertex3d(C.x, C.y, 0);
            glColor3f(0,0.77,0.73); glVertex3d(B.x, B.y, 0);
            glColor3f(0.01,0.66,0.62); glVertex3d(A.x, A.y, 0);
        glEnd ();
    }
    
    #包括
    #包括
    #包括
    使用名称空间std;
    结构点{glx,y;}//在我的母语中,“点”的意思是“点”
    点A、B、C;
    int n=0,mode=1;
    双l=1.6,ox=0,oy=0,刻度=1;
    中点(A点、B点);
    无效初始化();
    空隙线(点A、点B);
    空心三角形(点A、点B、点C);
    空隙分割(点A、点B、点C、点i);
    int main()
    {
    int宽度、高度;
    bool running=true;
    字符输入=NULL;
    glfwInit();
    如果(!glfwOpenWindow(800,800,0,0,0,0,0,GLFW_全屏))
    {
    glfwTerminate();
    返回0;
    }
    glfwSetWindowTitle(“Barictric”);
    (跑步时)
    {
    GLFWGetWindowsSize(宽度和高度);
    高度=高度>0?高度:1;
    glViewport(0,0,宽度,高度);
    glClearColor(0.0f、0.0f、0.0f、0.0f);
    glClear(GLU颜色缓冲位);
    //这些功能使我的屏幕变黑
    //glMatrixMode(GLU模型视图);
    //glLoadIdentity();
    //透视图(50*比例,宽度/高度,10.0,100.0);
    发起();
    if(glfwGetKey(GLFW_KEY_KP_ADD)和&glfwGetKey(GLFW_KEY_LCTRL))输入=“+”;
    如果(!glfwGetKey(GLFW_KEY_KP_ADD)&&input='+')){
    如果(n0)n--;
    输入='\n';
    }
    if(glfwGetKey(GLFW_KEY_KP_1)| | glfwGetKey('1'))input='1';
    如果(!glfwGetKey(GLFW_KEY_KP_1)&&input='1'){
    模式=1;
    输入='\n';
    }
    if(glfwGetKey(GLFW_KEY_KP_0)| | glfwGetKey('0'))input='0';
    如果(!glfwGetKey(GLFW_KEY_KP_0)&&input='0'){
    模式=0;
    输入='\n';
    }
    如果使用gluPerspective()时,(glfwGetKey(GLFW_KEY_KP_ADD)和&!glfwGetKey(GLFW_KEY_LCTRL))l+=0.002*(n+0.5);//“l”替换为“比例”
    如果(glfwGetKey(GLFW_KEY_KP_SUBTRACT)和&!glfwGetKey(GLFW_KEY_LCTRL))l-=0.002*(n+0.5);//'l'在使用GLUPperspective()时替换为'scale'
    如果(glfwGetKey(GLFW_KEY_UP))oy-=0.002*(n+0.5);
    如果(glfwGetKey(GLFW_KEY_DOWN))oy+=0.002*(n+0.5);
    如果(glfwGetKey(GLFW_KEY_RIGHT))ox+=0.002*(n+0.5);
    如果(glfwGetKey(GLFW_KEY_LEFT))ox-=0.002*(n+0.5);
    如果(n)除以(A,B,C,1);
    glfwSwapBuffers();
    运行=!glfwGetKey(GLFW_KEY_ESC)和&glfwGetWindowParam(GLFW_打开);
    }
    glfwTerminate();
    返回0;
    }
    中点(A点、B点){
    C点;
    C.x=(A.x+B.x)/2;
    C.y=(A.y+B.y)/2;
    返回C;
    }
    无效启动(){
    A.x=-(l/2)+ox;A.y=-(l*sqrt(3)/4)+oy;
    B.x=l/2+ox;B.y=A.y;
    C.x=0+ox;C.y=(l*sqrt(3)/4)+oy;
    glBegin(GL_QUADS);
    glColor3f(0.93,0.84,0.82);glVertex3d(-1,1,0);
    glColor3f(0.01,0.95,0.83);glVertex3d(-1,-1,0);
    glColor3f(0.80,0.71,0.80);glVertex3d(1,-1,0);
    glColor3f(0.8,1,0.8);glVertex3d(1,1,0);
    格伦德();
    glBegin(GL_三角形);
    glColor3f(0,0.6,0.88);glVertex3d(C.x,C.y,0);
    glColor3f(0,0.77,0.73);glVertex3d(B.x,B.y,0);
    glColor3f(0.01,0.66,0.62);glVertex3d(A.x,A.y,0);
    格伦德();
    如果(模式==0){
    glLineWidth(0.1);
    gl3f(0,0,0.36);
    glBegin(GL_线_环);
    glVertex3d(C.x,C.y,0);
    glVertex3d(B.x,B.y,0);
    glVertex3d(A.x,A.y,0);
    格伦德();
    }
    }
    空分(点A、点B、点C、点i){
    
    如果(我像以前很多人一样,你已经陷入了一种错误的观念,认为OpenGL是一个场景图。事实并非如此

    OpenGL是一个绘图API。您的操作系统提供一个画布(窗口、PBuffer、Pixmap等),OpenGL提供点、线或三角形形式的绘图工具

    OpenGL的透视变化函数和视点(gluPerspective()、gluLookAt()、glFrustum()等)是否用不同的坐标重新绘制了整个图形


    他们所做的只是改变一些矩阵的值。屏幕上的任何内容都不会因此而改变。你必须重新绘制整个内容以进行可见的更改。

    像以前很多人一样,你已经陷入了一种错误的观念,认为OpenGL是一个场景图。事实并非如此

    OpenGL是一个绘图API。您的操作系统提供一个画布(窗口、PBuffer、Pixmap等),OpenGL提供点、线或三角形形式的绘图工具

    OpenGL的透视变化函数和视点(gluPerspective()、gluLookAt()、glFrustum()等)是否用不同的坐标重新绘制了整个图形

    他们所做的只是更改一些矩阵的值。屏幕上的任何内容都不会因此而改变。你必须重新绘制整个内容,以进行可见的更改