Sample_BezierPatch源码简析

来源:互联网 发布:c语言项目开发实例 编辑:程序博客网 时间:2024/05/06 13:55

 贝塞尔曲线的应用

#ifndef __BezierPatch_H__
#define __BezierPatch_H__

#include "SdkSample.h"

using namespace Ogre;
using namespace OgreBites;

class _OgreSampleClassExport Sample_BezierPatch : public SdkSample
{
public:

 Sample_BezierPatch()
 {
  mInfo["Title"] = "Bezier Patch";
  mInfo["Description"] = "A demonstration of the Bezier patch support.";
  mInfo["Thumbnail"] = "thumb_bezier.png";
  mInfo["Category"] = "Geometry";
 }

mInfo是个Ogre::NameValuePairList参数 保存的是程序刚开始运行时左边显示的介绍信息

 void checkBoxToggled(CheckBox* box)
 {
  mPatchPass->setPolygonMode(box->isChecked() ? PM_WIREFRAME : PM_SOLID);
 }

 void sliderMoved(Slider* slider)
 {
  mPatch->setSubdivision(slider->getValue());
 }

上面两个函数是程序左上角UI的处理函数 至于何时调用,那应该和Ogre内在GUI系统(通过一个叫做“tray”的实现)有关,virtual的关系。用查找的方式可以找到其基类virtual版本以及调用

protected:

#if OGRE_COMPILER == OGRE_COMPILER_MSVC
# pragma pack(push, 1)
#endif

这里的pragma pack的解释请看http://blog.csdn.net/a523330620/article/details/7257415
    struct PatchVertex
 {
        float x, y, z;
        float nx, ny, nz;
        float u, v;
    };
#if OGRE_COMPILER == OGRE_COMPILER_MSVC
# pragma pack(pop)
#endif

 void setupContent()
 {
  // setup some basic lighting for our scene
  mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
        mSceneMgr->createLight()->setPosition(100, 100, 100);

  // define the control point vertices for our patch
  PatchVertex verts[9] =
  {
   {-50, -35, -50, -0.5, 0.5, 0.0, 0.0, 0.0},
   {  0,   0, -50,  0.0, 0.5, 0.0, 0.5, 0.0},
   { 50,  35, -50,  0.5, 0.5, 0.0, 1.0, 0.0},
   {-50,   0,   0, -0.5, 0.5, 0.0, 0.0, 0.5},
   {  0,   0,   0,  0.0, 0.5, 0.0, 0.5, 0.5},
   { 50,   0,   0,  0.5, 0.5, 0.0, 1.0, 0.5},
   {-50,  35,  50, -0.5, 0.5, 0.0, 0.0, 1.0},
   {  0,   0,  50,  0.0, 0.5, 0.0, 0.5, 1.0},
   { 50, -35,  50,  0.5, 0.5, 0.0, 1.0, 1.0}
  };

通过Ogre左手坐标系点的模拟,上面的点确定的就是一块由9个顶点做成的布。从法向量的坐标值来看,这块布的正面是朝上的,只要这些自定义的法向量确定的平面是正确的即可,具体我觉得还需要空间模拟以及空间想象力。纹理坐标:对角线的纹理坐标分别是(0,0)和(1,1), 其他点的纹理坐标可以按比例设置。

  // specify a vertex format declaration for our patch: 3 floats for position, 3 floats for normal, 2 floats for UV
        VertexDeclaration* decl = HardwareBufferManager::getSingleton().createVertexDeclaration();
        decl->addElement(0, 0, VET_FLOAT3, VES_POSITION);
        decl->addElement(0, sizeof(float) * 3, VET_FLOAT3, VES_NORMAL);
        decl->addElement(0, sizeof(float) * 6, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);

顶点声明,定义了顶点的数据格式,如果没有这个声明,那么上面的PatchVertex结构就无法被识别。

addElement函数的参数:1 起始地址 2 偏移地址 3 数据格式 4 数据的类型

顶点声明以及顶点结构(例如PatchVertex)中数据的声明顺序至关重要:

位置, 混合权重, 法线, 漫反射颜色, 镜面颜色, 纹理坐标

并且如果其中有缺少项,内存中不能留白,内存地址需要紧密,例如上面的VES_POSITION和VES_NORMAL之间的内存地址。

  // create a patch mesh using vertices and declaration
        mPatch = MeshManager::getSingleton().createBezierPatch("patch",
   ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, (float*)verts, decl, 3, 3, 5, 5, PatchSurface::VS_BOTH);

创建贝塞尔曲线的函数,效果可以通过修改观察不同的效果。

        mPatch->setSubdivision(0);   // start at 0 detail

设置曲线的细节层次0 - 1之间,可能是弯曲度吧?

  // create a patch entity from the mesh, give it a material, and attach it to the origin
        Entity* ent = mSceneMgr->createEntity("Patch", "patch");
  ent->setMaterialName("Examples/BumpyMetal");
        mSceneMgr->getRootSceneNode()->attachObject(ent);

  // save the main pass of the material so we can toggle wireframe on it
  mPatchPass = ent->getSubEntity(0)->getMaterial()->getTechnique(0)->getPass(0);

  // use an orbit style camera
  mCameraMan->setStyle(CS_ORBIT);

设置相机的控制模式:CS_ORBIT 鼠标左键旋转 右键上下移动控制拉近拉远
  mCameraMan->setYawPitchDist(Degree(0), Degree(30), 250);

设置相机的初始旋转以及与原点的距离

  mTrayMgr->showCursor();

显示光标

  // create slider to adjust detail and checkbox to toggle wireframe
  mTrayMgr->createThickSlider(TL_TOPLEFT, "Detail", "Detail", 120, 44, 0, 1, 6);
  mTrayMgr->createCheckBox(TL_TOPLEFT, "Wireframe", "Wireframe", 120);

创建GUI
 }

    void cleanupContent()
    {
  mPatchPass->setPolygonMode(PM_SOLID);
  MeshManager::getSingleton().remove(mPatch->getHandle());
    }

 PatchMeshPtr mPatch;
 Pass* mPatchPass;
};

#endif

 

原创粉丝点击