• 북마크
  • 추가메뉴
어디로 앱에서 쉽고 간편하게!
애플 중고 거래 전문 플랫폼
오늘 하루 보지 않기
KMUG 케이머그

소프트웨어

[App 개발] NeHe Lesson 19

본문

강의 19번째입니다. 지금까지 여러 가지를 배워 오셨는데, 이제부터는 갖고 놀고 싶으실 겁니다. 저는 이번 강의에서 새로운 명령을 하나 소개하려고 합니다. 삼각 막대입니다. 아주 간단하고, 많은 수의 삼각형을 그리는 프로그램을 빠르게 만드는데 도움이 될 것입니다.

이번 강의에서는 아주 어렵지 않은 파티클 엔진을 만드는 법을 배울 것입니다. 파티클 엔진이 어떻게 동작하는지 배우고 나면 불이나 연기나 폭포같은 효과를 만드는 것은 아주 식은 죽 먹기일 것입니다.

주의사항이 있습니다. 지금까지 저는 파티클 엔진을 짜본 적이 없습니다. 아이디어를 처음 얻은 곳은 유명한 파티클 엔진의 아주 복잡한 코드였습니다. 그것을 구현하려고 지금까지 몇 번 시도해 보았습니다만, 모든 조각들을 다 컨트롤하려고 하다보니 미쳐버릴 것 같아서 포기했습니다.

제 말씀을 못 믿으시겠지만, 이 강의는 100% 처음부터 짜여진 것입니다. 다른 사람의 생각도 빌리지 않았고, 저에게는 당장 기술적인 정보도 없었습니다. 저는 파티클에 대해 생각하기 시작하는데 갑자기 제 머리에 아이디어가 떠올랐습니다. (머리에 발동이?) 각 파티클들이 점으로서 A 지점에서 B 지점으로 움직이는 것을 생각하는 대신, 각 파티클들이 주변에 널려있는 독립적인 물체라고 생각하게 되었습니다. 저는 각자의 파티클에게 수명, 나이, 색상, 속도, 중력의 영향 등을 부여했습니다.

곧바로 저는 프로젝트를 끝냈습니다. 그리고 시계를 쳐다보았는데, 마치 에일리언이 저를 어디로 납치했던 것 같았습니다. 4시간이나 지나버린 것입니다. 제 기억에는 일을 마치고 커피 한 잔 마시고 눈 깜빡 했는데, 네 시간이나?

따라서, 제 눈에는 이 프로그램이 좋아 보이고 제가 원하는대로 동작도 잘 됩니다만, 파티클 엔진을 구현하는 정확한 방법은 아닐지도 모릅니다. 잘 동작하기 때문에 개인적으로는 상관 안하고, 프로젝트에도 사용할 수 있습니다. 만약에 여러분이 기존의 원칙을 잘 따르는 사람이어서 인터넷에서 이에 대한 정보를 검색해보시는 분들이라면 주의하셔야 하는데, 코드의 몇 가지 부분은 조금 애매모호해 보이실 것입니다.

이번 강의는 lesson 1의 코드를 기본으로 작성했습니다. 하지만 새로운 코드가 많이 첨가되어 있기 때문에, 새로운 부분이 있는 코드는 모두 새로 실어놓겠습니다. (이해하시기 편하게끔)

Lesson 1의 코드의 윗부분에 코드 다섯 줄을 첨가할 것입니다. 먼저 stdio.h 를 첨가하여 파일 읽기가 가능하도록 합니다. 텍스쳐 매핑 할 때 첨가했던 것과 같은 코드입니다. 그 다음은 파티클 몇 개 생성해서 화면에 출력시킬지를 정의하는 숫자입니다. define명령은 우리 프로그램에서 MAX_PARTICLES 가 어떤 숫자를 가리키는지를 알려주는 명려입니다. 여기서는 1000을 정의했습니다. 세 번째는 레인보우 기능을 켜고 끄는 데에 쓰는 변수입니다. 기본값으로는 켜는 것으로 했습니다. 변수 sp와 rp는 스페이스키와 리턴키가 계속 눌려 있을때 계속해서 동작하는 것을 방지하는 변수입니다.


#include

#define MAX_PARTICLES 1000

bool rainbow=true;
bool sp;
bool rp;


다음의 4줄은 다용도 변수들입니다. slowdown변수는 얼마나 빨리 파티클들을 움직이는지를 제어합니다. 숫자가 크면 클수록 움직임은 느려지고, 숫자가 작을 수록 빨라집니다. 만약 숫자가 작게 설정되어 있다면 파티클들은 굉장히 빨리 움직일 것입니다. 파티클이 움직이는 속도는 화면에서 어떻게 움직이느냐에 영향을 줍니다. 느린 파티클은 멀리 움직이게 할 수 없습니다. 기억해 두십시오.

변수 xspeed와 yspeed는 꼬리의 방향을 제어합니다. xspeed는 파티클의 x축 방향으로의 움직이는 속도에 더해집니다. 만약 xspeed가 양수라면 파티클은 오른쪽으로 더 많이 움직이게 되고, 음수라면 파티클들은 왼쪽으로 더 많이 움직이게 됩니다. 큰 값을 가질 수록 한 쪽 방향으로 더 깊이 움직입니다. yspeed도 y축 방향에서 동일하게 작용합니다. 제가 특정한 방향으로 ‘더’라고 말씀드리는 이유는 파티클의 움직이는 방향에는 다른 요소들이 작용하기 때문입니다. xspeed와 yspeed는 우리가 원하는 방향으로 파티클들을 움직이는데에 도움이 됩니다.

마지막으로 zoom변수가 있습니다. 이 변수로 씬의 앞 뒤 위치를 결정합니다. 파티클 엔진은 한 번에 많이 출력해 보면, 그 다음에는 아주 가까이서 보시면 아주 근사합니다.


float slowdown=2.0f;
float xspeed;
float yspeed;
float zoom=-40.0f;


이제 다용도 루프 변수 loop를 선언합니다. 파티클을 미리 선언하고 화면에 파티클을 출력하는 데에 사용할 것입니다. 변수 col은 파티클을 만들 때 사용된 색상을 기록하는 변수입니다. 변수 delay는 레인보우 모드에서 색상의 변환을 기록합니다.

마지막으로 텍스쳐 한 개를 저장하 변수를 선언합니다. (파티클 텍스쳐) OpenGL의 포인트 대신 텍스쳐를 쓰기로 결정한 것에는 몇 가지 이유가 있습니다. 가장 큰 이유는 포인트가 그렇게 빠르지 않고, 멋있어 보이지 않는다는 점입니다. 두 번째 이유는 텍스쳐가 훨씬 보기 좋다는 점입니다. 여러분은 사각형 파티클이나 여러분의 얼굴을 작게 하거나 별 모양의 그림을 이용하는 등의 더 많은 선택이 가능합니다.


GLuint loop;
GLuint col;
GLuint delay;
GLuint texture[1];


자, 이제부터 재미있는 부분입니다. 다음 코드들은 각 파티클을 표현하는 구조를 만드는 것입니다. 여기에서 파티클에게 어떠한 특성들을 부여하게 됩니다.

먼저 active라는 논리 변수를 선언합니다. 이 변수가 true라면 파티클은 살아서 움직이게 되고, false라면 파티클이 죽었거나 우리가 죽인 것입니다. 이번 프로그램에서 active 변수를 사용하지는 않습니다만, 있으면 편리할 것입니다.

변수 life와 fade는 얼마나 오랫동안 파티클이 출력될 것인지, 그리고 출력되는 동안 어느 정도의 밝기를 가질지를 결정합니다. 변수 life는 변수 fade가 가지는 값만큼 점차로 감소됩니다. 이번 프로그램에서는 이 값들이 어떤 파티클이 다른 파티클보다 더 오래 화면에 남는 효과를 만들 것입니다.


typedef struct
{
bool active;
float life;
float fade; // Fade Speed


변수 r, g, b 는 파티클의 빨간색, 녹색, 파란색의 밝기를 갖고 있습니다. r값이 1.0f에 가까와질수록 파티클은 빨간색을 띠게 됩니다. 세 변수가 모두 1.0f이 되면 파티클은 흰 색이 됩니다.


float r;
float g;
float b;


변수 x, y, z 는 파티클의 화면 어디에 위치하는지를 가리킵니다. x값은 x축 상의 파티클의 위치, y 는 y축 상에서의 위치, z 는 z축 상에서 파티클의 위치를 나타냅니다.


float x;
float y;
float z;


이 세 변수는 중요합니다. 세 변수는 파티클이 얼마나 빨리, 어떤 방향으로 어떤 축 상에서 움직이는지를 표시합니다. 만일 xi 가 음수라면 파티클은 왼쪽으로 움직이고 양수이면 오른쪽으로 움직입니다. 만일 yi 가 음수라면 아래쪽으로, 양수라면 위쪽으로 움직입니다. 만일 zi 가 음수라면 파티클은 화면 뒤쪽으로, 양수라면 화면 앞쪽으로 움직이게 됩니다.


float xi;
float yi;
float zi;


마지막으로 세 변수가 더 남았습니다. 각 변수들은 마치 중력과 같은 개념입니다. 만약 xg 가 양수라면 파티클은 오른쪽으로 잡아당겨지고, 음수라면 왼쪽으로 잡아당겨집니다. 따라서 파티클이 왼쪽으로 (음수) 움직이고 있는 상태에서 양수의 중력이 적용된다면 속도는 서서히 감소하게 되어 마침내 파티클은 반대편으로 움직이게 됩니다. yg 는 위 아래로 잡아당기는 역할을 하고 zg 는 화면 안팎으로 잡아당겨지는 역할입니다.


float xg;
float yg;
float zg;


particles 는 우리가 선언하는 구조체의 이름입니다.


}
particles;


이제 particle 이라는 이름의 배열을 만듭니다. 이 배열은 MAX_PARTICLES 만큼의 길이입니다. 우리말로 번역하면 우리는 1000(MAX_PARTICLES) 개의 파티클을 저장할 장소를 만든 것입니다. 이 저장소에는 각 파티클들의 정보를 저장됩니다.


particles particle[MAX_PARTICLES];


이제 우리 프로그램에서 필요한 만큼의 코드를 할당해서 색상 배열에 12개의 다른 색상을 저장할 것입니다. 0부터 11까지의 각 색상들은 빨간색, 녹색, 파란색의 밝기를 갖습니다. 아래의 색상 테이블은 빨간색부터 보라색까지 변화되는 12개의 색상을 저장합니다.


static GLfloat colors[12][3]=
{
{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
};


비트맵 로딩 코드는 변화가 없습니다.


AUX_RGBImageRec *LoadBMP(char *Filename)
{
FILE *File=NULL;
if (!Filename)
{
return NULL;
}

File=fopen(Filename,"r");
if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
return NULL;
}


다음 코드는 (위에 있는 코드를 호출하여) 비트맵을 읽어들여서 텍스쳐로 변환하는 코드입니다. 변수 Status 는 텍스쳐가 만들어졌는지를 기록합니다.


int LoadGLTextures()
{
int Status=FALSE;

AUX_RGBImageRec *TextureImage[1];

memset(TextureImage,0,sizeof(void *)*1);


우리 텍스쳐 로딩 코드는 파티클 비트맵을 읽어서 선형 필터링된 텍스쳐로 변환할 것입니다.


if (TextureImage[0]=LoadBMP("Data/Particle.bmp"))
{
Status=TRUE;
glGenTextures(1, &texture[0]);

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 (TextureImage[0]->data)
{
free(TextureImage[0]->data);
}
free(TextureImage[0]);
}
return Status;
}


화면 리사이징 코드에서 가시 거리를 좀 더 깊이 만들었습니다. 100.0f대신 200.0f로 바꾸어 화면 안쪽 깊숙한 파티클들을 볼 수 있습니다.


GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0)
{
height=1;
}

glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,200.0f); // 변경된 부분

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}


만약 lesson 1의 코드를 이용하시는 분들은 다음의 코드를 바꿔 주십시오. 텍스쳐를 읽어들이고 파티클의 블렌딩을 셋업하는 코드를 첨가했습니다.


int InitGL(GLvoid)
{
if (!LoadGLTextures())
{
return FALSE;
}


Smooth shading 을 활성화하고, 검은 색으로 화면을 지우고, depth testing 을 비활성화하고, 블렌딩과 텍스쳐 매핑을 활성화합니다. 그 다음 파티클 텍스쳐를 선택합니다.


glShadeModel(GL_SMOOTH);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glClearDepth(1.0f);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture[0]);


다음은 파티클을 초기화하는 코드입니다. 일단 각 파티클들을 활성화시키는 것으로 시작합니다. 만약 활성화되지 않으면 life 가 얼마나 남았건 간에 화면에 출력되지 않습니다.

파티클 활성화 다음에는 생명을 불어넣습니다. life값을 적용해서 점점 사라지게 만드는 이 방법이 최선인지는 잘 모르겠습니다만, 확실히 동작은 합니다. 완전한 수명은 1.0f 입니다. 이 때 파티클은 최대 밝기를 갖습니다.


