查看: 1622|回复: 21

如何显示自己写的几何模型???

[复制链接]

该用户从未签到

发表于 2012-12-28 11:13:40 | 显示全部楼层 |阅读模式
本帖最后由 1162810317 于 2012-12-28 11:37 编辑

我根据程序中读取文件模型,重写了简单的几何模型,但就是会出错,不知道为什么,请大神们解释下哈!
osg::Group * root = new osg::Group () ;
        //读取文件,作为结点
        root ->addChild (cOSG::SetGeometry()) ;
        //设置场景数据结点
        mOSG->InitSceneGraph (root);
       
         mThreadHandle = (HANDLE)_beginthread(&cOSG::Render,0,mOSG);

static osg::Node *SetGeometry() ;为设置模型
未命名.jpg

该用户从未签到

发表于 2012-12-28 12:13:33 | 显示全部楼层
您应该把关键地方的代码贴出来

该用户从未签到

发表于 2012-12-28 12:27:26 | 显示全部楼层
??

该用户从未签到

 楼主| 发表于 2012-12-28 17:25:01 | 显示全部楼层
本帖最后由 1162810317 于 2012-12-29 20:48 编辑

#include "stdafx.h"
#include "MFC_OSG.h"


cOSG::cOSG(HWND hWnd) :
   m_hWnd(hWnd)
{
}

cOSG::~cOSG()
{
    mViewer->setDone(true);
    Sleep(1000);
    mViewer->stopThreading();

    delete mViewer;
}

void cOSG::InitOSG()//改写了,原来为void cOSG::InitOSG(str::string modelname;   )//
{
    // Store the name of the model to load
   // m_ModelName = modelname;原来的注释掉

    // Init different parts of OSG

   InitManipulators();
    InitSceneGraph(m);
    InitCameraConfig();
}

void cOSG::InitManipulators(void)
{
    // Create a trackball manipulator
    trackball = new osgGA::TrackballManipulator();

    // Create a Manipulator Switcher
    keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

    // Add our trackball manipulator to the switcher
    keyswitchManipulator->addMatrixManipulator( '1', "Trackball", trackball.get());

    // Init the switcher to the first manipulator (in this case the only manipulator)
    keyswitchManipulator->selectMatrixManipulator(0);  // Zero based index Value
}


void cOSG::InitSceneGraph()
{
    // Init the main Root Node/Group
    mRoot  = new osg::Group;

    // Load the Model from the model name
//  mModel = osgDB::readNodeFile(m_ModelName);原来的注释掉
          mModel =SetGeometry();//直接用自己的模型代替
    // Optimize the model
    osgUtil::Optimizer optimizer;
    optimizer.optimize(mModel.get());
    optimizer.reset();

    // Add the model to the scene
    mRoot->addChild(mModel.get());
}

void cOSG::InitCameraConfig(void)
{
    // Local Variable to hold window size data
    RECT rect;

    // Create the viewer for this window
    mViewer = new osgViewer::Viewer();

    // Add a Stats Handler to the viewer
    mViewer->addEventHandler(new osgViewer::StatsHandler);
   
    // Get the current window size
    ::GetWindowRect(m_hWnd, &rect);

    // Init the GraphicsContext Traits
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

    // Init the Windata Variable that holds the handle for the Window to display OSG in.
    osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd);

    // Setup the traits parameters
    traits->x = 0;
    traits->y = 0;
    traits->width = rect.right - rect.left;
    traits->height = rect.bottom - rect.top;
    traits->windowDecoration = false;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;
    traits->setInheritedWindowPixelFormat = true;
    traits->inheritedWindowData = windata;

    // Create the Graphics Context
    osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get());

    // Init a new Camera (Master for this View)
    osg::ref_ptr<osg::Camera> camera = new osg::Camera;

    // Assign Graphics Context to the Camera
    camera->setGraphicsContext(gc);

    // Set the viewport for the Camera
    camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height));

    // Set projection matrix and camera attribtues
    camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f));
    camera->setProjectionMatrixAsPerspective(
        30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0, 1000.0);

    // Add the Camera to the Viewer
    //mViewer->addSlave(camera.get());
    mViewer->setCamera(camera.get());

    // Add the Camera Manipulator to the Viewer
    mViewer->setCameraManipulator(keyswitchManipulator.get());

    // Set the Scene Data
    mViewer->setSceneData(mRoot.get());

    // Realize the Viewer
    mViewer->realize();

    // Correct aspect ratio
    /*double fovy,aspectRatio,z1,z2;
    mViewer->getCamera()->getProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);
    aspectRatio=double(traits->width)/double(traits->height);
    mViewer->getCamera()->setProjectionMatrixAsPerspective(fovy,aspectRatio,z1,z2);*/
}

