現在地: メニュー >> 発展編06 >> 発展編06::まとめコード

問題

以下の図のような色分布を持つ3次元テクスチャを解像度(64×64×64)で作成し、3次元テクスチャマッピングを行え。



動作確認として、直線に3次元テクスチャマッピングをする。
  • 2点のうち1点は原点固定。もう1点はキーボードで動かす ⇒ 直線の色の与えられ方を確認する。
  • 「↑」「↓」「←」「→」でx,y方向の移動
  • 「f」「d」でz方向の移動をする

答え

#include <iostream>
#include <gl/glew.h>
#include <gl/glut.h>


#pragma comment(lib,"glew32.lib")

//----- テクスチャID -----//
GLuint texture[1];

enum{POSX,POSY,POSZ};

float pos[3]={0,0,0};
//------------- プロトタイプ宣言 --------------------//
void display();
void reshape(int w, int h);
void DRAW_XYZ();
void specialkey(int key, int x, int y);
void keyboard(unsigned char key, int x, int y);



void build3DTexture(int width, int height,int depth)
{
	unsigned char *Data = new unsigned char[width*height*depth*3];

	memset(Data,0,sizeof(unsigned char)*width*height*depth*3);//初期化
	int widthStep = width*3;

	//ここでカラー設定
	for(int loopZ = 0;loopZ < depth;++loopZ)
	{
		for(int loopY = 0; loopY < height;++loopY)
		{
			for(int loopX = 0;loopX < width;++loopX)
			{
				Data[loopZ*(width*height*3) +loopY*widthStep + loopX*3+0] = static_cast<unsigned char>((255/width)*loopX);//r
				Data[loopZ*(width*height*3) +loopY*widthStep + loopX*3+1] = static_cast<unsigned char>((255/height)*loopY);//g
				Data[loopZ*(width*height*3) +loopY*widthStep + loopX*3+2]= static_cast<unsigned char>((255/depth)*loopZ);//b
			}
		}
	}

	glGenTextures(1, &texture[0]);
	glBindTexture(GL_TEXTURE_3D, texture[0]);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); //フィルタ
	glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);

	glGenerateMipmapEXT(GL_TEXTURE_3D);//ミップマップ自動生成
	glTexImage3D(GL_TEXTURE_3D,0,GL_RGB, width,height,depth,0, GL_RGB,GL_UNSIGNED_BYTE,Data);

	delete Data;
}




//-------------OpenGLの初期設定------------------//
void GLUT_CALL_FUNC()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutSpecialFunc(specialkey);
	glutKeyboardFunc(keyboard);
}


void GLUT_INIT()
{
	glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutCreateWindow("3D Texture");
	GLUT_CALL_FUNC();
	
}

void MY_INIT()
{
	glClearColor(1.0, 1.0, 1.0, 1.0);
	glEnable(GL_DEPTH_TEST);
}



//--------- ここから各種コールバック ---------//
void display()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLoadIdentity();
	gluLookAt(2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

	//3次元テクスチャマッピング
	glEnable(GL_TEXTURE_3D);

	glLineWidth(5);
	glBegin(GL_LINES);
	glTexCoord3f(0,0,0);
	glVertex3f(0,0,0);

	glTexCoord3f(pos[0],pos[1],pos[2]);//s,t,r
	glVertex3fv(pos);
	glEnd();
	glLineWidth(1);
	glDisable(GL_TEXTURE_3D);

	//位置確認のための擬似的な影
	glColor3f(0.9f,0.9f,0.9f);
	glBegin(GL_LINES);
	glVertex3f(0,0,0);
	glVertex3f(pos[0],0,pos[2]);
	glEnd();
	
	//移動目安用キューブ
	glColor3f(0,0,0);
	glPushMatrix();
	glTranslatef(0.5,0.5,0.5);
	glutWireCube(1);
	glPopMatrix();

	DRAW_XYZ();
	glutSwapBuffers();

}

void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, w / static_cast<double>(h), 0.1, 200.0);
	glMatrixMode(GL_MODELVIEW);
}

//----------- メイン関数 -------------//
int main(int argc, char **argv)
{
	glutInit(&argc,argv);
	GLUT_INIT();

	GLenum err;
	err = glewInit();
	if (err != GLEW_OK){
		std::cerr << glewGetErrorString(err) << '\n'; //エラーを出力
		return -1;
	}

	build3DTexture(64,64,64);//3次元テクスチャ作成
	MY_INIT();

	glutMainLoop();

	glDeleteTextures(1, &texture[0]);//本来は削除する

	return 0;
}

void DRAW_XYZ()
{
	glBegin(GL_LINES);

	glColor3d(1,0,0);//x
	glVertex2d(-100,0);
	glVertex2d(100, 0);

	glColor3d(0,1,0);//y
	glVertex2d(0,0);
	glVertex2d(0,100);

	glColor3d(0,0,1);//z
	glVertex3d(0,0,-100);
	glVertex3d(0,0, 100);
	glEnd();
	glColor3d(1,1,1);
}

void specialkey(int key, int x, int y)
{
     if( key == GLUT_KEY_UP )//矢印「上」
     {
		pos[POSY] += 0.05f;
		
     }

     if( key == GLUT_KEY_DOWN )//矢印「下」
     {
		 pos[POSY] -= 0.05f;
     }

     if( key == GLUT_KEY_LEFT )
     {
		 pos[POSX] -= 0.05f;
     }

     if( key == GLUT_KEY_RIGHT )
     {
		 pos[POSX] += 0.05f;
     }

	 glutPostRedisplay();

}

void keyboard(unsigned char key, int x, int y)
{
	if(key == 'f')
	{
		pos[POSZ] += 0.05f;
	}

	if(key == 'd')
	{
		pos[POSZ] -= 0.05f;
	}

	glutPostRedisplay();
}

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます