⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawglscene.cpp

📁 environment_mapped_bump_mapping using opengl
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////
// scene.cpp: implementation of the scene class.
//
//////////////////////////////////////////////////////////////////////
#include "scene.h"
//////////////////////////////////////////////////////////////////////

void static DrawSphereBase(int del_uhol_x, int del_uhol_y);

inline static void SetCombineARB( unsigned int unit, unsigned int combiner=GL_MODULATE, \
				unsigned int source0=GL_PREVIOUS_ARB, unsigned int operand0=GL_SRC_COLOR, \
				unsigned int source1=GL_TEXTURE, unsigned int operand1=GL_SRC_COLOR, \
				unsigned int source2=GL_TEXTURE, unsigned int operand2=GL_SRC_ALPHA )
{
	glActiveTextureARB( GL_TEXTURE0_ARB + unit );			// aktivovanie jednotky
	glEnable(GL_TEXTURE_2D);
	glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );	// budeme kombinovat, t.j. pouzijeme rozsirenie GL_ARB_texture_env_combine
	glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, combiner );

	glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, source0 );
	glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, operand0 );
	glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, source1 );
	glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, operand1 );
	glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, source2 );
	glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, operand2 );

// nastavujeme sposob kombinovania medzi texturou a ostatnymi moznymi zdrojmi == combiner
//	GL_REPLACE             Arg0
//	GL_MODULATE            Arg0 * Arg1
//	GL_ADD                 Arg0 + Arg1
//	GL_ADD_SIGNED_ARB      Arg0 + Arg1 - 0.5
//	GL_SUBTRACT_ARB        Arg0 - Arg1
//	GL_INTERPOLATE_ARB     Arg0 * (Arg2) + Arg1 * (1-Arg2)
//	GL_DOT3_RGB_ARB		4*((Arg0_r-0.5)*(Arg1_r-0.5) + (Arg0_g-0.5)*(Arg1_g-0.5) + (Arg0_b-0.5)*(Arg1_b-0.5))
//	GL_DOT3_RGBA_ARB	vysledok je ulozeny aj v alpha ( r,g,b,a )

// zdroje source0, source1, source2: GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
// operandy operand0, operand1, operand2
//	GL_PRIMARY_COLOR_ARB       primarna farba prichadzajuceho fragmentu (vypocita sa z osvetlenia)
//	GL_TEXTURE                 farba textury prisluchajuca korespondujecej texturovacej jednotke
//	GL_CONSTANT_ARB            konstantna farba (nastavena s glColor)
//	GL_PREVIOUS_ARB            vysledko predchadzajucej texturavacej jednotky na texturovacej jednotky 0, je to mapovane z PRIMARY_COLOR_ARB
}

inline static void DisableAllUnits()
{
	for( unsigned int gl_texture = GL_TEXTURE1_ARB; gl_texture < (unsigned int)(GL_TEXTURE0_ARB + ext.max.max_texture_units); gl_texture++)
	{
		glActiveTextureARB( gl_texture );
		glDisable(GL_TEXTURE_2D);
	}
	SetCombineARB( 0);
}

static inline void GetSphereMappingCoordinates( float *s, float *t, const CVector &vertex, const CVector &n, const CMatrix4 &m)
{
	CVector r,v;
	v = m*vertex;
	v.Normalise();
	r = ReflectedRay( v, n);
	r.z +=1.f;
	float mul = 0.5f/r.Length();
	*s = r.x*mul + 0.5f;
	*t = r.y*mul + 0.5f;
}

