IT도서관:포프

From IT도서관

Jump to: navigation, search

목차

nehe 9강

3D 공간에서의 비트맵 이동 - 소개

lesson09.jpg

이 강좌에서는 여러분들이 요청하신 몇몇 주제들을 다룰 것입니다. 3D 공간에서 화면 주위로 물체들을 움직이는 방법을 알고 싶어하시는 분들이 계셨죠? 비트맵의 검정색 부분이 뒷화면을 가리지 않도록 그리는 법을 알고 싶어하셨던 분들도 계셨습니다. 간단한 애니메이션과 블렌딩은 다른 용도를 알고 싶어하셨던 분들도 계셨더군요. 이 강좌는 이 모두를 가르쳐드릴 것입니다. 더이상 한자리에서 뱅글뱅글 도는 상자는 없을 것입니다. 여지까지의 강좌들은 OpenGL의 기초를 다뤘습니다. 각 강좌는 바로 전의 강좌에서 확장을 한 것이었습니다. 이 강좌는 여태까지 배우신 모든 것들의 조합에 3차원에서 물체를 움직이는 법에 대한 정보를 추가합니다. 이 강좌는 이전 강좌들에 비해 조금 더 어려우니 지난 강좌들을 잘 숙지하도록 하세요.


This tutorial covers a few of the topics you guys had requested. You wanted to know how to move the objects you've made around the screen in 3D. You wanted to know how to draw a bitmap to the screen, without the black part of the image covering up what's behind it. You wanted simple animation and more uses for blending. This tutorial will teach you all of that. You'll notice there's no spinning boxes. The previous lessons covered the basics of OpenGL. Each tutorial expanded on the last. This tutorial is a combination of everything that you have learned up till now, along with information on how to move your object in 3D. This tutorial is a little more advanced, so make sure you understand the previous lessons before you jump into this tutorial.

본문

제9강에 오신것을 환영합니다. 지금쯤이면 모두들 OpenGL을 매우 잘 이해하고 계시겠군요. 여러분은 OpenGL 창을 설정하는 법부터 텍스처매핑, 조명, 블렌딩에 이르기까지 모든 것을 배우셨습니다. 이번 강좌가 첫 중급 강좌가 되겠군요. 이 강좌에서는 3D 공간 속에서 비트맵을 움직여 화면에 보이는 법과 비트맵 주변의 검정 픽셀들을 제거하는 법(블렌딩을 사용), 흑백 텍스처에 색깔을 더하는 법과 여러색의 텍스처들을 혼합하여 그럴듯한 색상과 간단한 애니메이션을 만드는 법을 배울 것입니다.

Welcome to Tutorial 9. By now you should have a very good understanding of OpenGL. You've learned everything from setting up an OpenGL Window, to texture mapping a spinning object while using lighting and blending. This will be the first semi-advanced tutorial. You'll learn the following: Moving bitmaps around the screen in 3D, removing the black pixels around the bitmap (using blending), adding color to a black & white texture and finally you'll learn how to create fancy colors and simple animation by mixing different colored textures together.

자, 그럼 제1강에서 사용했던 코드를 수정해볼까요? 우선 프로그램의 앞부분에 몇개의 새로운 변수를 추가합시다. 이 코드부분을 모두 다시 작성해 보여드리겠습니다. 이것이 어디를 바꿨는지 알아보기에 더 편하겠죠?

We'll be modifying the code from lesson one for this tutorial. We'll start off by adding a few new variables to the beginning of the program. I'll rewrite the entire section of code so it's easier to see where the changes are being made.


#include	<windows.h>					// 윈도우즈용 헤더파일
#include	<stdio.h>					// 표준 입축력용 헤더파일
#include	<gl\gl.h>					// OpenGL32 라이브러리용 헤더파일
#include	<gl\glu.h>					// GLu32 라이브러리용 헤더파일
#include	<gl\glaux.h>					// GLaux 라이브러리용 헤더파일

HDC		hDC=NULL;					// 전용 GDI 장치 컨텍스트
HGLRC		hRC=NULL;					// 렌더링 컨텍스트
HWND		hWnd=NULL;					// 이 프로그램 창의 핸들
HINSTANCE	hInstance;					// 이 프로그램의 인스턴스