for (loop=0;loop {
particle[loop].active=true;
particle[loop].life=1.0f;


이제 난수값을 fade에 넣어서 얼마나 빨리 파티클이 사라지도록 할지를 결정합니다. 변수 life 는 파티클이 화면에 출력될 때마다 fade 값만큼 줄어들게 됩니다. 우리가 사용하는 난수값은 0부터 99입니다. 이것을 1000으로 나누면 아주 작은 부동소숫점 값이 됩니다. 이 값에 .003을 더하여 fade 값이 0이 되지 않도록 만듭니다.


particle[loop].fade=float(rand()%100)/1000.0f+0.003f;


파티클들이 활성화되었고, 생명도 불어 넣었습니다. 이제는 색상을 입힐 시간입니다. 기본적으로 각 파티클들이 다른 색상을 가지도록 할 것입니다. 프로그램 위에서 정의해둔 색상 테이블의 12색상중의 하나를 각 파티클에 적용할 것입니다. 공식은 간단합니다. 변수 loop 값을 취하여 색상 테이블의 갯수를 곱한 다음 최대 파티클 갯수로 나눕니다. 이렇게 하면 마지막 색상 값이 최대 색상 값 (12) 보다 커지지 않게 됩니다.

예: 900*(12/900)=12. 1000*(12/1000)=12, 기타등등


particle[loop].r=colors[loop*(12/MAX_PARTICLES)][0];
particle[loop].g=colors[loop*(12/MAX_PARTICLES)][1];
particle[loop].b=colors[loop*(12/MAX_PARTICLES)][2];


이제 각 파티클의 움직이는 방향과 속도를 지정합니다. 계산값에 10.0f 를 곱하여 프로그램 처음 시작에 스펙타클한 폭발을 만들겠습니다.

이 값들은 양수 혹은 음수의 난수로 이루어집니다. 이 값들은 무작위의 방향에 무작위한 속력으로 파티클이 움직이도록 하는데 쓰입니다.


particle[loop].xi=float((rand()%50)-26.0f)*10.0f;
particle[loop].yi=float((rand()%50)-25.0f)*10.0f;
particle[loop].zi=float((rand()%50)-25.0f)*10.0f;


마지막으로 각 파티클에 중력 값을 지정합니다. 일반적으로 중력은 아래로 끌어내리는 힘이지만, 여기서의 중력은 위, 아래, 좌, 우, 앞, 뒤로 끌어당깁니다. 처음에는 아래쪽으로 약한 힘으로 잡아당겨지게 하기 위하여 xg 를 0.0f 로 놓습니다. 따라서 x 축을 따라서 좌우로의 당겨짐은 없습니다. 변수 yg 를 -0.8f 로 놓아서 아래쪽으로 약하게 잡아당겨집니다. 이 값이 양수라면 파티클은 위로 잡아당겨집니다. 파티클이 앞뒤로 잡아당겨지지 않게 하기 위해서 zg 를 0.0f 로 놓습니다.


particle[loop].xg=0.0f;
particle[loop].yg=-0.8f;
particle[loop].zg=0.0f;
}
return TRUE;
}


이제 재미있는 부분입니다. 다음은 파티클을 그리고 중력을 검사하는 등의 역할을 하는 코드입니다. 어떻게 구현되었는지 이해하시는 것이 중요하기 때문에 차근차근 읽어 주십시오.

모델뷰 매트릭스를 딱 한 번 초기화합니다. 파티클들은 translation 함수를 사용하지 않고 glVertex3f() 를 이용해서 위치를 결정합니다. 이렇게 하면 파티클을 그리면서 모델뷰 매트릭스를 따로 사용하지 않아도 됩니다.


int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();


이제 루프를 만듭니다. loop값은 각 파티클들의 상태를 갱신할 것입니다.


for (loop=0;loop {


맨 먼저 해야 할 일은 파티클이 활성화되어 있는지를 점검하는 일입니다. 만약에 비활성화되어 있다면 갱신되지 않습니다. 이 프로그램에서는 모두 활성화된 상태이기 때문에 항상 갱신될 것입니다. 그러나 여러분이 프로그램을 만드실 때에는 어떤 파티클들을 비활성화시킬 수 있습니다.


if (particle[loop].active)
{


변수 x, y, z 는 파티클의 x, y, z 위치를 기록하는 임시 변수입니다. 여기서는 z 위치에 zoom 을 더하여 우리가 만드는 씬이 zoom 값만큼 화면 깊숙히 들어가 있게 됩니다. particle[loop].x 는 우리가 그리는 (loop가 가리키는) 파티클의 x 좌표 위치이고, particle[loop].y 는 파티클의 y 좌표 위치, particle[loop].z 는 z 좌표 위치입니다.


float x=particle[loop].x;
float y=particle[loop].y;
float z=particle[loop].z+zoom;


이것으로 파티클의 위치는 잡았고, 파티클의 색상을 입히겠습니다. particle[loop].r 은 파티클의 빨간색 밝기, particle[loop].g 는 녹색 밝기, particle[loop].b 는 파란색 밝기입니다. 여기서 파티클의 life 변수를 알파값으로 사용했습니다. 파티클은 죽어갈수록 점점 더 투명하게 되고, 결국에는 사라지게 됩니다. 그래서 변수 life 값이 1.0f 보다 크면 안 됩니다. 만약에 파티클이 더 오랫동안 남게 만들려면 fade 속력을 줄여 보십시오. 그러면 파티클들이 빨리 사라지지 않을 것입니다.


glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);




파티클의 위치와 색상이 되었습니다. 이제는 파티클을 그릴 차례입니다. 텍스쳐 입힌 사각형을 그리는 대신 텍스쳐 삼각형 막대를 사용하여 프로그램을 빠르게 하겠습니다. 대부분의 3D 비디오 카드들은 사각형보다 삼각형을 훨씬 더 빠르게 그릴 수 있습니다. 어떤 3D 카드들은 사각형을 삼각형 두 개로 나누어서 처리하지만, 어떤 것은 그렇지 않습니다. 따라서 여기서는 직접 구현하겠습니다. 먼저 OpenGL에게 삼각형 막대를 그릴 것을 알립니다.


glBegin(GL_TRIANGLE_STRIP);


Red Book의 인용: 삼각형 막대는 삼각형(세 선분을 가진 다각형)을 꼭지점 v0, v1, v2, 그리고 v2, v1, v3 (순서를 잘 보세요), 그리고 v2, v3, v4, 이런 식으로 차레대로 그려 나갑니다. 이 순서는 삼각형들이 동일한 기준점으로 그려지게 함으로써 막대의 표면이 바르게 정렬되도록 합니다. 기준점을 확보하는 것은 culling 같은 기능에 중요합니다. 무엇인가 그리기 위해서는 적어도 세 점이 필요합니다.

따라서 첫 번째 삼각형은 꼭지점 0, 1, 2 를 이용해서 그립니다. 여러분이 그림을 보신다면 꼭지점 0, 1, 2 가 첫 번째 삼각형 ( 오른쪽 위, 왼쪽 위, 오른쪽 아래) 을 이루게 됩니다. 두 번째 삼각형은 꼭지점 2, 1, 3 으로 그립니다. 그림을 보시면 꼭지점 2, 1, 3 이 두 번째 삼각형 ( 오른쪽 아래, 왼쪽 위, 왼쪽 아래 ) 을 만듭니다. 두 삼각형이 같은 회전방향 (반시계방향) 으로 그려짐을 볼 수 있습니다. 저는 어떤 웹사이트에서 삼각형들이 매번 반대방향으로 그려진다는 불평을 가끔 보곤 하는데, 이것은 그런 것이 아닙니다. OpenGL은 꼭지점을 재정렬해서 모든 삼각형들이 동일한 방식으로 그려지도록 하고 있습니다.

삼각형 막대를 사용하면 두 가지 장점이 있습니다. 첫 번째, 맨 처음 삼각형의 세 꼭지점을 지정하고 나면 그 다음 삼각형을 그리기 위해서 한 점만 지정해 주면 됩니다. 새로 지정해준 점과 이전의 두 점을 합하여 새로운 삼각형을 만들게 됩니다. 두 번째, 삼각형을 만들기 위한 데이터의 양이 줄어들게 되므로 프로그램이 더 빨라지고, 물체를 그리는 코드와 데이터의 양이 상당히 줄어들게 됩니다.

Note: 화면에 보는 삼각형의 갯수는 여러분이 지정하는 꼭지점의 갯수 빼기 2 입니다. 다음의 코드에서는 꼭지점 네 개를 지정하고 있으므로, 여러분은 두 개의 삼각형을 보게 됩니다.


glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z);
glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z);
glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z);
glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z);