void static DrawSphereBaseSphereMapping(int del_uhol_x, int del_uhol_y )
{
	float delta=0.002f;
	CVector a,b,ay,by;
	float dy=360.f/del_uhol_y;
	float dx=180.f*PI180/del_uhol_x;

	float s,t;
	CVector r,vertex,n;
	CMatrix4 m,m1;
	m.glGetMatrix();
	m1.glGetMatrix();
	m1.m14 = 0;	m1.m24 = 0;	m1.m34 = 0;	m1.m44 = 1;

	for(int x=0; x<del_uhol_x; x++)
	{
		float tx = (float)x/(float)del_uhol_x;
		float ang = tx*180.f*PI180-90.f*PI180;
		a.set( 0, (float)sin(ang) , (float)cos(ang));
		b.set( 0, (float)sin(ang+dx), (float)cos(ang+dx));
		
		glBegin( GL_TRIANGLE_STRIP);


		GetSphereMappingCoordinates( &s, &t, a, m1*a, m);
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0, tx);
		glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, tx);

		glNormal3fv(a.v);
		glVertex3fv(a.v);
		GetSphereMappingCoordinates( &s, &t, b, m1*b, m);
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
		glMultiTexCoord2fARB( GL_TEXTURE0_ARB, 0, tx+1.f/del_uhol_x);
		glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, tx+1.f/del_uhol_x);
		glNormal3fv(b.v);
		glVertex3fv(b.v);

		ay = a;	by = b;
		for(int y=1; y<del_uhol_y+1; y++)
		{
			float ty = (float)y/(float)del_uhol_y;
			ay = a;	ay.RotY( ty*360.f);
			by = b;	by.RotY( ty*360.f);
			GetSphereMappingCoordinates( &s, &t, ay, m1*ay, m);
			glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
			glMultiTexCoord2fARB( GL_TEXTURE0_ARB, ty, tx);
			glMultiTexCoord2fARB( GL_TEXTURE2_ARB, ty, tx);
			glNormal3fv(ay.v);
			glVertex3fv(ay.v);
			vertex = m*by;  vertex.Normalise();
			GetSphereMappingCoordinates( &s, &t, by, m1*by, m);
			glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
			glMultiTexCoord2fARB( GL_TEXTURE0_ARB, ty, tx+1.f/del_uhol_x);
			glMultiTexCoord2fARB( GL_TEXTURE2_ARB, ty, tx+1.f/del_uhol_x);
			glNormal3fv(by.v);
			glVertex3fv(by.v);
		}
		glEnd();
	}
}

void static DrawPlaneBaseSphereMapping(int del_x=4, int del_y=4, CVector &p=CVector(-1,-1,0), CVector &n=CVector(0,0,1), CVector &ds=CVector(2,0,0), CVector &dt=CVector(0,2,0))
{
	float delta=0.002f;
	float t,s;
	float dx=1.f/del_x;
	float dy=1.f/del_y;
	CMatrix4 m,m1;
	CVector a,b,a1,b1;

	m.glGetMatrix();
	m1.glGetMatrix();
	m1.m14 = 0;	m1.m24 = 0;	m1.m34 = 0;	m1.m44 = 1;
	glNormal3fv( n.v);
	n = m1*n;

	ds *= dx;
	dt *= dy;

	a = p;
	b = p+dt;
	for(float y=0; y<1.f; y+=dy, a+=dt, b+=dt)
	{
		float y1=y+dy;
		glBegin(GL_TRIANGLE_STRIP);
		GetSphereMappingCoordinates( &s, &t, a, n, m);
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
		glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,0 ,y);
		glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,0 ,y);
		glVertex3fv(a.v);
		GetSphereMappingCoordinates( &s, &t, b, n, m);
		glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
		glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,0 ,y1);
		glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,0 ,y1);
		glVertex3fv(b.v);

		a1 = a; b1=b;
		for(float x=dx; x<1.f+dx; x+=dx)
		{
			a1+=ds;
			b1+=ds;
			GetSphereMappingCoordinates( &s, &t, a1, n, m);
			glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
			glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,x ,y);
			glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,x ,y);
			glVertex3fv(a1.v);
			GetSphereMappingCoordinates( &s, &t, b1, n, m);
			glMultiTexCoord2fARB( GL_TEXTURE1_ARB ,s-0.5f+delta ,t-0.5f+delta);
			glMultiTexCoord2fARB( GL_TEXTURE0_ARB ,x ,y1);
			glMultiTexCoord2fARB( GL_TEXTURE2_ARB ,x ,y1);
			glVertex3fv(b1.v);
		}
		glEnd();
	}
}