bool		keys[256];					// 키보드 루틴에 사용하는 배열
bool		active=TRUE;					// 창 활성화 플래그. 기본 값은 TRUE
bool		fullscreen=TRUE;				// 전체화면 플래그. 기본값은 전체화면

다음 코드들은 새로운 것입니다. twinkle과 tp는 불리언 변수로서 TRUE(참)나 FALSE(거짓)의 값을 가집니다. twinkle은 반짝이는 효과를 사용하는지 여부를 기억할 것이며, tp는 'T'키가 눌렸는지 아니면 더이상 눌리고 있지 않은지를 확인합니다. (tp=TRUE이면 눌린 것이고 tp=FALSE이면 더 이상 안눌리고 있는 것입니다.)

The following lines are new. twinkle and tp are BOOLean variables meaning they can be TRUE or FALSE. twinkle will keep track of whether or not the twinkle effect has been enabled. tp is used to check if the 'T' key has been pressed or released. (pressed tp=TRUE, relased tp=FALSE).

BOOL	twinkle;						// 반짝 반짝 작은 별
BOOL	tp;							// 'T' 키가 눌렸는가?

num은 화면에 그를 별들의 숫자를 기억합니다. 이것은 상수(const)로 정의되었으므로 이 코드안에서 이 값을 다시 바꾸는 것은 불가능합니다. 이것은 상수로 정의한 이유는 배열을 재정의할수 없기 때문입니다. 우리는 오직 50개의 별만을 가지는 배열을 만들었으므로 나중에 코드 어디에선가 num을 51로 증가시켜도 배열을 51로 자라나게 할 수 없습니다. 따라서 오류가 발생할 것입니다. 이 라인에서만 이 값을 변경할수 있습니다. 코드의 다른 부분에서 이 값을 변경하려고 하지 마십시요. 만약 그러면 불행한 일(?)이 일어날 것입니다.

num will keep track of how many stars we draw to the screen. It's defined as a CONSTant. This means it can never change within the code. The reason we define it as a constant is because you can not redefine an array. So if we've set up an array of only 50 stars and we decided to increase num to 51 somewhere in the code, the array can not grow to 51, so an error would occur. You can change this value to whatever you want it to be in this line only. Don't try to change the value of num later on in the code unless you want disaster to occur.


const	num=50;							// 화면에 그릴 별의 수


이제 구조체를 하나 만듭니다. 구조체라는 말이 어렵게 들린다구요? 전혀 그렇지 않습니다. 간단히 말해 구조체는 단순한 데이터(변수 등)을 한데 모아놓은 그룹에 지나지 않습니다. 우리는 별들의 정보를 저장해야합니다. 코드를 7줄 더 아래로 내려보면 stars 구조체가 보일 것입니다. 각 별은 색상 값 3개를 가지고, 각 값은 정수형이 될 것입니다. 3번째 라인인 int r, g, b는 3개의 정수 값을 기억합니다. 당연히 r = 빨강색, g = 녹색, b = 파랑색이겠지요. 각 별들은 화면 중앙으로부터 상이한 거리에 위치할 것이며, 중앙과 별사이의 각도도 다양할 것입니다. 4번째 라인을 보신다면 dist라는 부동소수점 변수를 보실수 있을 것입니다. 이것이 거리를 기억합니다. 5번째 라인은 angle이라는 부동소수점 값입니다. 이것은 별들의 각도를 기억합니다.

Now we create a structure. The word structure sounds intimidating, but it's not really. A structure is a group simple data (variables, etc) representing a larger similar group. In english :) We know that we're keeping track of stars. You'll see that the 7th line below is stars;. We know each star will have 3 values for color, and all these values will be integer values. The 3rd line int r,g,b sets up 3 integer values. One for red (r), one for green (g), and one for blue (b). We know each star will be a different distance from the center of the screen, and can be place at one of 360 different angles from the center. If you look at the 4th line below, we make a floating point value called dist. This will keep track of the distance. The 5th line creates a floating point value called angle. This will keep track of the stars angle.

