計算機圖形學(OpengGl版) 實驗(一)
阿新 • • 發佈:2018-11-09
結果展示:
#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;
}
幾點需要主要的
- opengl 中畫圖形,都要呼叫glBegin() 和glEnd(), 並設定圖形的形狀。
- 對於glColor3f()等設定顏色的函式來說,就是將當前畫圖的顏色狀態轉換到設定值,如果接下來不再重新設定,那麼這個顏色將一直沿用到結束。
- GLUT_RGB 是指定當前視窗的顏色模式為RGB
- 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;
}
幾點需要注意的:
- 通過這個實驗我們應該可以意識到,對於我們想要畫一個圖形來說,一個圖形 = 點集 + 顏色 + (周長 | 面積) ,這樣 就可以描述所有的圖形,當然畫圖形的時候也可以這樣。
- 這裡需要強調一下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;
}
注意:
- 畫圖形的時候要多考慮 圖形的特徵,這樣的話我們可以用旋轉,平移,遞迴等各種方法來減少程式碼量,減少時間
總結 :第一次的實驗,主要是對opengl的熟悉,還有簡單圖形的處理。