OpenGL (7) 靜宜大學資工系 蔡奇偉 副教授 2001-2010.

Slides:



Advertisements
Similar presentations
单元二:面向对象程序设计 任务二:借书卡程序设计.
Advertisements

项目6 通用堆栈.
数据结构 杨鹏宇 QQ: 版权所有,转载或翻印必究
四資二甲 第三週作業 物件導向程式設計.
Memory Pool ACM Yanqing Peng.
第三章 鏈結串列 Linked List.
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
第五章 树 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
講師:聯捷聯合會計師事務所 張志勝會計師(所長)
第八讲: OpenGL的组合图形.
第二章 JAVA语言基础.
升學應選擇符合自己性向、興趣或能力的學校就 讀,有五專、高職、高中、綜合高中或進修學校, 可要多花些時間了解一下哦!
類別與物件 Class & Object.
真实感图形 授课教师: 单位:.
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
第六章 三维真实感物体显示技术 虚拟现实(Virtual Reality,简称VR)技术是一种逼真的模拟人在自然环境中视觉、听觉、运动等行为的人机界面技术。其目的是:不仅能够在多维空间仿真建模,而且能够帮助人们获取知识和形成新的概念,Mark Green给出了一个简明的虚拟现实应用系统模型,如图6.1所示。
走向C++之路 WindyWinter WindyWinter感谢诸位前来捧场。
第二章 C# 基础知识.
4.1 概述 4.2 类与对象的实现 4.3 对象的初始化和析构 4.4 类的包含 4.5 类模板
Chap 3 堆疊與佇列 Stack and Queue.
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
第七章 搜索结构 静态搜索结构 二叉搜索树 AVL树.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
本單元介紹何謂變數,及說明變數的宣告方式。
程式設計實作.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
并发机制 结果应该为: 线程 1: 1 线程 1: 2 线程 1: 3 线程 1: 4 线程 1: 5 线程 2: 6 线程 2: 7
第一章 绪论.
纹理映射.
Introduction to OpenGL (2)
第四章 图元的属性 曾智勇 软件学院.
明解C++教學手冊 柴田望洋 博士 著 書號:PG20269
Ch02-基礎語法.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
$10 可空类型.
Animation(動畫) 靜宜大學資工系 蔡奇偉 副教授
第三章 C# 基础知识.
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
辅导课程八.
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
實作輔導 2 日期: 3/24(星期六) 09:10~16:00 地點:臺北市立大學 臺北市中正區愛國西路一號 (中正紀念堂站7號出口)
第二章Java基本程序设计.
Chapter 5 Attributes of Output Primitives (图元的属性)
C#程序设计基础 $3 成员、变量和常量.
第16章 数据的共享和流通 一、浅拷贝和深拷贝 二、只读成员函数 三、友元friend.
C++复习2----类与对象.
保留字與識別字.
第二章 Java基本语法 讲师:复凡.
第四章 栈和队列 栈 ( Stack ) 队列 ( Queue ) 优先队列 (Priority Queue) 小结.
王豐緒 銘傳大學資訊工程學系 問題:判斷是否為長方形.
第三章 数据抽象.
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
第二章 类型、对象、运算符和表达式.
Review 1~3.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
判斷(選擇性敘述) if if else else if 條件運算子.
PROGRAM 1 Simple E. Angel, Interactive Computer Graphics A Top-Down Approach with OpenGL, Third Edition Addison-Wesley Longman, 2003.
第二章 Java基础语法 北京传智播客教育
小組製作人介紹 2 年 14 班 21 號 高嘉駿 2 年 14 班 20 號 林宏恩 2 年 14 班 14 號 林立仁.
自由曲线与曲面(II) 计算机科学与技术.
Presentation transcript:

OpenGL (7) 靜宜大學資工系 蔡奇偉 副教授 2001-2010

多面體模型 多邊形 OpenGL 相關函式

多邊形 何謂多邊形? 多邊形的種類 多邊形的正面與反面 填滿多邊形 OpenGL 多邊形相關函式

何謂多邊形? n 邊的多邊形(polygon)是由 n 個共平面的端點 v1, v2, …, vn 和 n 條邊線 (v1, v2),(v2, v3), …, (vn-1, vn), (vn, v1) 所組成。 v1 v2 v3 v4 v1 v2 v3 v1 v2 v3 v4 v5 v6 v7 v1 v2 v3 v4 v5