void cOSG::Render(void* ptr)
{
    cOSG* osg = (cOSG*)ptr;

    osgViewer::Viewer* viewer = osg->getViewer();

    // You have two options for the main viewer loop
    //      viewer->run()   or
    //      while(!viewer->done()) { viewer->frame(); }

    //viewer->run();
    while(!viewer->done())
    {
        osg->reFrameUpdate();
        viewer->frame();
        osg->PostFrameUpdate();
        //Sleep(10);         // Use this command if you need to allow other processes to have cpu time
    }

     _endthread();
}
osg::Node *cOSG::SetGeometry()
{
        osg::Group * root=new osg::Group ();//geomery->geode->root
        osg::Geode * trianglegeode= new osg::Geode ();
        osg::Geometry * trianglegeometry = new osg::Geometry ();
        trianglegeode->addDrawable (trianglegeometry);
        root->addChild (trianglegeode);//把三角形加入根节点中

        //建立3个顶点
        osg::Vec3Array * trianglevertices=new osg::Vec3Array ();
        trianglevertices->push_back (osg::Vec3 (0,0,0));
        trianglevertices->push_back (osg::Vec3 (20,10,0));
        trianglevertices->push_back (osg::Vec3 (30,0,15));
        //把顶点关联到三角形中
        trianglegeometry->setVertexArray (trianglevertices);

        //决定节点的组织方式
        osg:rawElementsUInt * trianglebase=
                new osg::DrawElementsUInt (osg:rimitiveSet ::TRIANGLES ,0);
        trianglebase->push_back (2);
        trianglebase->push_back (1);
        trianglebase->push_back (0);

         //下面来设置颜色,用四元组来存放,把三个顶点关联三个颜色
        osg::Vec4Array * colors =new osg::Vec4Array ();
        colors->push_back (osg::Vec4 (1.0f,0.0f,0.0f,1.0f));//红
        colors->push_back (osg::Vec4 (0.0f,1.0f,0.0f,1.0f));//绿
        colors->push_back (osg::Vec4 (0.0f,0.0f,1.0f,1.0f));//蓝
         //建立颜色结点索引,该类是从ARRAY继承而来
        osg::TemplateIndexArray <unsigned int,osg::Array ::UIntArrayType ,3,3> *colorindexarray;
        colorindexarray=new osg::TemplateIndexArray<unsigned int,osg::Array ::UIntArrayType ,3,3>;
                colorindexarray->push_back (0);
                colorindexarray->push_back (1);
                colorindexarray->push_back (2);
       
        //设置颜色组
                trianglegeometry->setColorArray (colors);
                //设置索引
                trianglegeometry->setColorIndices (colorindexarray);
                //设置绑定方式
                trianglegeometry->setColorBinding (osg::Geometry ::BIND_PER_VERTEX );
                osg::MatrixTransform *trans=new osg::MatrixTransform ;
                trans->setMatrix (osg::Matrix ::rotate (osg::DegreesToRadians (125.0),1.0,0.0,0.0));
                 //把物体旋转125度,围绕X轴,再次加入到场景中
   //移动后再次加入几何体到根结点中,此时加入两个三角形
                trans->addChild (trianglegeode);
                root->addChild (trans);
                return (osg::Node *)root;
}

// osgmfc_geoView.cpp : Cosgmfc_geoView 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "osgmfc_geo.h"
#endif

#include "osgmfc_geoDoc.h"
#include "osgmfc_geoView.h"
#include "MFC_OSG.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// Cosgmfc_geoView

IMPLEMENT_DYNCREATE(Cosgmfc_geoView, CView)

BEGIN_MESSAGE_MAP(Cosgmfc_geoView, CView)
        // 标准打印命令
        ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
        ON_COMMAND(ID_FILE_PRINT_PREVIEW, &Cosgmfc_geoView::OnFilePrintPreview)
        ON_WM_CONTEXTMENU()
        ON_WM_RBUTTONUP()
//        ON_WM_NCCREATE()
        ON_WM_CREATE()
END_MESSAGE_MAP()

// Cosgmfc_geoView 构造/析构

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

}

Cosgmfc_geoView::~Cosgmfc_geoView()
{
}

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

        return CView::PreCreateWindow(cs);
}

// Cosgmfc_geoView 绘制

void Cosgmfc_geoView::OnDraw(CDC* /*pDC*/)
{
        Cosgmfc_geoDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
        if (!pDoc)
                return;

        // TODO: 在此处为本机数据添加绘制代码
}