마지막으로 삼각형 막대를 다 그렸다고 OpenGL에게 알려줍니다.


glEnd();


이제 파티클을 움직입니다. 밑에 보시는 산수는 좀 이상해 보입니다만, 사실 굉장히 쉽습니다. 먼저 현재 파티클의 x 위치를 취하고, x 축으로 움직이는 값에 slowdown 곱하기 1000을 한 값을 나눈 것을 더합니다. 따라서 파티클이 x 축의 중앙 (0) 에 있고, x 축 움직임 변수 (xi) 가 +10 (오른쪽으로 움직임) 이고 slowdown 이 1이라면, 파티클은 오른쪽으로 10/(1*1000)=0.01f 만큼 움직입니다. 만약 slowdown 값이 2라면 파티클은 0.005f 만큼 움직입니다. slowdonw이 어떻게 동작하는지 잘 설명되었기를 바랍니다.

그리고 움직임 시작값을 10.0f 로 한 것은 픽셀의 움직임 아주 빠르게 하여, 폭발하는 모습을 만든 것입니다.

동일한 공식을 y축, z축에 적용하여 파티클이 화면에서 움직이도록 합니다.


particle[loop].x+=particle[loop].xi/(slowdown*1000);
particle[loop].y+=particle[loop].yi/(slowdown*1000);
particle[loop].z+=particle[loop].zi/(slowdown*1000);


파티클의 다음 위치가 어디인지를 계산한 다음에는 중력/저항을 적용해야 합니다. 다음 첫 번째 줄에서 파티클의 움직임 속도 (xi) 에 중력/저항값 (xg) 를 더합니다.

움직임 속도가 10 이었고 저항이 1이라고 해봅시다. 설정된 저항값은 매 회 적용이 됩니다. 따라서 두 번째 파티클이 그러질 때에는 저항값이 적용되어 움직임 속도는 10에서 9로 줄어들어 있을 것이고, 파티클은 약간 속도가 줄어들게 됩니다. 세 번째 그려질 때에는 저항이 다시 적용되어 속도는 8로 줄어들게 됩니다. 계속해서 파티클이 10번 이상 그려지고 나면 움직임 속도가 음수로 변하여 결국 파티클은 반대 방향으로 움직입니다.

저항값은 x축에 쓰인 방법과 마찬가지로 y축과 z축에도 동일하게 적용됩니다.


particle[loop].xi+=particle[loop].xg;
particle[loop].yi+=particle[loop].yg;
particle[loop].zi+=particle[loop].zg;


이번에는 파티클의 life 값을 줄여나갑니다. 이 과정이 없으면 파티클은 결코 없어지지 않습니다. 파티클의 현재 life 값을 취하여 파티클의 fade 값만큼 감소시킵니다. 각 파티클은 다른 fade 값을 갖고 있어서 서로 다른 속도로 사라져갑니다.


particle[loop].life-=particle[loop].fade;


life값이 줄어든 다음 아직도 파티클이 살아있는지 검사합니다.


if (particle[loop].life<0.0f)
{


만약 파티클이 죽었다면 (타없어졌다면), 회춘(?)시킵니다. 파티클에 새로 life 값과 fade 값을 부여합니다.


particle[loop].life=1.0f;
particle[loop].fade=float(rand()%100)/1000.0f+0.003f;


그리고 파티클을 화면 중앙에 놓습니다. 파티클의 x, y, z 위치값을 0으로 만들어놓으면 됩니다.


particle[loop].x=0.0f;
particle[loop].y=0.0f;
particle[loop].z=0.0f;


파티클이 화면 중앙으로 옮겨져 초기화시킨 후 새로운 움직임 속도와 방향을 부여합니다. 여기서는 난수값을 50에서 60으로 증가시켜 파티클 움직임의 최대값과 최소값을 증가시켰지만, 여기서는 움직임 속도에 10을 곱하지 않았습니다. 새로 만들어지는 파티클에는 폭발 효과를 넣지 않기 때문에 파티클 움직임을 서서히 만들어 줍니다.

그리고 x축 움직임 속도에 xspeed를 더하고 y축 움직임 속도에 yspeed를 더해서, 프로그램이 진행되면서 파티클이 어느 방향으로 움직일지를 조정합니다.


particle[loop].xi=xspeed+float((rand()%60)-32.0f);
particle[loop].yi=yspeed+float((rand()%60)-30.0f);
particle[loop].zi=float((rand()%60)-30.0f);


마지막으로 파티클에 새로운 색상을 부여합니다. 변수 col 은 0부터 11까지 (12색상)의 숫자를 갖고 있습니다. 이 변수를 이용해서 앞에서 만들었던 색상 테이블에서 빨간색, 녹색, 파란색 밝기를 얻어냅니다. 밑에 첫째 줄은 colors[col][0]에 저장된 빨간색 밝기입니다. 만약 col 이 0이었다면 빨간색 밝기는 1.0f 가 됩니다. 녹색 파란색도 동일한 방식으로 읽어들입니다.

왜 col 이 0 일 때 빨간색 밝기가 1.0f 가 되는지 이해가 안 가시면 제가 조금 자세히 설명하겠습니다. 프로그램 맨 위로 가서 이 줄을 찾아보십시오: static Glfloat colors[12][3]. 거기에는 3개의 숫자로 된 12개의 그룹이 있을 겁니다. 숫자 세 개중 첫 번째 숫자가 빨간색 밝기입니다. 두 번째가 녹색, 세 번째가 파란색 밝기입니다. 밑에 있는 [0], [1], [2] 는 방금 말씀드린 첫 번째, 두 번째, 세 번째 숫자를 뜻합니다. 만약 col 이 0이라면 첫 번째 그룹을 보는 것입니다. 11이라면 마지막 그룹(12번째 색상)입니다.


particle[loop].r=colors[col][0];
particle[loop].g=colors[col][1];
particle[loop].b=colors[col][2];
}


다음은 위쪽으로 잡아당겨지는 중력의 크기를 조절합니다. 키패드의 8번을 두르면 변수 yg (y 중력) 가 증가하게 되고, 따라서 위쪽으로 잡아당겨집니다. 이 코드를 루프 내에 위치함으로써 모든 파티클의 중력에 쉽게 적용할 수 있게 됩니다. 이것이 루프 밖에 있었다면 비슷한 일을 하기 위해서 또 다른 루프를 만들어서 여기서 하던 것과 비슷한 일을 해야 합니다.


if (keys[VK_NUMPAD8] && (particle[loop].yg<1.5f)) particle[loop].yg+=0.01f;


