Jump to content
  • Advertisement
Sign in to follow this  
mthomas

Directshow inside d3d9

This topic is 4769 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Everyone, I am using vs.net c++. This is my first experience with direct show. I would like to be able to load an avi file and display it on the screen in full screen 3D mode. I have a 3D world created using d3d9. I have a ui interface created with buttons on it. When I click a button I want to display the movie is a part of the screen. I guess lock it to a surface like I am displaying the buttons, images, aminmations, shapes, radio groups, etc. I created a movie class (which is posted below). When I create instance of the movie class and click the play button, which calls the Run of the movie class, my full screen d3d9 application gets minimized and a new window gets created displaying the avi file. How can I get the movie class to not create a new window and display it in a surface. Notes** The CPrimitive class is a base class for anything that is drawn on the screen. This includes graphics, text, shapes, and hopefully movies. Thanks Michael
#ifndef _Movie_H__
#define _Movie_H__

#include "Primitive.h"
#include <dshow.h>

class CMovie : public CPrimitive
{
public:
    static SetWindow(HWND hWindow);
    static CMovie* Create(char *szFilename);
    virtual ~CMovie();

    virtual void Render(VECTOR vPosition,RECT srcRect,DWord dwColorAttributes = ARGB(255,255,255,255),VECTOR vScale = VECTOR(1.0f,1.0f),VECTOR vRotCenter = VECTOR(0.0f,0.0f), float fRotAngle = 0.0f);

    void Play();
    void Stop();
    void SetPosition(int iPosition);

protected:
    CMovie();

    char m_szFilename[512];
    bool Init(char *szFilename);
    static HWND m_hWindow;

    IGraphBuilder* m_pGraph;
    IMediaControl* m_pControl;
    IMediaEvent* m_pEvent;
    IBasicAudio* m_pAudio;
    IMediaPosition*	m_pPosition;
    IVideoWindow* m_pVideoWindow;
};

#endif
================================================

================================================
#include "Movie.h"
#include <stdio.h>

HWND CMovie::m_hWindow = 0;

CMovie::SetWindow(HWND hWindow)
{
    m_hWindow = hWindow;
}

CMovie* CMovie::Create(char *szFilename)
{
    CMovie* pMovie = 0;

    pMovie = new CMovie();
    if (pMovie)
    {
        if (pMovie->Init(szFilename) == false)
        {
            delete pMovie;
            pMovie = 0;
        }
    }

    return (pMovie);
}

CMovie::CMovie() : 
    m_pGraph(0),
    m_pControl(0),
    m_pEvent(0),
    m_pAudio(0),
    m_pPosition(0),
    m_pVideoWindow(0)
{
    sprintf(m_szFilename,"");
}

CMovie::~CMovie()
{
    if (m_pVideoWindow)
    {
        m_pVideoWindow->Release();
        m_pVideoWindow = 0;
    }
    if (m_pPosition)
    {
        m_pPosition->Release();
        m_pPosition = 0;
    }
    if (m_pAudio)
    {
        m_pAudio->Release();
        m_pAudio = 0;
    }
    if (m_pControl)
    {
        m_pControl->Release();
        m_pControl = 0;
    }
    if (m_pEvent)
    {
        m_pEvent->Release();
        m_pEvent = 0;
    }
    if (m_pGraph)
    {
        m_pGraph->Release();
        m_pGraph = 0;
    }
}

