LOD地形设计(六)

来源:互联网 发布:java二级考试历年真题 编辑:程序博客网 时间:2024/06/10 06:24

这一节开始把前面介绍的内容放入视图类中,完成地形的显示渲染工作。我们在视图类内设置了渲染设备,摄像机,视截体,以及地形变量。

/****************************************************************************
*    Copyright Reserved by Qinge
*    Filename :LODTerrainView.h
*    Date :2008-1-30
****************************************************************************/

 

#pragma once
#include "Frustum.h"
#include "Camera.h"
#include "MyTerrain.h"

class CLODTerrainView : public CView
{
protected: // 仅从序列化创建
    CLODTerrainView();
    DECLARE_DYNCREATE(CLODTerrainView)

// 属性
public:
    CLODTerrainDoc* GetDocument() const;

// 操作
public:
    BOOL InitOpenGLSetting();
    void Render();
// 重写
public:
    virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
    virtual ~CLODTerrainView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnSize(UINT nType, int cx, int cy);
public:
    virtual void OnInitialUpdate();
private:

    //显示渲染用到的成员变量
    HGLRC m_hRC;           
    CFrustum m_Frustum;
    Camera   m_Camera;
    CMyTerrain m_Terrain;
    afx_msg void OnTimer(UINT_PTR nIDEvent);
};

#ifndef _DEBUG  // LODTerrainView.cpp 中的调试版本
inline CLODTerrainDoc* CLODTerrainView::GetDocument() const
   { return reinterpret_cast(m_pDocument); }
#endif

 

/****************************************************************************
*    Copyright Reserved by Qinge
*    Filename :LODTerrainView.cpp
*    Date :2008-1-30
****************************************************************************/

#include "stdafx.h"
#include "LODTerrain.h"

#include "LODTerrainDoc.h"
#include "LODTerrainView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CLODTerrainView

IMPLEMENT_DYNCREATE(CLODTerrainView, CView)

BEGIN_MESSAGE_MAP(CLODTerrainView, CView)
    // 标准打印命令
    ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
    ON_WM_SIZE()
    ON_WM_TIMER()
END_MESSAGE_MAP()

// CLODTerrainView 构造/析构

CLODTerrainView::CLODTerrainView()
{
    // TODO: 在此处添加构造代码

}

CLODTerrainView::~CLODTerrainView()
{
}

BOOL CLODTerrainView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: 在此处通过修改
    //  CREATESTRUCT cs 来修改窗口类或样式

    return CView::PreCreateWindow(cs);
}

// CLODTerrainView 绘制

void CLODTerrainView::OnDraw(CDC* pDC)
{
    CLODTerrainDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: 在此处为本机数据添加绘制代码
    Render();
    SwapBuffers(pDC->m_hDC);
}

// CLODTerrainView 打印

BOOL CLODTerrainView::OnPreparePrinting(CPrintInfo* pInfo)
{
    // 默认准备
    return DoPreparePrinting(pInfo);
}

void CLODTerrainView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: 添加额外的打印前进行的初始化过程
}

void CLODTerrainView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: 添加打印后进行的清除过程
}

// CLODTerrainView 诊断

#ifdef _DEBUG
void CLODTerrainView::AssertValid() const
{
    CView::AssertValid();
}

void CLODTerrainView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CLODTerrainDoc* CLODTerrainView::GetDocument() const // 非调试版本是内联的
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLODTerrainDoc)));
    return (CLODTerrainDoc*)m_pDocument;
}
#endif //_DEBUG