void Cosgmfc_geoView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
        ClientToScreen(&point);
        OnContextMenu(this, point);
}

void Cosgmfc_geoView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
        theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// Cosgmfc_geoView 诊断

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

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

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


// Cosgmfc_geoView 消息处理程序


//BOOL Cosgmfc_geoView::OnNcCreate(LPCREATESTRUCT lpCreateStruct)
//{
//        if (!CView::OnNcCreate(lpCreateStruct))
//                return FALSE;
//
//        // TODO:  Add your specialized creation code here
//        mOSG = new cOSG(m_hWnd);
//        return TRUE;
//}


void Cosgmfc_geoView::OnInitialUpdate()
{
        CView::OnInitialUpdate();

        // TODO: Add your specialized code here and/or call the base class
                mOSG->InitSceneGraph (); //原本为mOSG->InitSceneGraph ("cow.osg"); 可以运行的       
         mThreadHandle = (HANDLE)_beginthread(&cOSG::Render,0,mOSG);
}
int Cosgmfc_geoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
        if (CView::OnCreate(lpCreateStruct) == -1)
                return -1;

        // TODO:  Add your specialized creation code here
        mOSG = new cOSG(m_hWnd);
        return 0;
}
顺便问下,在《step into Osg》中,说到实例化 m_pViewer->realize(Producer::CameraGroup::SingleThreaded); 什么意思啊??
   

该用户从未签到

 楼主| 发表于 2012-12-28 17:28:37 | 显示全部楼层
本帖最后由 1162810317 于 2012-12-29 20:48 编辑
小手一拿 发表于 2012-12-28 12:13
您应该把关键地方的代码贴出来


请问,那错误是什么意思呢???

该用户从未签到

 楼主| 发表于 2012-12-28 17:31:25 | 显示全部楼层
liuzhiyu123 发表于 2012-12-28 12:27
??

代码红色的地方貌似不对,不知道应该怎么写,????不知道如何才能让自己写的那个几何模型显示出来???

该用户从未签到

发表于 2012-12-28 18:16:53 | 显示全部楼层
我建议您先在控制台下实验看自己的程序是否正确,如果正确的话就是线程操作的安全性问题。您给出的错误信息就是非法的地址操作,不能说明什么问题

该用户从未签到

 楼主| 发表于 2012-12-28 18:39:09 | 显示全部楼层
array 发表于 2012-12-28 18:16
我建议您先在控制台下实验看自己的程序是否正确,如果正确的话就是线程操作的安全性问题。您给出的错误信息 ...

呃,,,,,我只是想把那个读取已有模型,简单的替换成自己写的模型,其他也没改什么啊????但不知道替换工程中出了什么问题???或说应该怎么去替换???

该用户从未签到

发表于 2012-12-28 20:13:44 | 显示全部楼层
   root ->addChild (cOSG::SetGeometry()) ; 这句话。。。SetGeometry()静态函数??

该用户从未签到

 楼主| 发表于 2012-12-28 21:02:32 | 显示全部楼层
buaahc 发表于 2012-12-28 20:13
root ->addChild (cOSG::SetGeometry()) ; 这句话。。。SetGeometry()静态函数??

的确,现在可以运行了,以前貌似有野指针,但没有图像,一般没有图像是什么原因啊???可以运行但没图像,貌似不太好调诶??

该用户从未签到

发表于 2012-12-28 21:43:33 | 显示全部楼层
你没有定义对象 直接使用类调用当然会有问题了。。。。没有图像啥意思,模型上面没有图像?

该用户从未签到

 楼主| 发表于 2012-12-29 09:32:37 | 显示全部楼层
buaahc 发表于 2012-12-28 21:43
你没有定义对象 直接使用类调用当然会有问题了。。。。没有图像啥意思,模型上面没有图像?

就是只有蓝色的底,上面什么都没有。就是要实例化一个对象吗???那如果是直接读取的模型的话就是读取的对象而不是类?
不对啊?geometry是COSG(新建的那个核心类)中的一个成员,也就是要实例化一个COSG 对象喽???还请多多指教谢谢!

该用户从未签到

发表于 2012-12-29 13:20:33 | 显示全部楼层
在不是静态函数的情况下要初始化对象 。。。 类就是自定义的数据类型,就相当int char double这些类型,只不过后者是系统定义的,。。。这是c++的基础知识没有什么可指教的。。。
类只是一个定义,对象就是这个类的一个实体,没有对象你对谁操作。。。
你说的geoetry是类的一个成员,就相当于人的胳膊,但是你对胳膊进行操作时,先要有这个“人”
不知道怎么解释,需要先看点c++的基础知识。。。

该用户从未签到

 楼主| 发表于 2012-12-29 15:21:08 | 显示全部楼层
本帖最后由 1162810317 于 2012-12-29 15:57 编辑
buaahc 发表于 2012-12-29 13:20
在不是静态函数的情况下要初始化对象 。。。 类就是自定义的数据类型,就相当int char double这些类型,只不 ...


我用的不是静态函数,但是只是在读取模型时做了一个替换,用自己的模型替换读取的已有模型。没涉及其他的操作,如果读取的模型出现,那我只是替换了这个模型而已,按理说也可以出来啊?当然这样也就不涉及初始化问题,就像人本来是存在的,我只是给他换了一只手而已,对吧?所以没有出现模型应该还是替换过程中出现了问题,况且如果核心类不实例化的话应该编译无法通过,现在既然能运行,那就不是实例化的问题了,应该是替换过程或者是建立模型过程出了问题,或者是其它哪里???

该用户从未签到

发表于 2012-12-29 18:19:55 | 显示全部楼层
没见你调用 InitOSG() 这个函数呢,好好捋一下思路

该用户从未签到

发表于 2012-12-29 19:09:41 | 显示全部楼层
小手一拿说到了你问题的最关键部分,怪我没有看你的源代码,只是一味的在解释 root ->addChild (cOSG::SetGeometry()) ; 这句话。。。
但是如果按你所说不是静态函数怎么会编译通过。。。这应该肯定会报错的。。。
root ->addChild (cOSG::SetGeometry()) ; 这句话明显不对。。。这违背c++语法。。。所以我猜想你还有关键代码保证了这句话。。。
根据小手一拿的说话你自己捋一下思路,看看你到底少了什么,致使其出现一个蓝屏
提示一下:viewer->setSceneData()~

该用户从未签到

 楼主| 发表于 2012-12-29 20:28:15 | 显示全部楼层
小手一拿 发表于 2012-12-29 18:19
没见你调用 InitOSG() 这个函数呢,好好捋一下思路

哦,忘说了,代码已经改过了,而且已经试过,就是读取已有的程序是有用的,但用自己的几何模型替代就是一个蓝屏,我把代码改过了了,你有空帮我看看吧,也没改什么就是用自己写的模型节点去代替读取的模型的节点。其他都不变。谢谢啦!

该用户从未签到

 楼主| 发表于 2012-12-29 20:32:05 | 显示全部楼层
buaahc 发表于 2012-12-29 19:09
小手一拿说到了你问题的最关键部分,怪我没有看你的源代码,只是一味的在解释 root ->addChild (cOSG::SetG ...

嗯嗯,我还想问下,你们以前有没有遇到这种情况??、或是有没有看到有关这样的解决方法的帖子什么的?有的话是怎样解决的???谢谢啊!

该用户从未签到

发表于 2012-12-29 22:35:27 | 显示全部楼层
蓝屏是因为场景中没有模型,你读取的模型没有加入到场景进行渲染,即没有调用viewer->setSceneData(root)
你生成一个全屏的蓝屏而不是mfc窗口蓝屏是因为 你自己写的InitCameraConfig();函数没有被调用。。。
当然这个函数里面你已经写了
    // Set the Scene Data
    mViewer->setSceneData(mRoot.get());
所以这是一个非常简单的问题甚至根本就不是什么问题,也不需要什么解决方案 只是你没有理解罢了

该用户从未签到

 楼主| 发表于 2012-12-29 22:36:27 | 显示全部楼层
谢谢大家!问题解决了!总之有收获!

该用户从未签到

 楼主| 发表于 2012-12-29 22:42:37 | 显示全部楼层
buaahc 发表于 2012-12-29 22:35
蓝屏是因为场景中没有模型,你读取的模型没有加入到场景进行渲染,即没有调用viewer->setSceneData(root) ...

谢谢,不是没调用,是模型里面少了一句话,因为其他我根本就没有改。我只是简单的用自己的模型节点去替代了读取的模型罢了,所以其他当然不会有问题。问题出在我的模型了少了一句 triangleGeometry->addPrimitiveSet(triangleBase); 加上这句就可以了,不过还是谢谢大家,总之还是有许多收获的,比如说学会了一种新的调试方法,就是一位大神说的,用osgviewer。exe去看模型,是不是有问题。然后我就转变了思路去看模型,果然被找出来了,,,,,总之,灰常感谢。在这里可以结贴了!

该用户从未签到

发表于 2012-12-30 00:10:03 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表