이제 별 하나의 색상, 거리, 각도를 묘사하는 데이터 그룹을 만들었습니다. 불행히도 우리가 기억해야할 별의 수는 하나가 아니지요? 50개의 빨강색 값, 50개의 녹색 값, 50개의 파랑색 값, 50개의 거리 값, 50개의 각도 값을 생성하는 대신 star라고 불리는 배열을 만들 것입니다. star 배열의 각 번호는 stars 구조체에 이 모든 정보를 담을 것입니다. 8번째줄 코드에서 star 배열을 만듭니다. 8번째줄을 자세히 살펴볼까요? Stars star[num]이라고 되어 있군요. 배열의 형(type)은 stars가 될 것입니다. stars는 구조체입니다. 따라서 이 배열은 이 구조체에 모든 정보를 저장할 것입니다. 이 배열의 이름은 star입니다. 이 배열의 숫는 [num]입니다. num=50이므로 이제 star라고 불리는 배열을 가지고 있습니다. 우리의 배열은 stars구조체의 요소들을 저장할 것입니다. 여러개의 변수들을 사용해 각 별의 정보를 기억하는 것보다 훨씬 쉽습니다. 그리고 num의 const값을 변경함으로써 쉽게 별들을 추가하고 제거할 수 있게 해주지요.

So now we have this group of data that describes the color, distance and angle of a star on the screen. Unfortunately we have more than one star to keep track of. Instead of creating 50 red values, 50 green values, 50 blue values, 50 distance values and 50 angle values, we just create an array called star. Each number in the star array will hold all of the information in our structure called stars. We make the star array in the 8th line below. If we break down the 8th line: stars star[num]. This is what we come up with. The type of array is going to be stars. stars is a structure. So the array is going to hold all of the information in the structure. The name of the array is star. The number of arrays is [num]. So because num=50, we now have an array called star. Our array stores the elements of the structure stars. Alot easier than keeping track of each star with seperate variables. Which would be a very stupid thing to do, and would not allow us to add remove stars by changing the const value of num.

typedef struct							// 별 구조체
{
	int r, g, b;						// 별 색상
	GLfloat dist;						// 중점으로부터 별까지의 거리
	GLfloat angle;						// 별의 현재 각도
}
stars;								// 구조체 이름이 stars임
stars star[num];						// 'stars'구조체에 담겨있는 정보로부터 'num' 개수 만큼의 'star' 배열을 만듬

초벌

Next we set up variables to keep track of how far away from the stars the viewer is (zoom), and what angle we're seeing the stars from (tilt). We make a variable called spin that will spin the twinkling stars on the z axis, which makes them look like they are spinning at their current location.

loop is a variable we'll use in the program to draw all 50 stars, and texture[1] will be used to store the one b&w texture that we load in. If you wanted more textures, you'd increase the value from one to however many textures you decide to use.

GLfloat	zoom=-15.0f;						// 별의 가시거리
GLfloat tilt=90.0f;						// 뷰를 기울인다
GLfloat	spin;							// 반짝이는 별들을 회전시킨다

GLuint	loop;							// 일반 루프 변수
GLuint	texture[1];						// 텍스처 하나를 저장할 공간

LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);		// WndProc 선언

Right after the line above we add code to load in our texture. I shouldn't have to explain the code in great detail. It's the same code we used to load the textures in lesson 6, 7 and 8. The bitmap we load this time is called star.bmp. We generate only one texture using glGenTextures(1, &texture[0]). The texture will use linear filtering.

AUX_RGBImageRec *LoadBMP(char *Filename)			// 비트맵 이미지를 로딩함
{
	FILE *File=NULL;					// 파일 핸들

	if (!Filename)						// 파일명을 매개변수로 받았는지 확인
	{
		return NULL;					// 그렇지 않다면 NULL을 반환
	}

	File=fopen(Filename,"r");				// 파일이 존재하는지 확인

	if (File)						// 파일이 존재하는가?
	{
		fclose(File);					// 파일 핸들을 닫음
		return auxDIBImageLoad(Filename);		// 비트맵을 로딩하고 포인터를 반환
	}
	return NULL;						// 로딩이 실패한 경우 NULL을 반환
}

This is the section of code that loads the bitmap (calling the code above) and converts it into a textures. Status is used to keep track of whether or not the texture was loaded and created.

int LoadGLTextures()						// Load Bitmaps And Convert To Textures
{
	int Status=FALSE;					// Status Indicator

	AUX_RGBImageRec *TextureImage[1];			// Create Storage Space For The Texture

	memset(TextureImage,0,sizeof(void *)*1);		// Set The Pointer To NULL

	// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
	if (TextureImage[0]=LoadBMP("Data/Star.bmp"))
	{
		Status=TRUE;					// Set The Status To TRUE

		glGenTextures(1, &texture[0]);			// Create One Texture

		// Create Linear Filtered Texture
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
	}

	if (TextureImage[0])					// If Texture Exists
	{
		if (TextureImage[0]->data)			// If Texture Image Exists
		{
			free(TextureImage[0]->data);		// Free The Texture Image Memory
		}

		free(TextureImage[0]);				// Free The Image Structure
	}

	return Status;						// Return The Status
}

Now we set up OpenGL to render the way we want. We're not going to be using Depth Testing in this project, so make sure if you're using the code from lesson one that you remove glDepthFunc(GL_LEQUAL); and glEnable(GL_DEPTH_TEST); otherwise you'll see some very bad results. We're using texture mapping in this code however so you'll want to make sure you add any lines that are not in lesson 1. You'll notice we're enabling texture mapping, along with blending.

int InitGL(GLvoid)						// All Setup For OpenGL Goes Here
{
	if (!LoadGLTextures())					// Jump To Texture Loading Routine
	{
		return FALSE;					// If Texture Didn't Load Return FALSE
	}

	glEnable(GL_TEXTURE_2D);				// Enable Texture Mapping
	glShadeModel(GL_SMOOTH);				// Enable Smooth Shading
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);			// Black Background
	glClearDepth(1.0f);					// Depth Buffer Setup
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);			// Set The Blending Function For Translucency
	glEnable(GL_BLEND);					// Enable Blending

The following code is new. It sets up the starting angle, distance, and color of each star. Notice how easy it is to change the information in the structure. The loop will go through all 50 stars. To change the angle of star[1] all we have to do is say star[1].angle={some number} . It's that simple!

	for (loop=0; loop<num; loop++)				// Create A Loop That Goes Through All The Stars
	{
		star[loop].angle=0.0f;				// Start All The Stars At Angle Zero

I calculate the distance by taking the current star (which is the value of loop) and dividing it by the maximum amount of stars there can be. Then I multiply the result by 5.0f. Basically what this does is moves each star a little bit farther than the previous star. When loop is 50 (the last star), loop divided by num will be 1.0f. The reason I multiply by 5.0f is because 1.0f*5.0f is 5.0f. 5.0f is the very edge of the screen. I don't want stars going off the screen so 5.0f is perfect. If you set the zoom further into the screen you could use a higher number than 5.0f, but your stars would be alot smaller (because of perspective).

You'll notice that the colors for each star are made up of random values from 0 to 255. You might be wondering how we can use such large values when normally the colors are from 0.0f to 1.0f. When we set the color we'll use glColor4ub instead of glColor4f. ub means Unsigned Byte. A byte can be any value from 0 to 255. In this program it's easier to use bytes than to come up with a random floating point value.

		star[loop].dist=(float(loop)/num)*5.0f;		// Calculate Distance From The Center
		star[loop].r=rand()%256;			// Give star[loop] A Random Red Intensity
		star[loop].g=rand()%256;			// Give star[loop] A Random Green Intensity
		star[loop].b=rand()%256;			// Give star[loop] A Random Blue Intensity
	}
	return TRUE;						// Initialization Went OK
}

The Resize code is the same, so we'll jump to the drawing code. If you're using the code from lesson one, delete the DrawGLScene code, and just copy what I have below. There's only 2 lines of code in lesson one anyways, so there's not a lot to delete.