다음은 정 반대의 효과를 만듭니다. 키패드 2번을 누르면 yg 가 감소하게 되고 밑으로 더 세게 잡아당겨집니다.


if (keys[VK_NUMPAD2] && (particle[loop].yg>-1.5f)) particle[loop].yg-=0.01f;


이제 코드를 수정해서 오른쪽으로 잡아당겨지게 합니다. 키패드 6번을 누르면 오른쪽으로 잡아당겨지는 힘이 늘어납니다.


if (keys[VK_NUMPAD6] && (particle[loop].xg<1.5f)) particle[loop].xg+=0.01f;


마지막으로 키패드 4번이 눌리면 파티클은 왼쪽으로 잡아당겨집니다. 키 입력은 아주 괜찮은 효과를 만듭니다. 예를 들어, 공중을 향해서 발사되는 파티클 줄기를 만들 수 있습니다. 아래로 향하는 중력을 더하게 되면 파티클 줄기들이 폭포수처럼 쏟아지게 됩니다.


if (keys[VK_NUMPAD4] && (particle[loop].xg>-1.5f)) particle[loop].xg-=0.01f;


이 코드들은 재미로 덧붙인 것입니다. 동생이 그러는데 폭발 효과가 끝내준다는군요. 탭 키를 누르면 모든 파티클들을 화면 중앙으로 되모읍니다. 움직임 속도에 10을 다시 곱하여 파티클의 대폭발을 만듭니다. 파티클이 모두 사라지고 나면 원래 효과가 다시 나타날 것입니다.


if (keys[VK_TAB])
{
particle[loop].x=0.0f;
particle[loop].y=0.0f;
particle[loop].z=0.0f;
particle[loop].xi=float((rand()%50)-26.0f)*10.0f;
particle[loop].yi=float((rand()%50)-25.0f)*10.0f;
particle[loop].zi=float((rand()%50)-25.0f)*10.0f;
}
}
}
return TRUE;
}


(주: 다음은 거의 윈도우 specific 이므로 넘어가겠습니다. 양해 바랍니다.)

다음은 키패드의 + 키가 눌렸는지를 검사합니다. 키가 눌려졌고 변수 slowdown 이 1.0f 보다 클 경우 slowdown 을 0.01f 만큼 감소시킵니다. 이렇게 하면 파티클이 빨리 움직이게 됩니다. 위에서 slowdown 을 설명할 때 파티클의 움직이는 속도에 어떻게 영향을 주는지 기억해 주십시오.


if (keys[VK_ADD] && (slowdown>1.0f)) slowdown-=0.01f;


다음은 키패드의 ­ 키가 눌렸는지를 검사합니다. 키가 눌려졌고 변수 slowdown 이 4.0f 보다 작다면 slowdown 의 값을 증가시킵니다. 이렇게 하면 파티클의 속도가 느려집니다. 한계를 4.0f 로 놓아서 너무 느려지지 않도록 만들었습니다. 여러분이 원하시는 대로 최고 최저 속도를 변경하셔도 됩니다.


if (keys[VK_SUBTRACT] && (slowdown<4.0f)) slowdown+=0.01f;


다음은 PageUp 키가 눌렸는지를 검사하고, 눌렸으면 변수 zoom 값을 증가시킵니다. 이것은 파티클을 보는 사람에게 가까이 만들게 됩니다.


if (keys[VK_PRIOR]) zoom+=0.1f;


다음은 반대 효과를 나타냅니다. PageDown 키를 누르면 zoom 값이 감소하고, 파티클은 화면 깊숙히 들어갑니다. 이렇게 하면 화면에 좀 더 많은 파티클을 표시할 수 있지만, 파티클 크기가 작아지게 됩니다.


if (keys[VK_NEXT]) zoom-=0.1f;


다음은 리턴키가 눌려졌는지를 검사하는 코드입니다. 리턴이 눌렸고, 계속 눌려져있는 상태가 아니라는 것을 알리기 위해서 rp 값을 true 로 바꾸어 놓습니다. 그 다음 무지개 모드를 바꾸어줍니다. 만약 rainbow 가 true 였으면 false 가 되고, false 였으면 true 로 바뀝니다. 마지막 줄은 리턴 키가 떨어졌는지를 검사하고, 그렇다면 rp 값을 false 로 만들어서 키보드가 더 이상 눌려있지 않음을 알려줍니다.


if (keys[VK_RETURN] && !rp)
{
rp=true;
rainbow=!rainbow;
}
if (!keys[VK_RETURN]) rp=false;


다음 코드는 약간 복잡합니다. 첫 번째 줄은 스페이스 바가 눌렸고, 계속 눌린 상태가 아닌지 검사합니다. 그리고 무지개 모드인지를 검사해서, 만일 그렇다면 변수 delay 가 25보다 큰지를 검사합니다. 변수 delay 는 무지개 효과를 만들기 위한 카운터입니다. 만약 매 프레임마다 색상을 바꿔준다면 파티클은 모두 다른 색상을 갖게 되지만, delay 를 만들어 줌으로써 다른 색상으로 바뀌기 전까지 파티클은 무리져서 한 색상을 갖게 됩니다.

만일 스페이스 바가 눌려졌고 무지개가 켜져 있고 delay 가 25보다 크다면 색상은 변합니다.


if ((keys[] && !sp) || (rainbow && (delay>25)))
{


다음 줄에서는 스페이스 바가 눌려 있다면 무지개 모드가 꺼지도록 만드는 것입니다. 무지개 모드를 꺼 주지 않으면 리턴키가 눌리기 전까지 색상이 계속해서 바뀌게 됩니다. 당연히 사람이 리턴 대신 스페이스를 눌렀을 때 게속해서 색상이 변하게 됩니다.


if (keys[]) rainbow=false;


스페이스 바가 눌렸고 무지개 모드가 켜졌고 delay 가 25보다 크다면 sp 를 true 로 놓아서 스페이스가 눌려 있음을 알립니다. 그다음은 delay 를 0 으로 돌려놓아서 다시 25까지 카운트할 수 있도록 합니다. 마지막으로 변수 col 을 증가시켜 다음번 색상 테이블의 색상으로 변경시킵니다.


sp=true;
delay=0;
col++;


만약 색상이 11 보다 크다면 이것을 0으로 되돌립니다. 이렇게 하지 않으면 프로그램은 13번째 색상을 찾게 되고, 우리는 12 색상밖에 없습니다. 없는 색상 정보를 찾으려고 하기 때문에 프로그램은 충돌하게 됩니다.


if (col>11) col=0;
}


스페이스 바가 더 이상 눌리지 않았으면 sp 를 false 로 만들어 놓습니다.


if (!keys[]) sp=false;


이제 파티클을 제어할 코드를 만듭니다. 프로그램 처음 시작할 때 변수 두 개 만든 거 기억하십니까? xspeed와 yspeed 였습니다. 그리고 파티클의 전부 타들어가면 우리는 파티클에게 새로운 움직임 속도에 xspeed 나 yspeed 를 더했습니다. 이렇게 하면 우리는 파티클이 새로 생성될 때 어떤 방향으로 움직이게 만들 수 있습니다.

