1. 程式人生 > >OpenGL3D圖形繪製/紋理對映

OpenGL3D圖形繪製/紋理對映

1.3D圖形繪製

3D圖形也是由2D的面片組合而成,一個需要注意的問題是所有的面片繪製要麼是逆時針要麼是順時針,因此每三個點確定一個三角形或者每四個點確定一個四邊形,再有餘下的點時,按新的形狀處理。以下以一個旋轉的金字塔和立方體為例,

/*******************************************************************************************************************************************
*int DrawGLScene(GLvoid)		
*功能:繪圖
*引數:無
*返回值:BOOL
********************************************************************************************************************************************/
int DrawGLScene(GLvoid)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// 清除螢幕和深度快取
	glLoadIdentity();	// 重置當前的模型觀察矩陣
	//新增繪圖程式碼
	glTranslatef(-1.5f,0.0f,-6.0f);	// 左移 1.5 單位,並移入螢幕 6.0
	glRotatef(30.0f,0.0f,1.0f,0.0f);	// 繞Y軸旋轉金字塔
	glBegin(GL_TRIANGLES);	// 繪製三角形
		//開啟平滑著色模式
		glColor3f(1.0f,0.0f,0.0f);		// 紅色
		glVertex3f( 0.0f, 1.0f, 0.0f);	// 三角形的上頂點 (前側面)
		glColor3f(0.0f,1.0f,0.0f);		// 綠色
		glVertex3f(-1.0f,-1.0f, 1.0f);	// 三角形的左下頂點 (前側面)
		glColor3f(0.0f,0.0f,1.0f);		// 藍色
		glVertex3f( 1.0f,-1.0f, 1.0f);	// 三角形的右下頂點 (前側面)

		glColor3f(1.0f,0.0f,0.0f);		// 紅色
		glVertex3f( 0.0f, 1.0f, 0.0f);	// 三角形的上頂點 (右側面)
		glColor3f(0.0f,0.0f,1.0f);		// 藍色
		glVertex3f( 1.0f,-1.0f, 1.0f);	// 三角形的左下頂點 (右側面)
		glColor3f(0.0f,1.0f,0.0f);		// 綠色
		glVertex3f( 1.0f,-1.0f, -1.0f);	// 三角形的右下頂點 (右側面)

		glColor3f(1.0f,0.0f,0.0f);		// 紅色
		glVertex3f( 0.0f, 1.0f, 0.0f);	// 三角形的上頂點 (後側面)
		glColor3f(0.0f,1.0f,0.0f);		// 綠色
		glVertex3f( 1.0f,-1.0f, -1.0f);	// 三角形的左下頂點 (後側面)
		glColor3f(0.0f,0.0f,1.0f);		// 藍色
		glVertex3f(-1.0f,-1.0f, -1.0f);	// 三角形的右下頂點 (後側面)

		glColor3f(1.0f,0.0f,0.0f);		// 紅色
		glVertex3f( 0.0f, 1.0f, 0.0f);	// 三角形的上頂點 (左側面)
		glColor3f(0.0f,0.0f,1.0f);		// 藍色
		glVertex3f(-1.0f,-1.0f,-1.0f);	// 三角形的左下頂點 (左側面)
		glColor3f(0.0f,1.0f,0.0f);		// 綠色
		glVertex3f(-1.0f,-1.0f, 1.0f);	// 三角形的右下頂點 (左側面)
	glEnd();

	glLoadIdentity();	// 重置當前的模型觀察矩陣
	glTranslatef(1.50f,0.0f,-7.0f);	// 右移1.5單位,並移入螢幕6個單位
	glRotatef(30.0f,1.0f,1.0f,1.0f);	// 繞XYZ軸旋轉立方體
	glBegin(GL_QUADS);		//  繪製立方體
		//開啟單調著色模式,保證立方體的每個面的顏色都不同
		glColor3f(0.0f,1.0f,0.0f);		// 一次性將當前色設定為綠色
		glVertex3f( 1.0f, 1.0f,-1.0f);	// 四邊形的右上頂點 (頂面)
		glVertex3f(-1.0f, 1.0f,-1.0f);	// 四邊形的左上頂點 (頂面)
		glVertex3f(-1.0f, 1.0f, 1.0f);	// 四邊形的左下頂點 (頂面)
		glVertex3f( 1.0f, 1.0f, 1.0f);	// 四邊形的右下頂點 (頂面)

		glColor3f(1.0f,0.5f,0.0f);		// 顏色改成橙色
		glVertex3f( 1.0f,-1.0f, 1.0f);	// 四邊形的右上頂點(底面)
		glVertex3f(-1.0f,-1.0f, 1.0f);	// 四邊形的左上頂點(底面)
		glVertex3f(-1.0f,-1.0f,-1.0f);	// 四邊形的左下頂點(底面)
		glVertex3f( 1.0f,-1.0f,-1.0f);	// 四邊形的右下頂點(底面)

		glColor3f(1.0f,0.0f,0.0f);		// 顏色改成紅色
		glVertex3f( 1.0f, 1.0f, 1.0f);	// 四邊形的右上頂點(前面)
		glVertex3f(-1.0f, 1.0f, 1.0f);	// 四邊形的左上頂點(前面)
		glVertex3f(-1.0f,-1.0f, 1.0f);	// 四邊形的左下頂點(前面)
		glVertex3f( 1.0f,-1.0f, 1.0f);	// 四邊形的右下頂點(前面)

		glColor3f(1.0f,1.0f,0.0f);		// 顏色改成黃色
		glVertex3f( 1.0f,-1.0f,-1.0f);	// 四邊形的右上頂點(後面)
		glVertex3f(-1.0f,-1.0f,-1.0f);	// 四邊形的左上頂點(後面)
		glVertex3f(-1.0f, 1.0f,-1.0f);	// 四邊形的左下頂點(後面)
		glVertex3f( 1.0f, 1.0f,-1.0f);	// 四邊形的右下頂點(後面)

		glColor3f(0.0f,0.0f,1.0f);		// 顏色改成藍色
		glVertex3f(-1.0f, 1.0f, 1.0f);	// 四邊形的右上頂點(左面)
		glVertex3f(-1.0f, 1.0f,-1.0f);	// 四邊形的左上頂點(左面)
		glVertex3f(-1.0f,-1.0f,-1.0f);	// 四邊形的左下頂點(左面)
		glVertex3f(-1.0f,-1.0f, 1.0f);	// 四邊形的右下頂點(左面)

		glColor3f(1.0f,0.0f,1.0f);		// 顏色改成紫羅蘭色
		glVertex3f( 1.0f, 1.0f,-1.0f);	// 四邊形的右上頂點(右面)
		glVertex3f( 1.0f, 1.0f, 1.0f);	// 四邊形的左上頂點(右面)
		glVertex3f( 1.0f,-1.0f, 1.0f);	// 四邊形的左下頂點(右面)
		glVertex3f( 1.0f,-1.0f,-1.0f);	// 四邊形的右下頂點(右面)
	glEnd();	// 立方體繪製結束

	return TRUE;	//  一切 OK
}
示例效果:

