3. Custom Scene Node

Posted 2007/09/15 19:18 by 수달

--------------------------------------------------------------------------

튜토리얼 3 : 일반적인 씬 노드

---------------------------------------------------------

이번 튜토리얼은 조금 심화된 내용이다. 만약 IRRLICHT 엔진으로 무언가를 바로 돌려보고 싶다면, 먼저 다른 예제들부터 찾아 보는게 낫다. 튜토리얼은 일반적인 씬 노드를 어떻게 만들고, 어떻게 엔진 내에서 사용하는지를 보여준다. 일반적인 씬 노드는 IRRLICHT 엔진이 일반적으로 지원하지 않는 특수한 렌더링 기술을 사용해야 할 때 필요하다. 예를 들자면, indoor portal-based renderer나 advanced terrain scene node를 구현할 수 있다. 일반적인 씬 노드를 통해 쉽게 IRRLICHT 엔진을 확장할 수 있으며, 필요에 의해 적용할 수 있는 것이다.

예제는 짧고 간단하게 보여줄 것이다. 이 튜토리얼의 최종 결과는 아래의 그림과 같다. 별로 신통찮게 보이지만 일반적인 씬 노드의 모든 것이며, 사용자가 만드는 씬 노드의 좋은 출발점이다.

(역자 주 : 튜토리얼에 대한 나의 생각은 최하단에 있다.)


--------------------------------------------------------------------------

시작

----

먼저 헤더 파일과 네임 스페이스, 라이브 파일을 코드에 넣자.


#include <irrlicht.h>

using namespace irr;

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


이 부분이 이번 튜토리얼에서 가장 까다로운 부분이다. 임의의 씬 노드를 정하는 곳으로, 단순하게 하기 위해 indoor portal renderer나 terrain scene node는 사용하지 않고, 4개의 점으로 이뤄진 3D 객체를 만들도록 하겠다. 씬 노드를 IRRLICHT 엔진에서 사용할 수 있도록 클래스는 ISceneNode에서 상속 받고, 몇가지 함수를 재정의(overriding) 한다.


class CSampleSceneNode : public scene:ISceneNode

{


일단 몇가지 멤버 변수를 선언해, 이제부터 만들 tetraeder(지형의 한 사각 면을 이루기 위한 네 개의 점)를 위한 메모리를 정한다. 바운딩 박스, 4 정점, 그리고 tetraeder의 재질 정보를 확보하면 된다.


core::aabbox3d<f32> box;

video::S3DVertex Vertices[4];

video::SMaterial Material;


클래스 생성자는 씬 노드의 부모, 씬 매니저 포인터, 씬 노드의 아이디를 인자로 갖게 한다. 이 생성자는 내부적으로 부모 클래스 생성자를 호출하여 이후에 그려낼 4 정점과 씬 노드의 매터리얼 사양 등을 설정하게 된다.


public:

CSampleSceneNode(scene::ISceneNode * parent,

scene::ISceneManager * mgr,

s32 id)

: scene::ISceneNode(parent, mgr, id)

{

Material.Wireframe = false; Material.Lighting = false;

Vertices[0] =

video::S3DVertex(0,0,10,1,1,0,video::SColor(255,0,255,255),0,1);

Vertices[1] =

video::S3DVertex(10,0,-10,1,0,0,video::SColor(255,255,0,255),1,1);

Vertices[2] =

video::S3DVertex(0,20,0,0,1,1,video::SColor(255,255,255,0),1,0);

Vertices[3] =

video::S3DVertex(-10,0,-10,0,0,1,video::SColor(255,0,255,0),0,0);


IRRLICHT 엔진은 이런 방식으로 만들어지는 씬 노드의 바운딩 박스를 알아야 한다. 그것은 자동 컬링(안보이는 면 제거:은면 제거) 등 여러 부분에 쓰인다. 그렇기에 사용할 4 정점으로부터 바운딩 박스를 만들겠다. 만약 엔진에서 자동 컬링을 원치 않거나 할 경우에는 그냥 AutomaticCullingEnabled = false; 를 사용하면 된다.


Box.reset(Vertices[0].Pos);

for(s32 i = 1; i < 4; ++i)

Box.addInternalPoint(Vertices[i].Pos);

}


이들이 그려지기 전에 매 씬 노드의 OnPreRender()함수가 씬 매니저에 의해 호출된다. 이때 씬 노드는 자신이 그려져야 한다면, 자신을 씬 매니저에 등록한다. (역자 주 : 최적화를 통해 그려질 지형 면만 그려지게 한다. 즉 너무 먼 곳, 카메라 뒤, 앞선 물체에 가려 그릴 필요가 없는 부분 등을 OnPreRender()가 확인해 해당 씬 노드가 그려질지 안 그려질지 판단해 씬 매니저에 등록하거나 안 하거나 한다는 의미)

::render() 함수가 호출될 때 씬 매니저에게 반드시 알려주어야 한다. 왜냐하면 스텐실 버퍼 그림자는 다른 모든 씬 노드가 모두 그려진 다음에 그려지는 반면, 맞춤형 씬 노드는 처음부터 차례대로 자신의 내용을 그릴 것이기 때문이다. 게다가 카메라와 광원은 다른 씬 노드가 그려지기 전에 그려져야 할 필요가 있다. (역자 주 : 그래야 최적화 계산을 할 테니.)

자, 그럼 씬 노드를 등록해 보자. 카메라나 광원을 적용하고자 한다면, SceneManager->registerNodeForRendering(this, SNRT_LIGHT_AND_CAMERA);를 호출한다. 이제 기반 클래스인 ISceneNode의 OnPreRender()함수를 호출하고, 모든 자식 노드들을 등록하도록 하자.


virtual void OnPreRender()

{

if(IsVisible)

SceneManager->registerNodeForRendering(this);

ISceneNode::OnPreRender();

}


render() 함수에서 자질구레한 일이 일어난다. 함수에선 씬 노드가 자기 자신을 그리는데, 우리는 이 함수를 재정의해 tetraeder를그리도록 하자.


virtual void render()

{

u16 indices[] = { 0, 2, 3, 2, 1, 3, 1, 0, 3, 2, 0, 1 };

video::IVideoDriver * driver = SceneManager->getVideoDriver();

driver->setMaterial(Material);

driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);

driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 4);

}


적어도 세개의 추가적인 함수 호출이 필요하다. GetBoundingBox()는 이 씬 노드의 바운딩 박스를 리턴해줄 것이며, GetMaterialCount()는 이 씬 노드의 재질들 수를 리턴할 것이고(이번 예제에선 재질이 하나다.), getMaterial()은 해당 인덱스(차례)의 재질을 리턴할 것이다. 여기서는 단지 하나의 재질만 있기 때문에 0보다 큰 인덱스의 재질은 없다고 가정한다. (역자 주 : 그렇기에 한번만 호출했고 1을 리턴했다. 아니라면 매터리얼 수 만큼 반복해야 할 것.)


vitrual const core::aabbox3d<f32> & getBoundingBox() const

{

return Box;

}

virtual s32 getMaterialCount() { return 1; }

virtual video::SMaterial & getMaterial(s32 i) { return Material; }

}; //class CSampleSceneNode


씬 노드 클래스를 만들었다. 자, 이제 가뿐하게 엔진을 시작하고, 씬 노드를 만들며, 카메라를 배치해 결과를 살펴보도록 하자.


int main()

{

IrrlichtDevice * device =

createDevice(video::EDT_OPENGL,coredimension<s32>(640,480),16,false);

device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo");

video::IVideoDriver * driver = device->getVideoDriver();

scene::ISceneManager * smgr = device->getSceneManager();

smgr->addCameraSceneNode(0,core::vector3df(0,-40,0),

core::vector3df(0,0, 0));


씬 노드를 만들어보자. 만들고 나서 즉시 ->drop() 해줘야 한다는 것을 주목하라. 이게 가능한 이유는 일단 한번 만들면 씬 매니저가 그것을 관리 하기 때문이다. 그러나 프로그램이 끝날 때 해도 가능하긴 하다. (역자 주 : 아마 이 부분 때문에 IRRLICHT 엔진을 분석한 다른 분들이 '메모리 단편화'를 걱정하는 모양이다.)


CSampleSceneNode * myNode =

new CSampleSceneNode(smgr->getRootSceneNode(), smgr, 666);

myNode->drop();


단지 하나의 지형면으로만 구성된면 재미없으니, 씬 노드에 약간의 회전을 넣어 보자. 이런 방법은 다른 씬 노드에서도 할 수 있다.


scene::ISceneNodeAnimator * anim =

smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f));

myNode->addAnimator(anim);

anim->drop();


모든 것을 그린 후 마치자.


while(device->run())

{

driver->beginScene(true, true, video::SColor(0, 100, 100, 100));

smgr->drawAll();

driver->endScene();

}

device->drop();

return 0;

}


굿! 컴파일 후 프로그램을 돌려보자.

--------------------------------------------------------------------------

이번 엔진 튜토리얼에 대한 나의 생각.


처음 해석할 때 제목부터 좀 이해가 안되었는데, 해석을 마친 후, 튜토리얼 1. 2. 와 연계해 생각해 보니 어느 정도 윤곽이 잡힌다. 즉 튜토리얼 1. 2.에서 각각 캐릭터 모델링과 월드 맵핑(용어는 넓은 의미로 생각하라.)을 했다. 하지만 화면에 나타나는 모든 것을 이렇게 거대하고 폴리곤이 많은(?) 외부 모델로만 만들 수는 없는 것이다. 어떤 경우는 프로그래머가 직접 점 단위, 면 단위의 조정을 해야한다. 그것을 여기서 배워본 것이다.

이렇다고 한다면 Scene Node의 의미가 뚜렷해 진다. 각 노드는 각각 그리고자 하는 하나의 '무엇'이다. 그 '무엇'이 튜토리얼 1. 2.의 캐릭터나 월드일 수도 있고, 여기서처럼 직접 만든 점 혹은 면일 수 있다는 것이다.

이는 엔진 튜토리얼이 DirectX의 예제 순서와 역순임을 알 수 있다. DriectX의 예제는 먼저, 점, 선, 면을 이야기 하고, 카메라, 광원을 말한 후, 메시를 보이고, 애니메이션을 구현한다. 즉 작은데서부터 큰데로 나가는 것이다. 물론 이 방법은 기초를 충실히하며 천천히 단계를 밟을 수 있다는 이점이 있다. 하지만 기초 공부가 끝난 개발자 입장에서 당장 중요한 것은 큰 덩어리를 어떻게 보일 것인가이다. 게임을 만드는 것은 먼저 캐릭, 월드를 시작으로 인터페이스나 세세한 효과나 표현을 해내는 것이다. 그렇기에 엔진 튜토리얼의 구성이 Custome Scene Node부터가 아닌 캐릭터 씬 노드, 월드 씬 노드부터 시작한 것이다.

향후 엔진 튜토리얼의 구성도 직접적으로 게임을 만드는데 적용되는 것들을 순서로 되어 있다. 그렇기에 이 튜토리얼 서문에 '당장의 것이 필요하면 다른 튜토리얼부터 보라.'는 말이 담겨 있다. 이를 유의하며 계속해 나가도록 하겠다.


음......

여전히 한글화 한 제목 - '일반적인 씬 노드'는 어색하다. 그렇다고 '일반형'이라고 하면 모호해지고, '직접 찍은'이라고 하면 문장화된 제목이 될 것이다. 여기에 귀찮음까지 더해 그냥 두도록 하겠다.

2. Quake 3 Map

Posted 2007/09/15 19:16 by 수달

--------------------------------------------------------------------------

튜토리얼 2 : 퀘이크3 맵

이번 튜토리얼에서는 어떻게 하면 (1) 엔진 속으로 퀘이크3 맵을 읽어들이고, (2) 최적화된 렌더링을 위해 씬노드를 만들며, (3)유저가 움직이는 카메라를 배치할 수 있는지 보여준다. 이번 튜토리얼을 시작하기에 앞서 엔진 기초를 숙지할 것을 권한다. 아직 잘 모르더라도 튜토리얼 1. Hello World를 봤다면 무난할 것이다.

<예제 그림>


--------------------------------------------------------------------------

시작

----

Hello World 예제같이 시작해 보자. IRRLICHT 헤더 파일을 인클루드하고 콘솔 사용을 위한 드라이버 타입을 요청하자.


#include <irrlicht.h>

#include <iostream>


앞서 말한 바와 같이 IRRLICHT 엔진에서는 모든 것을 'irr' 네임 스페이스에서 찾을 수 있다. 매번 클래스 앞에 irr::를 사용하지 않으려면, 컴파일러에게 사용할 네임 스페이스를 미리 알려주어야 한다.

IRRLICHT엔진에는 서브 네임 스페이스로 'core', 'scene', 'video', 'io', 'gui'가 있다. Hello world 예제와는 다르게 이 다섯개를 'using namespace' 하지 않을 것이다. 이것들은 필요할 때마다 사용해야 한다. 물론 원한다면 다 써도 좋지만, 여기서는 단순하게 하겠다.


using namespace irr;


Irrlicht.DLL을 사용하기 위해 컴파일러 프로젝트 세팅을 추가하거나, 쉽게 #pragma 구문을 사용하자.


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


자, 시작이다. main()을 사용할 것이다. 왜냐하면 WinMain()을 치는 것보다 짧기 때문에.


int main()

{


Hello World 예제와 같이, createDevice()로 IrrlichtDevice를 생성한다. 다른 점이 있다면 하드웨어 가속을 할지 안 할지 사용자에게 물어본다는 것다. 소프트웨어 가속은 거대한 퀘이크 3 맵을 그리는데 너무 느리다. 하지만 원한다면 재미 삼아 해보는 것도 좋다.


//ask user for driver

video::E_DRIVER_TYPE driverType = video::EDT_DIRECTX9;

printf("Please select the driver you want dor this example:\n"\

" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGl 1.2\n"\

" (d) Software Renderer\n (e) NullDevice\n (otherKey) exit\n\n");


char il

std::cin >> i;

switch(i)

{

case 'a': driverType = video::EDT_DIRECTX9; break;

case 'b': driverType = video::EDT_DIRECTX8; break;

case 'c': driverType = video::EDT_OPENGL; break;

case 'd': driverType = video::EDT_SOFTWARE; break;

case 'e': driverType = video::EDT_NULL; break;

default: return 1;
}


//create device anf exit if creation failed

IrrlichtDevice * device =

createDevice(driverType, core::dimension2d<s32>(640, 480));

if(device == 0)

return 1;


device->getVideoDriver()와 device->getSceneManager()를 매번 사용하지 말고, 비디오 드라이버와 씬매니저 접근 포인터를 얻어놓자.


video::IVideoDriver * driver = device->getVideoDriver();

scene::ISceneManager * smgr = device->getSceneManager();


퀘이크 3 맵을 보이기 위해 먼저 그것을 읽어야 한다. 퀘이크 3 맵은 .zip과 다를 바 없는 .pk3파일에 들어 있다. 그렇기에 일단 파일 시스템에 .pk3 파일을 추가 한 후에야, 그 파일에 접근해 읽을 수가 있다.


device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");


이제 getMesh()를 통해 메시를 읽을 수 있다. IAnimatedMesh 포인터 하나를 얻자. 알다시피 퀘이크 3 맵은 실제로는 애니메이션이 안된다. 그것은 그저 몇가지 매터리얼이 적용된 정적인 기하물들의 거대 집합체다. 즉, IAnimated Mesh는 1 프레임으로 구성되기에, 애니메이션의 첫번째 프레임을 얻어 addOctTreeSceneNode()를 이용해 OctTree Scene을 만들어야 한다. OctTree는 현재 보이는 영역만을 보이게해 씬을 최적화 한다. (역자주:거대 지형은 쿼드트리나 옥트트리로 성능 최적화를 한다.) 최적화가 안된 완전한 메시를 출력하고자 한다면, OctTree대신에 AnimatedMeshSceneNode를 사용할 수 있다. 한번 해보는 것도 좋다. addOctTreeSceneNode 대신에 addAnimatedMeshSceneNode를 사용한 후 비디오 드라이버에 의해 그려지는 정점을 비교해 보기 바란다. (이는 IVideoDriver 클래스의 getPrimitiveCountDrawed() 함수를 통해 확인 할 수 있다.) OctTree를 이용한 최적화는 대량의 기하 정보를 가진 거대 메시를 그리는데 유용하다.


scene::IAnimatedMesh * mesh = smgr->getMesh("20kdm2.bsp");

scene::ISceneNode * node = 0;

if(mesh)

node = smgr->addOctTreeSceneNode(mesh->getMesh(0));


맵 레벨이 원점(0, 0, 0)에서 모델링 된 것이 아니기에, 약간의 이동이 필요하다.


if(node)

node->setPosition(core::vector3df(-1300, -144, 1249));


남은 것은 퀘이크 3 맵을 보기 위한 카메라 설정뿐이다. 또한 이 카메라는 사용자에 의해 다뤄져야 한다. IRRLICHT 엔진에선 몇가지 다른 형태의 카메라가 가능하다. 예를 들어 마야에서 쓰이는 카메라는 왼쪽 버튼을 누르면 회전하고, 양 버튼을 누르면 줌이 되며, 오른쪽 버튼을 누르면 이동한다. 이것은 addCameraSceneNodeMaya()를 통해 만들 수 있다. 하지만 이번 예에서는 FPS(일인칭 슈팅 게임)과 같은 카메라를 사용하겠다.


smgr->addCameraSceneNodeFPS();


마우스 커서는 필요 없으므로 안 보이게 한다.


device->getCursorControl()->setVisible(false);


모든 준비가 끝났으니 그리기만 하면 된다. 이번에는 윈도 캡션에 매 초당 프레임 수와 그려지는 정점의 수를 표시하자. 'if(device->isWindowActive())' 구문은 선택 사항이다. 하지만 다른 프로그램이 활성화 상태일 때, 마우스 커서의 위치가 교란되 엔진 렌더링에 방해되는 것을 막기 위해 사용하도록 하자.


int lastFPS = -1;


while(device->run())

{

driver->beginScene(true, true, video::SColor(0, 200, 200, 200));

smgr->drawAll();

driver->endScene();


int fps = driver->getFPS();


if(lastFPS != fps)

{

core::stringw str = L"Irrlicht Engine - Quake 3 map example [";

str += driver->getName();

str += "] FPS : ";

str += fps;

device->setWindowCaption(str.c_str());

lastFPS = fps;
}

}


마지막으로 IRRLICHT 디바이스를 해제한다.


device->drop();

return 0;

}


모두 됐다. 컴파일 하고 프로그램을 돌려라!


1. Hello World

Posted 2007/09/15 19:14 by 수달

튜토리얼 1 : HellowWorld

이 튜토리얼은 IRRLICHT 엔진을 사용하는 IDE 셋업 방법과 그것을 이용해 간단한 HelloWorld 프로그램을 만드는 법을 보여준다. 이 프로그램은 비디오 드라이버 기본 생성과 GUI환경, 그리고 SceneManager 기초를 보여준다. 그 결과의 예는 다음과 같다.


사용자 삽입 이미지


- IDE 셋업하기

엔진을 사용하기 위해서, 우리는 헤더 파일 <irrlicht.h>을 포함하는것을 할것이고, Irrlicht Engine SDK 디렉토리 \include에서 찾을수 있다. 컴파일러를 가게하는것은 이 헤더파일을 찾는다, 위치를 알아낸 디렉토리는 어디에서나 명시되야한다. 이것은 모든 IDE 와 컴파일러를 위해 다르다. 나는 Microsoft Visual Studio C++ 6.0과 .NET에서 이것의 사용법을 설명할 것이다.

* 만약 당신이 버젼 6.0을 사용한다면, Menu Extras -> Options 를 선택한다. directories tab 를 선택하고 콤보박스에서 'Include'항목을 선택하라. 일리히트 엔진의 \include 디렉토리를 디렉토리들의 리스트에 추가하라. 이제 컴파일러는 Irrlicht.h 헤더파일을 찾을것이다. 우리들은 또 목록에 나열된 irrlicht.lib의 위치를 필요로 하기때문에, Libraries'탭을 선택하고,\lib\VisualStudio 디렉토리를 추가하라.

* 만약 당신의 IDE가 Visual Studio .NET 이라면, Tools -> Options 선택한다. Projects entry 를 선택한다음 VC++ directories를 선택한다. 콤보박스에서 'show directories for include files' 를 선택하고, 일리히트 엔진 폴더의 디렉토리 \include 에서 디렉토리들의 리스트로 추가한다.
이와같이 하면 컴파일러는 Irrlicht.h헤더파일을 찾을 것이다. 우리는 또 irrlicht.lib 찾는것이 필요하기때문에, 'show directories for Library files' 를 선택하고, \lib\VisualStudio 디렉토리를 추가합니다.


---------------------------------------------------------------------------

시작

----

경로를 설정하면 컴파일러는 IRRLICHT를 사용할 수 있게 된다.


#include <irrlicht.h>


IRRLICHT 엔진에선 irr란 네임스페이스로 모든 것을 사용할 수 있다. IRRLICHT의 클래스를 사용하고 싶다면, 해당 클래스 이름 앞에 irr::를 붙이면 된다. 예를 들어 IrrlichtDevice를 사용하고 싶다면 irr:IrrlichtDevice라고 쓰면 된다. 모든 클래스에 irr::를 사용하기 위해, 우리는 컴파일러에게 사용할 네임 스페이스를 알려줘야 한다.


using namespace irr;


IRRLICHT 엔진에는 5개의 서브 네임 스페이스가 있다. 이것은 IRRLICHT 공식 포럼 상단의 Namespace List를 클릭해 보면 상세히 알 수 있을 것이다. 이번 예제에선 간편함을 위해 특별히 정한 서브 네임 스페이스를 사용하진 않는다.


using namespace core;

using namespace scene;

using namespace video;

using namespace io;

using namespace gui;


Irrlicht.Dll 파일을 사용하기 위해, 이에 대한 링크가 필요하다. 우리는 이 옵션을 프로젝트 세팅(컴파일러의)에서 설정할 수 있다. 하지만 여기선 쉽게 하기 위해 pragma 문법으로 처리했다.


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


이제 메인 함수(엔트리)다. 간단한 예를 위해 어떤 플랫폼에서나 가능한 void main()을 사용했다. 만약 윈도 플랫폼이라면 WinMain()을 사용할 수 있다.


int main()

{


엔진에서 가장 중요한 함수는 'createDevice'함수다. 엔진의 모든 일을 처리하는 루트 객체(the root object)인 IRRLICHT Device는 이 함수를 통해 만들어진다. createDevice()는 7개의 인자를 가진다.

- deviceType : 디바이스의 타입. 이것은 현재 Null device, Software Device, DirectX8/9, OpenGL등을 사용한다. 이 예에서는 EDT_SOFTWARE를 사용했다. 물론 EDT_NULL, EDT_DIRECTX8, EDT_OPENGL 등을 사용할 수 있다.

- windowSize : 윈도 크기나 풀스크린시 크기다. 예제에선 512 * 384를 사용한다.

- bits : 풀스크린 모드에서의 픽셀 당 비트 수다. 이는 16, 32 중 하나로 윈도 모드에선 무시된다.

- fullscreen : 장치를 풀스크린으로할지, 아닐지 결정.

- stencilbuffer : 그림자를 그리는데 스텐실 버퍼를 사용할지, 아닐지 결정.

- vsync : vsync가 가능하게 할지, 아닐지 결정. 풀스크린에서만 적용된다.

- eventReceiver : 이벤트를 받을 객체. 여기서는 사용하지 않을 것으로 0(=NULL)로 정했다.


IrrlichtDevice * device =

createDevice(EDT_SOFTWARE, dimension2d<s32>(512, 384), 16,

false, false, false, 0);


일단 윈도 캡션에 적절한 텍스트를 설정한다. 문자열 앞에 'L'이 있음을 주지하라. IRRLICHT 엔진은 문자열(wide character strings : WSZ-) 처리할 때 이 형식을 사용한다.

device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");


다음으로 비디오 드라이버와 씬매니저, GUI환경을 얻기 위한 포인터를 디바이스에서 얻어 기억해 둔다.


IVideoDriver * driver = device->getVideoDriver();

ISceneManager * smgr = device->getSceneManager();

IGUIEnvironment * guienv = device->getGUIEnvironment();


GUI 환경을 이용해 윈도 화면에 Hello World 라벨을 하나 넣어보자. 텍스트는 좌상단 (10, 10)에 위치해 우하단(200, 22)까지 자리를 잡는다.


guienv->addStaticText(L"Hello World! this is the Irrlicht Software Engine!",

rect<int>(10, 10, 200, 22), true);


흥미를 위해, 퀘이크 2 모델을 읽고 화면에 보이도록 하겠다. 우리는 단지 씬매니저의 getMesh()를 사용해 모델 메시를 읽을 것이고, addAnimatedMeshSceneNode()를 이용해 메시를 SceneNode에 추가 할 것이다. 퀘이크 2 파일(.md2)를 읽는 대신, 마야 목적파일(.obj), 퀘이크 3 맵(.bsp), 밀크쉐이프3D의(.ms3d)를 읽을 수도 있다. (참고로 여기서 사용할 sydney.md2는 브라이언 콜린스에 의해 만들어 졌다.)


IAnimatedMesh * mesh = smgr->getMesh("../../media/sydney.md2");

IAnimatedMeshSceneNode * node = smgr->addAnimatedMeshSceneNode(mesh);


모델 매터리얼(재질)을 살짝 조절해야 한다. 이렇게 안 하면 이 예제에선 다이나믹 라이트를 사용하지 않았기 때문에 모델이 시커멓게 보일 것이다. 그리고 애니메이션이 0에서 310 프레임으로 반복하도록 설정하자. 마지막으로 텍스쳐를 모델에 적용해 보자.


if(node)

{

node->setMaterialFlag(EMF_LIGHTING, false);

node->setFrameLoop(0, 310);

node->setMaterialTexture(0, driver->getTexture("../../media/sydnet.bmp"));
}


메시를 보기 위해 카메라를 3D 공간인 (0, 0, -40)에 위치시킨 후 지향점을 (0, 5, 0)에 둔다.


smgr->addCameraSceneNode(0, vector3df(0, 30, -40), vector3df(0, 5, 0));


자, 이제, 씬을 모두 설정했으니 화면에 그려보자! 디바이스를 while() 루프에 넣고, 끝날 때까지 계속 돌려보자. 사용자가 윈도를 닫거나 ALT+F4를 누를 때까지 반복 될 것이다.


while(device->run())

{

모든 것은 beginScene()과 endScene() 사이에서 그려진다. beginScene()은 한 색으로 화면을 청소하며, 원한다면 뎁스 버퍼(the depth buffer) 역시 클리어 한다. 여기에 씬매니저와 GUI 환경을 갖고 해당 내용을 그린다. endScene()이 불리면 화면에 현재 내용을 출력한다.


driver->beginScene(true, true, SColor(0, 200, 200, 200));

smgr->drawAll();

guienv->drawAll();


driver->endScene();

}


모든 것이 종료되면, createDevice()로 만들어졌던 Irrlicht Device를 제거해 줘야 한다. IRRLICHT 엔진에서는 create로 시작한 함수로 만든 모든 객체를 반드시 제거해야 하는데 간단히 ->drop()을 호출하면 된다. 이에 대해선 다른 문서를 참조하라.


device->drop();

return 0;

}


이제 컴파일 하고, 실행하라.


--------------------------------------------------------------------------

제대로 되었는지 모르겠지만 계속해보자.


http://www.skmsupport.com/Equipment%20Damage%20Curves%20Cables.shtml.htm

Equipment Damage Curves Cables

This technical guide contains information about equipment damage curves. The information is presented for review, approval, interpretation and application by a registered professional engineer only. SKM disclaims any responsibility and liability resulting from the use and interpretation of this technical guide.

Reproduction of this material is permitted provided proper acknowledgement is given to SKM Systems Analysis Inc.

Purpose

The purpose of this guide is to provide basic information about insulated power cable damage curves.

Ampacity (> 1-6 hours)

The ampacity of a conductor is the rated continuous current carrying capacity at a referenced ambient temperature and allowable temperature rise. If a conductor is loaded continuously above its rated ampacity the conductor and insulation temperature design limits will be exceeded. This will lead to loss of life not instantaneous failure.

For insulated power conductors the industry standard ambient reference temperature level is 40°C, for underground insulated power cables (>2000V) 20°C, for buried for insulated power cables (0-2000V) all installations 30°C. Temperature correction factors are then given to adjust the base ampacity for other ambient temperature levels.
The ampacity landmark is located in the top decade of a time-current curve (TCC) at 1000 seconds.

Intermediate Overload Limit Curve (10 seconds to 1-6 hours)

Conductor overcurrent operating limit that if exceeded will damage the insulation of an insulated power conductor. This will lead to loss of insulation life, not instantaneous failure. Limit curves are based on the thermal inertia of the conductor, insulation and surrounding material. As a result, it can take from 1 to 6 hours for the temperature of a cable to stabilize after a change in load current. Therefore, under these emergency operating conditions, currents much greater than the rated ampacity of the cable can be supported. See IEEE 242-2001 pages 312 to 318 for more information.

Short Circuit Damage Curve (0.01 to 10 seconds)

Conductor short circuit current operating limit, which if exceeded, will damage the insulation of an insulated power conductor. Damage curves are plotted in the lower 3 decades of a TCC.

Empirical formulas that consider all heat absorbed by the conductor metal and no heat transmitted from the conductor to the insulation are listed in equations 1 and 2. Both equations relate conductor temperature rise to conductor size, fault current magnitude and fault duration.

Copper conductors

t = 0.0297 log10[(T2+234)/(T1+234)] (A/I)2 (1)

Aluminum conductors

t = 0.0125 log10[(T2+228)/(T1+228)] (A/I)2 (2)

where:

A = conductor area – cmils
I = short circuit current – RMS amps
t = time of short circuit – 0.01 to 10 seconds
T1 = operating temperature
T2 = maximum short circuit temperature

Example

Plot the conductor landmarks for 3-1/C, 500MCM, THWN copper conductors installed in 2-1/2” conduit on a 480V distribution system.

FLA from NEC table 310.16

Ampacity = 380A

Intermediate points calculated from Tables 2 and 3

Damage points calculated from (1) using:

A = 500,000 cmils
t = time of short circuit – 0.01 to 10 seconds
T1 = 75°C (Table 1)
T2 = 150°C (Table 1)

References

Other SKM Technical Guides offered at www.skm.com.

The latest revision of IEEE Std 242, IEEE Recommended Practice for Protection and Coordination of Industrial and Commercial Power Systems (IEEE Buff Book).

http://www.skm.com/Equipment%20Damage%20Curves%20Conductors.shtml

Equipment Damage Curves Conductors

The information presented in this application guide is for review, approval, interpretation and application by a registered professional engineer only. SKM disclaims any responsibility and liability resulting from the use and interpretation of this information.

Reproduction of this material is permitted provided proper acknowledgement is given to SKM Systems Analysis Inc.

Purpose

The purpose of this guide is to provide basic information about conductor damage curves and characteristic landmarks necessary for plotting on time-current curves (TCC), for the purpose of equipment overcurrent protection.

Ampacity

The rated continuous current carrying capacity of the conductor at a referenced ambient temperature, allowable temperature rise, geometry and installation. For bare overhead conductors an ambient air temperature of 40°C is typical. For underground insulated power cables an ambient earth temperature of 20°C is typical. Temperature correction factors are then given to adjust the base ampacity for other ambient temperature levels.
If a cable is loaded continuously above rated ampacity the insulation temperature design limits will be exceeded. This will lead to loss of insulation life, not instantaneous failure.
If a bare overhead conductor is loaded continuously above rated ampacity the mechanical strength of the conductor is reduced. This will lead to a loss of mechanical life, not instantaneous failure.

Table 1 summarizes typical allowable conductor temperature limits under short circuit, emergency overload and normal operating conditions.

Table 1 Typical conductor operating temperature limits


Type

Insulation

Voltage

Short Circuit

Emergency

Normal

0.01 < t < 10 sec.

10 sec. < t < ~1-6 hrs

t > ~1-6 hrs

Al or Cu

TW

600V

150ºC

85ºC

60ºC

Al or Cu

THWN

600V

150ºC

90ºC

75ºC

Al or Cu

THHN

600V

150ºC

105ºC

90ºC

Al or Cu

XLP

5-15kV

250ºC

130ºC

90ºC

Al or Cu

EPR

5-15kV

250ºC

130ºC

90ºC

AAC

Air

All

340ºC

150ºC

100ºC

ACSR

Air

All

645ºC

150ºC

100ºC

The ampacity landmark is located in the top decade of a TCC at 1000 seconds.

Emergency Overload Limit Curve

Conductor overcurrent operating limit that if exceeded will reduce the insulation life of a cable or reduce the mechanical life of a bare overhead conductor beyond an acceptable design loss of life limit.

Cable limit curves are based on the thermal inertia of the conductor, insulation and surrounding material. As a result, it can take from 1 to 6 hours for the temperature of a cable to stabilize after a change in load current. Therefore, under these emergency operating conditions, currents much greater than the rated ampacity can be supported. Tables 2 and 3 provide factors and percent overload capability for various installations.

Table 2 Cable K factors


Cable Size

K Factors

Air

UG Duct

Direct Buried

No Conduit

Conduit

< #2 AWG

0.33

0.67

1.00

1.25

#2 - 4/0 AWG

1.00

1.50

2.50

3.00

> 4/0 AWG

1.50

2.50

4.00

6.00

Table 3 Emergency overload current at 40°C ambient


Time

Percent Overload

Seconds

K=0.5

K=1

K=1.5

K=2.5

K=4

K=6

EPR-XLP

TN = 90°C

TE = 130°C

10

1136

1602

1963

2533

3200

3916

100

374

518

629

807

1018

1244

1000

160

195

226

277

339

407

10000

126

128

132

140

152

168

18000

126

127

128

131

137

147

THH

TN = 90°C

TE = 105°C

10

725

1020

1248

1610

2033

2487

100

250

338

407

518

651

794

1000

127

146

163

192

229

270

10000

111

112

114

118

124

131

18000

111

111

112

113

116

121

THW

TN = 75°C

TE = 95°C

10

987

1390

1703

2197

2275

3396

100

329

452

548

702

884

1080

1000

148

117

202

245

298

357

10000

121

123

125

132

142

154

18000

121

121

122

125

130

137

Similar methods exist to determine the limit curve for bare overhead conductor applications, but are not covered in this guide.

Emergency overload curves are typically not shown on a TCC. However, when shown, are plotted in the upper 2 decades of the TCC.

Short Circuit Damage Curve

Curve that describes the conductor short circuit current operating limit, which if exceeded, will damage the conductor insulation. The curve is calculated assuming all heat is absorbed by the conductor metal, with no heat transmitted from the conductor to the insulation.

Separate equations are given for copper and aluminum cables. Both equations relate conductor temperature rise to conductor size, fault current magnitude and fault duration.
Insulated copper conductors

t = 0.0297 log10 [(T2+234) / (T1+234)] (A/I)2 (1)

Insulated aluminum conductors

t = 0.0125 log10 [(T2+228) / (T1+228)] (A/I)2 (2)

For bare conductors the short circuit damage temperature limit is much higher than those listed for insulated conductors. In this case the curve describes the conductor short circuit current operating limit at which the maximum acceptable loss in conductor mechanical strength is reached. Therefore, if this limit is exceeded, the conductor will be damaged.

For bare stranded aluminum conductors the upper temperature limit is 340ºC (300º rise over a 40ºC ambient). For bare stranded ACSR conductors the upper temperature limit is 645ºC (605º rise over a 40ºC ambient).

Bare stranded aluminum conductors

t = (0.0671A/I)2 (3)

Bare stranded ACSR conductors

t = (0.0862A/I)2 (4)

where:

A = conductor area – circular mils
I = short circuit current – RMS amperes
t = time of short circuit – 0.01 to 10 seconds
T1 = rated insulation operating temperature limit
T2 = rated maximum insulation short circuit temperature limit

Example 1

Plot the conductor landmarks for 3-1/C, 500kCM, THWN copper cables installed in metallic conduit on a 480V distribution system.

Solution

FLA from NEC table 310.16 is 380A

Emergency overload points calculated from Tables 2 and 3

Time (sec.)

Current (%)

Current (A)

10

2197

8,348

100

702

2,667

1,000

245

931

10,000

132

501

18,000

125

475

Damage points calculated from (1) using:

A = 500,000 cmils
t = time of short circuit – 0.01 to 10 seconds
T1 = 75°C (Table 1)
T2 = 150°C (Table 1)

Time (sec.)

SC Current (A)

10.00

8,371

0.01

264,711

The results are plotted in figure 1.

Fig. 1 500MCM, CU, 600V, THWN conductor damage curve

Example 2

Plot the conductor landmarks for 336.4 kCM ACSR conductors installed on a 138kV aerial distribution system.

Solution

FLA from the Electrical Transmission and Distribution Reference Book is 530A
Damage points calculated from (4) using:

A = 336,400 cmils
t = time of short circuit – 0.01 to 10 seconds

Time (sec.)

SC Current (A)

10.00

9,170

0.01

289,977

The results are plotted in figure 2.

Fig. 2 336.4kCM, ACSR conductor damage curve

References

Other Application Guides offered by SKM Systems Analysis at www.skm.com

  • Aluminum Electrical Conductor Handbook, The Aluminum Association Inc., Washington, D.C., 3rd edition, 1989.
  • Electrical Transmission and Distribution Reference Book, ABB Power T&D Company, Raleigh, North Carolina, 1997.

The latest revision of:

  • IEEE Std 242, IEEE Recommended Practice for Protection and Coordination of Industrial and Commercial Power Systems (IEEE Buff Book)

Equipment Damage Curves Conductors

The information presented in this application guide is for review, approval, interpretation and application by a registered professional engineer only. SKM disclaims any responsibility and liability resulting from the use and interpretation of this information.

Reproduction of this material is permitted provided proper acknowledgement is given to SKM Systems Analysis Inc.

Purpose

The purpose of this guide is to provide basic information about conductor damage curves and characteristic landmarks necessary for plotting on time-current curves (TCC), for the purpose of equipment overcurrent protection.

Ampacity

The rated continuous current carrying capacity of the conductor at a referenced ambient temperature, allowable temperature rise, geometry and installation. For bare overhead conductors an ambient air temperature of 40°C is typical. For underground insulated power cables an ambient earth temperature of 20°C is typical. Temperature correction factors are then given to adjust the base ampacity for other ambient temperature levels.
If a cable is loaded continuously above rated ampacity the insulation temperature design limits will be exceeded. This will lead to loss of insulation life, not instantaneous failure.
If a bare overhead conductor is loaded continuously above rated ampacity the mechanical strength of the conductor is reduced. This will lead to a loss of mechanical life, not instantaneous failure.

Table 1 summarizes typical allowable conductor temperature limits under short circuit, emergency overload and normal operating conditions.

Table 1 Typical conductor operating temperature limits


Type

Insulation

Voltage

Short Circuit

Emergency

Normal

0.01 < t < 10 sec.

10 sec. < t < ~1-6 hrs

t > ~1-6 hrs

Al or Cu

TW

600V

150ºC

85ºC

60ºC

Al or Cu

THWN

600V

150ºC

90ºC

75ºC

Al or Cu

THHN

600V

150ºC

105ºC

90ºC

Al or Cu

XLP

5-15kV

250ºC

130ºC

90ºC

Al or Cu

EPR

5-15kV

250ºC

130ºC

90ºC

AAC

Air

All

340ºC

150ºC

100ºC

ACSR

Air

All

645ºC

150ºC

100ºC

The ampacity landmark is located in the top decade of a TCC at 1000 seconds.

Emergency Overload Limit Curve

Conductor overcurrent operating limit that if exceeded will reduce the insulation life of a cable or reduce the mechanical life of a bare overhead conductor beyond an acceptable design loss of life limit.

Cable limit curves are based on the thermal inertia of the conductor, insulation and surrounding material. As a result, it can take from 1 to 6 hours for the temperature of a cable to stabilize after a change in load current. Therefore, under these emergency operating conditions, currents much greater than the rated ampacity can be supported. Tables 2 and 3 provide factors and percent overload capability for various installations.

Table 2 Cable K factors


Cable Size

K Factors

Air

UG Duct

Direct Buried

No Conduit

Conduit

< #2 AWG

0.33

0.67

1.00

1.25

#2 - 4/0 AWG

1.00

1.50

2.50

3.00

> 4/0 AWG

1.50

2.50

4.00

6.00

Table 3 Emergency overload current at 40°C ambient


Time

Percent Overload

Seconds

K=0.5

K=1

K=1.5

K=2.5

K=4

K=6

EPR-XLP

TN = 90°C

TE = 130°C

10

1136

1602

1963

2533

3200

3916

100

374

518

629

807

1018

1244

1000

160

195

226

277

339

407

10000

126

128

132

140

152

168

18000

126

127

128

131

137

147

THH

TN = 90°C

TE = 105°C

10

725

1020

1248

1610

2033

2487

100

250

338

407

518

651

794

1000

127

146

163

192

229

270

10000

111

112

114

118

124

131

18000

111

111

112

113

116

121

THW

TN = 75°C

TE = 95°C

10

987

1390

1703

2197

2275

3396

100

329

452

548

702

884

1080

1000

148

117

202

245

298

357

10000

121

123

125

132

142

154

18000

121

121

122

125

130

137

Similar methods exist to determine the limit curve for bare overhead conductor applications, but are not covered in this guide.

Emergency overload curves are typically not shown on a TCC. However, when shown, are plotted in the upper 2 decades of the TCC.

Short Circuit Damage Curve

Curve that describes the conductor short circuit current operating limit, which if exceeded, will damage the conductor insulation. The curve is calculated assuming all heat is absorbed by the conductor metal, with no heat transmitted from the conductor to the insulation.

Separate equations are given for copper and aluminum cables. Both equations relate conductor temperature rise to conductor size, fault current magnitude and fault duration.
Insulated copper conductors

t = 0.0297 log10 [(T2+234) / (T1+234)] (A/I)2 (1)

Insulated aluminum conductors

t = 0.0125 log10 [(T2+228) / (T1+228)] (A/I)2 (2)

For bare conductors the short circuit damage temperature limit is much higher than those listed for insulated conductors. In this case the curve describes the conductor short circuit current operating limit at which the maximum acceptable loss in conductor mechanical strength is reached. Therefore, if this limit is exceeded, the conductor will be damaged.

For bare stranded aluminum conductors the upper temperature limit is 340ºC (300º rise over a 40ºC ambient). For bare stranded ACSR conductors the upper temperature limit is 645ºC (605º rise over a 40ºC ambient).

Bare stranded aluminum conductors

t = (0.0671A/I)2 (3)

Bare stranded ACSR conductors

t = (0.0862A/I)2 (4)

where:

A = conductor area – circular mils
I = short circuit current – RMS amperes
t = time of short circuit – 0.01 to 10 seconds
T1 = rated insulation operating temperature limit
T2 = rated maximum insulation short circuit temperature limit

Example 1

Plot the conductor landmarks for 3-1/C, 500kCM, THWN copper cables installed in metallic conduit on a 480V distribution system.

Solution

FLA from NEC table 310.16 is 380A

Emergency overload points calculated from Tables 2 and 3

Time (sec.)

Current (%)

Current (A)

10

2197

8,348

100

702

2,667

1,000

245

931

10,000

132

501

18,000

125

475

Damage points calculated from (1) using:

A = 500,000 cmils
t = time of short circuit – 0.01 to 10 seconds
T1 = 75°C (Table 1)
T2 = 150°C (Table 1)

Time (sec.)

SC Current (A)

10.00

8,371

0.01

264,711

The results are plotted in figure 1.

Fig. 1 500MCM, CU, 600V, THWN conductor damage curve

Example 2

Plot the conductor landmarks for 336.4 kCM ACSR conductors installed on a 138kV aerial distribution system.

Solution

FLA from the Electrical Transmission and Distribution Reference Book is 530A
Damage points calculated from (4) using:

A = 336,400 cmils
t = time of short circuit – 0.01 to 10 seconds

Time (sec.)

SC Current (A)

10.00

9,170

0.01

289,977

The results are plotted in figure 2.

Fig. 2 336.4kCM, ACSR conductor damage curve

References

Other Application Guides offered by SKM Systems Analysis at www.skm.com

  • Aluminum Electrical Conductor Handbook, The Aluminum Association Inc., Washington, D.C., 3rd edition, 1989.
  • Electrical Transmission and Distribution Reference Book, ABB Power T&D Company, Raleigh, North Carolina, 1997.

The latest revision of:

  • IEEE Std 242, IEEE Recommended Practice for Protection and Coordination of Industrial and Commercial Power Systems (IEEE Buff Book)

'기본 카테고리' 카테고리의 다른 글

Irricht엔진튜토리얼 01. Hello World  (0) 2009.03.19
Equipment Damage Curves Cables , 단시간 허용전류2  (0) 2009.03.19
수치해석학  (0) 2009.03.18
c# 리스트뷰에 등록된 파일 실행~  (0) 2009.03.16
arc drawing  (0) 2009.03.10

http://mathlinux.kku.ac.kr/~kimchang/lect/na/수치해석학

Code::Blocks IDE || Dev-Cpp|| 예제 및 라이브러리 설치
Octave(Matlab Clone)
Octave 사용법

	0.장수치해석이란 무엇인가?
1.장 수 체계와 오차 1.1 정수의 표현 1.2 소수의 표현 1.3 부동소수 1.4 오차와 유효자리수의 상실 1.5 수치해석에 필요한 수학적 기초
2.장 다항식 보간법 2.1다항식의 계산 2.2 보간 다항식의 존재성과 유일성 라그랑즈 보간 다항식 2.3 분할 차분표와 보간 다항식의 계산 뉴턴 보간 다항식 2.4 보간 다항식의 오차 2.5 Spline 보간법
3장 비선형 방정식의 해법 - 이분법 - 뉴턴법 - secant법 - 고정점 반복법 - 고차원 비선형 방정식의 해법 - Muller 방법
4장 선형방정식의 해법과 고유값 문제 4.1 가우스 소거법 4.2 LU 분해법 4.3 반복법 가우스 자코비 반복법 가우스 사이델 반복법 SOR 4.4 QR, 멱 방법 5장 수치 미분 과 적분 5.1 수치 미분 5.2 수치적분 - 사다리꼴 공식 - simpson 공식 5.3 Gauss 구적법
6장 근사이론과 곡선의 적합 - 자료의 적합과 최소 제곱 근사 - Garlekin 근사 - 직교 다항식과 근사법
7장 미분 방정식의 수치해법 Euler 방법과 변형 Taylor 방법 / Runge -Kutta 법 고계 미분 방정식과 연립 미분 방정식의 해법
8장 경계치 문제와 유한 차분법 - Garlekin 근사
9장 편미분 방정식의 수치해법

액션 스크립트 용어 및 정리

플래셔
2007.03.16 14:02:00
http://cafe.naver.com/q69/86171

용어
다른 스크립팅 언어와 마찬가지로 ActionScript는 자체 용어를 사용합니다. 중요한 ActionScript 용어는 다음과 같습니다.



액션은 SWF 파일이 재생되는 동안 SWF 파일에 작업을 지시하는 명령문입니다. 예를 들어 gotoAndStop()은 재생 헤드를 특정 프레임이나 레이블로 보냅니다. 이 설명서에서 액션명령문이라는 용어는 같은 의미입니다.



부울은 true 또는 false 값입니다.



클래스는 새 유형의 객체를 정의하기 위해 만들 수 있는 데이터 유형입니다. 클래스를 정의하려면 액션 패널에서 현재 작성하고 있는 스크립트가 아닌 외부 스크립트 파일에 class 키워드를 사용합니다.



상수는 바뀌지 않는 요소입니다. 예를 들어, Key.TAB 상수는 항상 같은 의미로서 키보드의 Tab 키를 나타냅니다. 상수는 값을 비교하는 데 유용합니다.



생성자는 클래스의 속성 및 메서드를 정의하는 데 사용하는 함수입니다. 생성자는 클래스 정의에 포함된 클래스와 동일한 이름을 가진 함수입니다. 예를 들어, 다음 코드에서는 Circle 클래스를 정의하고 생성자 함수를 구현합니다.



// file Circle.as
class Circle {
private var radius:Number
private var circumference:Number
// constructor
function Circle(radius:Number) {
circumference = 2 * Math.PI * radius;
}
}



생성자는 특정 클래스에 기초한 객체를 생성(인스턴스화)할 때에도 사용됩니다. 다음 명령문은 내장 클래스인 Array와 사용자 정의 클래스인 Circle에 대한 생성자입니다:



my_array:Array = new Array();
my_circle:Circle = new Circle();



데이터 유형은 변수나 ActionScript 요소가 보유할 수 있는 정보의 종류를 설명합니다. ActionScript 데이터 유형으로는 String, Number, Boolean, Object, MovieClip, Function, null 및 undefined가 있습니다. 자세한 내용은 데이터 유형을 참조하십시오.



이벤트는 SWF 파일이 재생되는 동안 발생하는 액션입니다. 예를 들어 무비 클립을 로드할 때, 재생 헤드가 프레임에 들어올 때, 사용자가 버튼이나 무비 클립을 클릭할 때, 사용자가 키보드를 누를 때마다 서로 다른 이벤트가 생성됩니다.



이벤트 핸들러는 mouseDown이나 load와 같은 이벤트를 관리하는 특수 액션입니다. ActionScript 이벤트 핸들러의 종류는 이벤트 핸들러 메서드와 이벤트 리스너로 두 가지가 있습니다. 참고로, 이벤트 핸들러의 종류도 on() 및 onClipEvent()로 두 가지가 있으며 이 이벤트 핸들러를 버튼이나 무비 클립에 직접 지정할 수 있습니다. 액션 도구 상자에서 이벤트 핸들러 메서드 또는 이벤트 리스너가 있는 각 ActionScript 객체에는 이벤트 또는 리스너라는 하위 범주가 있습니다. 일부 명령은 이벤트 핸들러 및 이벤트 리스너 모두로 사용될 수 있으며 이 두 하위 범주에 포함될 수도 있습니다.



표현식은 값을 나타내는 ActionScript 심볼의 올바른 조합입니다. 표현식은 연산자와 피연산자로 구성됩니다. 예를 들어 x + 2 표현식에서 x와 2는 피연산자이고 +는 연산자입니다.



함수는 매개 변수를 받고 값을 반환할 수 있는 다시 사용할 수 있는 코드의 블록입니다. 자세한 내용은 함수 만들기를 참조하십시오.



식별자는 변수, 속성, 객체, 함수 또는 메서드를 나타내는 데 사용하는 이름입니다. 첫 문자는 글자, 밑줄(_) 또는 달러 기호($)여야 합니다. 그 이후의 문자는 문자, 숫자, 밑줄 또는 달러 기호여야 합니다. 예를 들어 firstName은 변수의 이름입니다.



인스턴스는 특정 클래스에 속하는 객체입니다. 클래스의 각 인스턴스에는 해당 클래스의 모든 속성과 메서드가 들어 있습니다. 예를 들어, 모든 무비 클립은 MovieClip 클래스의 인스턴스입니다. 따라서 어떠한 무비 클립 인스턴스에서도 MovieClip 클래스의 모든 메서드와 속성을 사용할 수 있습니다.



인스턴스 이름은 스크립트에서 무비 클립 및 버튼 인스턴스를 대상으로 지정할 수 있도록 하는 고유 이름입니다. 속성 관리자를 사용하여 인스턴스 이름을 스테이지의 인스턴스에 지정합니다. 예를 들어, 라이브러리의 마스터 심볼은 counter이고 SWF 파일에 있는 해당 심볼의 두 인스턴스의 이름은 scorePlayer1_mc와 scorePlayer2_mc라고 합니다. 다음 코드는 인스턴스 이름을 사용하여 각 무비 클립 인스턴스에 score라는 변수를 설정합니다.



_root.scorePlayer1_mc.score += 1;
_root.scorePlayer2_mc.score -= 1;



인스턴스 이름을 지정할 때 특수한 접미사를 사용하면 코드를 입력할 때 코드 힌트(코드 힌트 사용 참조)가 표시되도록 할 수 있습니다. 자세한 내용은 접미어를 사용하여 코드 힌트 표시를 참조하십시오.



키워드는 특수한 의미를 가진 예약된 단어입니다. 예를 들어 var는 로컬 변수를 선언할 때 사용하는 키워드입니다. 키워드는 식별자로 사용할 수 없습니다. 예를 들어 var는 올바른 변수 이름이 아닙니다. 키워드 목록을 보려면 키워드를 참조하십시오.



메서드는 클래스와 연관된 함수입니다. 예를 들어 getBytesLoaded()는 MovieClip 클래스와 연관된 내장 메서드입니다. 내장 클래스에 기반한 객체 또는 사용자 정의 클래스에 기반한 객체에 사용하기 위해 메서드 역할을 하는 함수를 만들 수 있습니다. 예를 들어 다음 코드에서 clear()는 이전에 정의한 controller 객체의 메서드가 됩니다.



function reset(){
this.x_pos = 0;
this.x_pos = 0;
}
controller.clear = reset;
controller.clear();



객체는 속성과 메서드의 컬렉션입니다. 각 객체는 특정 클래스의 인스턴스이며 고유 이름이 있습니다. 내장 객체는 ActionScript 언어에 미리 정의되어 있습니다. 예를 들어, 내장 Date 객체는 시스템 시계의 정보를 제공합니다.



연산자는 하나 이상의 값으로부터 새 값을 계산하는 용어입니다. 예를 들어, 더하기(+) 연산자는 두 개 이상의 값을 더하여 새 값을 만듭니다. 연산자가 처리하는 값을 피연산자라고 합니다.



매개 변수는 인수라고도 하며 함수에 값을 전달할 수 있도록 하는 자리 표시자입니다. 예를 들어, 다음 welcome() 함수는 매개 변수로 받은 firstName 및 hobby의 두 값을 사용합니다.



function welcome(firstName, hobby) {
welcomeText = "Hello, " + firstName + "I see you enjoy " + hobby;
}



패키지는 클래스 파일이 하나 이상 포함된 디렉토리이며 지정된 클래스 경로 디렉토리에 있습니다(클래스 경로 이해 참조).



속성은 객체를 정의하는 특성입니다. 예를 들어, _visible은 모든 무비 클립의 속성으로서 무비 클립을 표시할지 또는 숨길지 여부를 정의합니다.



대상 경로는 SWF에 있는 무비 클립 인스턴스 이름, 변수 및 객체의 계층 주소입니다. 무비 클립 속성 관리자에서 무비 클립 인스턴스의 이름을 지정합니다. 기본 타임라인의 이름은 항상 _root입니다. 대상 경로를 사용하여 무비 클립의 액션을 지정할 수 있으며 변수의 값을 가져오거나 설정할 수 있습니다. 예를 들어, 다음 명령문은 stereoControl 무비 클립 안에 있는 volume 변수의 대상 경로입니다.


_root.stereoControl.volume


대상 경로에 대한 자세한 내용은 절대 및 상대 대상 경로 사용을 참조하십시오.



변수는 모든 데이터 유형의 값을 보유하는 식별자입니다. 변수는 만들거나, 변경하거나, 업데이트할 수 있습니다. 변수에 저장된 값을 가져와 스크립트에 사용할 수 있습니다. 다음 예제에서 등호의 왼쪽에 있는 식별자가 변수입니다.



var x = 5;
var name = "Lolo";
var c_color = new Color(mcinstanceName);



변수에 대한 자세한 내용은 변수를 참조하십시오.








<<플래쉬 액션 스크립트flash action script>>

----------------------------------------------------------------------------
// ..... 주석 기호
/* ..... */주석 기호
----------------------------------------------------------------------------
r// 리턴 코드(ASC 13)
n// 줄바꿈 코드 (ASC 10)
rn// 줄바꿈 코드(2줄)
t// Tab 코드 (ASC 9)
b// Backspce 코드 (ASC 8)
& // text 파일 데이타 구분 코드
----------------------------------------------------------------------------
산술연산자+, -, *, /, % //%나머지를 구한다
대입연산자=, +=, -=, *=, /=, %= //i+=4 와i=i+4 는 같다
증감연산자++, --//i++와 i=i+1 는 같다
비교연산자==, !=, >, <, >=, <=//!='같지않다' 로 해석
비교연산자=== //숫자 와 문자 구분
a = 5;b = "5";//숫자 5 와 문자 "5"
(a == b)//숫자 5 와 문자 "5"는 같다 (true)
(a === b) //숫자 5 와 문자 "5" 는 틀리다 (false)
논리연산자&&, ||, ! //그리고(AND), 또는(OR), 아니면(NOT)
조건연산자?( a ) ? b : c ;//a 조건이 맞으면 b 틀리면 c 실행
x=5;y=10;z=(x<6) ? x: y; trace (z); //z 은 5 이다
문자연산자eqnenotoradd//eq(==) ne(!=) not(!) or(||) add(+ 문자열의 연결)
( ) //연산의 순서를 정한다
[ ] //배열을 지정한다
" " //문자를 지정한다
a=1+2;trace(a); //연산 결과 출력.결과는 3
aaa=1;set("ccc", aaa );trace(ccc);//변수에 값을 지정.결과는 1
aaa=1;set("ccc", "aaa");trace(ccc); //변수에 값을 지정.결과는 aaa
set("ooo", getProperty ("ppp", _x )); //ppp x 좌표를ooo 에 지정.
----------------------------------------------------------------------------
for (a=1; a<=10; a++){ trace("a="+a); }; //for반복문
for (i=1; i<=120;i+=12) { continue; }; //for step 반복문
while(true) {if(a == 0) { break; }; }; //while반복문
do { if(a == 0) { break; }; };while(true); //do 반복문
if((n == 0) || (n >= 5)&&(n <= 55)!(n=15)) { //if 조건문
 gotoAndPlay(1);
} else if (n == 2) {
 gotoAndPlay(2);
} else {
 gotoAndPlay(3);
};
num_ch = 3; //switch 조건문
switch (num_ch) {
case 1:trace ( " case 1 tested true " );break;
case 2:trace ( " case 2 tested true " );break;
default:trace ( " no case tested true " );
};
----------------------------------------------------------------------------
function sumnumber(a,b,c) {return(aaa= a+b+c); };// 함수
sumnumber(1,2,3);
trace(aaa);
----------------------------------------------------------------------------
Math.abs(-1)//절대값. 결과는 1
Math.sin(1) //sin 값. 결과는 0.841470984807897
Math.cos(1) //cos 값. 결과는 0.54030230586814
Math.tan(1) //tan 값. 결과는 1.5574077246549
Math.log(2) //log 값. 결과는 0.693147180559945
Math.exp(1) //지수 값.결과는 2.71828182845905
Math.sqrt(9)//제곱근 값.결과는 3
Math.pow(2 , 4) //거듭제곱 값.결과는 16
Math.ceil(1.1)//가까운 정수로 올림 값.결과는 2
Math.ceil(1.5)//가까운 정수로 올림 값.결과는 2
Math.floor(1.2) //가까운 정수로 내림 값.결과는 1
Math.floor(1.7) //가까운 정수로 내림 값.결과는 1
Math.round(1.2) //가까운 정수로 반올림 값.결과는 1
Math.round(1.5) //가까운 정수로 반올림 값.결과는 2
Math.max(1 , 2) //두 정수 중 큰 정수값.결과는 2
Math.min(1 , 2) //두 정수 중 작은 정수값.결과는 1
int(1.12 ); //수치를 정수화. 결과는 1
int(1.82 ); //수치를 정수화. 결과는 1
parseInt("3.2");//문자열을 정수화.결과는 3
parseInt("3.7");//문자열을 정수화.결과는 3
parseInt("5abc"); //문자열을 정수화.결과는 5
parseInt("abc5"); //문자열을 정수화.결과는 NaN
parseInt("3E8", 16);//16 진수로 변환. 결과는 1000
parseInt("777", 8); //8 진수로 변환. 결과는 511
parseInt("1010", 2);//2 진수로 변환. 결과는 10
parseFloat("2") // 문자열을 부동점 숫자로 변환.결과는 2
parseFloat("2.4") // 문자열을 부동점 숫자로 변환.결과는 2.4
parseFloat("2.6abc")// 문자열을 부동점 숫자로 변환.결과는 2.6
Number("11")//문자열을 숫자로 변환. 결과는 11
Number("12.34") //문자열을 숫자로 변환. 결과는 12.34
Number("12.34abc")//문자열을 숫자로 변환. 결과는 NaN
sss = 123;uuu = sss.toString();// 숫자를 문자로변환.결과는 123
ord("abc");//ASCII 값. 결과는 97
s = "abc"; sss = s.charCodeAt(0);//1번째 ASCII 값 . 결과는 97
s = "abc"; sss = s.charCodeAt(1);//2번째 ASCII 값.결과는 98
chr(65); //ASCII 코드를 문자화.결과는 A
String.fromCharCode(64,65,66); //ASCII 코드를 문자화.결과는 @AB
Math.random(); // 난수 발생.결과는 0 - 1 사이의 소숫점 포함한 값
random(5); // 난수 발생.결과는 0,1,2,3,4 중 하나
----------------------------------------------------------------------------
// delete 변수 또는 객체 ; // 변수를 삭제(var 로 선언된 변수는 삭제할 수 없다)
account = 1; trace (account) ;// 결과는 1
account = 1; delete account;trace (account);// 결과는 undefined
delete onEnterFrame;// 반복 실행 중지
----------------------------------------------------------------------------
typeof( );// String, Number, MovieClip, Object, Boolean, Function 여부를 지정
trace (typeof(1));// 결과는 Number
trace (typeof("1"));// 결과는 String
trace (typeof(aaa));// aaa가 무비클립 이라면결과는 MovieClip
----------------------------------------------------------------------------
isFinite( );// 숫자가 유한수이면 true 무한수거나 음의 무한대이면 false
trace (isFinite(aaa));// aaa 값이 NaN 이라면 결과는 false
----------------------------------------------------------------------------
Mouse.show(); // 마우스 보임
Mouse.hide(); // 마우스 감춤
myClip.onMouseDown = function () {trace (" depth 무시"); }; // 마우스 누를 때
myClip.onMouseUp = function () {trace ("depth 무시"); };// 마우스 눌렀다 놓을 때
myClip.onMouseMove = function () { trace ("depth 무시"); }; // 마우스 이동할 때
myClip.onPress = function () { trace ("depth 적용"); }; // 마우스 누를 때
myClip.onRelease = function () { trace ("depth 적용 "); };// 마우스 눌렀다 놓을 때
myClip.onReleaseOutside = function () { trace ("Outside"); }; // 마우스 나가서 놓을 때
myClip.onRollOver = function () { trace ("Over called"); }; // 마우스 오버 때
myClip.onRollOut = function () { trace ("Out called"); }; // 마우스 아웃 때
----------------------------------------------------------------------------
// 단추무비클립 클릭후 액션 스크립트를 넣는다
on (press){ }// 마우스 버튼을 누를 때 };x}o
on (release){ }// 마우스 버튼을 눌렀다 뗄 때
on (releaseOutside){}// 마우스 버튼을 누르고 나가서 뗄 때
on (rollOver){}// 마우스 포인트가 위로 올라올 때
on (rollOut){ }// 마우스 포인트가 밖으로 나갈 때
on (dragOver){}// 누른 채로 밖으로 나갔다가 다시 들어올 때
on (dragOut){ }// 마우스버튼을 누르고 바깥으로 드래그할 때
on (keyPress){}// 지정한 키를 누를 때
----------------------------------------------------------------------------
// 무비클립 클릭후 액션 스크립트를 넣는다
onClipEvent (load) {}// 시작 될때};x}o
onClipEvent (unload) {}// 제거 될때
onClipEvent (enterFrame) {}// 트리거 될때
onClipEvent (mouseMove) { }// 마우스가 이동할 때
onClipEvent (mouseDown) { }// 마우스 클릭 시
onClipEvent (mouseUp) { }// 마우스 클릭 후
onClipEvent (keyDown) { }// 키를 누를 때
onClipEvent (keyUp) { }// 키를 눌렀다 놓을 때
onClipEvent (data) {}// loadVariables 또는 loadMovie 액션에서 데이터가 수신될 때
----------------------------------------------------------------------------
TextField.onChanged = function () { trace ("onChanged called"); };
// 텍스트 필드의 내용이 변경될 때
TextField.onSetFocus = function () { trace ("onSetFocus called"); };
// 텍스트 필드의 내용 부분에 마우스가 클릭 될 때
TextField.onKillFocus = function () { trace ("onKillFocus called"); };
// 텍스트 필드의 내용 바깥 부분에 마우스가 클릭 될 때
TextField.onScroller = function () { trace ("onScroller called"); };
// 텍스트 필드의 내용이 스크롤 될 때
----------------------------------------------------------------------------
myMovieClip.onData = function () { trace ("onData called"); };
// 무비 클립이 loadVariables 또는 loadMovie 호출로부터 데이터를 받을 때
myMovieClip.onLoad =function () { trace ("onLoad called"); };
// 무비 클립이 load 호출로부터 데이터를 받을 때
myMovieClip.onUnLoad =function () { trace ("onUnLoad called"); };
// 무비 클립이 Unload 때
myMovieClip.stop()
// 작업 중지
----------------------------------------------------------------------------
myDate = new Date(); // 날짜 로드
myDate = new Date (년,월,일,시,분,초); // 날짜 지정
yyyy = (myDate.getFullYear() + "-" + (myDate.getMonth() + 1) + "-" + myDate.getDate());
tttt = (myDate.getHours()+ " :" + myDate.getMinutes() + " :" +myDate.getSeconds());
----------------------------------------------------------------------------
_root.onEnterFrame = function() { }; // 메인화면에서 프레임 반복
onEnterFrame = function() { }; // 심볼화면에서 프레임 반복
----------------------------------------------------------------------------
tmtm = getTimer();
onEnterFrame = function() {
if ( (getTimer()-tmtm) >= 500 ) { tmtm=getTimer(); trace (tmtm); }; // 0.5초후 반복실행
if ( (getTimer()-tmtm) >= 1000 ) { tmtm=getTimer(); trace (tmtm); };// 1초후 반복실행
if ( (getTimer()-tmtm) >= 2000 ) { tmtm=getTimer(); trace (tmtm); };// 2초후 반복실행
};
----------------------------------------------------------------------------
onEnterFrame = function() {
nr += 1;if (nr > 5 ){deleteonEnterFrame;}; // 5번 반복실행후 중지
trace (nr);
};
----------------------------------------------------------------------------
createTextField ("ins", 1, 100, 100, 50, 50)
ins.border = true;
function callback() {
ins._x += 5;
if ( ins._x > 400 ) { clearInterval( intervalID );};// 중지 (clearInterval)
}
var intervalID;
intervalID = setInterval( callback, 100 ); //0.1초후 반복실행 (setInterval)
----------------------------------------------------------------------------
#include "script.as" // script.as 파일 넣기 (액션 스크립트 txt 파일)
----------------------------------------------------------------------------
System.useCodepage = true; // 한글 깨짐 방지
trace(System.capabilities.language)// Flash Player가 지원하는 언어. 결과는 ko
trace(System.capabilities.hasVideoEncoder) // 지원되는 비디오 인코더. 결과는 true, false.
trace(System.capabilities.hasAudioEncoder )// 지원되는 오디오 인코더. 결과는 true, false.
trace(System.capabilities.hasAudio)// 오디오 성능이 있는지 여부. 결과는 true, false.
trace(System.capabilities.hasMP3)// MP3 디코더가 있는지 여부. 결과는 true, false.
----------------------------------------------------------------------------
escape("abc가나다"); // URL에 사용하기 위해 인코딩.
// System.useCodePage= true; 일때 결과는 abc%B0%A1%B3%AA%B4%D9
// System.useCodePage= false; 일때 결과는 abc%EA%B0%80%EB%82%98%EB%8B%A4
----------------------------------------------------------------------------
trace(targetPath(this)); // 대상 패스를 반환.결과는 _level0.instance1 로 표시
trace(this.valueOf()); // 결과는 _level0 로 표시
----------------------------------------------------------------------------
trace(this.getBytesLoaded());// 무비클립의 로드된 바이트 수를 알려준다.
trace(this.getBytesTotal()); // 무비클립의 전체용량 바이트 수를 알려준다.
----------------------------------------------------------------------------
getURL("C:/")// 탐색기 열기
getURL("C:/Windows/NOTEPAD.EXE"); }; // 메모장 열기
getURL("C:/Program Files/Accessories/WORDPAD.EXE");// 워드패드 열기
getURL("C:/Program Files/Accessories/MSPAINT.EXE");// 그림판 열기
getURL("C:/Windows/CALC.EXE"); // 계산기 열기
getURL ("aaa.exe");// aaa.exe 파일 열기 (message)
getURL ("aaa.txt", "_self"); // aaa.txt 파일 열기
getURL ("movie.html", "_self");// movie.html 파일 열기
getURL ("http://www", "_blank"); //
http://www 를 새로운 창으로 열기
----------------------------------------------------------------------------
Stage.showMenu = "true";// 스크린 메뉴 보임
Stage.showMenu = "false"; // 스크린 메뉴 감춤
Stage.scaleMode = "noScale";// 화면의 사이즈를 고정
Stage.align = "TL"; // 화면의 정렬을 T(위) L(왼쪽)
//"T" 위 가운데"B" 아래 가운데"L" 가운데 왼쪽"R" 가운데 오른쪽
//"TL" 위쪽 왼쪽 "TR" 위쪽 오른쪽 "BL" 아래쪽 왼쪽 "BR" 아래쪽 오른쪽
Stage.height// 픽셀로 표시된 스테이지의 높이
Stage.width // 픽셀로 표시된 스테이지의 넓이
----------------------------------------------------------------------------
_root.createEmptyMovieClip("box",1);// 스테이지 테두리 주기
with (_root.box) {moveto(1, 1); linestyle(10, 0x00cc00, 100);
lineto(stage.width, 1); lineto(stage.width, stage.height);
lineto(1, stage.height);lineto(1, 1); };
----------------------------------------------------------------------------
fscommand("showmenu", true);// 스크린 메뉴 보임
fscommand("showmenu", false); // 스크린 메뉴 감춤
fscommand("allowscale", true);// 스크린 크기에 따라 무비의 크기도 변함
fscommand("allowscale", false); // 스크린 크기에 따라 무비의 크기도 안변함
fscommand("fullscreen", true);// 풀 스크린 (esc키 누르면 해제)
fscommand("fullscreen", false); // 풀 스크린을 원래의 크기로 만든다
fscommand("trapallkeys", true); // 키보드 키 사용할 수 없음 (풀 스크린 일때 esc키 먹통)
fscommand("trapallkeys", false);// 키보드 키 사용할 수 있음
fscommand("quit");// 스크린 닫기
fscommand ("exec", "a.exe");// a.exe 파일 실행 (no message)
플래시 무비(exe) 가 위치하는 폴더안에 fscommand 라는 하위 폴더를 만들고
fscommand 디렉토리에a.exe 가 있을때 플래시 무비(exe)를 실행하면 a.exe파일 실행
----------------------------------------------------------------------------
// getURL 로 javascript 사용하기
var hello = "Hello, World";
getURL("javascript:alert(" "+ hello + "")"); // 메세지 띄우기
getURL("javascript:window.self.close()");// 윈도우창 닫기
getURL("javascript:window.external.AddFavorite('http://','가')" );//즐겨찾기 추가
----------------------------------------------------------------------------
// fscommand 로 javascript 사용하기
1.fscommand ("messagebox", "This is a Flash."); // aaa.swf flash script
2.파일메뉴 - 제작설정 - 포맷 (HTML체크) - HTML (템플릿: with FSCommand 체크)
3.파일메뉴 - 제작 (파일명은 aaa.swf) -aaa.html 파일이 디렉토리에 만들어 진다
4.aaa.html 파일을 열고function aaa_DoFSCommand(command, args) {아래에
if (command == "messagebox") {alert(args);}; 을 적고 저장 한다
5.aaa.html 실행 (실행후 제작설정 해제)
----------------------------------------------------------------------------
// fscommand 로 javascript 의 변수값 불러오기
1. fscommand ("search", TextFieldvar); // aaa.swf flash script
2. if (command == "search") {// aaa.html script
EEEfind = "FFFFFFFF";
window.d0cument.aaa.SetVariable("TextFieldvar", EEEfind) ;
return TextFieldvar;
};
3. aaa.html 실행
----------------------------------------------------------------------------
_root.loadMovie("a.swf");// swf 파일 불러오기
_root.bbb.loadMovie("a.swf") // swf 를 메인에 있는 bbb무비클립인스턴스에 불러오기
_root.loadMovie("a.swf", 1); // swf 를 레벨1로 불러오기 (2 는 1를screen over)
_root.loadMovie("aaa.jpg");// jpg 파일 불러오기
_root.bbb.loadMovie("aaa.jpg");// jpg 파일을 메인에 있는 bbb무비클립인스턴스에 불러오기
unloadMovie (1); // 레벨 1에 로드된 무비를 언로드
unloadMovie ("a.swf"); // 현재 무비에 로드된 a.swf 무비를 언로드
_root.bbb.unloadMovie(); // 메인 타임라인의 bbb 무비클립에 로드된 무비를 언로드
this["bbb"].unloadMovie(); // 현재 타임라인의 bbb 무비클립에 로드된 무비를 언로드
sss.bbb.unloadMovie(); // sss 심볼 타임라인의 bbb 무비클립에 로드된 무비를 언로드
----------------------------------------------------------------------------
button.onPress = function() { _root.loadMovie("aaa.swf"); } // aaa.swf 실행중 초기화 하기
----------------------------------------------------------------------------
_root["ball_"+counter]._x = 11; //메인 화면의 클립 좌표
this["ball_"+counter]._x = 11;//현재 화면의 클립 좌표
aaa["ball_"+counter]._x = 11; //aaa 심볼 화면의 클립 좌표
----------------------------------------------------------------------------
this.createEmptyMovieClip("aaa", 1); //무비클립 생성 (2 는 1를 screen over)
this.duplicateMovieClip (aaa, bbb, 1); //aaa 무비클립bbb 로 복사
this.bbb.removeMovieClip();//bbb 무비클립 삭제
myClip._visible = true;//클립 보임
myClip._visible = false; //클립 감춤
myClip.swapDepths(100);//클립 깊이 100 으로 지정 (2 는 1를 screen over)
myClip.swapDepths(otherClip);//클립 깊이 otherClip 과 바꿈
for (i=1; i<=360; i++){//클립 복사
duplicateMovieClip (ins1, "mc"+i, i);
setProperty ("mc"+i, _x, random(300));
setProperty ("mc"+i, _y, random(300));
setProperty ("mc"+i, _alpha, random(300));
setProperty ("mc"+i, _xscale, 150);
setProperty ("mc"+i, _yscale, 150);
};
for (i=1; i<=360; i++){//클립 복사
duplicateMovieClip (ins1, "mc"+i, i);
this["mc" + i]._x = i;
this["mc" + i]._y = i;
};
for (i=1; i<=50; i++){// 클립 이동
this["mc_"+i]._x += 10;
this["mc_"+i]._y += 10;
};
for (i=1; i<=360; i++){ // 클립 삭제
this["mc" + i].removeMovieClip ();
};
----------------------------------------------------------------------------
setProperty ("mv", _x, 150); // mv 무비클립 x좌표 속성 변경
myMovieX = getProperty( mv, _x); // mv 무비클립 x좌표 속성 읽기
trace(myMovieX);
----------------------------------------------------------------------------
_alpha알파값(%)
_currentframe 현재재생중인 프레임(#)
_droptarget 드래그 앤드드롭 할때 놓는 타깃위치(name)
_framesloaded 로드된 프레임수(#)
_height 높이(#)
_name 인스턴스(string)
_rotation 회전값(#)
_soundbuftime 사운드버퍼링 시간(기본값 5초:#)
_totalframes총프레임수(#)
_url다운로드한 URL(string)
_visible보인다,안보인다 (true,false)
_width가로길이(#)
_xx좌표(#)
_yy좌표(#)
_xmouse 마우스x좌표(#)
_ymouse 마우스y좌표(#)
_xscale x배율(%)
_yscale y배율(%)
----------------------------------------------------------------------------
_root.a.play;//메인에 있는 a무비클립프레임 재생
_root.a.stop;//메인에 있는 a무비클립프레임 중지
play();//stop으로 정지된 현재타임라인의 프레임 재생
stop();//현재타임라인의 프레임 중지
gotoAndPlay(1);//현재 Scene의 1프레임 재생
gotoAndPlay("a");//현재 Scene의 Label명 a 재생
gotoAndPlay("Scene 2", "c"); //Scene 2의 Label명 c 재생
a.gotoAndPlay(1);//a무비클립의 1프레임 재생
gotoAndStop(1);//현재 Scene의 1프레임 중지
nextScene(); //다음 장면의 프레임 1로 보내고 중지
prevSecne(); //이전 장면의 프레임 1로 보내고 중지
nextFrame(); //다음 프레임으로 보내고 중지
prevFrame(); //이전 프레임으로 보내고 중지
toggleHighQuality ();//저해상도와 고해상도 간을전환
updateAfterEvent();//화면을 갱신 (onClipEvent 핸들러 내에서만 사용)
//(onMouseDown,onMouseUp,onMouseMove)
----------------------------------------------------------------------------
tellTarget ("../a") { nextFrame(); } //../a 무비클립을 호출후 다음 프레임 재생
if (_framesloaded = 10) {} // 만약 무비의 10프레임이 로드되면
----------------------------------------------------------------------------
// with 문
for (i=0; i<1000; i++) {
with (aaa[i]) {
_x = Math.floor(Math.random() * 500);
_y = random(500);
_rotation = random(360);
}
}
// tellTarget 문 (속도빠름)
for (i=0; i<1000; i++) {
tellTarget (aaa[i]) {
_x = Math.floor(Math.random() * 500);
_y = random(500);
_rotation = random(360);
}
}
----------------------------------------------------------------------------
aaa = new Array();// 배열 초기화
aaa = new Array("1","2","3"); // 배열값 넣기
bbb = ["Sun","Mon","Tue"];// 배열값 넣기
aaa[1] = "abc"; // 배열값 변환( "2" 가 "abc" 로 변환)
aaa[0] = "Jan" ;aaa[1] = "Feb" ;aaa[2] = "Mar" ; // 배열값 변환
aaa[3] = "Apr"// 배열 추가 (aaa 값은"Jan,Feb,Mar,Apr" )
ccc = aaa.concat(bbb);// 배열 합침 (ccc 값은"Jan,Feb,Mar,Apr,Sun,Mon,Tue" )
ddd = ccc.join("/");// ,를/로 변환(ddd 값은"Jan/Feb/Mar/Apr/Sun/Mon/Tue" )
ddd = ccc.length; // 배열값 갯수 (ddd 값은7 )
ddd = ccc.slice(2,4); // 배열값 읽기 (ddd 값은"Mar,Apr" )
eee = ccc.push("z","zz"); // 배열추가후배열값 갯수 (eee 값은9 )
//(ccc 값은 "Jan,Feb,Mar,Apr,Sun,Mon,Tue,z,zz" 로 변함)
eee = ccc.pop();// 마지막 배열 분리후 값(eee 값은"zz" )
//(ccc 값은"Jan,Feb,Mar,Apr,Sun,Mon,Tue,z" 로 변함)
eee = ccc.shift();// 첫번째 배열 분리후 값 (eee 값은"Jan" )
//(ccc 값은"Feb,Mar,Apr,Sun,Mon,Tue,z" 로 변함)
eee = ccc.reverse();// 배열값 순서바꿈 (eee 값은"z,Tue,Mon,Sun,Apr,Mar,Feb" )
//(ccc 값도"z,Tue,Mon,Sun,Apr,Mar,Feb" 로 변함)
eee = ccc.splice(2,5,"x","xx","xxx");// 배열값 읽기후변환(eee 값은"Mon,Sun,Apr,Mar,Feb" )
//(ccc 값은"z,Tue,x,xx,xxx" 로 변함)
eee = ccc.unshift("1","2"); // 첫번째 배열추가후값(eee 값은"7" )
//(ccc 값은"1,2,z,Tue,x,xx,xxx" 로 변함)
sss = new Array(1,2,3); // 숫자 배열값 넣기
uuu = sss.toString(); // 문자로변환.결과는 1,2,3
vvv = uuu.toLowerCase();// 대문자를소문자로 변환.원래 값은 변경되지 않음
vvv = uuu.toUpperCase();// 소문자를대문자로 변환.원래 값은 변경되지 않음
xxx = Number("111") //숫자로 변환. 결과는 111
xxx = Number("aaa") //숫자로 변환. 결과는 NaN
xxx = Number(true)//숫자로 변환. 결과는 1
xxx = Number(false) //숫자로 변환. 결과는 0
----------------------------------------------------------------------------
cliparray = new Array(); // 무비클립을 배열로 저장하기
for (a=1; a<=3; a++){
cliparray[a] =_root["clip"+a];
cliparray[a].x =_root["clip"+a]._x;
cliparray[a].y =_root["clip"+a]._y;
trace(cliparray[a].x);
trace(cliparray[a].y);
}
----------------------------------------------------------------------------
myString = new String(); // 문자 변수초기화
myString = new String("가나다"); // 문자 넣기
tet="가나다"; myString = new String(tet);// tet변수 넣기
text0=myString.charAt(0);// text0 값은 "가"-1개 읽기
text1=myString.charAt(1);// text1 값은 "나"-1개 읽기
text2=myString.charAt(2);// text2 값은 "다"-1개 읽기
text3=myString.concat("라마","바사","다"); // text3 값은 "가나다라마바사다"-추가
text4=text3.substr(2,4); // text4 값은 "다라마바"-여러개 읽기
text5=text3.substring(2,4);// text5 값은 "다라"-여러개 읽기
text6=text3.slice(2,4);// text6 값은 "다라"-여러개 읽기
text7=myString.charCodeAt(1);// text7 값은45208- 문자를 코드화
text8="a" + String.fromCharCode(64) + "m"; // text8 값은 "a@m"- 코드를 문자화
text9= text3.indexOf("다");// text9 값은 2-문자위치
text10= text3.lastIndexOf("다"); // text10 값은 7-마지막 문자위치
text11= text3.length;// text11 값은 8-문자길이
text12= text3.split("나"); // text12 값은 "가,다라마바사다"-문자분리
text13= text6.concat(text3); // text13 값은 "다라가나다라마바사다"-문자합침
text14= text13.substr((text13.length-1),1);// text14 값은 "다"-마지막 문자 읽기
sss = myDate.toString();day = sss.substring(0,3); // 문자로변환
----------------------------------------------------------------------------
// aaa 문장을 bbb 배열로 저장하기// 문장을 배열로 저장하기
// 결과는 bbb[0]="a" bbb[1]="b" bbb[2]="c" bbb[3]="d" bbb[4]="e"
aaa = "a b c d e";
aaalen = aaa.length;
bbb = new Array();
for (a=0; a<=aaalen; a++){ bbb[a] = "";};
bbbno = 0; bbbchr = "";
for (a=0; a<=aaalen; a++){
if ( aaa.charAt(a) == " " ) {bbb[bbbno] = bbbchr; bbbno += 1; bbbchr = "";
} else { bbbchr += aaa.charAt(a); };
};
for (a=0; a<=bbbno; a++){trace( "*" + bbb[a] + "*" ) };
----------------------------------------------------------------------------
for (a=1; a<=22; a++) { // 텍스트 필드 글자속성
this["k"+(a)].textColor=0xff0000;
this["k"+(a)].border=true;
this["k"+(a)].borderColor=0xff0000;
this["k"+(a)].background=true;
this["k"+(a)].backgroundColor=0xffffff;
};
----------------------------------------------------------------------------
TextField.removeTextField(); // 텍스트 필드 삭제
----------------------------------------------------------------------------
createTextField ("instanceName", depth, x, y, width, height) // 텍스트 필드 생성
instanceName 새 텍스트 필드의 인스턴스 이름
depth 새 텍스트 필드의 깊이를 지정하는 양의 정수 (2 는 1를screen over)
x 새 텍스트 필드의 x 좌표를 지정하는 정수
y 새 텍스트 필드의 y 좌표를 지정하는 정수
width 새 텍스트 필드의 넓이를 지정하는 양의 정수
height 새 텍스트 필드의 높이를 지정하는 양의 정수
instanceName.type = "dynamic"; // 텍스트 필드의 기본 속성(dynamic 또는 input)
instanceName.autoSize = "false"; // (글자수에 맞게 테두리 크기 자동 조절 true false center right)
instanceName.border = false; // (테두리)
instanceName.borderColor = 0xff0000; // (테두리 색상)
instanceName.background = false; // (배경)
instanceName.backgroundColor=0xffffff; // (배경 색상)
instanceName.textColor = 0xff0000; // (글자 색상)
instanceName.multiline = false;// (한줄또는여러줄)
instanceName.selectable = true;// (텍스트 필드를 선택할 수 있는지 여부)
instanceName.maxChars = null;// (사용자가 입력할 수 있는 최대 문자 수) (null 이면 무한대)
instanceName.length = 0; // (글자 수)
instanceName._name = ""; // (인스턴스 이름)
instanceName.variable = "";// (변수 이름)
instanceName.html = false; // (html 태그 사용 여부)
instanceName.htmlText = "";// (html 태그)
instanceName.wordWrap = tr

c# 리스트뷰에 등록된 파일 실행~
leafnaid 2007.12.09 22:32
답변 2| 조회 1,159

리스트 뷰에 폴더내의 파일들을 받아와 출력 시켰습니다.

탐색기같은걸 만들어 보았는데요, 트리 메뉴랑 리스트 뷰 메뉴까진 작성했어요.

문제는 리스트 뷰에 있는 아이템을 클릭시 실행을 시켜야 하는대요,

이건 제가 작성된 프로그램이 아닌 기본 연결된 프로그램으로 실행 시키고 싶습니다.

만약 시스템에 avi 파일이 미플과 연결되 있다면 미플을 실행 시키려구요.

해당 명령어와 리스트 뷰에 어떤 이벤트 처리를 하면 되나요?

리스트뷰에 DoubleClick 과 MouseDoubleClick 에다 다음과 같이 넣어 봤는데요,

File.OpenRead(pathdir + List_file.SelectedItems[0].SubItems[1].Text);

요렇게 넣어 봤어요. 틀린 명령어일 거라 생각은 하는데 아무리 더블 클릭 해도 무응답 인거 보면

아무래도 다른 이벤트에다 넣어야 할듯 하네요. 어디다 넣어야 하는지랑 어떤 명령어 넣어야 하는지

알려 주세요.

또한 리스트 뷰에 불러온 파일들이 직접 설정한 이미지 리스트가 아닌 시스템에 있는 본래의 아이콘으로

보여지게 하려면 어떻게 해야 하나요? 그리고 버튼을로 선택된 아이템의 이미지를 이미지 리스트가 아닌

사용자가 직접 하드에서 가져다 쓰게 하고 싶은데요. 이건 어떻게 해야 하나요?

답변해 주시면 감사하겠습니다.

신고

의견 쓰기
질문자 채택된 경우, 추가 답변 등록이 불가합니다.
re: c# 리스트뷰에 등록된 파일 실행~
gwanunjang 답변채택률 85.4%
2007.12.10 18:02
질문자인사 뭔진 잘모르겠네요., 좀더 노력해봐야 할듯...-ㅅ-

책에 파일탐색기 만들기 예제가 있는데 이렇게 씌여있네요

//~~

파일탐색기는 폴더 및 파일 아이콘을 Win32 함수인 SHGetFileInfo()로 얻어옵니다. 또한 선택한 파일을 실행하는데도 Win32 함수인 ShellExecute()를 사용합니다. 이들 함수에 대한 정보는 MSDN에서 필터링 기준을

Platform SDK로 설정하고 검색하면 얻을 수 있습니다. 파일탐색기 프로그램은 DllImport어트리뷰트 기법을 사용해 두 함수를 사용합니다.

[DllImport("Shell32.dll")]

private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi,

uint cbFileInfo, SHGFI uFlags);

[System.Runtime.InteropServices.DllImport("shell32.dll")]

public static extern int ShellExecute(int hwnd, string lpOperation, string lpFile, string lpParameters,

string lpDirectory, int nShowcmd);

~~//

출처 : 책 >> C# Programming Bible with .Net framework 3.0

Hi,

I was starting to think along the same lines as you.
By the way do you have an A level or degree in maths or something?

I came up with the following.

If point1 coordinates are x1,y1
If point2 coordinates are x2,y2
If circle/arc centre coordinates are cx,cy then>>

cx=(x1+x2)/2
cy=(y1+y2)/2

Now for distances and angles>>

Angle1 is the angle to point1
Angle2 is the angle to point2

Angle1 is given by>>

Angle1=ArcSin( (y1-cy) / ( x1-cx) ) 'Opposite/ajacent

and Angle2 by>>

Angle2=ArcSin( (y2-cy) / ( x2-cx) ) 'Opposite/ajacent


I've been looking up code to do ArcSin ( or Inverse Sine ) function
on GOOGLE.

Anyway once i get the angle values and convert to RADIANS by dividing
the angles by the following number.>>
57.2957795 which is also equal to 360/(2*PI)

and the RADIUS=SQR( ((x1-cx)^2)) + ((y1-cy)^2) )

you can then say>>

SORRY THIS CODE IS FOR VB.NET
DOWNLOAD THE EXPRESS EDITION for FREE!!
( WHICH THIS CODE SHOULD WORK WITHIN ) HERE>>

http://msdn.microsoft.com/vstudio/express/vb/


        'cx and cy are the centre coordinates of the circle.        Dim cx As Integer        Dim cy As Integer        'x2 and y2 are the plotted positions that are calculated.        Dim x2 As Integer        Dim y2 As Integer        Dim Radius As Double        Dim PI As Double        'Just a loop Count variable to go plot each point        'on the arc or circle.        Dim Count As Double        'Set up a white PEN of width=1        Dim aPen As New Pen(Color.White, 1)        Radius = SQR( ((x1-cx)^2)) + ((y1-cy)^2) )        PI = Math.PI             For Count = Angle1 To Angle2 Step 0.05 'Can be any step value.            x2 = Math.Round(Radius * Math.Sin(Count) + cx, 3)            y2 = Math.Round(Radius * Math.Cos(Count) + cy, 3)           pictureBox1.CreateGraphics.DrawLine(aPen, x2, y2, x2 + 1, y2)        Next Count


I know this method is not "ideal" for some people as i'm not using
SetPixel, but to do that I believe you need to load a bitmap first.
With the above METHOD you can plot on the FORM itself.
To do this i think the last line needs to be changed within
the FOR NEXT loop to>>

Me.CreateGraphics.DrawLine(aPen, x2, y2, x2 + 1, y2)


To go backwards (anti-clockwise), put a minus sign in either equation in the code above so it reads as>>

x2 = Math.Round(-Radius * Math.Sin(Count) + cx, 3)
'or but not in both
y2 = Math.Round(-Radius * Math.Cos(Count) + cy, 3)

You could multiply the radius by minus 1.

I'm off to give it a try....


Regards,

Dr M.

P.S. Richard, i followed the bit about a right angled line for
all of the points to plot from but the arc from any other point, other than the centre, would be a partial ellipse, sometimes
a diagonal ellipse.

요약 (Summary)

이 문서는 닷넷 프레임워크 환경과 이기종 환경 간의 소켓 통신을 위한 간략한 개요를 제시합니다. 특히 HTTP 또는 SOAP 등의 텍스트 기반의 통신이 아닌, C/C++ 개발자들이 선호하는 구조체 패킷을 이용한 통신에 초점을 두었습니다.

뿐만 아니라 이를 지원하기 위한 소켓 라이브러리(C# 2.0 지원)도 함께 제공합니다. MIT 라이센스를 채택하였으며, 라이센스에 명시된 바와 같이 상업적인 목적으로도 사용할 수 있습니다.


소개 (Introduction)

이 문서는 닷넷 프레임워크 기반의 소켓 프로그램을 작성하려는 개발자를 위해 작성되었습니다. 닷넷 개발자는 C/C++ 등으로 작성된 서버/클라이언트와 통신하기 위한 모듈 또는 소프트웨어를 제작해야 하는 상황에 부닥치게 됩니다. 닷넷 환경에서의 소켓 프로그래밍에 익숙하지 않은 개발자는 많은 어려움에 직면하게 됩니다.

이 문서는 다음과 같은 문제점을 해결하기 위한 가이드라인을 제시합니다.

  • 닷넷 환경에서 구조체를 이용한 소켓 통신 구현이 어렵습니다.
  • 닷넷 환경과 이기종 환경 간의 통신에서는 데이터의 타입 변환을 신중히 생각해야 합니다.
  • 그밖에 문자열 변환 등에서 부닥치게 되는 예기치 못한 문제들이 있습니다.

또한 닷넷 환경에서 소켓 통신을 할 때 자주 쓰이는 주요 함수 또는 패턴을 기술합니다.

이 문서의 주요 섹션은 다음과 같이 구성되어 있습니다.


시스템 요구사항 (System Requirements)

이 문서 상에 기술된 작업을 위한 시스템 요구사항은 다음과 같습니다.

  • Microsoft Windows?? 2000, Windows XP Professional, or Windows 2003 operating system

  • Microsoft .NET Framework Software Development Kit (SDK), version 1.1.

이 문서 상에 기술된 작업이 테스트된 환경은 다음과 같습니다.

  • Microsoft Windows?? 2000 Professional operating system

  • Microsoft .NET Framework Software Development Kit (SDK), version 1.1

  • Microsoft Visual Studio?? 2003 development system

  • Microsoft Windows?? XP Professional operating system

  • Microsoft .NET Framework Software Development Kit (SDK), version 2.0

  • Microsoft Visual Studio?? 2005 development system


참고 문헌 (Related Links)


누가 이 문서를 읽어야 하는가? (Who Should Read This Document?)

이 문서는 C/C++ 소켓 프로그래밍에 익숙하지만 닷넷 프레임워크 환경에서 소켓 프로그래밍을 해야 하는 개발자를 위해 가이드라인을 제시합니다.


반드시 알아야 할 것 (What You Must Know)

C/C++ 환경에서의 소켓 프로그래밍에 대한 기본적인 지식이 필요합니다. 관리되는 메모리의 구조 및 관리되지 않는 메모리의 구조에 대한 차이를 이해하고 있어야 합니다. 닷넷 기반에서 Binary 데이터를 다루기 위해 필요한 기본적인 지식이 필요합니다.


새로운 사항 (What’s New)

  1. 2006. 사용자 정의 함수 ExtendedTrim의 버그 수정.

  2. 2007.07.25. 소켓 라이브러리 추가


닷넷 환경에서 구조체는 관리되는 메모리 구조를 갖는다

일반적인 C/C++에서는 구조체를 이용하여 소켓 통신을 합니다. 다음은 인증을 위한 구조체를 정의하고, 이를 통해 통신을 하는 예제 코드입니다.

[표: 인증을 위한 패킷 구조체]

[C]typedef struct tag_BIND{char szID[16];char szPWD[16];} BIND;#define BIND_SIZE sizeof(BIND)

[표: 인증 패킷 송신 예제]

[C]if( SendData(sockfd,(char*)&packetbind,BIND_SIZE) != BIND_SIZE ){// Error Handlingcout << "ERROR : BIND 송신 실패" << endl;return 0;}

닷넷 환경에서는 위와 같이 구조체를 사용한 소켓 통신이 지원되지 않습니다.

[표: C#으로 작성된 인증 패킷 구조체

[C#]public struct BIND{public char szID[16];public char szPWD[16];};

만약 위와 같은 구조체를 선언해서 전송하면, 수신하는 측에서는 16 bytes + 16 bytes을 받아야 합니다. 그러나 실제로는 약 100 bytes의 데이터를 수신하게 됩니다. 이는 닷넷 환경에서 구조체가 관리되는 메모리 구조를 갖기 때문입니다.


닷넷 환경에서의 구조체를 이용한 소켓 통신 구현 방법

닷넷 환경에서 구조체를 이용한 소켓 통신을 지원하기 위한 방법은 크게 두 가지로 나뉩니다.

  • 마샬링(Marshaling)을 이용한 구조체 사용.
  • 바이너리 포매터(Binary Formatter)의 사용.

마샬링을 이용하면, C/C++에서와 비슷한 방식으로 소켓 프로그래밍을 할 수 있습니다. 하지만 이 문서에서는 두 번째 방법을 사용합니다.


패킷 송신 방법

다음과 같은 인증 요청 패킷을 송신해야 한다고 가정합니다.

[표: 인증 요청 패킷]

[C]typedef struct tag_BIND{int nCode;char szPWD[16];} BIND;

이러한 구조의 패킷을 보내기 위해 다음과 같은 코드가 필요합니다.

[C#]// 패킷 사이즈 public int BODY_BIND_SIZE = 4 + 16;// 인증 패킷 구조체 public struct Bind{public int nCode;public string strPWD;}// 인증 패킷 구조체를 바이트 배열로 변환하는 함수. public byte[] GetBytes_Bind(Bind bind){byte[] btBuffer = new byte[BODY_BIND_SIZE];MemoryStream ms = new MemoryStream(btBuffer,true); BinaryWriter bw = new BinaryWriter(ms);// nCode bw.Write( IPAddress.HostToNetworkOrder( bind.nCode ) );// szPWD try{byte[] btPWD = new byte[16];Encoding.Default.GetBytes(bind.strPWD,0,bind.strPWD.Length,btPWD,0);bw.Write( btPWD );}catch(Exception ex){// Error Handling }bw.Close();ms.Close();return btBuffer;}// 사용 예제Bind bind = new Bind();bind.nCode = 12345;bind.strPWD = “98765”;byte[] buffer = GetBytes_Bind(bind);socket.Send(buffer);

BinaryWriter를 사용하여 4 bytes의 Integer값과 16 bytes의 문자열을 바이트 배열에 써넣습니다. 위의 GetBytes_Bind를 실행하면 다음과 같은 구조의 바이트 배열이 생성됩니다. 이때 Integer 타입의 nCode를 Network Byte Order로 변환하는 것에 주의하십시오.

9

8

7

6

5

\0

\0

\0

\0

\0

\0

\0

\0

\0

\0

\0

파란색: Integer 타입의 nCode
녹색: String 타입의 strPWD
흰색: NULL로 구성된 바이트 배열

패킷 수신

위에서 송신한 인증 요청에 대한 응답을 다음과 같은 형태로 받는다고 가정합니다.

[표: 인증 요청 패킷]

[C] typedef struct tag_BIND_ACK{int nCode;char szPWD[16];int nResult;} BIND_ACK;

위와 같은 패킷을 수신하기 위해서는 다음과 같은 코드가 필요합니다.

[C#] public struct BindAck{public int nCode;public string strPWD;public int nResult;}public static BodyAck0 GetBindAck(byte[] btBuffer){BindAck bindAck = new BindAck();MemoryStream ms = new MemoryStream(btBuffer,false);BinaryReader br = new BinaryReader(ms);// Integer 타입의 nCodebindAck.nCode = IPAddress.NetworkToHostOrder( br.ReadInt32() );// 16 bytes의 문자열bindAck.strPWD = ExtendedTrim( Encoding.Default.GetString(br.ReadBytes(16)) );// Integer 타입의 nResultbindAck.nResult = IPAddress.NetworkToHostOrder( br.ReadInt32() );br.Close();ms.Close();return bindAck;}// 문자열 뒤쪽에 위치한 NULL을 제거한 후에 공백문자를 제거한다.public string ExtendedTrim(string source){string dest = source;int index = dest.IndexOf('\0');if( index > -1 ){dest = source.Substring(0,index+1);}return dest.TrimEnd('\0').Trim();}// 사용 예제int BIND_ACK_SIZE = 4 + 16 + 4;byte[] buffer = new byte[BIND_ACK_SIZE];if( socket.Receive(buffer) == BIND_ACK_SIZE ){BindAck bindAck = GetBindAck(buffer);}else{// ERROR HANDLINGM}

위에서 ExtendedTrim() 라는 함수를 정의해서 사용했습니다. 이 함수가 필요한 이유에 대해서는 다음 장에서 설명하겠습니다.


주요 함수

  1. System.Net.IPAddresss.NetworkToHostByteOrder(…)

    1. 요약

      네트워크 바이트 순서에서 호스트 바이트 순서로 숫자를 변환합니다. NetworkToHostByteOrder 함수는 오버로딩 되어 있어서 short, int, long 타입을 모두 변환할 수 있습니다.

    2. 설명

      서로 다른 컴퓨터에서는 멀티바이트 정수 값 내에서 바이트의 순서를 지정하는 데 서로 다른 규칙을 사용합니다. 일부 컴퓨터에서는 MSB(최상위 바이트)를 먼저 배치(big-endian 순서)하지만 다른 컴퓨터에서는 LSB(최하위 바이트)를 먼저 배치(little-endian 순서)합니다. 바이트 순서가 다르게 지정된 컴퓨터를 사용하려면 네트워크를 통해 보내는 모든 정수 값을 네트워크 바이트 순서로 보냅니다.

    3. 예제

      [C#] public void NetworkToHostOrder_Long(long networkByte){long hostByte;// Converts a long value from network byte order to host byte order. hostByte = IPAddress.NetworkToHostOrder(networkByte);Console.WriteLine("Network byte order to Host byte order of {0} is {1}", networkByte, hostByte);}
  2. System.Net.IPAddresss.HostToNetworkByteOrder(…)

    1. 요약

      호스트 바이트 순서에서 네트워크 바이트 순서로 숫자를 변환합니다. HostToNetworkByteOrder 함수는 오버로딩 되어 있어서 short, int, long 타입을 모두 변환할 수 있습니다.

    2. 설명

      여기를 참고하십시오.

  3. System.Text.Encoding.Default.GetBytes(…)

    1. 요약

      지정된 String 이나 문자의 전부 또는 일부를 바이트 배열로 인코딩한 후, 패킷을 전송합니다. Encoding 타입은 Default 외에도 여러 가지가 있습니다.

    2. 인코딩 타입

      1. Default: 시스템의 현재 ANSI 코드 페이지에 대한 인코딩을 가져옵니다.

      2. ASCII: ASCII(7비트) 문자 집합에 대한 인코딩을 가져옵니다.

      3. BigEndianUnicode

        1. 요약

          big-endian 바이트 순서로 유니코드 형식에 대한 인코딩을 가져옵니다.

        2. 설명

          유니 코드 문자는 big-endian과 little-endian의 두 가지 바이트 순서로 저장할 수 있습니다. Intel 컴퓨터 같이 little-endian 플랫폼을 사용하는 컴퓨터에서는 일반적으로 유니코드 문자를 little-endian 순서로 저장하는 것이 보다 효율적이지만 대부분의 다른 플랫폼에서는 유니코드 문자를 big-endian 순서로 저장합니다.

          유니코드 파일은 big-endian 플랫폼에서는 16진수 0xFE 0xFF로 표시되고 little-endian 플랫폼에서는 16진수 0xFF 0xFE로 표시되는 바이트 순서 표시(U+FEFF)로 구별할 수 있습니다.

      4. Unicode: little-endian 바이트 순서로 유니코드 형식에 대한 인코딩을 가져옵니다.

      5. UTF7: UTF-7 형식에 대한 인코딩을 가져옵니다.

      6. UTF8: UTF-8 형식에 대한 인코딩을 가져옵니다.

    3. 예제

      [C#]string strPWD = "password";try{byte[] btPWD = new byte[16];Encoding.Default.GetBytes(strPWD,0,strPWD.Length,btPWD,0);}catch(Exception ex){// Error Handling }
  4. System.Text.Encoding.Default.GetString(…)

    1. 요약

      지정된 바이트 배열을 지정된 인코딩 타입의 문자열로 디코딩합니다.

    2. 인코딩 타입

      인코딩 타입을 참조하십시오.

    3. 예제

      다음 예제에서는 GetString의 오버로드된 버전에 대한 사용법을 보여 줍니다. 사용할 수 있는 다른 예제를 보려면 개별 오버로드 항목을 참조하십시오.

      [C#] private string ReadAuthor(Stream binary_file) {System.Text.Encoding encoding = System.Text.Encoding.UTF8;// Read string from binary file with UTF8 encoding byte[] buffer = new byte[30];binary_file.Read(buffer, 0, 30);return encoding.GetString(buffer);}
  5. 사용자 정의 함수 ExtendedTrim(…)

    1. 요약

      NULL 종료 문자열을 유니코드 기반의 System.String 으로 변환하기 위한 함수입니다. 종료문자 NULL 이후의 문자열을 제거합니다.

    2. 함수 정의

      // 문자열 뒤쪽에 위치한 NULL을 제거한 후에 공백문자를 제거한다.public string ExtendedTrim(string source){string dest = source;int index = dest.IndexOf('\0');if( index > -1 ){dest = source.Substring(0,index+1);}return dest.TrimEnd('\0').Trim();}
    3. 설명

      아래와 같은 코드를 고려해보겠습니다.

      [C#] string strPWD = "password";byte[] btPWD = new byte[16]; try { Encoding.Default.GetBytes(strPWD,0,strPWD.Length,btPWD,0); } catch(Exception ex) { // Error Handling }

      위의 코드가 실행되면 바이트 배열 btPWD의 구조는 다음과 같습니다.

      p

      a

      s

      s

      w

      o

      r

      d

      \0

      \0

      \0

      \0

      \0

      \0

      \0

      \0

      녹색: String 타입의 strPWD
      흰색: NULL로 구성된 바이트 배열

      바이트 배열 btPWD를 다시 문자열로 변환해보겠습니다.

      [C#] string strPassword = Encoding.Default.GetString(btPWD);strPassword.Trim();Console.WriteLine(strPassword + "!");

      위의 코드에서 기대했던 출력값은 password!였습니다. 그러나 실제로 코드를 실행시켜보면 password !라고 출력됩니다. 클래스 System.String 에 정의된 Trim()함수는 문자열 양측에 놓인 공백문자는 제거하지만, NULL은 제거하지 않습니다.

      이 문제 때문에 여러 가지 기능이 예치기 않게 오작동할 수 있습니다. 특히 이벤트 로그에 NULL이 들어간 문자열을 기록하려고 시도하면, 문제가 발생합니다. 다음 예제에서 위에서 생성한 문자열을 이벤트 로그에 기록합니다.

      [C#] // Create the source, if it does not already exist.if(!EventLog.SourceExists("MySource")){EventLog.CreateEventSource("ySource", "MyNewLog");Console.WriteLine("CreatingEventSource");}// Create an EventLog instance and assign its source.EventLog myLog = new EventLog();myLog.Source = "MySource";// Write an informational entry to the event log. string strLog = String.Format("{0}{1}{2}",strPassword,Environment.NewLine,strPassword);myLog.WriteEntry(strLog);

      위의 예제에서 기대했던 출력 값은 다음과 같습니다.

      passwordpassword

      그러나 실제로는 다음과 같은 출력을 얻게 됩니다.

      password

      문자열 strLog 중간에 NULL이 포함되어 있기 때문에, 뒤에 이어지는 문자열은 기록되지 않습니다. 일반적인 C/C++ 프로그래밍에서는 처음 문자열 뒤쪽에 위치한 NULL을 제외하고, 두 번째 문자열을 연결합니다. 다음의 예제 코드를 보십시오.

      [C++] char szPassword[16];memset(szPassword,NULL,sizeof(szPassword));sprintf(szPassword,"%s","password");char szBuffer[128];memset(szBuffer,NULL,sizeof(szBuffer));sprintf(szBuffer,"%s%s",szPassword,szPassword);printf("%s",szBuffer);

      위의 코드에서 szPassword 두 개를 연결하여 szBuffer에 저장합니다. 이 경우에 다음과 같은 메모리 구조가 됩니다.

      p

      a

      s

      s

      w

      o

      r

      d

      p

      a

      s

      s

      w

      o

      r

      d

      \0

      \0

      \0

      \0

      \0

      \0

      녹색 : 첫번째 문자열
      파란색 : 두번째 문자열

      위에서 알 수 있듯이 일반적으로 C/C++ 프로그래밍에서는 NULL을 제외하고 두 문자열을 연결합니다. 그러나 닷넷에서 기본으로 제공되는 Trim() 함수는 NULL을 제외하지 않고 두 문자열을 연결합니다. 그 때문에 앞서 제시한 이벤트로그 예제에서는 다음과 같은 메모리 구조를 갖게 됩니다.

      p

      a

      s

      s

      w

      o

      r

      d

      \0

      \0

      p

      a

      s

      s

      w

      o

      r

      d

      \0

      녹색 : 첫번째 문자열
      파란색 : 두번째 문자열

데이터 타입

일반적으로 C/C++의 경우에 CPU의 종류에 따라 숫자형 데이터 타입의 크기가 달라집니다. 32 bits CPU 환경에서 Long Integer 타입은 4 bytes(32 bits)이지만, 64 bits CPU 환경에서는 8 bytes (64 bits)가 됩니다. 보통의 경우라면 닷넷 개발자는 32 bits환경의 이기종 서버/클라이언트와 통신하는 소프트웨어를 제작하게 됩니다. 이때 다음의 표를 참고하여 데이터 변환을 하도록 해야 합니다.

형식

범위

크기

.Net Framework 형식

Sbyte

-128 ~ 127

부호 있는 8비트 정수

System.SByte

Byte

0 ~ 255

부호 없는 8비트 정수

System.Byte

Char

U+0000 ~ U+ffff

유니코드 16비트 문자

System.Char

Short

-32,768 ~ 32,767

부호 있는 16비트 정수

System.Int16

Ushort

0 ~ 65,535

부호 없는 16비트 정수

System.UInt16

Int

-2,147,483,648 ~ 2,147,483,647

부호 있는 32비트 정수

System.Int32

Uint

0 ~ 4,294,967,295

부호 없는 32비트 정수

System.UInt32

Long

?9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

부호 있는 64비트 정수

System.Int64

Ulong

0 ~ 18,446,744,073,709,551,615

부호 없는 64비트 정수

System.UInt64

예를 들어 32 bits CPU 환경일지라도 .Net Framework 하에서 Long Integer 타입의 크기는 8 bytes입니다.


소켓 라이브러리

Application Block for socket communication의 역사

  1. 2005.02.03. 버전 1.0 출시.

  2. 2005.03.25. 버전 1.5 출시.

  3. 2007.07.25. 버전 2.0 출시.

    • MIT 라이센스 채택.

    • C# 2.0용으로 변환.

    • 약간의 리팩토링.

    • XML 설정 파일 지원하지 않음.

    • Microsoft Enterprise Library와 같은 외부 라이브러리에 대한 의존성 제거.


라이브러리에 대해

라이브러리를 다운로드 받은 후, Visual Studio 2005나 Visual Studio 2005 Express Edition에서 솔루션 파일을 열고 빌드하면 됩니다.

예제나 설명서를 제공하진 않지만 Tests 폴더에 단위 테스트 코드가 있습니다. 특별히 이해하기 어려운 코드가 없으니 문제 없으리라 생각합니다.

C# 문자열(System.String)을 ANSI 바이트 코드(char[])로 변환하기
  1. MemoryPacketCommandcmd=newMemoryPacketCommand();
  2. //CreateaFirstParameter.-Binary
  3. stringsource1="GoodCompany";
  4. byte[]dest1=StringToByteArray(source1);
  5. MemoryPacketParameterpacket1=newMemoryPacketParameter();
  6. packet1.ParameterName="@ByteArray1";
  7. packet1.Size=dest1.Length;
  8. packet1.Value=dest1;
  9. packet1.MpType=MpType.Binary;
  10. packet1.FixedSize=false;
  11. //AddaFirstParametertotheCommand
  12. cmd.Parameters.Add(packet1);
  13. //CreateaMemoryPacketByteArray
  14. cmd.ToBytes();
ANSI 바이트 코드(char[])를 C# 문자열(System.String)로 변환하기
  1. MemoryPacketCommandcmd=newMemoryPacketCommand();
  2. //CreateaFirstParameter.-Binary
  3. stringsourceString1="GoodCompany";
  4. byte[]source1=StringToByteArray(sourceString1);
  5. MemoryPacketParameterpacket1=newMemoryPacketParameter();
  6. packet1.ParameterName="@SomeString";
  7. packet1.Size=source1.Length;
  8. packet1.MpType=MpType.String;
  9. packet1.FixedSize=true;
  10. //AddaFirstParametertotheCommand
  11. cmd.Parameters.Add(packet1);
  12. MemoryPacketParameterCollectioncollection=cmd.FromBytes(source1);
  13. MemoryPacketParameternewParm1=(MemoryPacketParameter)collection["@SomeString"];
  14. Assert.AreEqual(sourceString1,newParm1.Value);


Introduction to Programming with Managed DirectX 9.0

by Jacek Artymiak
06/02/2003

The industry standard 3D API, OpenGL, is not the only 3D API that you can use on the .NET platform in the Microsoft Windows environment. Another choice is DirectX, which has been steadily increasing its functionality, stability, and market share among developers writing all sorts of Windows multimedia software, games, and other applications that make use of 2D and 3D graphics. While earlier versions of DirectX often left a lot to be desired, its latest incarnation, DirectX 9.0, is a serious product worth a longer look, especially if you want to target multiple Microsoft platforms: Microsoft Windows, PocketPC, or X-Box.

With DirectX 9.0, you have a choice of two 3D APIs on the Microsoft Windows platform, but that doesn't mean that it must be one or the other. Even if you stay with the OpenGL for 3D API (it's an industry standard after all, and there's a lot of information and talent to draw upon) you may still need DirectX's other components that you will simply not find in OpenGL. Direct3DX is only a part of the DirectX puzzle, and other pieces are equally interesting. If you have never considered using DirectX before, the following summary will give you a better view of what's in store:

  • Direct3D Graphics: The DirectX 3D API. You will use it for 3D graphics and animation programming.
  • DirectDraw: Direct, fast, low-level access to display the hardware's memory, blitter, overlays, etc. Essential in game programming, where timing is everything.
  • DirectInput: Support for various input devices (keyboard, mice, joysticks, paddles, steering wheels, pedals, etc.), including devices with force feedback.
  • DirectSound: Advanced sound playback and recording, including support for three-dimensional sound and sound effects. Works with WAV files; for more playback options, use DirectMusic.
  • DirectMusic: Handles dynamic sound tracks, 3D sound positioning, and hardware acceleration. Uses MIDI, WAV, and DirectMusic Producer tracks. You can think of DirectMusic as the playback side of DirectSound on steroids.
  • DirectPlay: Support for networked gaming, including support for real-time voice conferencing. This could have applications that go beyond gaming.
  • DirectShow: Playback and capture of audio and video streams. This author's favorite feature is support for TV cards.
  • DirectSetup: Simple API for setting up DirectX on user's machines.

Just like OpenGL, DirectX too used to be aimed at developers coding in C/C++. That's natural, because compiled C/C++ code is faster than interpreted Visual Basic. However, Microsoft knows that in order to make .NET a success, they need to attract as many developers as they can. To do that, all of their crucial APIs must be available in managed form, so they can be easily incorporated into applications written in C#, Visual Basic .NET, and other .NET languages.

The recently released DirectX 9.0 SDK is a clear sign that Microsoft wants to broaden the use of DirectX among developers who do not speak C++ and MFC programmers. The official release of the DirectX 9.0 SDK is available in three forms:

  • DirectX 9.0 SDK: The whole package for C/C++, C#, Visual Basic .NET, and other languages available on the .NET platform.
  • DirectX 9.0 SDK for C#: A cut-down, managed version of the DirectX 9.0 SDK for programmers writing C# code.
  • DirectX 9.0 SDK for Visual Basic .NET: A cut-down, managed version of the DirectX 9.0 SDK for programmers writing Visual Basic .NET code.

The managed versions (for C# or VB.NET) can also be used in Visual C++ (when writing managed code), and JScript .NET applications. Other languages available for the .NET platform ought to be able to make use of them, as well. This lowers the barrier of entry for those programmers who code in C# or VB .NET for a living, and could potentially lead to some interesting software titles appearing on the market.

Starting managed DirectX 9.0 development is quite inexpensive; if you do not need the visual tools, you can get by with the free SDKs. But you would really be doing yourself a disservice if you did not use the Visual development products, as they really help developers manage their work better and work more efficiently.

Here's the list of tools you need to start coding with DirectX 9.0:

  • A fast PC (think at least 1GHz).
  • A decent video card with a GPU (for programming shaders), which means a recently manufactured card with the latest chips from ATI or nVidia. Older cards, like the TNT, will also work, but you will not be able to explore the joys of writing shaders, which is the latest craze in 3D graphics programming.
  • A copy of either the Microsoft Windows 2000 or XP operating system with the latest patches installed before you install other components.
  • A copy of one of the Visual Studio development environments: Microsoft Visual Studio, Microsoft Visual C++, Microsoft Visual C#, or Microsoft Visual Basic .NET. If you cannot afford them, you can try to get by with the command-line C# and VB.NET compilers that you can find in the .NET Framework SDK, but you will lose all of the handy features that these environments offer.
  • A copy of the .NET Framework 1.1 SDK (after you install it, run Windows Update to check for the latest patches).
  • A copy of the .NET Framework 1.1 Redistributable (if you plan to distribute applications for the .NET Framework 1.1).
  • A copy of the DirectX 9.0 SDK for C# or VB.NET, if you want to save space on disk, but even if you don't plan to use the full SDK, you might want to install it anyway, because sometimes reading C++ code can help you understand the things that are not explained well enough in the SDK d0cumentation. Again, after you install this component, check for updates.
  • A copy of the DirectX 9.0 Redistributable if you plan to distribute your applications.

Despite their best efforts to provide managed versions of the whole of DirectX, Microsoft does not (yet) provide managed versions of DirectMusic, DirectShow, or DirectSetup. One additional component that you will find is a basic support for audio and video playback.

Installing the DirectX 9.0 SDK

While all components listed earlier in this article behave quite reasonably during installation, DirectX 9.0 SDK is a bit temperamental and may waste some of your time, if you let it. The following tips should help you avoid wasting time.

If you haven't already done so, update your Windows system with the latest patches from Microsoft. Next, download the latest release of the .NET Framework SDK, install it, and check for updates with Windows Update and manually, in MSDN's .NET Framework section. Now you can download your choice of the DirectX 9.0 SDK versions (full, C#, or VB.NET) and double-click on it to unpack the installation files to a temporary directory.

When you run setup, it will ask you for a path to install the SDK. There is a bug in the installer that, in some cases, does not accept the path you choose when you click on the Browse button. If the problem persists and you cannot force the installer to obey you, the solution to this problem is to quit the setup, remove temporary files, unpack the archive again, and then, when the installer asks for the path, change C:\DXSDK to a different path (e.g., E:\DXSDK) manually, by typing it into the Path text field.

Another strange thing that you might run into is a problem with DLL locations. The DirectX DLLs are put into the C:\WINDOWS\assembly\GAC directory, where they are essentially inaccessible to your development environment, be it Visual C# or Visual Basic .NET. It doesn't always happen, but if you open a sample project from the DirectX 9.0 SDK and you see exclamation marks in the References list next to Microsoft.DirectX libraries, then that's the sign of this particular installer misbehavior. Fortunately, it is very easy to fix this problem. Simply open the command line (console) window and type:

cd c:\windows\assembly\gacdir

and you should see this:

Microsoft.DirectXMicrosoft.DirectX.AudioVideoPlaybackMicrosoft.DirectX.DiagnosticsMicrosoft.DirectX.Direct3DMicrosoft.DirectX.Direct3DXMicrosoft.DirectX.DirectDrawMicrosoft.DirectX.DirectInputMicrosoft.DirectX.DirectPlayMicrosoft.DirectX.DirectSound

The DLLs we are looking for are located in subdirectories with long names like:

Microsoft.DirectX.Direct3D\1.0.900.31bf3856ad364e35\    Microsoft.DirectX.Direct3D.dll

Create a normal folder in your chosen location and copy each DLL to it. Then, update the References in your project and Build a sample application. Everything should work fine now.

Note: If you downloaded the DirectX 9.0 Redistributable, do not install it, but keep it on CD-R until you have your application ready for distribution. It contains files that Microsoft lets developers distribute to end users, and is of not much use to programmers. It's the same story with the NET Framework Redistributable.

Where now?

Programming with Managed DirectX 9.0 is currently a somewhat unexplored territory, and you will need a good guide to help you along. Your first resource will be various places on the Web and the C/C++ code in the SDK itself. Good books on this subject are yet to appear, but that should not be the case for too long.

Note that programming with Managed DirectX 9.0 is something that you should attempt after you master programming C# or VB.NET, or you will find it a frustrating experience. O'Reilly has published very good books on this subject: .NET Framework Essentials, .NET Windows Forms in a Nutshell, C# Essentials, and VB.NET Language in a Nutshell ought to be your essential reading if you are new to .NET.

To get a better understanding of computer graphics, get a copy of Computer Graphics: Principles and Practice in C or Computer Graphics. Also, the Cg Tutorial is an excellent introduction to the world of real-time shader programming techniques.

If you want to get deep into the subject, consider SIGGRAPH membership. It is an inexpensive way to gain access to a vast library of SIGGRAPH proceedings, which are a goldmine of ideas.

Happy coding!

Jacek Artymiak started his adventure with computers in 1986 with Sinclair ZX Spectrum. He's been using various commercial and Open Source Unix systems since 1991. Today, Jacek runs devGuide.net, writes and teaches about Open Source software and security, and tries to make things happen.


Return to ONDotnet.com


Environment: DirectX, Windows

DirectX Programming in C#

A little background info:

DirectX projects require more processing power from the computer and they could become really complex because of all the math that is required.

Most DirectX projects are games, but it isn't only limited to games. So for these types of projects it is necessary to keep everything simple and get everything that is not used out of the actual program. Performance is also another issue but only is required for larger, more complex programs.

Requirements

This project was created using Microsoft Visual Studio 2005, if you don't have it, you could try using earlier versions but I don't know if it will work the same way. If you don't have Microsoft Visual Studio 2005 or it is just too expensive you can get a free version on http://msdn.microsoft.com/vstudio/express/visualcsharp/. You will also need the DirectX SDK which can be found on http://msdn.microsoft.com/directx/sdk/.

Programming

This article is intended to be a sort of step by step tutorial to start writing a program for DirectX using C#.

First open Microsoft Visual Studio 2005 and create an empty C# project. Insert a new class into your project. Next you can delete or comment the following 2 lines of code:

using System.Collections.Generic;
using System.Text;

You can also remove the following references from your project:

System.Data System.Xml

You have to specify that the program is a windows program so go to Project-> Project Properties. Put the output type as Windows Application.

Next we have to add the necessary DirectX resources for this project. Put the namespaces in the beginning of the file:

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

Now go to the add reference dialog and click browse. Go to the directory you installed the DXSDK into and go to the "developer runtime" folder then go to x86 folder then go to the "DirectX for Managed Code" folder. Select the Microsoft.DirectX.Direct3D.DLL, Microsoft.DirectX.Direct3DX.DLL and Microsoft.DirectX.DLL references and click ok. Next go to add reference again and select System.Drawing and System.Windows.Forms reference. Now you have the project set up for DirectX.

You start off with:

Device DX_Device = null; // Drawing device

to make the drawing device. Next you have to put the information for your window into the constructor:

public UsingDirectX()
{
this.ClientSize = new Size(256,256); // Specify the client size
this.Text = "My First DirectX Program"; // Specify the title
}

Next you must tell the device how to render to the screen and handle any exceptions.

public bool InitializeDirect3D()
{
try
{
PresentParameters pps = new PresentParameters();
pps.Windowed = true; // Specify that it will be in a window
pps.SwapEffect = SwapEffect.Discard; // After the current screen is drawn, it will be automatically // deleted from memory
DX_Device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, pps); // Put everything into the device
return true;
}
catch(DirectXException e)
{
MessageBox.Show(e.ToString(), "Error"); // Handle all the exceptions
return false;
}
}

The next function handles the main rendering that is done all in one neat package.

private void Render()
{
if(DX_Device == null) // If the device is empty don't bother rendering
{
return;
}

DX_Device.Clear(ClearFlags.Target, Color.White, 1.0f, 0); // Clear the window to white
DX_Device.BeginScene();

// Rendering is done here

DX_Device.EndScene();
DX_Device.Present();
}

The main function is what its name implies. It is the main function were everything in our program takes place, including the message loop.

static void Main()
{

UsingDirectX form = new UsingDirectX(); // Create the form
if (form.InitializeDirect3D() == false) // Check if D3D could be initialized
{
MessageBox.Show("Could not initialize Direct3D.", "Error");
return;
}
form.Show(); // When everything is initialized, show the form
while(form.Created) // This is our message loop
{
form.Render(); // Keep rendering until the program terminates
Application.DoEvents(); // Process the events, like keyboard and mouse input
}
}

I hope you learned the basics of creating a simple directx program. All this program does is basically set up a loop and keep rendering, or in this case just clearing the screen to white since there is no rendering being done. Full code to this project can be found here.


Attachments

Project Files First DirectX Sample

1

+ Recent posts