Dear all:

To play AVI from within OSG, I wrote a simple app. that plays (or should play) AVI files in OSG. The app. proceeds frame by frame displaying the AVI contents on a quad inside OSG. My problem is that only the first frame is generated and shown on the quad. As soon as the app. steps to another one, it breaks.

Shortly speaking, my sequence is as follows:

- open avi file, stream
- get the first frame
- create the quad, and apply the texture // so far, so good!
- init viewer
loop:
   increase frame count
   grab the bext frame
   apply the texture // frame no. 2 - crash
   ....
end

It is inside the viewer's loop that the code breaks when I apply the AVI data (at frame no. 2) to the new image through:
   while (!viewer.done())
{ viewer.frame();
       frame = ((frame+1)>lastframe) ? 0 : (frame+1);

       GrabAVIFrame(frame);
image->allocateImage(256, 256, 1,
           GL_RGB, GL_UNSIGNED_BYTE);
       // BREAKS HERE
       image->setImage(256,256,1,
           GL_TEXTURE_2D,GL_RGB,
           GL_UNSIGNED_BYTE, data,
           osg::Image::USE_NEW_DELETE);
texture->setImage(0,image.get()); }

I have tracked the error down to deallocateData() in Image.cpp. I would appreciate any advice on how to solve this. The source code that recreates the error in a simple way is below.

The AVI part comes from the NeHe site.
Again, appreciate any reply on the cause of the problem here.
Rgds, Janusz

-----
/* Code where it breaks: Image.cpp

void Image::deallocateData()
{
   if (_data) {
       if (_allocationMode==USE_NEW_DELETE) delete [] _data;
       else if (_allocationMode==USE_MALLOC_FREE) ::free(_data);
       _data = 0;
   }
}

*/

#include <windows.h>

#include <iostream>
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osg/TexEnv>
#include <osg/TexGen>
#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Projection>
#include <osg/PolygonOffset>
#include <osg/MatrixTransform>
#include <osg/Camera>
#include <osg/FrontFace>
#include <osgText/Text>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>

#include <osgViewer/CompositeViewer>
#include <osg/io_utils>
#include <osg/Texture2D>
#include <osg/TextureRectangle>

#include <vfw.h>

#pragma comment( lib, "vfw32.lib" )
int    frame=0;
AVISTREAMINFO psi;
PAVISTREAM    pavi;
PGETFRAME    pgf;

BITMAPINFOHEADER bmih;
long lastframe;
int width;
int height;

char *pdata;

HDRAWDIB hdd; HBITMAP hBitmap; HDC hdc = CreateCompatibleDC(0); unsigned char* data = 0;
int mpf;

osg::ref_ptr<osg::Texture2D> texture;
osg::ref_ptr<osg::Image> image;

// Flips The Red And Blue Bytes (256x256)
void flipIt(void* buffer) { void* b = buffer; __asm { mov ecx, 256*256 mov ebx, b label: mov al,[ebx+0] mov ah,[ebx+2] mov [ebx+2],al mov [ebx+0],ah add ebx,3 dec ecx jnz label }
}

void OpenAVI(LPCSTR szFile) { AVIFileInit(); hdd = DrawDibOpen(); // Opens The AVI Stream if (AVIStreamOpenFromFile(&pavi, szFile, streamtypeVIDEO, 0, OF_READ, NULL) !=0)
   {
MessageBox (HWND_DESKTOP, "Failed To Open The AVI Stream", "Error", MB_OK | MB_ICONEXCLAMATION);
   }

AVIStreamInfo(pavi, &psi, sizeof(psi)); width=psi.rcFrame.right-psi.rcFrame.left; height=psi.rcFrame.bottom-psi.rcFrame.top; lastframe=AVIStreamLength(pavi); mpf=AVIStreamSampleToTime(pavi,lastframe)/lastframe; bmih.biSize = sizeof (BITMAPINFOHEADER); bmih.biPlanes = 1; bmih.biBitCount = 24; bmih.biWidth = 256; bmih.biHeight = 256; hBitmap = CreateDIBSection (hdc, (BITMAPINFO*)(&bmih), DIB_RGB_COLORS, (void**)(&data), NULL, NULL); SelectObject (hdc, hBitmap); pgf=AVIStreamGetFrameOpen(pavi, NULL); if (pgf==NULL)
   {
MessageBox (HWND_DESKTOP, "Failed To Open The AVI Frame", "Error", MB_OK | MB_ICONEXCLAMATION); } }