void static DrawCubeBaseSphereMapping(int del_x=4, int del_y=4,float size=0.75)
{
	CVector p,n,s,t;
	// pozerame na +x
	n.set(-1,0,0);
	s.set(0,0,2*size);
	t.set(0,2*size,0);
	p = CVector(-size,0,0) -0.5*s -0.5*t;
	DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
	// pozerame na -x
	n.set(1,0,0);
	s.set(0,0,-2*size);
	t.set(0,2*size,0);
	p = CVector(size,0,0) -0.5*s -0.5*t;
	DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
	// pozerame na +y
	n.set(0,-1,0);
	s.set(2*size,0,0);
	t.set(0,0,2*size);
	p = CVector(0,-size,0) -0.5*s -0.5*t;
	DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
	// pozerame na -y
	n.set(0,1,0);
	s.set(2*size,0,0);
	t.set(0,0,-2*size);
	p = CVector(0,size,0) -0.5*s -0.5*t;
	DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
	// pozerame na +z
	n.set(0,0,1);
	s.set(-2*size,0,0);
	t.set(0,2*size,0);
	p = CVector(0,0,-size) -0.5*s -0.5*t;
	DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
	// pozerame na -z
	n.set(0,0,1);
	s.set(2*size,0,0);
	t.set(0,2*size,0);
	p = CVector(0,0,size) -0.5*s -0.5*t;
	DrawPlaneBaseSphereMapping(del_x, del_y, p, n, s, t);
}
// Tu je vsetko co sa kresli
void scene::DrawGLScene()
{
	if(keys['L'] && keys[VK_CONTROL]){ english = !english; keys['L']=0; }
	static int mode=ROTATE_WALK|ROTATE_ABOUT_POINT;		// volba modu pre cameru
	if(keys['V'])		// menime mod
	{
		switch(mode)
		{
		case ROTATE_WALK: mode=ROTATE_WALK|ROTATE_ABOUT_POINT; break;
		case ROTATE_WALK|ROTATE_ABOUT_POINT: mode=ROTATE_FLY|ROTATE_ABOUT_POINT; break;
		case ROTATE_FLY|ROTATE_ABOUT_POINT: mode=ROTATE_WALK; break;
		default: mode=ROTATE_WALK;
		}
		if(mode&ROTATE_ABOUT_POINT)c->set.k_remap_mouse_button_vd_vpd=1;
		else c->set.k_remap_mouse_button_vd_vpd=0;
		c->setKeys();
		c->Reset();			// reset camery
		keys['V']=0;
	}
	c->MoveWorld(fps, mode);	// otoci svetom na zaklade vstupov od mysi a klavesnice

	// VYTVORENIE SPHERE MAP
	// sphere map je textura ktora, predsatavuje reflexnu gulu sfotenu rovnobeznymi lucmi
	// mozme ju vytvorit pomocou vykreslenej gule pri zapnutom cube mapping
	// viewport velkost sphere map, pravouhle premietanie, 
	// camera co najdalej od gule, pretoze reflesny luc sa pocita z luca iduceho od kamery k akt. vertex
	glViewport(0,0,renderableTexture,renderableTexture);		// Viewport (pohlad)
//	glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	//cisti buffer v aktualnom viewporte a to iba color a hlbkovy bit
//	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glMatrixMode(GL_PROJECTION);		// projekcia
	glLoadIdentity();					// Reset pohladu - nacita jednotkovu maticu
	glOrtho(-1,1,-1,1,-1,200);			// nastavuje standardne pravouhle premietanie
	glMatrixMode(GL_MODELVIEW);			// Modelview

	CMatrix4 cam;					// nastavyme kameru
	cam.Translate(0,0,-200);		// konstantne posunutie 200
	cam.MakeMatrix( c->vr, c->vu, -c->vd);	// vytvorenie matice z vektorov
	cam.glSetMatrix();				// nastavime maticu

	CubeMapBegin();
	cubemap.glBindTextureCube();
	DrawSphereBase(40,40);
	CubeMapEnd();


	spheremap.glBindTexture2D();
	glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, renderableTexture, renderableTexture );	// skopirujeme do sphere map
	if(keys[VK_F11]){ SaveScreen_BMP(0,0,renderableTexture,renderableTexture);keys[VK_F11]=0;	}
	
	ReSizeGLScene(sirka, vyska);			// naspat nastavyme view port + projekciu
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	//cisti buffer v aktualnom viewporte a to iba color a hlbkovy bit

	c->SetTransform();			// nastavyme kameru
	glEnable( GL_TEXTURE_2D);