2.紋理對映

紋理對映也就是紋理的貼片技術,某些情況下,為了使某個圖形和真實的食物特別相似,就需要採用紋理貼片技術。比如,我們需要一個三維立體的西瓜,我們可以畫一個球體,然後在這個球體上貼上一張西瓜的紋理(圖片),就能得到相對逼真的三維立體西瓜。

1)在上例的基礎上,新增如下兩個函式:

/*******************************************************************************************************************************************
*AUX_RGBImageRec *LoadBMP()	
*功能:載入點陣圖
*引數:無
*返回值:AUX_RGBImageRec
********************************************************************************************************************************************/
AUX_RGBImageRec *LoadBMP()
{
	FILE *File=NULL;		// 檔案控制代碼
	File=fopen("Thistle.bmp","r");		// 嘗試開啟檔案,只讀方式
	if (File)				// 檔案存在麼?
	{
		fclose(File);			// 關閉控制代碼
		return auxDIBImageLoad(L"Thistle.bmp");	// 載入點陣圖並返回指標
	}
	return NULL;		// 如果載入失敗,返回 NULL
}

/*******************************************************************************************************************************************
*int LoadGLTextures()	
*功能:載入點陣圖並轉換成紋理
*引數:無
*返回值:無
********************************************************************************************************************************************/
int LoadGLTextures()								
{
	int Status=FALSE;	// 狀態指示器
	AUX_RGBImageRec *TextureImage[1];	// 建立紋理的儲存空間
	memset(TextureImage,0,sizeof(void *)*1);	// 將指標設為 NULL
	// 載入點陣圖,檢查有無錯誤,如果點陣圖沒找到則退出
	if (TextureImage[0]=LoadBMP())
	{
		Status=TRUE;	// 將 Status 設為 TRUE
		glGenTextures(1, &texture[0]);	// 建立紋理
		// 使用來自點陣圖資料生成 的典型紋理
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		// 生成紋理
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	// 線形濾波
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	// 線形濾波
	}
	if (TextureImage[0])	// 紋理是否存在
	{
		if (TextureImage[0]->data)	// 紋理影象是否存在
		{
			free(TextureImage[0]->data);	// 釋放紋理影象佔用的記憶體
		}
		free(TextureImage[0]);	// 釋放影象結構
	}
	return Status;	// 返回 Status
}