void GrabAVIFrame(int frame) { LPBITMAPINFOHEADER lpbi; lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf, frame); pdata=(char *)lpbi+lpbi->biSize+lpbi->biClrUsed * sizeof(RGBQUAD); DrawDibDraw (hdd, hdc, 0, 0, 256, 256, lpbi, pdata, 0, 0, width, height, 0); flipIt(data); }

void CloseAVI(void) { DeleteObject(hBitmap); DrawDibClose(hdd); AVIStreamGetFrameClose(pgf); AVIStreamRelease(pavi); AVIFileExit(); }

/*create a in-memory texture */
osg::StateSet* createInMemoryTextureFromAVI(osg::StateSet* stateset, int imWidth, int imHeight)
{
   unsigned int uiTextureId =0;

   // texture mapping part - osg
   if (data)
   {
       texture = new osg::Texture2D;
       texture->setDataVariance(osg::Object::DYNAMIC);
texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); texture->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER ); texture->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER ); texture->setWrap( osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER);
       texture->setBorderColor( osg::Vec4( 0.0, 0.0, 0.0, 0.0 ) );
       texture->setInternalFormat(GL_RGB);

       osg::TexEnv* texenv = new osg::TexEnv;
       texenv->setMode(osg::TexEnv::BLEND);

       image = new osg::Image();
       image->setDataVariance(osg::Object::DYNAMIC);
       image->allocateImage(imWidth, imHeight, 1,
           GL_RGB, GL_UNSIGNED_BYTE);
image->setImage(imWidth,imHeight,1,
           GL_TEXTURE_2D,GL_RGB,
           GL_UNSIGNED_BYTE, data,
osg::Image::USE_NEW_DELETE);
       texture->setUnRefImageDataAfterApply(false);
texture->setImage(uiTextureId,image.get()); stateset->setDataVariance(osg::Object::DYNAMIC);
       stateset->setTextureAttribute(uiTextureId,
           texenv,osg::StateAttribute::ON);
       stateset->setTextureAttributeAndModes(uiTextureId,
           texture.get(),osg::StateAttribute::ON);
       stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
   }

   return stateset;
}

// osgmovie stuff
osg::ref_ptr<osg::Geometry> myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,float height,
               bool useTextureRectangle, bool xyPlane, bool option_flip)
{

   bool flip=option_flip;
osg::ref_ptr<osg::Geometry> pictureQuad = osg::createTexturedQuadGeometry(pos,
       osg::Vec3(width,0.0f,0.0f),
       xyPlane ? osg::Vec3(0.0f,height,0.0f) : osg::Vec3(0.0f,0.0f,height),
       0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f);
pictureQuad->setStateSet(createInMemoryTextureFromAVI(pictureQuad->getOrCreateStateSet(), 256,256));
   return pictureQuad;
}




int main(int argc, char* argv[])
{
   osgViewer::Viewer viewer;
   viewer.getCamera()->setClearColor(osg::Vec4f(0.5,0.5,0.5,1.0));
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
   traits->x = 100;
   traits->y = 100;
   traits->width = 800;
   traits->height = 600;
   traits->windowDecoration = true;
   traits->doubleBuffer = true;
   traits->sharedContext = 0;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
   if (gc.valid())
   {
osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<<std::endl;
       gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } viewer.getCamera()->setViewport(new osg::Viewport(0,0, traits->width, traits->height));
   viewer.getCamera()->setGraphicsContext(gc.get());
   viewer.getCamera()->setDrawBuffer(GL_BACK);
   viewer.getCamera()->setReadBuffer(GL_BACK);

   viewer.setCameraManipulator(new osgGA::TrackballManipulator);

   OpenAVI("c:\\libs\\openscenegraph-data\\movies\\Face2.avi");
// get first frame
   frame = 0;
   GrabAVIFrame(0);

   osg::Geode* geode = new osg::Geode;
   geode->addDrawable(
myCreateTexturedQuadGeometry(osg::Vec3f(0,0,0),256,256,false, false, false).get()); viewer.setSceneData(geode);
   viewer.realize();
while (!viewer.done()) { viewer.frame();
       frame = ((frame+1)>lastframe) ? 0 : (frame+1);

       GrabAVIFrame(frame);
image->allocateImage(256, 256, 1,
           GL_RGB, GL_UNSIGNED_BYTE);
       image->setImage(256,256,1,
           GL_TEXTURE_2D,GL_RGB,
           GL_UNSIGNED_BYTE, data,
           osg::Image::USE_NEW_DELETE);
texture->setImage(0,image.get()); }
   CloseAVI();
}


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to