bool CMovie::Init(char *szFilename)
{
    bool bStatus = false;
    HRESULT hr = S_OK;

    // Create the filter graph manager and query for interfaces.
    hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&m_pGraph);
    if SUCCEEDED(hr)
    {
        hr = m_pGraph->QueryInterface(IID_IMediaPosition, (void **)&m_pPosition);
        if SUCCEEDED(hr)
        {
            hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pControl);
            if SUCCEEDED(hr)
            {
                hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pEvent);
                if SUCCEEDED(hr)
                {
                    hr = m_pGraph->QueryInterface(IID_IBasicAudio, (void **)&m_pAudio);
                    if SUCCEEDED(hr)
                    {
                        hr = m_pGraph->QueryInterface(IID_IVideoWindow, (void **)&m_pVideoWindow);
                        if SUCCEEDED(hr)
                        {
                            m_pVideoWindow->put_Owner((OAHWND)m_hWindow);
	                        WCHAR* wfilename;
                            wfilename = new WCHAR[strlen(szFilename)+1];
	                        MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wfilename, (int)strlen(szFilename));
                            hr = m_pGraph->RenderFile(wfilename, NULL);
                            if SUCCEEDED(hr)
                            {
                                bStatus = true;
                            }
                            else
                            {
                                m_pVideoWindow->Release();
                                m_pVideoWindow = 0;
                                m_pAudio->Release();
                                m_pAudio = 0;
                                m_pEvent->Release();
                                m_pEvent = 0;
                                m_pControl->Release();
                                m_pControl = 0;
                                m_pPosition->Release();
                                m_pPosition = 0;
                                m_pGraph->Release();
                                m_pGraph = 0;
                            }
                            delete [] wfilename;
                            wfilename = 0;
                        }
                        else
                        {
                            m_pAudio->Release();
                            m_pAudio = 0;
                            m_pEvent->Release();
                            m_pEvent = 0;
                            m_pControl->Release();
                            m_pControl = 0;
                            m_pPosition->Release();
                            m_pPosition = 0;
                            m_pGraph->Release();
                            m_pGraph = 0;
                        }
                    }
                    else
                    {
                        m_pEvent->Release();
                        m_pEvent = 0;
                        m_pControl->Release();
                        m_pControl = 0;
                        m_pPosition->Release();
                        m_pPosition = 0;
                        m_pGraph->Release();
                        m_pGraph = 0;
                    }
                }
                else
                {
                    m_pControl->Release();
                    m_pControl = 0;
                    m_pPosition->Release();
                    m_pPosition = 0;
                    m_pGraph->Release();
                    m_pGraph = 0;
                }
            }
            else
            {
                m_pPosition->Release();
                m_pPosition = 0;
                m_pGraph->Release();
                m_pGraph = 0;
            }
        }
        else
        {
            m_pGraph->Release();
            m_pGraph = 0;
        }
    }

    return (bStatus);
}

void CMovie::Render(VECTOR vPosition, RECT srcRect,DWord dwColorAttributes,VECTOR vScale,VECTOR vRotCenter, float fRotAngle)
{
}

void CMovie::Play()
{
    if (m_pControl)
    {
        m_pVideoWindow->SetWindowForeground(OATRUE);
        m_pVideoWindow->SetWindowPosition(0,0,256,256);
        m_pControl->Run();
    }
}

void CMovie::Stop()
{
    if (m_pControl)
    {
        m_pControl->Stop();
    }
}

void CMovie::SetPosition(int iPosition)
{
    if (m_pPosition)
    {
        m_pPosition->put_CurrentPosition(iPosition);
    }
}

[Edited by - Coder on July 27, 2005 3:17:15 PM]

Share this post


Link to post
Share on other sites
Advertisement
you need to call set_Owner or something like that on the IVideoWindow interface, if it doesnt have a parent HWND, it will create a new window. However, thats with standard windows applications - i have no idea if that is useful for displaying on textures etc

Share this post


Link to post
Share on other sites
I tried this. Haven't been able to get it to work. The first thing is that the method you are using is creating a DirectDraw interface and rendering to it and not your D3D9 interface (if I understood it correctly). DirectDraw is the standard rendering interface foir DShow (except for VMR9)

In my experience the video displayed correctly until I started rendering the video and then you wouldn't see anything even if you stop rendering.

You could also use the VMR9 where the standard rendering interface is D3D9, but I only could get it to display the video between rendering about 80% of the time. (PS I want to make my own cutscenes)

I must admit I am not the best coder out there and might have made a couple of mistakes here and there.

The other technique is Render to texture (which everybody seems to recommend). However all the samples I've seen involves writing your own filter. Which is quite daunting for a less experienced coder. You might want to look at this http://www.gamedev.net/community/forums/topic.asp?topic_id=334551&forum_id=10&gforum_id=0 or in Chapter 14 of "Advanced Animation with DirectX" there is also an example. I bet if you SEARCH hard enough you can find a copy for very cheap. There is also a sample in the DX SDK sample browser, but good luck with that one. It's only MS that seems to think that teaching samples should be difficult for some reason.

Hope this helps. If anybody finds a easier technique to do cutscenes in fullscreen. PLS let me know.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!