2)在初始化函式中新增載入紋理函式的初始化語句,如下所示:
/*******************************************************************************************************************************************
*int InitGL(GLvoid)		
*功能:初始化OpenGL繪圖環境
*引數:無
*返回值:BOOL
********************************************************************************************************************************************/
int InitGL(GLvoid)		// 此處開始對OpenGL進行所有設定
{
	if (!LoadGLTextures())		// 呼叫紋理載入子例程
	{
		return FALSE;		// 如果未能載入,返回FALSE
	}
	glEnable(GL_TEXTURE_2D);	// 啟用紋理對映
	glShadeModel(GL_SMOOTH);	// 啟用陰影平滑
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);	// 黑色背景
	glClearDepth(1.0f);		// 設定深度快取
	glEnable(GL_DEPTH_TEST);	// 啟用深度測試
	glDepthFunc(GL_LEQUAL);	// 所作深度測試的型別
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// 告訴系統對透視進行修正
	return TRUE;	// 初始化 OK

}

3)為立方體新增紋理對映,所以在DrawGLScene(GLvoid)函式中新增紋理的處理函式,如下所示:
/*******************************************************************************************************************************************
*int DrawGLScene(GLvoid)		
*功能:繪圖
*引數:無
*返回值:BOOL
********************************************************************************************************************************************/
int DrawGLScene(GLvoid)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// 清除螢幕和深度快取
	glLoadIdentity();	// 重置當前的模型觀察矩陣
	//新增繪圖程式碼
	glTranslatef(.0f,0.0f,-5.0f);	// 並移入螢幕5個單位
	glRotatef(xrot,1.0f,0.0f,0.0f);	// 繞X軸旋轉
	glRotatef(yrot,0.0f,1.0f,0.0f);	// 繞Y軸旋轉
	glRotatef(zrot,0.0f,0.0f,1.0f);	// 繞Z軸旋轉
	glBindTexture(GL_TEXTURE_2D, texture[0]);	// 選擇紋理
	glBegin(GL_QUADS);		//  繪製立方體
		// 前面
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// 紋理和四邊形的左下
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// 紋理和四邊形的右下
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// 紋理和四邊形的右上
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// 紋理和四邊形的左上
		// 後面
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	// 紋理和四邊形的右下
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	// 紋理和四邊形的右上
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	// 紋理和四邊形的左上
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	// 紋理和四邊形的左下
		// 頂面
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	// 紋理和四邊形的左上
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// 紋理和四邊形的左下
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// 紋理和四邊形的右下
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	// 紋理和四邊形的右上
		// 底面
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	// 紋理和四邊形的右上
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	// 紋理和四邊形的左上
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// 紋理和四邊形的左下
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// 紋理和四邊形的右下
		// 右面
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);	// 紋理和四邊形的右下
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);	// 紋理和四邊形的右上
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);	// 紋理和四邊形的左上
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);	// 紋理和四邊形的左下
		// 左面
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);	// 紋理和四邊形的左下
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);	// 紋理和四邊形的右下
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);	// 紋理和四邊形的右上
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	// 紋理和四邊形的左上
	glEnd();	// 立方體繪製結束
	xrot+=0.3f;		// X 軸旋轉
	yrot+=0.2f;		// Y 軸旋轉
	zrot+=0.4f;		// Z 軸旋轉

	return TRUE;	//  一切 OK
}

4)準備一張.bmp格式的點陣圖檔案放在工程所在的目錄下,然後編譯執行,即可獲得一個紋理貼片的立方體,如下所示:


相關推薦

OpenGL3D圖形繪製/紋理對映