int DrawGLScene(GLvoid)						// Here's Where We Do All The Drawing
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
	glBindTexture(GL_TEXTURE_2D, texture[0]);		// Select Our Texture

	for (loop=0; loop<num; loop++)				// Loop Through All The Stars
	{
		glLoadIdentity();				// Reset The View Before We Draw Each Star
		glTranslatef(0.0f,0.0f,zoom);			// Zoom Into The Screen (Using The Value In 'zoom')
		glRotatef(tilt,1.0f,0.0f,0.0f);			// Tilt The View (Using The Value In 'tilt')

Now we move the star. The star starts off in the middle of the screen. The first thing we do is spin the scene on the x axis. If we spin 90 degrees, the x axis will no longer run left to right, it will run into and out of the screen. As an example to help clarify. Imagine you were in the center of a room. Now imagine that the left wall had -x written on it, the front wall had -z written on it, the right wall had +x written on it, and the wall behind you had +z written on it. If the room spun 90 degrees to the right, but you did not move, the wall in front of you would no longer say -z it would say -x. All of the walls would have moved. -z would be on the right, +z would be on the left, -x would be in front, and +x would be behind you. Make sense? By rotating the scene, we change the direction of the x and z planes.

The second line of code moves to a positive value on the x plane. Normally a positive value on x would move us to the right side of the screen (where +x usually is), but because we've rotated on the y plane, the +x could be anywhere. If we rotated by 180 degrees, it would be on the left side of the screen instead of the right. So when we move forward on the positive x plane, we could be moving left, right, forward or backward.

		glRotatef(star[loop].angle,0.0f,1.0f,0.0f);	// Rotate To The Current Stars Angle
		glTranslatef(star[loop].dist,0.0f,0.0f);	// Move Forward On The X Plane

Now for some tricky code. The star is actually a flat texture. Now if you drew a flat quad in the middle of the screen and texture mapped it, it would look fine. It would be facing you like it should. But if you rotated on the y axis by 90 degrees, the texture would be facing the right and left sides of the screen. All you'd see is a thin line. We don't want that to happen. We want the stars to face the screen all the time, no matter how much we rotate and tilt the screen.

We do this by cancelling any rotations that we've made, just before we draw the star. You cancel the rotations in reverse order. So above we tilted the screen, then we rotated to the stars current angle. In reverse order, we'd un-rotate (new word) the stars current angle. To do this we use the negative value of the angle, and rotate by that. So if we rotated the star by 10 degrees, rotating it back -10 degrees will make the star face the screen once again on that axis. So the first line below cancels the rotation on the y axis. Then we need to cancel the screen tilt on the x axis. To do that we just tilt the screen by -tilt. After we've cancelled the x and y rotations, the star will face the screen completely.

		glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);	// Cancel The Current Stars Angle
		glRotatef(-tilt,1.0f,0.0f,0.0f);		// Cancel The Screen Tilt

If twinkle is TRUE, we'll draw a non-spinning star on the screen. To get a different color, we take the maximum number of stars (num) and subtract the current stars number (loop), then subtract 1 because our loop only goes from 0 to num-1. If the result was 10 we'd use the color from star number 10. That way the color of the two stars is usually different. Not a good way to do it, but effective. The last value is the alpha value. The lower the value, the darker the star is.

If twinkle is enabled, each star will be drawn twice. This will slow down the program a little depending on what type of computer you have. If twinkle is enabled, the colors from the two stars will mix together creating some really nice colors. Also because this star does not spin, it will appear as if the stars are animated when twinkling is enabled. (look for yourself if you don't understand what I mean).

Notice how easy it is to add color to the texture. Even though the texture is black and white, it will become whatever color we select before we draw the texture. Also take note that we're using bytes for the color values rather than floating point numbers. Even the alpha value is a byte.

		if (twinkle)					// Twinkling Stars Enabled
		{
			// Assign A Color Using Bytes
			glColor4ub(star[(num-loop)-1].r,star[(num-loop)-1].g,star[(num-loop)-1].b,255);
			glBegin(GL_QUADS);			// Begin Drawing The Textured Quad
				glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);
				glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);
				glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
			glEnd();				// Done Drawing The Textured Quad
		}

Now we draw the main star. The only difference from the code above is that this star is always drawn, and this star spins on the z axis.

		glRotatef(spin,0.0f,0.0f,1.0f);			// Rotate The Star On The Z Axis
		// Assign A Color Using Bytes
		glColor4ub(star[loop].r,star[loop].g,star[loop].b,255);
		glBegin(GL_QUADS);				// Begin Drawing The Textured Quad
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);
			glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f);
			glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
		glEnd();					// Done Drawing The Textured Quad

