opengl+mfc+vs2008

9902 단어
프로그램 작성 및 수정
-- - 단일 문서 등록 정보 외에 다른 모든 기본 선택을 사용하는 MFC SDI Windows 응용 프로그램 Text를 설정합니다.메뉴 프로젝트에서 Settings 대화상자를 열고 링크 속성 페이지의 Object/library modules 편집 상자에 Opengl32를 추가합니다.lib glu32.lib glaux.lib 세 개의 GL 라이브러리우리는 이 라이브러리 함수를 이용하여 도형 편집 작업을 완성한다.
----VC++의 AppWizard에서 생성된 SDI 응용 프로그램이 OpenGL 드로잉을 사용할 수 있도록 다음과 같은 수정이 필요합니다.
----1.PreCreateWindow 함수 설명
----OpenGL 창에는 WS 가 있어야 합니다.CLIPCHILDREN(모 윈도우를 생성하는 데 사용되는 Windows 스타일, 하위 윈도우를 다시 그릴 때 덮어쓰는 영역을 자르는 데 사용) 및 WSCLIPIBLINGS(하위 창을 생성하는 데 사용되는 Windows 스타일, 다시 그릴 때 다른 하위 창이 덮어쓰는 영역을 자르는 데 사용) 두 가지 스타일.또한 창 클래스 속성에는 CS 을 포함할 수 없습니다.PARENTDC 스타일.구체적인 절차는 다음과 같다.

BOOL  CTextView::PreCreateWindow
(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs

//An OpenGL window must be created with the following flag 
// and must not include CS_PARENTIDC for the class style.
  cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN;

    return CView::PreCreateWindow(cs);
}

----2.Oncreate 함수에서 픽셀 형식 정의 PIXELFORMAT 및 RC 만들기
-- -- 창에서 OpenGL 드로잉을 지원하려면 창을 초기화해야 합니다.여기에는 픽셀 형식 PIXELFORMAT 정의 및 RC 작성, OpenGL에 적합한 픽셀 형식 지정, 음영처리된 컨텍스트 작성 및 창의 장치 컨텍스트 연관 등이 포함됩니다.음영처리된 컨텍스트는 현재 음영처리된 환경에 대한 정보를 저장합니다.Oncreate에서 다음과 같은 자체 뷰포트 멤버 함수 SetupPixelFormat()를 호출할 수 있습니다.