1.3D圖形繪製 3D圖形也是由2D的面片組合而成,一個需要注意的問題是所有的面片繪製要麼是逆時針要麼是順時針,因此每三個點確定一個三角形或者每四個點確定一個四邊形,再有餘下的點時,按新的形狀處理。以下以一個旋轉的金字塔和立方體為例, /******************

計算機圖形學-紋理對映

先放個圖 利用MFC框架實現紋理對映 紋理對映主要包括紋理定義、紋理控制、紋理對映方式、紋理座標和紋理物件等 1 首先建立點陣圖類 class CBMPLoader { public: CBMPLoader(); ~CBMPLoader(); bool Lo

OpenGL基礎圖形程式設計--紋理對映

12.1 基本步驟     計算機三維圖形通過給面貼紋理來表現表面細節。OpenGL預設設定是關閉貼紋理的,所以必須先用命令開啟紋理計算。OpenGL體系內有一塊紋理記憶體,在有硬體加速的情況下,可能是位於顯示卡的VRAM裡,否則會是OpenGL庫管理的一塊記憶

使用QT搭建點雲顯示框架系列五·基於QT的QML影象選點、動態繪製十字絲功能 ,以及紋理對映

本文所有原始碼分享就看我最新的文章,歡迎各位大佬前來交流。http://blog.csdn.net/qq_30547073/article/details/79092419上一次利用QTeststream讀取了任意格式的點雲。這一次我花了一天的時間學習並實現了一個基於QML的

圖形學_opengl紋理對映

學了半學期的圖形學,除了幾個用python或是matlab比較方便的實驗外,用的大多數是opengl,在這總結一下紋理貼圖實驗中opengl的用法。 1、編譯器連線靜態庫 有用到glaux.h的程式,在加入相應的.h、.lib檔案後,需要加入兩行程式碼強行連線靜態庫: #pragma comment(lib

c++中txt檔案的讀取以及在MFC中讀取txt座標資料並完成圖形繪製

主要介紹如何讀取txt檔案中的座標資料,並在MFC視窗中繪製出來,工程建立方法和繪圖方法與上一篇博文基本一致,這裡就不再詳贅述,可參考上一篇博文vs2010、MFC視窗中繪製點、線、面。 C++中讀取檔案的方法有兩種,一種是來自於C語言的“檔案指標”方法,另一種是C++中的“檔案流”思想。

Direct3D 11 Tutorial 7:Texture Mapping and Constant Buffers_Direct3D 11 教程7:紋理對映和常量緩衝區

概述 在上一個教程中,我們為專案引入了照明。 現在我們將通過向我們的立方體新增紋理來構建它。 此外,我們將介紹常量緩衝區的概念,並解釋如何使用緩衝區通過最小化頻寬使用來加速處理。 本教程的目的是修改中心立方體以將紋理對映到其上。   資源目錄 (SDK root)\Samples\C++\

Python123(Python程式語言設計)-------練習2:Python基本圖形繪製

例項2: Python蟒蛇繪製 使用turtle庫繪製一個蟒蛇形狀的圖形 #PythonDraw.py import turtle turtle.setup(650, 350, 200, 200) turtle.penup() turtle.fd(-250) turtle.pend

WebGL---3.繪製紋理

一、例項程式碼 <html> <canvas id='c' width='480' height='320'></canvas> <script type="x-shader/x-vertex" id="vertex-shader">

投影紋理對映(Projective Texture Mapping)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

007.Zabbix監控圖形繪製

一 Graphs配置 1.1 新建圖形 Graphs是將資料展示為影象,以視覺化形式展示,Graphs的配置儲存在主機和模板中。 Configuration---->Hosts---->Graphs---->Graphs---->Create graph,新建所需

Java中常見圖形繪製方式與實現

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

【181121】VC++ 圖形繪製,可設定線寬、顏色、樣式等原始碼

原始碼下載簡介 VC++ 圖形繪製,可設定線寬、顏色、樣式,通過本例將瞭解如何使用自定義畫筆定義線體的顏色,線寬,線形等,以及如何為程式中新增選項選單和選項設定對話方塊,如何使用標準顏色對話方塊,如何使用字型對話方塊,在選項對話方塊中實現預覽功能。實現選項對話方塊和視窗類中的資料交換。如何改

Visual C++ MFC的圖形繪製——常見問題彙總(不定期更新)

                  Visual C++ MFC的圖形繪製——常見問題彙總 目錄 一.常見問題 1. 選單介面製作 2.命令響應函式  3.新增私有變數 4.訊

測驗2: Python基本圖形繪製 (第2周)

測驗2: Python基本圖形繪製 (第2周) 1.哪個選項不能正確引用turtle庫進而使用setup()函式?‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬ A、import

python_week2_基本圖形繪製

1 Python基本圖形繪製 1.1 Python蟒蛇繪製 import turtle as t t.setup(650, 300) t.penup() t.fd(-250) t.pendown() t.pensize(25) t.pencolor("purple") t.set

常用圖形繪製過程的常用格式

過程名 格式 GPLOT過程 proc gplot data=資料集名;symbolN <i=資料點連線方式 v=資料點符號圖形>;axisN <選項>;plot 縱軸座標

圖形繪製

GPLOT過程繪圖 常用於繪製二維圖形,可以繪製散點圖、曲線圖和線圖等。 格式: proc gplot data=資料集名; symbolN <選項>; *i=資料點連線方式 v=資料點圖形符號; axisN <選項>; plot 縱座標變數Y*橫座標變數X

【計算機圖形學】用python的turtle進行簡單的圖形繪製

【計算機圖形學】用python的turtle進行簡單的圖形繪製 python的turtle模組 繪製圖形 繪製點 繪製直線 繪製橢圓 繪製六邊形 繪製n次貝塞爾曲線 結語 python

mooc-python語言程式設計練習2-基本圖形繪製turtle

1.‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬# 00390031003900310038427 哪個選項不能正確引用turtle庫進而使用setup()函式?‪‬‪‬‪‬