Here's where we do all the movement. We spin the normal stars by increasing the value of spin. Then we change the angle of each star. The angle of each star is increased by loop/num. What this does is spins the stars that are farther from the center faster. The stars closer to the center spin slower. Finally we decrease the distance each star is from the center of the screen. This makes the stars look as if they are being sucked into the middle of the screen.

		spin+=0.01f;					// Used To Spin The Stars
		star[loop].angle+=float(loop)/num;		// Changes The Angle Of A Star
		star[loop].dist-=0.01f;				// Changes The Distance Of A Star

The lines below check to see if the stars have hit the center of the screen or not. When a star hits the center of the screen it's given a new color, and is moved 5 units from the center, so it can start it's journey back to the center as a new star.

		if (star[loop].dist<0.0f)			// Is The Star In The Middle Yet
		{
			star[loop].dist+=5.0f;			// Move The Star 5 Units From The Center
			star[loop].r=rand()%256;		// Give It A New Red Value
			star[loop].g=rand()%256;		// Give It A New Green Value
			star[loop].b=rand()%256;		// Give It A New Blue Value
		}
	}
	return TRUE;						// Everything Went OK
}

Now we're going to add code to check if any keys are being pressed. Go down to WinMain(). Look for the line SwapBuffers(hDC). We'll add our key checking code right under that line. lines of code.

The lines below check to see if the T key has been pressed. If it has been pressed and it's not being held down the following will happen. If twinkle is FALSE, it will become TRUE. If it was TRUE, it will become FALSE. Once T is pressed tp will become TRUE. This prevents the code from running over and over again if you hold down the T key.

		SwapBuffers(hDC);				// Swap Buffers (Double Buffering)
		if (keys['T'] && !tp)				// Is T Being Pressed And Is tp FALSE
		{
			tp=TRUE;				// If So, Make tp TRUE
			twinkle=!twinkle;			// Make twinkle Equal The Opposite Of What It Is
		}

The code below checks to see if you've let go of the T key. If you have, it makes tp=FALSE. Pressing the T key will do nothing unless tp is FALSE, so this section of code is very important.

		if (!keys['T'])					// Has The T Key Been Released
		{
			tp=FALSE;				// If So, make tp FALSE
		}

The rest of the code checks to see if the up arrow, down arrow, page up or page down keys are being pressed.

		if (keys[VK_UP])				// Is Up Arrow Being Pressed
		{
			tilt-=0.5f;				// Tilt The Screen Up
		}

		if (keys[VK_DOWN])				// Is Down Arrow Being Pressed
		{
			tilt+=0.5f;				// Tilt The Screen Down
		}

		if (keys[VK_PRIOR])				// Is Page Up Being Pressed
		{
			zoom-=0.2f;				// Zoom Out
		}

		if (keys[VK_NEXT])				// Is Page Down Being Pressed
		{
			zoom+=0.2f;				// Zoom In
		}

Like all the previous tutorials, make sure the title at the top of the window is correct.

		if (keys[VK_F1])				// Is F1 Being Pressed?
		{
			keys[VK_F1]=FALSE;			// If So Make Key FALSE
			KillGLWindow();				// Kill Our Current Window
			fullscreen=!fullscreen;			// Toggle Fullscreen / Windowed Mode
			// Recreate Our OpenGL Window
			if (!CreateGLWindow("NeHe's Textures, Lighting & Keyboard Tutorial",640,480,16,fullscreen))
			{
				return 0;			// Quit If Window Was Not Created
			}
		}
	}
}

In this tutorial I have tried to explain in as much detail how to load in a gray scale bitmap image, remove the black space around the image (using blending), add color to the image, and move the image around the screen in 3D. I've also shown you how to create beautiful colors and animation by overlapping a second copy of the bitmap on top of the original bitmap. Once you have a good understanding of everything I've taught you up till now, you should have no problems making 3D demos ofyour own. All the basics have been covered!

소스코드 다운로드

이 강좌의 소스코드를 다운받으실 수 있습니다. 자신의 환경에 맞는 파일을 받아 사용하세요.



원문 정보

  • 저자: Jeff Molofee (NeHe)
  • 원문보기: Lesson 09

번역문 정보

현재 상태

  • 초벌번역시작 (2006년 8월 7일)