// CLODTerrainView 消息处理程序
BOOL CLODTerrainView::InitOpenGLSetting()
{
    USES_CONVERSION;
    float fogColor[3]={0.0,0.0,0.0};
    static PIXELFORMATDESCRIPTOR pfd =                                            // pfd Tells Windows How We Want Things To Be
    {
        sizeof (PIXELFORMATDESCRIPTOR),                                    // Size Of This Pixel Format Descriptor
        1,                                                                // Version Number
        PFD_DRAW_TO_WINDOW |                                            // Format Must Support Window
        PFD_SUPPORT_OPENGL |                                            // Format Must Support OpenGL
        PFD_DOUBLEBUFFER,                                                // Must Support Double Buffering
        PFD_TYPE_RGBA,                                                    // Request An RGBA Format
        16,                                                                // Select Our Color Depth
        0, 0, 0, 0, 0, 0,                                                // Color Bits Ignored
        0,                                                                // No Alpha Buffer
        0,                                                                // Shift Bit Ignored
        0,                                                                // No Accumulation Buffer
        0, 0, 0, 0,                                                        // Accumulation Bits Ignored
        16,                                                                // 16Bit Z-Buffer (Depth Buffer) 
        0,                                                                // No Stencil Buffer
        0,                                                                // No Auxiliary Buffer
        PFD_MAIN_PLANE,                                                    // Main Drawing Layer
        0,                                                                // Reserved
        0, 0, 0                                                            // Layer Masks Ignored
    };

    GLuint PixelFormat;                                                    // Will Hold The Selected Pixel Format   

    CDC *m_pDC=GetDC();                                // Grab A Device Context For This Window
    if (m_pDC == NULL)                                        // Did We Get A Device Context?
    {                                // Destroy The Window
        MessageBox(A2W("Failed to GetDC"));                                                                    // Zero The Window Handle
        return FALSE;                                                    // Return False
    }

    PixelFormat = ChoosePixelFormat (m_pDC->m_hDC, &pfd);                // Find A Compatible Pixel Format
    if (PixelFormat == 0)                                                // Did We Find A Compatible Format?
    {
        // Failed
        ReleaseDC(m_pDC);                            // Release Our Device Context
        m_pDC = NULL;                                            // Zero The Device Context
        return FALSE;                                                    // Return False
    }

    if (SetPixelFormat (m_pDC->m_hDC , PixelFormat, &pfd) == FALSE)        // Try To Set The Pixel Format
    {
        // Failed
        ReleaseDC(m_pDC);                            // Release Our Device Context
        m_pDC = NULL;                                            // Zero The Device Context
        return FALSE;                                                            // Return False
    }

    m_hRC = wglCreateContext (m_pDC->m_hDC);                        // Try To Get A Rendering Context
    if (m_hRC == NULL)                                                // Did We Get A Rendering Context?
    {
        // Failed
        ReleaseDC(m_pDC);                            // Release Our Device Context
        m_pDC = NULL;                                            // Zero The Device Context
        return FALSE;                                                    // Return False
    }

    // Make The Rendering Context Our Current Rendering Context
    if (wglMakeCurrent (m_pDC->m_hDC, m_hRC) == FALSE)
    {
        // Failed
        wglDeleteContext (m_hRC);                                // Delete The Rendering Context
        m_hRC = NULL;                                            // Zero The Rendering Context
        ReleaseDC(m_pDC);                            // Release Our Device Context
        m_pDC = NULL;                                            // Zero The Device Context
        return FALSE;                                                    // Return False
    }
    glShadeModel(GL_SMOOTH);                            // Enable Smooth Shading
    glClearColor(0.4f, 0.5f, 0.8f, 0.3f);                // Black Background
    glClearDepth(1.0f);                                    // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);                            // Enables Depth Testing
    glDepthFunc(GL_LEQUAL);                                // The Type Of Depth Testing To Do
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);    // Really Nice Perspective Calculations.
    glEnable(GL_FOG);
    glFogi(GL_FOG_MODE, GL_LINEAR);            // Set the fog mode to LINEAR (Important)
    glFogfv(GL_FOG_COLOR,fogColor );        // Give OpenGL our fog color
    glFogf(GL_FOG_START, 0.0);                // Set the start position for the depth at 0
    glFogf(GL_FOG_END, 30.0);
//    glEnable(GL_CULL_FACE);
//    glFrontFace(GL_CCW);
//    glCullFace(GL_FRONT_AND_BACK);
     glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
    m_Terrain.LoadRawFile("Terrain.raw");
    m_Frustum.CalculateFrustum();
    m_Camera.PosotionCamera(m_Terrain.m_nMapSize/2,800,m_Terrain.m_nMapSize/2,m_Terrain.m_nMapSize ,400,m_Terrain.m_nMapSize,0,1,0);
    m_Terrain.SetCamera(&m_Camera);
    m_Terrain.SetFrustum(&m_Frustum);

    return TRUE;
}

void CLODTerrainView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);

    // TODO: 在此处添加消息处理程序代码
    if (cy==0)                                            // Prevent A Divide By Zero By
    {
        cy=1;                                            // Making Height Equal One
    }

    glViewport(0,0,cx,cy);                                // Reset The Current Viewport

    glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
    glLoadIdentity();                                    // Reset The Projection Matrix

    // Calculate The Aspect Ratio Of The Window
    gluPerspective(45.0,(GLfloat)cx/(GLfloat)cy,0.1f,100000.0f);

    glMatrixMode(GL_MODELVIEW);                            // Select The Modelview Matrix
    glLoadIdentity();   
}

void CLODTerrainView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
    InitOpenGLSetting();
    SetTimer(1,100,NULL);
    // TODO: 在此添加专用代码和/或调用基类
}
void CLODTerrainView::Render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glPushMatrix();
//    glColor3f(1.0,1.0,1.0);
    m_Camera.Look();   
    m_Frustum.CalculateFrustum();
    m_Terrain.Render();
    glPopMatrix();
}
void CLODTerrainView::OnTimer(UINT_PTR nIDEvent)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_Camera.Update();
    Invalidate(NULL);
    CView::OnTimer(nIDEvent);
}

 

到此为止,LOD地形的学习暂告一段落,所涉及内容都是最基本的,而且很大一部分不是我的原创,是从教材中抄袭而来,目的就是学习,欢迎高手给于补充、指正!

原创粉丝点击