예를 들어, 파티클이 x 축으로 움직임 속도 5, y 축으로 0을 갖고 있습니다. 우리가 xspeed 를 -10까지 줄였다면, 파티클은 이제 -10(xspeed) +5(원래 움직임 속도) 를 갖게 됩니다. 따라서 오른쪽으로 10 만큼 움직이는 것이 아니라, 왼쪽으로 -5 만큼 움직이도록 만드는 것입니다. 이해가 되시죠?

어쨌든, 다음 코드는 위쪽 화살표키가 눌렸는지를 확인해서 yspeed 를 증가시킵니다. 이렇게 하면 파티클들이 위쪽으로 움직이게 됩니다. 파티클들은 위쪽으로 최고 200 까지의 속도로 움직일 수 있습니다. 그보다 빠르면 보기에 별로 좋지 않습니다.


if (keys[VK_UP] && (yspeed<200)) yspeed+=1.0f;


다음은 아래쪽 화살표키를 검사해서 yspeed를 감소시킵니다. 이것은 파티클을 아래쪽으로 움직이게 됩니다. 동일하게 아래쪽 최고 속력은 200으로 제한되어 있습니다.


if (keys[VK_DOWN] && (yspeed>-200)) yspeed-=1.0f;


이제는 오른쪽 화살표키를 검사해서 xspeed 를 증가시킵니다. 파티클들을 오른쪽으로 움직이게 합니다. 최고 속도는 200으로 제한되어 있습니다.


&n
0 0
로그인 후 추천 또는 비추천하실 수 있습니다.
포인트 228,692
가입일 :
2003-02-18 14:12:30
서명 :
미입력
자기소개 :
미입력

최신글이 없습니다.

최신글이 없습니다.

댓글목록 0

등록된 댓글이 없습니다.
전체 529 건 - 10 페이지
2005.03
07

[App 개발] oracle 10g를 페더에 설치가 가능한가요??

이번 학기에 데이터 베이스 수업과.. JAVA수업을 듣게 되었는데.. JAVA는 아이북에서 설치가 가능하다고 하신거 같은데.. oracle 10g는 맥 서버용으로 나온건 알고 있습니다.. 그런데 그걸 그냥 일반 페더에도 깔수가 있…

2005.02
18

[App 개발] 한글 파일이름 open 이 원래 안되나요?

python 에서 한글 파일 이름으로 write 하려고 open 했는데 에러가 나는군요. 다른 프로그램으로 open 해도 화일이름이 한글이면 에러가 나는 것 같습니다. 한글이름이면 open 시스템콜이 안되나 봅니다 예) >>> f = ope…

2005.02
12

[App 개발] gnu c library

mac os x 에 설치된 c library 는 gnu c library 가 아니군요. BSD 계열이니 당연한 것이겠지만서도..... 수치계산할 때 complex 형 변수를 선언할 수 없어 불편하군요. 그런데 c library를 손…

2005.02
10

[App 개발] hdf5설치 성공하신 분 있나요?

라이브러리 설치 문제가 계속 걸려서 fink 를 이용해 봤습니다만, 안되는군요. :-( libpng, libjpeg 등을 모두 설치해도 h5utils 를 configure 하는 도중에 이 라이브러리들이 없다고 하는군요. hdf5 역…

2005.02
01

[App 개발] hdf5 라이브러리는 어디에...

리눅스에서 제가 작성했던 코드를 가져와서 컴파일 하려 하니 hdf5 라이브러리가 없다며 실패하는군요. hdf5 를 포트에서 설치하면 될 줄 알았는데 그게 아니었나 봅니다. h5cc 등의 툴만 있지 실제적으로 C 코드에서 호출해서 …

2005.01
28

[App 개발] [질문] 개발자에게 있어서 맥이란 플랫폼이란...?

안녕하세요. 컴퓨터 전공하는 학생입니다. 4년전에 대학교 입학할 때 컴퓨터를 장만하면서 맥도 고려했었습니다. 큐브가 어찌나 이뻐 보이던지 ^^; 하지만 PC에 비해 너무 고가의 장비였고... 무엇보다 맥으로 코딩 작업이 …

2005.01
06

[App 개발] apple developer 사이트에서 샘플 긁어오기 스크립트

본격적으로 osx 공부를 해볼까해서 apple developer 사이트를 보면서 샘플을 하나하나 다운로드하니 노가다성이 심하다 생각되서 파이손 스크립트 하나 만들었습니다. :) 페이지에 있는 *.sit 파일들만 쭉 다 다운로드 해줍니다. 저는 터…

2005.01
02

[App 개발] 프로그래밍 공부하는 방법

-------------------------------------------------------------------------------- 그냥 나름대로 정리해봄.. ----------------------------------------…

2004.12
28

[App 개발] MPC 7448 그리고 MPC 8641

프리스케일 웹사이트에 드디어 MPC 7448 과 MPC 8641 이 정식으로 명명되어 대략 설명이 올라왔습니다. 정말 내년 초 파워북 G4 의 업그레이드가 헛소문만은 아닌가봅니다. MPC7448 은 200MHz 의 MPX 버스를 가지게 되었습니다…

2004.12
18

[App 개발] GUI 인터페이스의 vim

새로 iMac 을 장만하고, 프로그래밍을 해 보겠다는 꿈을 품고 Xcode 를 무작정 실행해 보니 확실히 잘 모를것들이 많더군요. 앞으로 어찌 공부해야 할지, 갈길이 멀군요. 일단 고지식하게 Vim 을 찾았습니다. 터미널에 vi 는 있었지만, …

2004.12
06

[App 개발] 유용한 MacOS X external commands

요즘 타 맥관련 사이트에서도 열심히 글타래를 정독하면서 OS X의 근본적인 unix나 이래저래 공부를 하고 있습니다. 그중에서 unix 커맨드중에서 유용한 것들에 대한 설명이 되어있는 글을 보고 이렇게 올려드려요~ 공부하시는 분들에겐 도…

2004.11
29

[App 개발] MOD Player 를 만들어보자 2

지난 4월이었던가요 유닉스용 소스에 퀵타임 루틴을 첨가하여 간단하게 MOD 플레이어를 만들어본 적이 있는 것을 기억하실 것입니다. 그 때에는 첫 번째 시도이기도 하고, 괜찮은 소스를 입수하는 것도 여의치 않아서, 오리지날 4채널 MOD 포맷만을 지원했…

2004.11
17

[App 개발] MACOSX용 BBS WebStation 1.0 공개합니다.

MACOS용 BBS WebStation 1.0 공개합니다. 패키지로 구성된 파일을 실행하시면 자신의 MACOSX에서 BBS를 운영하실 수 있습니다. Perl 기반으로 작성되어있으며 FileDB를 사용하므로 별다른 작업없이 커뮤니티 구성이 가능합…

2004.11
11

[App 개발] 슈퍼컴퓨터 컨퍼런스 2004

제가 살고있는 피츠버그에서 슈퍼컴퓨터 컨퍼런스가 열리고 있습니다. 저는 오늘 하루 전시회 입장권만 구입해서 잠시 구경을 했습니다. 원래는 차기에 구매할 number crunching 기계 중에서 물망에 오르고 있는 4-way Opteron 제품을 직접…

