Presentation is loading. Please wait.

Presentation is loading. Please wait.

1.비디오 메모리 잠그기 2.화면에 픽셀찍기 학습목표

Similar presentations


Presentation on theme: "1.비디오 메모리 잠그기 2.화면에 픽셀찍기 학습목표"— Presentation transcript:

1 1.비디오 메모리 잠그기 2.화면에 픽셀찍기 학습목표
이번절에서는 평면을 만든후에 평면을 잠그고 평면에 데이타값을 복사해 넣어서 정확한 위치에 픽셀을 찍는원리와 프로그램코드를 공부해보기로하겟읍니다 픽셀은 선으로이어지고 선은 면으로 이어지니 기초를 충실히 딱아야하겟읍니다

2 첫번째 예제 – 화면에 픽셀찍기 모니터의 마지막 줄은 비디오 메모리상에 며번째 바이트인가???????? 640* 비트모드의 스크린 화면에 어떤점을 찍을려면 디스플레이모드가 해상도 640*480 이고칼라 뎁스가 8비트로로 셋팅되어져 있다고 가정한다고 팔레트를 사용하지 않는다면 먼저 화면에 관계되는 비디오 메모리의 첫번째 포인터를 얻어야한다 그리고 한바이트안에 래드 ,그린, 블루 값들을 각각 세팅해 넣어야하고 원하는 곳에 이점을 디스플레이하기위해서는 화면상에 한라인에 소요되는 비디오 메모리의 피치를 알아야한다 왜냐면 비디오 메모리리는 연속적인 메모리 구조를 가지기 때문이다 위그림과 같이 연속적인 메모리구조를 선형구조를 가진다고 이야기한는데 모니터의 한줄을 찍을려면 비디오메모리상에는 몇바이트를 소모하는지 알아야 다음줄을 찍을수 잇기 때문이다

3 Game_Init() { LPDIRECTDRAW lpDD; if(FAILED(DirectDrawCreate(NULL,&lpDD,NULL))) return (0); if(FAILED(lpDD->QueryInterface(IID_IDirectDraw4,(LPVOID *)&lpdd4))) return (0); lpDD->Release(); if(FAILED(lpdd4->SetCooperativeLevel(m_hWnd, DDSCL_EXCLUSIVE| DDSCL_FULLSCREENDDSCL_ALLOWMODEX|DDSCL_ALLOWREBOOT))) return (0); if (FAILED(lpdd4->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0))) return(0); DDSURFACEDESC ddsd; DRAW_INIT_STRUCT(ddsd); //표면 구조체 초기화와 만들 표면 묘사 ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if(FAILED(lpdd4->CreateSurface(&ddsd,&lpddsprimary,NULL))) return (0); return 1; } 전반적인 코딩의 흐름 위의 그림과 같은 전반적인 흐름을 이해하면서 코딩을 분석하자 Game_Init() 에서하는일은 전반적인게임루틴에서팔요한 다이렉트 드로우객체를 만들고 윈도우 레벨을 전체화면으로할것인지그렇지 않을것인지 설정하는부분과 디스플레이 모드설정부분 그리고 DDSURFACEDESC2구조체를 이용한 주평면의 생성하는부분이 Game_Init() 에서 하는일이다 LPDIRECTDRAW lpdd4; LPDIRECTDRAWSURFACE lpddsprimary; LPDIRECTDRAWPALETTE lpddpal ;

4 Int Game_Main() { DDSURFACEDESC ddsd; DDRAW_INIT_STRUCT(ddsd); if(FAILED(pddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL))) return 0; int lpitch16=(int)(ddsd.lPitch>>1); USHORT*video_buffer=(USHORT*)ddsd.lpSurface; int Red,Blue,Green,x,y; for(int i=0;i<1000;i++) { Red=rand()%255; Blue=rand()%255; Green=rand()%255; x=rand()%640; y=rand()%480; Plot_Pixel_Faster16(x,y,Red,Blue,Green,video_buffer,lpitch16); } if(FAILED(lpddsprimary->Unlock(NULL))) return 0; return 1; Game_Main()함수에서하는일은 주평면을 잠궈서 주평면의 첫번째 포인터를 얻은후 픽셀을 찍을 색을 랜덤하게 설정한후 주평면으 첫번째 포인터와 함깨 랜덤한 색을 Plot_Pixel_Faster16()함수의 인자를 통해 건네주는 역할을한다

5 비디오 메모리 잠그기 HRESULT Lock( LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent ); 첫번째 인자는 잠귈 영역을 표시한다 만일 NULL이면 전체 화면에 대해 잠근다 두번째인자는 DDSURFACEDES2 구조체 포인터 로서 잠그는 평면 정보를 이 구조체에 복사한다 세번째 인자는 컨트롤 플래그로서 아래 표에 있는 값을 준다 네번째 인자는 확장기능을 대비한것으로 NULL값을 대입한다 주 평면의 비디오 메로리에 직접 접근하기 위해서는 Lock()함수를 이용한다 이 함수의 첫번째 인자는 잠귈 영역을 표시한다 만일 NULL이면 전체 화면에 대해 잠근다 두번째인자는 DDSURFACEDES2 구조체 포인터 로서 잠그는 폄면 정보를 이 구조체에 복사한다 세번째 인자는 컨트롤 플래그로서 아래 표에 있는 값을 준다 네번째 인자는 확장기능을 대비한것으로 NULL값을 대입한다 그림과 같이 주평면을 잠그면 구조체의 인자pSurface멤버에 이비디오 메모리의 첫번째 포인터를 알으켜 주므로 이것을 가지고 일반 메모리다루듯이 데이터를 읽어올수도 있고 복사할수도 있다 주의 할것은 데이터를 다룬후 반드시 UnLock()함수를 호출해 모니터로 다시그릴수있게 해주어야한다 DDSURFACEDESC ddsd; DDRAW_INIT_STRUCT(ddsd); if(FAILED(pddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL))) return 0; USHORT*video_buffer=(USHORT*)ddsd.lpSurface;

6 화면에 픽셀찍기(계속) 화면에 점을 원하는곳에 표현하기위해서는 1,디스플레이모드를 알아야한다 즉 픽셀당 먗바이트를 쓰고 있는지알아야한다 2 주평면의 첫번째 포인터에 접근해야한다Lock(),InLock() 3 한라인을 찍기위해 비디오 메모리상에 몇바이트를 쓰는지 알아야한다 밑에 그림은 간단한 모니터를 표현한것이다 모니터는 디스플레이 모드가 10*10 /8비트모드 로 설정되어있다고 가정하고 주평면을 만들면 피치는 한라인을찍기위한 비디오 메모리의 바이트수를 의미하니 피치=10이 될것이다 그럼 이비디오 메모리의 첫번째 포인터를 Lock()함수를 이용해얻었다면 Lock()함수는 void*형을 리턴하기 때문에 알맞은 형으로 타입캐스트하여 사용하면 될것이다 따라서 모니터 좌표 X=2,Y=0에 해당하는 비디오 메모리의 배열형은 (char*)pa[2]가될것이다

7 화면에 픽셀찍기(계속) 다음과 같이 디스플레이 모드가 5*5 /16비트모드 와 같다면 위의그림과 같이 될것이다 그럼X=1,Y=2의 빨간점의 실제 비디오 메모리는 어디에 위치할까 이 계산은 위의 공식처럼 행하면 되겟다 실제 비디로 메모리 포인터를 (ushort*)으로 타입캐스트하면 배열로 표현하면 11번째 배열이다 그럼 모니터 좌표만으로 11번째 배열을 어떻게 알아낼까 pa[X+Y*(피치/2)]과 같은 공식을 이용해서 알아내면 쉽게 메모리 좌표를 얻을수 있다

8 16 비트 칼라값을 위한 매크로 8 비트 모드일때 픽셀 찍기 16 비트 칼라값을 위한 매크로 는 위와 같이 정의 하여 매크로 함수로 만들어 놓으면 편리하다 그리고 Game_Main() 마지막줄에 호츨되는 Plot_Pixel_Faster16()함수는 8비트 모드일때 그리고 16 비트 모드일때 함수의 인자를 달리하여 비디오메모리의 원하는 곳에 픽셀 값을 입히면 되겟다 16 비트 모드일때 픽셀찍기

9 프로그램 실행 프로그램을 실행하면 다음과 같이 풀화면으로 출력되고 픽셀칼라값이 랜덤하게 찍히는것을 볼수 있다 그리고
프로그램을 실행하면 다음과 같이 풀화면으로 출력되고 픽셀칼라값이 랜덤하게 찍히는것을 볼수 있다 그리고 윈도우 스타일을 팝업윈도우스타일로 바꾼다 화면윈도우가 풀화면으로 출력되는동시에 다이렉트X프로그램이 실행이된다 물론 이것을 꼭 이렇게 바꿀 필요는없지만 잠시나마 이렇게 안하면 작은윈도우가 보이고 풀화면이 뜨기때문에 눈에 거슬리는것을 방지하기 위해서이다 윈도우 스타일을 팝업윈도우스타일로 바꾼다 화면윈도우가 풀화면으로 출력되는동시에 다이렉트X프로그램이 실행이된다 물론 이것을 꼭 이렇게 바꿀 필요는없지만 잠시나마 이렇게 안하면 작은윈도우가 보이고 풀화면이 뜨기때문에 눈에 거슬리는것을 방지하기 위해서이다

10 다이렉트 드로우 인터페이스 해제 마지막으로 해야할일은 다이렉트 드로우 인터페이스 해제인데 해당인터페이스의 Release()함수를 호츨해주므로서 COM을 쓰지 않는다는것을 알린다

11 단원요약 1 픽셀을 화면에 찍기위해서는 우선 주 평면을 만들고 이주평면에 데이터를 복사하기위해 평면을 잠그는함수인 Lock()함수를 이용한다 2. 평면의 정보를 알아내기위해 Lock()함수는 DDSURFACEDESC 구조체를 이용한다

12 평가 1 표면에 데이터를 복사하기위해 사용되어지는함수는 ? 2LOCK()함수는 어떤구조체를 이용하여 표면의 정보를 알아내는가?

13 답안 1.Lock()함수 2. DDSURFACEDESC 구조체


Download ppt "1.비디오 메모리 잠그기 2.화면에 픽셀찍기 학습목표"

Similar presentations


Ads by Google