多邊形的種類 簡單多邊形(simple polygon) 邊線都不相交而且沒有洞的多邊形。又可分成: 凸多邊形(convex polygon) 假定 a 和 b 是多邊形中任意的兩點。線段 ab 上所有的點也都在多邊形中。 凹多邊形(concave polygon) 不是凸的簡單多邊形即為凹多邊形。 非簡單多邊形(non-simple polygon) 邊線相交或有洞的多邊形。

凸多邊形 凹多邊形 非簡單的多邊形

多邊形的正面與反面 在三度空間中,多邊形有正反兩面。端點順序符合逆時針方向的那一面稱為正面,另一面即為反面。 v3 v2 反面 正面 v4

OpenGL 多邊形相關函式 glRect*() glBegin() …glEnd() glPolygonMode() glFrontFace() glCullFace() glPolygonStipple()

glRect{sifd} (TYPE x1, TYPE y1, TYPE x2, TYPE y2) 在 z = 0 的平面上,畫一個以 (x1, y1) 和 (x2, y2) 為對角端點的矩形。 (x1, y1) (x2, y2) (x1, y1) (x2, y2) glRect{sifd}v (TYPE *v1, TYPE *v2) v1: 用來存第一個端點的陣列 v2: 用來存第二個端點的陣列

glBegin(type) /* 一連串的 glVertex*() 呼叫 */ glEnd() 參數 type 可以是下面的常數值: GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP GL_POLYGON

glPolygonMode (GLenum face, GLenum mode) 控制多邊形的繪製的方式。 參數 face 設定繪製多邊形的正面或反面,其值可為: GL_FRONT_AND_BACK 正反面都畫(此為預設值) GL_FRONT 只畫正面 GL_BACK 只畫反面 參數 mode 設定繪製的模式,其值可為: GL_FILL 填滿多邊形內部(此為預設的模式) GL_LINE 只畫多邊形的框線 GL_POINT 只畫多邊形的端點

GL_FILL GL_LINE GL_POINT

glFrontFace (GLenum mode) 設定多邊形正面的決定方式。 參數 mode 設定正面的方向,其值可為: GL_CCW 逆時針方向為正面(此為預設值) GL_CW 順時針方向為正面 v3 v3 v2 v2 正面 GL_CCW GL_CW 正面 v4 v4 v1 v1

glCullFace (GLenum mode) GL_FRONT 正面 GL_BACK 反面 GL_FRONT_AND_BACK 正面和反面 呼叫此函式之前,你必須已經呼叫 glEnable(GL_CULL_FACE) 來啟動此 OpenGL 的剔除功能。 若要關閉此功能,則可呼叫: glDisable(GL_CULL_FACE)

繪製曲面的線框圖 typedef double (*UVFuncPtr) (double, double); class Mesh { public: Mesh (); void set_XYZFunc (UVFuncPtr xfp, UVFuncPtr yfp, UVFuncPtr zfp); void compute (float umin, float umax, float vmin, float vmax, int m, int n); void set_foreground (float r, float g, float b) { fgRed = r; fgGreen = g; fgBlue = b; } void set_background (float r, float g, float b) { bgRed = r; bgGreen = g; bgBlue = b; } void draw (int mode, bool bHiddenLineRemoval = false); protected: float *vertex (int i, int j) { return data + (i*uSize+j)*3; } void drawObj (); private: void alloc (int m, int n); UVFuncPtr x, y, z; int uSize, vSize; float bgRed, bgGreen, bgBlue; float fgRed, fgGreen, fgBlue; float *data; };

static double stdXFunc (double u, double v) { return u; } static double stdYFunc (double u, double v) return v; static double stdZFunc (double u, double v) return u+v; Mesh::Mesh () : uSize(0), vSize(0), data(0), x(stdXFunc), y(stdYFunc), z(stdZFunc)

void Mesh::set_XYZFunc (UVFuncPtr xfp, UVFuncPtr yfp, UVFuncPtr zfp) { if (xfp) x = xfp; if (yfp) y = yfp; if (zfp) z = zfp; } void Mesh::alloc (int m, int n) uSize = n + 1; vSize = m + 1; data = new float[uSize*vSize*3];