2004.11
07

[App 개발] eclipse 사용해보시지 않으실래요..

안녕하세요.. 일본머그지기 시니입니다.. 저도.. 오픈소스를 넘 좋아해서리.. ㅋㅋㅋ 그나저나.. 개발하시는분들중엔 사용하고 계실지 모르지만.. 전 자바를 좋아해서리..ㅋㅋㅋ 새로나온.. 머 좀 지났지만 이클립스 3.0.1 함 사용해보세요.…

2004.11
03

[App 개발] 신형 아이북, 파워맥 벤치마크 결과

아이북, 파워맥 1.8GHz 벤치마크 느린 버스속도가 싱글 파워맥 성능저하의 요인 By James Galbraith 최근 애플에서 신형 아이북과 저가형 파워맥 G5가 발표되었습니다. 전체 리뷰를 진행하면서 동시에 Speedmark 테스트 …

2004.10
31

[App 개발] 게임엔진 NeoEngine 의 컴파일

SourceForge.net 에서 제일 인기있는 공개 소스 버젼 게임엔진 NeoEngine 이 있습니다. 모질라 라이센스를 따르고 있어서 소스의 변경 수정이 자유롭다는 특징이 있고, 공개 버젼 중에서는 가장 완성도가 높은 라이브러리가 아닌가 생각됩니다…

2004.10
18

[App 개발] [ 급질문 ] 맥용 웹하드 정도 만들어 볼려면..

음... 맥용 웹하드 정도 만들어 볼려면 어느정도 지식이 필요 할까요 아직 맥을 구경도 못해봤습니다..-_-;;; 맥이 어떻게 켜지는지도 모르고.... 맥에 관심이 어느날 부터 가기 시작하던데... 그런데 너무 맥에 관한 자료가 없더군요.. fi…

2004.10
13

[App 개발] X Code에서 include 포함 파일이나 라이브러리 파일의 경로는 어떻게 지정하나요 ?

안녕하세요.. 비주얼 스튜디오 같은 곳에서는 포함 파일이나 라이브러리 파일을 옵션에서 설정해 줄 수 있었습니다. X Code 에서는 이를 어떻게 설정해 주어야 하나요 예를 들어 /Volumes/Data/SDKLib 라는 곳에…

2004.09
10

[App 개발] 아이맥 G5 의 특이한 점 - 개발자 문서에서 살펴본 결과

아이맥 G5 의 개발자 문서가 드뎌 공개되었군요. 메모리 버스가 어떻게 구성되어 있는지 상세히 밝혀져 있습니다. 구형 파워맥 G5 의 구성과 비교해 보겠습니다. 신형 파워맥 G5 에서는 변경된 사항이 있을지도 모르겠습니다. 1. …

2004.08
31

[App 개발] 아이맥 G5 의 특이한 점???

개발실에 쓸 글은 아닙니다만... 딱히 좋은 장소가 없어서 여기에 글을 올립니다. 일단 오늘(8월 31일) 발표된 새 아이맥은 날씬하고 보기 좋고, 게다가 가격도 무척 저렴해서 크게 인기를 끌 수 있는 가능성이 풍부한 제품이라고 생각합니다. …

2004.07
05

[App 개발] 질문하나 있습니다.

아.. 소스를 카피해온다는 것이 못해왔네요. 다름이 아니라, Xcode에서 Interface Builder로 Custom View를 하나 만들었고, 이 클래스로 파일을 생성(.h, .m파일)하여 Xcode에서 .m파일에 이 Custom View에…

2004.05
24

[App 개발] 여기 아무두 안오세용? 도와주세요.

이제 막 코코아 개발을 시작하려고 하는 초보입니다. C에 대해선 어렴풋이나마 알고 있고 잘 알지 못하는 중에 코코아로 바로 뛰어들었는데요. 많이 부족함을 느낍니다. 천천히 하고있는데... 열심히 하고 싶지만 시간이 없네요. 지금 OR…

2004.05
15

[App 개발] 맥에서 Qt 사용 어떤가요?

사운드신세시스 프로그래밍을 공부하는데요 아무래도 GUI 가 필요해서 GUI 프로그래밍을 보려하는데, 리눅스환경에서 만들고 있어서 Qt 를 사용해서 GUI 를 만들어보려고요. 그런데 Qt 소개를 자세히 보니까 멀티플랫폼 API 이어…

2004.04
21

[App 개발] NeHe Lesson 23

무척 오랫만입니다... ㅎㅎㅎ 먹고 사는 것이 바쁘다보니... 일단 샘플 코드의 구현은 흥미로운 것 위주로 하도록 하고, 나머지는 텍스트를 익히는 것에 중점을 두려고 합니다. (제가 게을러졌다는 것을 우회적으로 표현하는 것입니다. ㅡㅡ;;;) …

2004.04
02

[App 개발] 국제컴퓨터, 소프트웨어, 통신전시회에 참석 하고자 분들 (리플부탁)

- 컴퓨터:휴대형단말기, PC(Desktop, Notebook, Laptop,Palmtop, Etc), 매킨토시, 네트웍컴퓨터, 서버, 워크스테이션, 메인프레임, 프리젠테이션장비, 기타 - 소프트웨어:WINDOWS/NT/UNIX기반 시스템ɨ…

2004.03
11

[App 개발] ModPlayer 를 만들어보자

MOD 는 Amiga 의 음악 파일 포맷입니다. 사실 아미가에서 쓰였기 때문에 유명해졌다기보다는 많은 도스 게임들이 MOD 배경음악을 지원하면서 탄탄한 지원군을 많이 얻음으로 인하여 공개 소스들이 많이 돌아다니게 되고, 유저의 손에서 더욱 더 확장되고…

2004.03
10

[App 개발] 맥마메 분석 - 5 사운드 출력

맥마메 분석 – 5 사운드 출력 개인적으로 가장 관심있는 부분으로 접어들었습니다. 오랫동안 피씨 프로그래밍만 해오다 보니 매킨토시의 사운드 출력이 어떻게 이루어지는지를 궁금해 해 왔습니다. 최근에는 맥과 피씨가 유사한 칩셋들을 많이 공…

2004.03
09

[App 개발] 맥마메 분석 - 4 HID 루틴

맥마메 분석 – 4 조이스틱 입력 네 번째 시간이 되었습니다. 솔직히 저는 조이스틱 지원에 대해서는 별로 관심은 없습니다. (집에 조이스틱이 없거든요. 하하…) 애플 II 에서는 조이스틱이 없으면 완전 바보였지만, 이제는 입력장치로 마…

2004.03
06

[App 개발] 맥마메 분석 - 3 마우스 입력

맥마메 분석 &#8211; 3 마우스 입력 마우스 입력도 키보드 입력과 거의 비슷한 방식으로 구현되어 있습니다. 메인 윈도우 이벤트 핸들러로 마우스 입력 핸들러를 등록하는 것, 그리고 이벤트 핸들러에서 입력된 값을 마우스 상태 배열에 …

2004.03
05

[App 개발] 맥마메 분석 - 2 키보드 입력

맥마메 분석 사실 마메의 진짜 핵심은 프로세서 에뮬레이션, 비디오 프로세서, 사운드 프로세서 에뮬레이션 루틴이죠. 한 번 마메 소스를 열어보신 분들이라면 실로 방대한 에뮬레이션 루틴들을 보면서 놀라셨을 것입니다. 그런데, 에뮬레이터를 제…

2004.03
04

[App 개발] 수박 겉핥기 MacMAME 분석 - 1. 디스플레이

수박 겉핥기 MacMAME 분석 Multiple Arcade Machine Emulator 의 약자인 MAME 는 게임 센터의 PCB 게임들의 에뮬레이터로서 고전 게임 매니아들에게 사랑받는 프로그램입니다. 대부분 기종에 이식되어 있고, 매킨토시에…

2004.02
18

[App 개발] NeHe Lesson 22

22번은 작문도 상당히 엉터리고, 그래서 번역도 엉터리고, 소스도 엉터리고... 이것을 붙잡고 계속 늘어지고 있는 것보다는 어서 앞으로 나아가야겠다는 생각에 예제도 만들지 못하고 건너뛰게 되었습니다. 대단히 송구스럽습니다. 별로 도움 안 되는 22번이…

2004.02
10

[App 개발] 10 bytes extended 형 데이터 처리.

안녕하세요 계속해서 Aiff 파일을 공부하고 있는데요. 헤더에 들어가있는 short, long, char 등의 데이터형의 데이터는 쉽게 읽고 쓸수가 있는데, Wave 화일과는 달리 Aiff 파일은 Sample Rate 를 기록하는 데이…

2004.02
08

[App 개발] NeHe Lesson 21

늦었습니다. ^^ 이번에는 내용도 많고, 간단하긴 하지만 그래도 게임 제작이고, 원래가 윈도우용으로 제작된 소스를 이식해야 하는 것이라 빼먹은 부분도 많고, 그래도 대충 돌아가게끔 맞춰놓긴 했습니다만... 어쨌든 즐겨 주십시오. ^^ ------…

2004.02
03

[App 개발] NeHe Lesson 20

강의 20번째입니다. 비트맵 이미지 포맷은 거의 모든 컴퓨터, 모든 운영체제에서 지원합니다. 사용하기 쉽고 텍스쳐로 읽고 만들기에 간단합니다. 지금까지 우리는 텍스트나 이미지를 출력할 때 배경을 지우지 않고 물체와 섞이도록 했습니다. 효과적이긴 하지만…

2004.02
01

[App 개발] Cocoa Design Patterns (7) 마지막

Facades 클래스 클러스터와 프록시를 설명할 때 이미 소개했습니다만, Facade(겉면 - 여기서는 포장지(Wrapper Facade)로 번역하겠습니다)는 복잡한 객체 집단을 간단히 단일화하여 보여주는 객체입니다. 포장지 패턴은 코코아에서 다른 …

2004.02
01

[App 개발] c++ file io 에서 기초적인 질문입니다.

Aiff 화일 헤더분석하는 프로그램을 만들어보려고 하는데요, 그냥 콘솔형으로 하려고, gcc 를 사용해서 하고 있습니다. 파일 입출력을 위해 ifstream 을 사용하는데요, aiff 화일로 부터 1바이트 char 형 데이터를 읽기위해…

2004.01
31

열람중 [App 개발] NeHe Lesson 19

강의 19번째입니다. 지금까지 여러 가지를 배워 오셨는데, 이제부터는 갖고 놀고 싶으실 겁니다. 저는 이번 강의에서 새로운 명령을 하나 소개하려고 합니다. 삼각 막대입니다. 아주 간단하고, 많은 수의 삼각형을 그리는 프로그램을 빠르게 만드는데 도움이 …

2004.01
30

[App 개발] Cocoa Design Patterns (6)

Notifications 코코아는 통지(notifications)기능을 이용해서 응용프로그램 내의 객체간에 중요한 일들이 발생했음을 알립니다. 어떤 통지 메세지들은 수신자가 여러 개일수도 있습니다. 물론 여러 개의 객체가 한 메세지를 보내거나 공시할…

2004.01
29

[App 개발] java2 network (chat server/client)

-- TCP기반의 에코서버/클라이언트 //EchoClientTest.java&nbsp;&nbsp; import java.io.*; import java.net.*; public class&nbsp;&nbs…

2004.01
29

[App 개발] 진짜 간단한 AWT 계산기입니다..

import java.awt.*; import java.awt.event.*; public class Calcurator_ex extends Frame implements ActionListener{ // 인스턴스 변수 선언 Butt…

2004.01
29

[App 개발] AWT java text 에디터입니다.

import java.awt.*; import java.awt.event.*; import java.io.*; class EditorDemo extends Frame implements ActionListener{ TextAr…

2004.01
29

[App 개발] NeHe Lesson 18

Quadrics Quadrics는 for 루프와 삼각함수를 이용하여 복잡한 물체를 그리는 방법을 뜻합니다. 강의 7 에서 사용한 코드를 이용할 것입니다. 일곱 개의 변수를 추가하고 텍스쳐를 바꾸어서 변화를 주었습니다. bool sp;…

2004.01
28

[App 개발] NeHe Lesson 17

이번 강의는 NeHe와 Giuseppe D’Agata에 의해 만들어졌습니다. 폰트때문에 힘드신 것 다 압니다. 지금까지 제가 만든 강의에서는 단순히 글자를 출력하는 것뿐만 아니라 3D 글자, 텍스쳐 매핑된 글자를 출력할 수 있고, 변수를 처리할 …

2004.01
25

[App 개발] CoreGraphics의 풀스크린 화면 만들기

박진철님께서 올리셨던 질문 중에 코코아에서 퀵드로우의 CopyBits대신 사용할 수 있는 방법으로서 아시는 분들은 다 아실만한 CGDirectDisplay 를 이용한 방법을 한 번 시도해 보았습니다. 프로그램은 심히 완성도가 떨어지는 관계로 감히…

2004.01
23

[App 개발] Cocoa Design Patterns (5)

Commands GOF의 패턴에 익숙하신 분들은 아마 타겟/액션이 마치 커맨드 패턴의 구현이라고 생각될 것입니다. 그러나 커맨드 패턴같은 것이 타겟/액션과 같은 구현이 이용된다 하더라도 Objective-C에서는 그것이 필요가 없습니다. 커맨드 패턴…

2004.01
22

[App 개발] Cocoa Design Patterns (4)

Enumeration 코코아의 모든 콜랙션 클래스는 계수기를 제공합니다. 이 패턴은 GOF의 반복기 패턴과 비슷합니다. 계수기는 객체의 집합을 훑어내고 각 객체에 어떤 일을 수행하는 방법을 제공합니다. 특정한 집합에 대하여 특수한 루프를 짜 주는 대…

2004.01
22

[App 개발] NeHe Lesson 16

이번 강의는 Chris Aliotta가 제작하였습니다. 당신의 OpenGL 프로그램에 안개를 넣고 싶으십니까 이번 강의에서 바로 그 방법을 보여드리려고 합니다. 저는 강의를 쓰는 것은 처음이고, OpenGL/C++ 프로그래밍은 근래에 시작한 것이…