Waving Texture in OpenGL (L5)

2015-11-17_111143

本篇要介紹如何將 texture mapping 到一個非平面上。以前是將整個 texture 映射到一個平面上,現在則是要將 pixel 個別映射到 3D 空間中( 每個 pixel 或 sub image 都有自己的映射平面)。

在定義的部分加入points[45][45][3],代表把 texture 影像切成 45x45 ,第三列為表示每一個 sub block 的 x, y, z 座標;Waving 則是表示讓 texture 做出像旗幟一樣飄逸的動作。記得要 include math.h ,因為會用到 sin() 函式。

#include "math.h"
#define pi 3.141592654
float points[45][45][3];
int Weaving;

load image 後,要加入以下的 code,定義多邊形( pylogon )的形式與 points 的座標位置。

	glPolygonMode(GL_BACK, GL_FILL);
	glPolygonMode(GL_FRONT, GL_LINE);
	// Waving plane
	Waving = 0;
	for(int x = 0; x < 45; x ++)
	{
		for(int y = 0; y < 45; y ++)
		{
			points[x][y][0] = float((x/5.0f) - 4.5f);
			points[x][y][1] = float((y/5.0f) - 4.5f);
			points[x][y][2] = float(sin((x/5.0f)*40.0f/180.0f*pi));			
		}
	}

glPolygonMode(GL_BACK, GL_FILL)  代表多邊形背向 rendering 的形式,GL_FILL 表示完全填滿。

glPolygonMode(GL_FRONT, GL_LINE) 則表示多邊形正向 rendering 的形式,GL_LINE表示以線條形式表現;另一種則是 GL_POINT。

waving plane 則是定義 points[45][45][3] 的三維座標位置。
2015-11-17_113415[GL_LINE]

2015-11-17_113440[GL_POINT]
 

接下來就是 painGL(),將 texture mapping 到一個 sine wave 平面上。隨著 Waving 增加而使 texture 飄逸。 

void myopenGL::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	if(Light)
		glEnable(GL_LIGHTING);
	else
		glDisable(GL_LIGHTING);

	glTranslatef(0.0f, 0.0f, -20.0f);
	glRotatef(rota_x, 1.0f, 0.0f, 0.0f);
	glRotatef(rota_y, 0.0f, 1.0f, 0.0f);
	glRotatef(rota_z, 0.0f, 0.0f, 1.0f);

	glBindTexture(GL_TEXTURE_2D, texture[2]);

	GLfloat float_x, float_y, float_xb, float_yb;
	glBegin(GL_QUADS);
	for(int x = 0; x < 44; x ++)
	{
		for(int y = 0; y < 44; y ++)
		{
			float_x = float(x)/44.0f;
			float_y = float(y)/44.0f;
			float_xb = float(x+1)/44.0f;
			float_yb = float(y+1)/44.0f;
			
			glTexCoord2f(float_x, float_y);
			glVertex3f(points[x][y][0], points[x][y][1], points[x][y][2]);	// bottom left
			glTexCoord2f(float_x, float_yb);
			glVertex3f(points[x][y+1][0], points[x][y+1][1], points[x][y+1][2]); //top left
			glTexCoord2f(float_xb, float_yb);
			glVertex3f(points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2]); // top right
			glTexCoord2f(float_xb, float_y);
			glVertex3f(points[x+1][y][0], points[x+1][y][1], points[x+1][y][2]); // bottom right
		}
	}

	if(Waving >= 0)
	{
		for(int y = 0; y < 45; y++)
		{
			double hold = points[0][y][2];
			for(int x = 0; x < 44; x ++)
			{
				points[x][y][2] = points[x+1][y][2];
			}
			points[44][y][2] = hold;
		}
		Waving ++;
	}
	glEnd();
}

 

執行結果:picasion.com_4f4d97b463678119b3d340eef014f06c

 

 

 


reference : http://nehe.gamedev.net/tutorial/flag_effect_(waving_texture)/16002/

 

Leave a Reply

Your email address will not be published. Required fields are marked *