void Mesh::compute (float umin, float umax, float vmin, float vmax, int m, int n) { if (data) delete [] data; alloc(m, n); double u, v, du = (umax-umin)/n, dv = (vmax-vmin)/m; int i, j; float *dp = data; for (i = 0, v = vmin; i <= n; i++, v += dv) for (j = 0, u = umin; j <= m; j++, u += du) { *dp++ = x(u,v); *dp++ = y(u,v); *dp++ = z(u,v); }

virtual void Mesh::drawObj () { for (int i = 0; i < vSize-1; i++) { glBegin(GL_QUAD_STRIP); for (int j = 0; j < uSize; j++) { glVertex3fv(vertex(i+1, j)); glVertex3fv(vertex(i, j)); } glEnd();

void Mesh::draw (int mode, bool bHiddenLineRemoval) { glPolygonMode(GL_FRONT_AND_BACK, mode); glColor3f( fgRed, fgGreen, fgBlue); drawObj(); if (bHiddenLineRemoval) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); glColor3f(bgRed, bgGreen, bgBlue); glDisable(GL_POLYGON_OFFSET_FILL); }

用法: Mesh mesh; double z (double u, double v) { return 2.0*exp(-u*u-v*v); } … void init () glEnable(GL_DEPTH_TEST); mesh.set_XYZFunc(0, 0, z); mesh.set_foreground(1.0, 0.0, 0.0); mesh.set_background(0.0, 0.0, 0.0); mesh.compute(-1, 1, -1, 1, 10, 10);

void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); mesh.draw(GL_LINE, true); glutSwapBuffers(); }

端點陣列 我們可以用 OpenGL 的端點陣列 (vertex array) 來預先儲存參數式的計算值。然後,用端點陣列中的資料來繪製曲線。這樣一來,就可以避免參數式的重新計算。

使用端點陣列的步驟 啟動端點陣列的功能。 建立端點陣列及儲存資料於其中。 運用端點陣列中的資料來繪製圖形。

啟動端點陣列的功能 void glEnableClientState (GLenum array) 參數 array 可以是以下的常數值: GL_VERTEX_ARRAY GL_COLOR_ARRAY GL_SECONDARY_COLOR_ARRAY GL_INDEX_ARRAY GL_NORMAL_ARRAY GL_FOG_COORDINATE_ARRAY GL_TEXTURE_COORD_ARRAY GL_EDGE_FLAG_ARRAY

關閉端點陣列的功能 void glDisableClientState (GLenum array) 參數 array 的值如前一頁所示。

建立端點陣列 void glVertexPointer ( Glint size, // 端點的維度 GLenum type, // 端點座標值的資料型態 GLsizei stride, // 兩端點資料的間隔 byte 數 const GLvoid *pointer // 端點資料的儲存位置 ) 例: float vlist3[3*100]; glVertexPointer(3, GL_FLOAT, 0, vlist3);

運用端點陣列 void glArrayElement (GLint ith) 輸出所有開啟陣列的第 i 個元素。

void glDrawElements (GLenum mode, GLsizei count, GLenum type, void *indices) vertex arrays index array

1 2 3 4 5 6 7 front back vertex array 1 2 3 4 5 6 7 GLubyte Front[] = {4,5,6,7}; GLubyte Right[] = {1,2,6,5}; GLubyte Bottom[] = {0,1,5,4}; GLubyte Back[] = {0,3,2,1}; GLubyte Left[] = {0,4,7,3}; GLubyte Top[] = {2,3,7,6}; glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, Front); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, Right); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, Bottom); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, Back); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, Left); glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, Top);

GLubyte allIndices[] = {4,5,6,7, 1,2,6,5, 0,1,5,4, 0,3,2,1, 0,4,7,3, 2,3,7,6}; glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, allIndices);

Normal Vectors(法向量) 垂直於曲面上一點的單位向量,稱為該點的法向量,如下圖所示: 在 OpenGL 中,你只能在端點上指定其法向量。法向量會決定端點所接受的光量。我們以後再來討論這個主題。 N

法向量的計算 平滑曲面 我們先計算 u 方向與 v 方向的切向量: 則法向量為:

範例 當 u = 1 和 v = 2 時,垂直於該點上的向量為 (-24, 2, 24)。 除以此向量的長度 34 之後,我們得到法向量為: (-0.70588, 0.058823, 0.70588)

平面多邊形(flat polygon) 我們知道平面上每一點的法向量都相同。假定 v1, v2, 和 v3 是平面上不共線的三點。 v3 N

範例 glNormal3{bsidf} (Type nx, Type ny, Type nz) glNormal3{bsidf}v (const Type *v) 設定目前的法向量,成為下一個 glVertex*() 定義之端點的法向量。 範例 glBegin(GL_POLYGON); glNormal3fv(n0); glVertex3fv(v0); glNormal3fv(n1); glVertex3fv(v1); glNormal3fv(n2); glVertex3fv(v2); glNormal3fv(n3); glVertex3fv(v3); glEnd();