/*
	GL_ATI_envmap_bumpmap
	- rozsirenie umoznuje environment mapped bump mapping (EMBM) - mapovanie okolia ma hrbolaty zrkadlovy povrch
	- metoda pouziva zavisle citanie
	- su pouzivane dve textury, jedna zakladna a druha vyjadrujuca posun texturovych suradnic (du,dv)
	- texturove koordinacie pre zakladnu texturu su pocitane takto:
	u' = u + du * Rot[00] + dv * Rot[01]
	v' = v + du * Rot[10] + dv * Rot[11]
	kde u,v su povodne texturove koordinacie zakladnej texturu, du,dv je hodnota z textury vyjadrujucej posuv
	a Rot je uzivatemom definovana rotacna matica

pouzitie:
	glActiveTextureARB(GL_TEXTURE2_ARB);							// aktivovanie jednotky
	glEnable(GL_TEXTURE_2D);
	glBindTexture( GL_TEXTURE_2D, dudv);							// nastavenie textury
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);		// budeme kombinovat, t.j. pouzijeme rozsirenie GL_ARB_texture_env_combine
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB,  GL_BUMP_ENVMAP_ATI);	// tato jednotka vyjadruje posuv
	glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE1_ARB);		// posuv sa aplikuje na jednotku 1
	glTexBumpParameterfvATI( GL_BUMP_ROT_MATRIX_ATI, rot);				// definovanie rotacnej matice

pracuje takto:
	jednotka s GL_BUMP_ENVMAP_ATI ma texturu, ktora obsahuje posunutia (du,dv)
	(du,dv) je rotovany maticou:
	du' = du * Rot[00] + dv * Rot[01]
	dv' = du * Rot[10] + dv * Rot[11]
	(du',dv') sa pouziju na posunutie (u,v) koordinacii pri citani z textury na jednotke GL_BUMP_TARGET_ATI:
	u = u + du'
	v = v + dv'

Funkcie a konstanty:
	// definovanie rotacnej matice
	glTexBumpParameterfvATI( GL_BUMP_ROT_MATRIX_ATI, GLfloat *param);
	glTexBumpParameterivATI( GL_BUMP_ROT_MATRIX_ATI, GLint *param);

	glGetTexBumpParameterivATI(GLenum pname, GLint *param);	
	glGetTexBumpParameterfvATI(GLenum pname, GLfloat *param);
pname:
	GL_BUMP_ROT_MATRIX_ATI			- vrati aktualnu rotacnu maticu (velkosti GL_BUMP_ROT_MATRIX_SIZE_ATI)
	GL_BUMP_ROT_MATRIX_SIZE_ATI		- vrati pocet poloziek v GL_BUMP_ROT_MATRIX_ATI
	GL_BUMP_NUM_TEX_UNITS_ATI		- vrati pocet jednotiek podporujucich bump mapping
	GL_BUMP_TEX_UNITS_ATI			- vrati pole jednotiek podporujucich bump mapping (velkost GL_BUMP_NUM_TEX_UNITS_ATI)

void glTexImage2D( GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
format, components:
	GL_DUDV_ATI
	GL_DU8DV8_ATI

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -