좌표계변환
Model – World -(좌표계변환 + 카메라
+ 조명)- view – project – NDC – screen
좌표계변환
Euler
좌표변환 참조
lookAt
Target vector = T
Camera vector = C
Dir = T – C
Up = World.Up
Side = Up x ^Dir
이 슬라이드 쇼에는 JavaScript가 필요합니다.
Model – World -(좌표계변환 + 카메라
+ 조명)- view – project – NDC – screen
좌표계변환
Euler
좌표변환 참조
lookAt
Target vector = T
Camera vector = C
Dir = T – C
Up = World.Up
Side = Up x ^Dir
이 슬라이드 쇼에는 JavaScript가 필요합니다.
Model -(좌표변환)- World – view – project – NDC – screen
좌표변환
Digital Differential Analyzer
- x가 하나 증가할 때 마다 부동소수점 곱셈과 덧셈 연산을 하게 된다.
부동 소수점 곱셈을 피하기
에서
->
은 각각의 증가량(,
)을 더해주면 된다. 즉,
Bresenham’s Line Algorithm : Midpoint Line Algorithm
중간점을 이용하여 지점의 값을 결정
직선의 함수
Wu&Rokne algorithm : Double Step
□□□ □□□ □□□ □□■
□□□ □□■ □■■ □■□
■■■ ■■□ ■□□ ■□□
기울기 > 1/2 패턴 1 불가
0< 기울기 < 1/2 4 패턴 불가
따라서 1 과 4는 공존 불가
-결정변수
-각 단계마다.
1) d<0 패턴 1
2) d = 0 or d > 0 and d<2dy 패턴 2 (cond)
d > 2dy 패턴 3
ex) (0, 0), (2, 0) => d = 4 0 – 2 0= -2 패턴 1
Extream Faster Algorithm
DDL shift 연산으로 치환.
| ScreenDC | MemoryDC | |
| DDB Video Mem 실제화면 |
<- BitBlt-> | DIB System Mem 가상화면 |
DIB는 DDB에 맞추지만 DDB는 맞추지 않는다. 예를 들어 DDB가 16비트면 DIB는 16트로 맞춘다. 하지만 색손실이 있다. DIB는 비트블릿을 할 때 마다 DDB에 맞추어주기 때문에 속도가 느리다. (1픽셀당 7~8번 일어난다.)
그래서 DDB와 DIB의 중간영역쯤에 DIBSection을 만든다.
DIB지만 DDB 같다. 중간영역쯤에 있고, DIB지만 DDB이기때문에 변환작업이 없다. 하지만 하는 일은 DIB와 똑같다. 그리고 픽셀을 직접 수정할 수 있다. 속도와 확장성을 봤을 때 DIB섹션을 사용할 수 밖에 없다. API정복 2권에 DDB와 DIB 설명이 조금 있다.(p.1095)
Bitmap 구조
비트맵 저장
| 1Bit | 2color |
| 4Bit | 16color |
| 8Bit | 256color |
| 24Bit | RGB |
| 32Bit | RGBA |
16비트를 256색에 넣을 경우 16비트는 8,8,8 이고, 256은 16 만 들어가므로 5,6,5로 변환되어서 주로 쓰고 5,5,5,1 같은 경우 마지막 1은 알파값으로 쓴다. 이같은 경우는 콘솔에서 많이 쓴다.5,5,6 이나 6,5,5 같은 경우도 있다.32비트는 3D에 들어가면 쓴다. tag, png파일의 경우 32비트 나머지는 24비트
DIB섹션은 WM_PAINT를 사용하는 것이 아니다. 밑의 아이들은 클래스화 되어 있어야 한다.
BYTE * pBits; BITMAPINFO BitInfo; BitInfo.bmiHeader.biSize = sizeof(BITMAPINFO); BitInfo.bmiHeader.biWidth = GetWidth(); BitInfo.bmiHeader.biHeight = GetHeight(); //+원점 아래 -원점위 BitInfo.bmiHeader.biPlanes = 1;//고정 BitInfo.bmiHeader.biBitCount = 24; BitInfo.bmiHeader.biCompression = BI_RGB;//무압축 BitInfo.bmiHeader.biSizeImage = 0;//(가로*세로*3) HBITMAP hDibBitmap = CreateDIBSection( m_pModel->GetMemDC(), // handle to DC (BITMAPINFO*)&BitInfo, // bitmap data DIB_RGB_COLORS, // data type indicator (LPVOID*)&pBits, // bit values NULL, // handle to file mapping object NULL); // offset to bitmap bit values HBITMAP hOldBitmap = (HBITMAP)SelectObject(m_pModel->GetMemDC(), hDibBitmap); m_pModel->SetBits(pBits);
패딩
(width + 3) & ~ 3
Offset : 어느 곳에 점을 찍기 위해 어떻게 얼마만큼 이동해야할 지 계산할 때
x * 3 + y * BPS
*(pBits + offset + 0) = b
*(pBits + offset + 1) = g
*(pBits + offset + 2) = r
그리고 싶은 도화지에 점찍고 싶은 만큼 이동한 다음, 한 바이트마다 bgr을 찍는다. (RGB가 아닌 반대로 저장되는 것에 주의할 것.)
DIB섹션을 만들었기때문에 거기에 이미지를 그리고 화면에 출력하기
File *fp=fopen(...) // 필히 rb로 읽어야함.
if(fp==0)
{
BITMAPFILEHEADER BMFH;
BITMAPINFOHEADER BMIH;
fread(&BMFH, sizeofBITMAPFILEHEADER),1,fp); //지정한 크기만큼 파일에서 읽어옴, 그리고 비트맵파일헤더에 넣어줌
if(BMFH, bfType!=0 x4d42) //그 타입이 0 x4d42가 아니면 나가라, 저것이 비트맵 타입임)
{
fread(&BMIH, sizeof(BITMAPINFOHEADER),1,fp); //인포헤더에 있는 크기의 정보만큼 읽어서
if(BMIH.biBitcount!=24 || BMIH.biCompression != BI_RGB) //24비트인지 체크하고, 압축이 안되어 있는지 체크를 함
{
int Width = BMIH.biWidth;
int Height = BMIH.hiHeight;
int BytePerScanline = Width * 3 + 3 & ~3;
int size = BMFH.bfsize;
BYTE* pImage=(BYTE*) malloc(size); //이미지를 불러올 것을 사이즈만큼 동적할당
fread(pImage,size,1,fp); //파일에 대한 필요한 정보를 다 가져 왔으니
fclose(fp); //파일을 닫아줌
=========파일에 받아온 것을 화면에 출력===============
//int offset = 0*width*3+0;
for(int i=0, i<Height; ++i)
{
memcpy(pBits, pImage, BytePerScanline);
pImage += BytePerScanline; //<중요>위에서 바이트퍼스캔라인만큼 그리고 난 뒤 내려오는 부분
pBits += iScanline; //DIB Scanline //<중요>pBits에서는 비츠만큼 위에서 그리고 난 뒤 내려오는 부분
}