1. 程式人生 > >計算機圖形學(OpengGl版) 實驗(一)

計算機圖形學(OpengGl版) 實驗(一)

結果展示:
在這裡插入圖片描述

#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

void myDisplay(void){
    glClearColor(0.0, 0, 0,0);  // 設定背景預設顏色
    glClear(GL_COLOR_BUFFER_BIT); // 清空當前可寫的顏色緩衝,並設為預設值(和上一個函式一起起作用)
    // 一個矩形
    glColor3f( 1.0,
1.0, 0.0); glRectf (-0.5, -0.5, 0.5, 0.5); // 一個三角形 glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); glVertex2f( 0.0, 1.0); glColor3f(0.0, 1.0, 0.0); glVertex2f( 0.8, -0.5); glColor3f(1.0, 0.0, 1.0); glVertex2f(-0.8, -0.5); glEnd(); // 三個點 glPointSize(3); // 設定點 的大小 glBegin(GL_POINTS)
; glColor3f(1.0, 0.0, 0.0); glVertex2f(-0.4, -0.4); glColor3f(1.0, 0.0, 0.0); glVertex2f( 0.0, 0.0); glColor3f(1.0, 0.0, 0.0); glVertex2f( 0.4, 0.4); glEnd(); glFlush(); // 用於強制重新整理緩衝,保證繪圖命令立即被執行 } int main(int argc, char *argv[]){ glutInit(&argc, argv); // 來識別要用glut來控制 glutInitDisplayMode
(GLUT_RGB | GLUT_SINGLE); // 設定顯示的模式 glutInitWindowPosition(100, 100); glutInitWindowSize(500, 500); glutCreateWindow("圖形學實驗1.1"); glutDisplayFunc(&myDisplay); // 呼叫顯示函式 glutMainLoop(); return 0; }

幾點需要主要的

  1. opengl 中畫圖形,都要呼叫glBegin() 和glEnd(), 並設定圖形的形狀。
  2. 對於glColor3f()等設定顏色的函式來說,就是將當前畫圖的顏色狀態轉換到設定值,如果接下來不再重新設定,那麼這個顏色將一直沿用到結束。
  3. GLUT_RGB 是指定當前視窗的顏色模式為RGB
  4. GLUT_SINGLE 和GLUT_DOUBLE 所對應都是儲存每幀中的畫素資訊,對於動畫來說,會設定為DOUBLE型,這樣的話,一個用來顯示當前正在顯示的影象,另一個離線載入下一幀的資訊,這樣來回切換就會顯示的更流暢。

結果顯示:
在這裡插入圖片描述

#include <bits/stdc++.h>
#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
using namespace std;

const double PI = acos(-1.0);
struct Point{
    double x, y;
    Point(){}
    Point(double _x, double _y){
        x = _x; y = _y;
    }
};
void myDisplay(void){
    glClearColor(0.0, 0.0, 0,0);
    glClear(GL_COLOR_BUFFER_BIT);

    // 矩形
    glColor3f( 1.0,  1.0, 1.0);
    glRectf  (-0.8, -0.8, 0.8, 0.8);

    double rate = 0.8;
    // 大三角形
    glBegin(GL_TRIANGLES);
        glColor3f(0.0, 1.0, 0.0); glVertex2f(-1 * rate,  1 * rate);
        glColor3f(1.0, 1.0, 0.0); glVertex2f( 1 * rate,  1 * rate);
        glColor3f(1.0, 0.0, 0.0); glVertex2f( 0 * rate, -1 * rate);
    glEnd();

    // 圓
    int N = 100; // 精度
    double R = 0.62 * rate;
    glColor3f(1.0, 0.0, 1.0);
    glBegin(GL_POLYGON);
        for(int i = 0; i < N; i++) {
            glVertex2f(R * cos(2 * PI/ N * i), R * sin(2 * PI / N * i));
        }
    glEnd();

    // 五角星
    Point arr[5];
    arr[0] = Point(-0.5, -0.65);
    arr[1] = Point( 0.5, -0.65);
    arr[2] = Point( 0.7,  0.2);
    arr[3] = Point( 0.0,  0.7);
    arr[4] = Point(-0.7,  0.2);
    glColor3f(0, 0, 1);
    glLineWidth(1 );  // 設定線寬
    for(int i = 0; i < 5; i++){
        glBegin(GL_LINES);
            glVertex2f(arr[i].x, arr[i].y);
            int j = (i + 2) % 5;
            glVertex2f(arr[j].x, arr[j].y);
        glEnd();
    }

    // 小三角形
    Point a[3];
    a[0] = Point(0.7 , -0.7);
    a[1] = Point(0.6 , -0.7);
    a[2] = Point(0.65, -0.6);
    glColor3f(1, 0, 1);
    for(int i = -1; i <= 1; i += 2){
        glBegin(GL_POLYGON);
        for(int j = 0; j < 3; j++){
            glVertex2f(i * a[j].x, a[j].y);
        }
        glEnd();
        glColor3f(1.0, 0.7, 0.0);
    }
    glFlush();
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(400, 400);
    glutCreateWindow("圖形學實驗1.2");
    glutDisplayFunc(&myDisplay);
    glutMainLoop();
    return 0;
}

幾點需要注意的:

  1. 通過這個實驗我們應該可以意識到,對於我們想要畫一個圖形來說,一個圖形 = 點集 + 顏色 + (周長 | 面積) ,這樣 就可以描述所有的圖形,當然畫圖形的時候也可以這樣。
  2. 這裡需要強調一下GL_POLYGON圖形的畫法(被坑很多次,QAQ)
    一: 它是畫一個封閉圖形(多邊形)並且顏色作用域是整個封閉圖形一
    二: 它的點集要是按照順時針給出,同時很重要的一點是這個圖形還要是一個凸多邊形,所以如果我們要畫一個一般多邊形,我們可以通過通過劃分這個多變型為多個凸多邊形

圖形結果:
在這裡插入圖片描述

#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>
#include <bits/stdc++.h>
using namespace std;

struct Point{
    double x, y;
    Point(){}
    Point(double _x, double _y){
        x = _x; y = _y;
    }
    Point operator + (const Point &a) const{
        return Point(this->x + a.x, this->y + a.y);
    }
    Point operator / (const int &a) const{
        return Point(this->x / a, this->y / a);
    }
};

const double PI = acos(-1.0);

void setColor(int id){
    double r, g, b;
    if(id == 1) {r = 0.0; g = 0.0; b = 0.0;}
    if(id == 2) {r = 1.0; g = 1.0; b = 1.0;}
    if(id == 3) {r = 1.0; g = 0.0; b = 0.0;}
    if(id == 4) {r = 1.0, g = 1.0; b = 0.0;}
    glColor3f(r, g, b);
}
void dfs(Point a[], int id){
    if(id > 4) return ;
    setColor(id);
    glBegin(GL_POLYGON);
        for(int i = 0; i < 4; i++) glVertex2f(a[i].x, a[i].y);
    glEnd();
    Point t[4]; for(int i = 0; i < 4; i++) t[i] = (a[i] + a[(i + 1 ) % 4]) / 2;
    dfs(t, id + 1);
}
void setcolor(int id){
    double r, g, b;
    if(id == 0) {r = 1.0, g = 0.0, b = 0.0;}
    if(id == 1) {r = 0.0, g = 1.0, b = 0.0;}
    if(id == 2) {r = 0.0, g = 0.0, b = 1.0;}
    if(id == 3) {r = 1.0, g = 1.0, b = 0.0;}
    glColor3f(r, g, b);
}
void myDisplay(void){
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    // 遞迴畫矩形巢狀
    Point a[4];
    a[0] = Point(-0.5, -0.5);
    a[1] = Point( 0.5, -0.5);
    a[2] = Point( 0.5,  0.5);
    a[3] = Point(-0.5,  0.5);
    dfs(a, 1);

    // 通過旋轉得到 四個三角形
    double r[4], t[4];
    r[1] = sqrt(2.0) / 2.0; t[1] = PI / 4.0;
    r[3] = 1.0;             t[3] = 0.0;
    r[2] = sqrt(2.0) / 2.0; t[2] = -PI / 4.0;
    for(int i = 0; i < 4; i++){
        setcolor(i);
        glBegin(GL_POLYGON);
            for(int j = 1; j <= 3; j++){
                glVertex2f(cos(t[j]) * r[j], sin(t[j]) * r[j]);
                t[j] += PI / 2;
            }
        glEnd();
    }
    glFlush();
}
int main(int argc, char *argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(500, 500);
    glutCreateWindow("圖形學實驗1.3");
    glutDisplayFunc(&myDisplay);
    glutMainLoop();
    return 0;
}

注意:

  1. 畫圖形的時候要多考慮 圖形的特徵,這樣的話我們可以用旋轉,平移,遞迴等各種方法來減少程式碼量,減少時間

總結 :第一次的實驗,主要是對opengl的熟悉,還有簡單圖形的處理。