我想用OpenGL做一个机器臂的运动仿真,想把它的运动记录下来,现在打算是运动过程生成AVI格式的文件,我再编一个播放器的对话框。

解决方案 »

  1.   

    直接使用OpenGL做动画还是比较复杂的,建议使用针对OpenGL的封装库,比如Open Inventor.
      

  2.   

    这个还真没有了解过,我在看看Open Inventor是怎么回事,和OpenGL对比后我再看看用不用更改我的方案。谢谢你
      

  3.   

    请问,你要程序是写论文,还是工作需要?这种程序可以用OpenGL写.也可以用AVI保存。(用MFC 加OpenGL).
      

  4.   

    你是本科还是研究生?这个程序可以用MFC 做框架。再用OpenGL画出机械.有现成的类完成AVI的输出。
      

  5.   

    OpenGL方面是不太难,关键是看你用的是怎么样的机械。
      

  6.   

    你用inventor,ug ,soliworks做吧, 不要考虑自己做,太难了。
    运动仿真很难。
    哥是搞这方面开发的。
     你老师说简单,你问他怎么做。 现在的导师都是sb
      

  7.   

    我是本科生,机械的,老师还准备让我一直做下去,要是好的话就可以当做毕业设计做的。
    我现在就是用的单文档的MFC框架,OpenGL绘制并且控制机械的运动。现在主要是把路走走,看能不能走通,目前的难点是怎么把运动的动作记录下来,也就是回放动作过程,以前想着是建立数据库,我还没接触过VC的数据库,因此就想把过程通过程序输出,再通过控件显示。现在还不知道那个类能实现AVI输出。
      

  8.   

    新运动时,把上次屏幕复制为bmp,加到AVI中。
      

  9.   


    要是做软件。 应该如此  比如你用鼠标拖动手,手左一些运动(因为关节等约束,手只能做半圆周转动)。这里面涉及到1 三维模型的表示 建立 选择,图形的约束求解等等。这种情况想都不要想,灰常的难。
    要是自己学,avi问题就当不存在(很简单),vc的数据库知识估计够你折腾的。但是相比上面根本就是小儿科,你学都不知道从哪来学。
      

  10.   

    这个就是机械的仿真运动,Bmp加入到AVI中是要用转换软件吗?
    我用的是约束方程的建立来实现机械的运动,现在我的机械零件能随着我的按键做一系列运动,现在就回放卡着了,有一个星期了,我在网上也没找到相关的资料,我有点怀疑自己的思路有问题了,看了上面liangjinjing的回答,我发现我的思路还是能实现的,不过还是没有代码可以参考,这样就有点难了,我前面的程序都是参考别人的代码来编程的,要是没有相似功能的代码我还真编不出来的,我也是过完年在课余时间学习VC的。
    因此说avi在会用的人眼中还是比较简单的,相对我而言就有点难度了,呵呵。
      

  11.   

    发一个例子做代码,希望对你有用。
    CPP 文件
    #include "stdafx.h"
    #include "3DEditor.h"
    #include "AVICapture.h"#ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif//////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////AVICapture::AVICapture() :
        width(-1),
        height(-1),
        frameRate(30.0f),
        frameCounter(0),
        capturing(false),
        aviFile(NULL),
        aviStream(NULL),
        compAviStream(NULL),
        image(NULL)
    {
        AVIFileInit();
    }
    AVICapture::~AVICapture()
    {
        cleanup();
        AVIFileExit();
    }
    bool AVICapture::start(CString filename,
                           int w, int h,
                           float fps)
    {
        if (capturing)
            return false;    width = w;
        height = h;
        frameRate = fps;    if (HIWORD(VideoForWindowsVersion()) < 0x010a)
        {
            // We need to be running on version 1.1 or later
            return false;
        }    // Compute the width of a row in bytes; pad so that rows are aligned on
        // 4 byte boundaries.
        int rowBytes = (width * 3 + 3) & ~0x3;
        image = new unsigned char[rowBytes * height];     HRESULT hr = AVIFileOpen(&aviFile,
                                 filename,
                                 OF_WRITE | OF_CREATE,
                                 NULL);
        if (hr != AVIERR_OK)
        {
            MessageBox(NULL,"Erroring creating avi file for capture.","ERROR",MB_OK);
            return false;
        }    AVISTREAMINFO info;
        ZeroMemory(&info, sizeof info);
        info.fccType = streamtypeVIDEO;
        info.fccHandler = 0;
        info.dwScale = 1;
        info.dwRate = (DWORD) frameRate;
        info.dwSuggestedBufferSize = rowBytes * height;
        SetRect(&info.rcFrame, 0, 0, width, height);
        hr = AVIFileCreateStream(aviFile, &aviStream, &info);
        if (hr != AVIERR_OK)
        {
            MessageBox(NULL,"Error creating AVI stream.","ERROR",MB_OK);
            cleanup();
            return false;
        }    // Display a dialog to allow the user to select compression options
        AVICOMPRESSOPTIONS options;
        AVICOMPRESSOPTIONS* arrOptions[1] = { &options };
        ZeroMemory(&options, sizeof options);    if (!AVISaveOptions(NULL, 0, 1, &aviStream, 
                            (LPAVICOMPRESSOPTIONS*) &arrOptions))
        {
            // The user either clicked on cancel or there was an error
            cleanup();
            return false;
        }    hr = AVIMakeCompressedStream(&compAviStream, aviStream, &options, NULL);
        if (hr != AVIERR_OK)
        {
            MessageBox(NULL,"Error creating compressed AVI stream.", "ERROR",MB_OK);
            cleanup();
            return false;
        }    BITMAPINFOHEADER bi;
        ZeroMemory(&bi, sizeof bi);
        bi.biSize = sizeof bi;
        bi.biWidth = width;
        bi.biHeight = height;
        bi.biPlanes = 1;
        bi.biBitCount = 24;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = rowBytes * height;
        bi.biXPelsPerMeter = 0;
        bi.biYPelsPerMeter = 0;
        bi.biClrUsed = 0;
        bi.biClrImportant = 0;    hr = AVIStreamSetFormat(compAviStream, 0, &bi, sizeof bi);
        if (hr != AVIERR_OK)
        {
            MessageBox(NULL,"AVIStreamSetFormat failed.","ERROR",MB_OK);
            cleanup();
            return false;
        }    capturing = true;
        frameCounter = 0;    return true;
    }
    bool AVICapture::end()
    {
        capturing = false;
        cleanup();    return true;
    }
    bool AVICapture::captureFrame()
    {
        if (!capturing)
            return false;    // Get the dimensions of the current viewport
        int viewport[4];
        glGetIntegerv(GL_VIEWPORT, viewport);    int x = viewport[0] + (viewport[2] - width) / 2;
        int y = viewport[1] + (viewport[3] - height) / 2;
        glReadPixels(x, y, width, height,
                     GL_BGR_EXT, GL_UNSIGNED_BYTE,
                     image);    int rowBytes = (width * 3 + 3) & ~0x3;    LONG samplesWritten = 0;
        LONG bytesWritten = 0;
        HRESULT hr = AVIStreamWrite(compAviStream,
                                    frameCounter,
                                    1,
                                    image,
                                    rowBytes * height,
                                    AVIIF_KEYFRAME,
                                    &samplesWritten,
                                    &bytesWritten);
        if (hr != AVIERR_OK)
        {
            MessageBox(NULL,"AVIStreamWrite failed on frame.", "ERROR",MB_OK);
            return false;
        }    // printf("Writing frame: %d  %d => %d bytes\n",
        //        frameCounter, rowBytes * height, bytesWritten);
        frameCounter++;    return true;
    }
    void AVICapture::cleanup()
    {
        if (aviStream != NULL)
        {
            AVIStreamRelease(aviStream);
            aviStream = NULL;
        }
        if (compAviStream != NULL)
        {
            AVIStreamRelease(compAviStream);
            compAviStream = NULL;
        }
        if (aviFile != NULL)
        {
            AVIFileRelease(aviFile);
            aviFile = NULL;
        }
        if (image != NULL)
        {
            delete[] image;
            image = NULL;
        }
    }
    int AVICapture::getWidth() const
    {
        return width;
    }int AVICapture::getHeight() const
    {
        return height;
    }float AVICapture::getFrameRate() const
    {
        return frameRate;
    }
    H 文件
    #if !defined(AFX_AVICAPTURE_H__703E89CE_2A4E_4DD7_8B80_8AF78597D8B8__INCLUDED_)
    #define AFX_AVICAPTURE_H__703E89CE_2A4E_4DD7_8B80_8AF78597D8B8__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    #include <vfw.h>class AVICapture  
    {
    public:
    AVICapture();
    virtual ~AVICapture();    bool start(CString filename, int w, int h, float fps);
        bool end();
        bool captureFrame();    int getWidth() const;
        int getHeight() const;
        float getFrameRate() const; private:
        void cleanup(); private:
        int width;
        int height;
        float frameRate;
        int frameCounter;
        bool capturing;
        PAVIFILE aviFile;
        PAVISTREAM aviStream;
        PAVISTREAM compAviStream;
        unsigned char* image;
    };#endif // !defined(AFX_AVICAPTURE_H__703E89CE_2A4E_4DD7_8B80_8AF78597D8B8__INCLUDED_)
      

  12.   

    把上面的CPP,H。直接加入到你的程序中,加工一下,应该可以用。(平台为MFC SDI add OpenGL VC6.0)
    祝你成功。
      

  13.   

    数据库方面用MFC ODBC。比较方便。用SQL语言直接驱动数据库。(看看书,对你来说应该不太难)
      

  14.   

    liangjinjing 你好,能不能把完整的例子发过来,我把你的代码加入我的程序中后,经过修改也能编译通过了,但是没有出现理想的效果,可能是我学艺不精吧,我还没看出来压缩的数据存放到那个位子,在我的程序目录下还没有发现。谢谢。
      

  15.   

    完整例子已发至你邮箱。耐心查看一下使用方法。我写的机械的例子你也可以看一下。Liang_Jin_Jing.