BOOL CTextView::SetupPixelFormat()
{
//Create a rendering context
CDC*	m_pDC=GetDC();
if(m_pDC==NULL)	//failure to get DC
{
	MessageBox(“Could't get a valid DC.");
	return FALSE;
}

//Default pixel format is a single-buffered,
//OpenGL support hardware-accelerated,RGBA mode format
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),//Structure size.
   1,						
  	// Structure version number.Property flags(    ):
  PFD_DRAW_TO_WINDOW |	// support window
   PFD_SUPPORT_OPENGL |	// support OpenGL
   PFD_DOUBLEBUFFER,					
   PFD_TYPE_RGBA,	// RGBA type
   24,		// 32-bit color.
0, 0, 0, 0, 0, 0,	// Not concerned with these:      
0,		// No alpha : alpha  
0,		// Shift bit ignored:     
0, 0, 0, 0, 0,// No accum buffer:      
   32,	// 32-bit depth buffer.
0,		// No stencil:     
0,		// No auxliliary buffers:     
PFD_MAIN_PLANE,	// Main layer type.:    
0,		// Reserved.:     
 0, 0, 0	// Unsupported.:      
};
	int nPixelFormat=
ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd);
if( nPixelFormat ==0)
{
	MessageBox(“ChoosePixelFormat failed.");
	return FALSE;	
}

if(SetPixelFormat(m_pDC->GetSafeHdc(),
    nPixelFormat,&pfd)==0)
{
	MessageBox(“SetPixelFormat failed.");
	return FALSE;	
}

	if( (m_hRC=wglCreateContext(m_pDC->
      GetSafeHdc())) ==0)
	{
	MessageBox(“wglCreateContext failed.");
	return FALSE;
	}
	if( (wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC)) ==0)
	{
	MessageBox(“wglMakeCurrent failed.");
	return FALSE;
	}

	if(m_pDC)	ReleaseDC(m_pDC);
	return	TRUE;
}

----3.Oncreate() 함수에서 초기화 배경 함수 InitializeOpenGL() 호출

void CTextView::InitializeOpenGL()
{
	glClearColor(0.2f,0.2f,0.2f,0.0f);
	glClearDepth(1.0);
	glDepthFunc(GL_LESS);
        glEnable(GL_DEPTH_TEST);
	glShadeModel(GL_SMOOTH);
}

----4.Oncreate()에서 타이머 시작
    SetTimer(0,40,NULL);
----5.WM 수신 중SIZE 메시지 시 장면 크기를 다시 계산하려면 OnSize를 사용하여 그래픽 디스플레이 모드를 설정합니다.
-- 물체가 적절하게 표시되도록 투영하고 뷰포트를 결정하는 작업을 거쳐야 한다.

void CTextView::OnSize(UINT nType, int cx, int cy) 
{
CView::OnSize(nType, cx, cy);
	
// TODO: Add your message handler code here
//Save the wide and height of the current window Client
GLsizei nWidth=(GLsizei)cx;	
GLsizei nHeight=(GLsizei)cy;
ratio=(double)cx/(double)cy;

//Coupute the aspect ratio
GLdouble dAspect=(GLdouble)nWidth/(GLdouble)nHeight;

glViewport(0,0,nWidth,nHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective
 (FOV,dAspect,NEARPLANE,FARPLANE);
		
glMatrixMode(GL_MODELVIEW);	
glLoadIdentity();
}

----6.OnDraw()에서 DrawScene()을 간단하게 호출하여 OpenGL 함수를 실행합니다.

void CTextView::OnDraw(CDC* pDC)
{
	CTextDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// TODO: add draw code for native data here
	DrawScene();
	//Invalidate();
}

----7.창을 취소할 때 위아래 문장을 삭제하고 타이머를 취소합니다

void CTextView::OnDestroy() 
{
	CView::OnDestroy();
	
     // TODO: Add your message handler code here
     //This call makes the current RC not current
	if(wglMakeCurrent(0,0)==FALSE)
	MessageBox(“wglMakeCurrent failed.");
	
	//delete the RC
	if(m_hRC && (wglDeleteContext(m_hRC)==FALSE))
	MessageBox(“wglDeleteContext fail.");	
	KillTimer(1);	
}

----8.40ms 타이머 시간이 되면 전체 장면의 고객 구역을 간단하게 무효화하여 다시 그립니다

void CTextView::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
Invalidate();
CView::OnTimer(nIDEvent);
}

인터페이스 수정
----메뉴 IDR 삭제MAINFRAME에서 File에서 Exit 메뉴 항목을 제외한 모든 옵션을 추가하고 'GDI 텍스트 보이기', '목록 제작 텍스트', '목록 3차원 텍스트' 세 가지 메뉴 항목을 추가하여 적절한 ID를 할당합니다.ClassWizard를 사용하여 이 세 가지 메뉴 항목에 대해 보기 클래스에 명령 처리 함수와 인터페이스 업데이트 함수를 추가하고 GDI 문자에 해당하는 함수를 다음과 같이 표시합니다.

void CTextView::OnGdiText() 
{
    // TODO: Add your command handler code here
	m_iWhichText=0;
	Invalidate();
}

void CTextView::OnUpdateGdiText(CCmdUI* pCmdUI) 
{
// TODO: Add your command update UI handler code here
if(m_iWhichText==0)	pCmdUI->SetCheck();
else pCmdUI->SetCheck(0);
}

----Draw3Dtext(), DrawListText(), DrawGdiText() 세 함수를 세 가지 다른 텍스트 그리기 방법에 추가합니다.장면을 그리는 데 사용되는 DrawScene() 함수를 추가합니다.DrawScene() 함수에서 miWhichText가 0, 1, 2일 경우 각각 DrawGdiText(), DrawListText(), Draw3Dtext()를 호출하여 텍스트를 표시합니다.구체적인 함수는 다음과 같습니다.

void CTextView::OnDraw(CDC* pDC)
{
	CTextDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

     // TODO: add draw code for native data here
	DrawScene();
     //Invalidate();
}

void CTextView::DrawScene()
{
 glClear
(GL_COLOR_BUFFERBIT|GL_DEPTH_BUFFER_BIT);
	
	glPushMatrix();
        glTranslatef(0.0f,0.0f,-FARPLANE);
	//TextureMap();
	glPopMatrix();	
	glPushMatrix();
	glTranslatef
 (0.0f,0.0f,-(FARPLANE+NEARPLANE)/2);

	if(m_iWhichText==1) DrawListText();
	if(m_iWhichText==2) Draw3DText(); 
 	glPopMatrix();
	glFinish();
	SwapBuffers(wglGetCurrentDC());

	if(m_iWhichText==0) DrawGdiText();
}

GDI 디스플레이 텍스트
--wglGetCurrentDC() 함수를 호출하여 현재 장치 상하문을 가져오고 TextOut 함수로 텍스트를 표시하지만 DoubleBuffer 모드에서 그리는 함수는 glFinish()와 SwapBuffers(wglGetCurrentDC()) 함수 다음에 호출해야 합니다. 그렇지 않으면 깜박임이 발생하고 OpenGL을 그리기 전에 GDI 함수를 사용하며 깜박임을 제거하려면 SingleBuffer 모드만 사용해야 합니다. 구체적인 함수는 다음과 같습니다.

void CTextView::DrawGdiText()
{
HDC		hdc=wglGetCurrentDC();
::SetBkMode( hdc, TRANSPARENT );
::SetTextColor( hdc, RGB(250,0,0) );
	
CString sState(“  GDI  。");
::TextOut(hdc,5,5,sState,sState.GetLength());
}

wglUseFontBitmaps
함수 표시 텍스트
----wglUseFontBitmaps()를 사용하여 ASCII 문자를 표시 목록에 불러온 다음 glCallLists() 함수를 사용하여 표시 목록 시퀀스를 사용하여 텍스트를 표시합니다.wglUseFontBitmaps에는 현재 사용되고 있는 DC, 몇 번째 ASCII 문자로부터 목록을 불러오기 시작하고, 목록을 불러오는 ASCII 문자수와 시작 목록의 번호가 네 개 있습니다.glListBase()는 glCallLists가 실행하는 시작 목록 일련 번호를 지정합니다.glCallLists () 에는 세 가지 인자가 있습니다. 실행 목록 서열의 개수, 목록 값의 유형, 표시할 텍스트입니다.표시할 텍스트가 문자열일 경우, 이 문자열이 제공하는 정보는 ASCII 문자를 불러오기 시작한 것과 비교되는 편이량입니다. 따라서 최종적으로 보이는 ASCII 문자는glListBase () 에서 지정한 목록 시작 번호가glCallLists () 를 통과한 후의 목록입니다. 따라서 wglUseFontBitmaps의 몇 번째 ASCII 문자부터 목록 인자,glListBase () 에서 지정한 glCallLists가 실행하는 시작 목록 시퀀스 번호와 glCallLists () 에서 표시할 텍스트 파라미터는 최종 디스플레이 결과에 영향을 줄 수 있습니다.ASCII 문자가 표시되므로 한자를 표시할 수 없습니다.glRasterPos3f 함수는 OpenGL 뷰포트 좌표계 아래에서 오프셋을 결정합니다.구체적인 함수는 다음과 같습니다.

void CTextView::DrawListText()
{
wglUseFontBitmaps(wglGetCurrentDC(),0,256,1000);
glListBase(1000);
glRasterPos3f(-5.0f,0.0f,0.0f);
glCallLists(20,GL_UNSIGNED
 _BYTE,“Draw with List Text."); 
}

wglUseFontOutlines
함수 3D 문자 표시
----wglUseFontOutlines를 사용하여 OpenGL에 3D 문자를 표시할 수 있습니다.그것의 사용법은 wglUseFontBitmaps 함수와 대체적으로 같지만, 계산 매개 변수, 글꼴 깊이, 표시 방식, 글꼴을 불러오는 캐시 네 개의 매개 변수가 많고, 트루타입 글꼴만 보일 수 있으며, 표시하기 전에 글꼴 형식을 선택해야 한다.구체적인 함수는 다음과 같습니다.

void CTextView::Draw3DText()
{
GLYPHMETRICSFLOAT agmf[256]; 
// create display lists for glyphs 0 through 255
// with 0.1 extrusion and default deviation. 
//The display list numbering starts at 1000 
  (it could be any number) 
wglUseFontOutlines(wglGetCurrentDC(),
   0,255,1000,0.3f,0.8f, WGL_FONT_LINES ,agmf); 
	 
// Set up transformation to draw the string 
	glTranslatef(-15.0f,0.0f,0.0f);
	glScalef(4.0f, 4.0f, 4.0f); 
	// Display a string 
	glListBase(1000);
// Indicates the start of display lists for the glyphs
// Draw the characters in a string 
	
glCallLists(26, GL_UNSIGNED_BYTE,
 “Draw outline list 3D text.");	
}

좋은 웹페이지 즐겨찾기