2013-05-30 75 views
0

我是OpenGL的初學者,也是我的第一個應用程序,我嘗試使用三角形的重心細分方法生成分形。我不知道OpenGL的透視變化功能,我的第一個想法是縮放和改變視點算法,每次按下一個按鍵時,只需重新繪製具有不同起點座標和縮放因子的整個分形(相機移動箭頭和+/- - 用於縮放)。假設對於重心細分的6次迭代繪製約56000個三角形(6^0 + 6^1 + 6^2 + 6^3 + 6^4 + 6^5 + 6^6個三角形)這個算法效率很低。所以我試圖用gluPerspective()進行縮放,結果令人傷心的是黑屏,而不是分形。我有兩個主要問題:OpenGL放大效率

  • 不OpenGL函數的角度變化和觀點(gluPerspective(),gluLookAt(),glFrustum()等)重繪使用不同的座標整個數字,或使用獲得的更有效的方法相同的結果?在我的情況下,他們的使用會更有效率嗎?
  • 我在代碼中做了什麼錯誤。爲什麼我會變黑屏?

    #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(); 
    } 
    

回答

3

像許多之前,你已經愛上了思維的OpenGL的誤解是一個場景圖。不是這種情況。

OpenGL是一個繪圖API。您的操作系統提供畫布(窗口,PBuffer,Pixmap等),OpenGL以點,線或三角形的形式提供繪圖工具。

不OpenGL的角度變化和觀點功能(gluPerspective(),gluLookAt(),glFrustum()等)重繪使用不同的座標整個身影,

他們所要做的就是改變值幾個矩陣。屏幕上的任何內容都不會因此而改變。你必須重新繪製整個事物才能做出明顯的改變。