in pbuffer zeichnen



  • hi!
    ich möchte gerne meine gesamte szene in einen pbuffer zeichnen und diesen dann als texture verwenden, aber es will einfach nicht funktionieren (ich hatte das problem schon einmal, hatte es aber irgendwann aufgegeben)

    auch werden nun meinen kompletten source code zur erzeugung des pbuffer posten, bitte lest ihn euch durhc, auch wenn es ziemlich viel ist und sagt mir was ich falsch mache (bei mir bleibt die texture einfach weiß)

    class CRenderTarget
    {
    public:
    	unsigned int mId;
    
    	HPBUFFERARB  mPBuffer;      //Handle zu PBuffer
        HDC          mHdc;          //Handle zu DC
        HGLRC        mHrc;			//Handle zu Rendering Context
        int          mWidth;        //Breite vom PBuffer
        int          mHeight;       //Höhe vom PBuffer
    
    	bool Create(int width, int height);
    	bool Bind();
    	bool Unbind();
    	bool Destroy();
    	bool MakeCurrent();
    	void SetDefaults();
    
    	CRenderTarget();
    	~CRenderTarget();
    };
    
    #include "RenderTarget.h"
    
    CRenderTarget::CRenderTarget()
    {
    	mWidth = mHeight = 0;
    }
    
    CRenderTarget::~CRenderTarget()
    {
    	Destroy();
    }
    
    bool CRenderTarget::Create(int width, int height)
    {
    	mWidth = width;
    	mHeight = height;
    	HDC hdc = wglGetCurrentDC();
    	HGLRC hrc = wglGetCurrentContext();
    
        //Richtiges Pixelformat
        int     format;
        int     pformat[256];
        unsigned int nformats;    
    	int     iattributes[2*256];
        float   fattributes[2*256];
        int     nfattribs = 0;
        int     niattribs = 0;
    
        //Attribute müssen Zero sein
        memset(iattributes,0,sizeof(int)*2*256);
        memset(fattributes,0,sizeof(float)*2*256);
    
    	//Ein PBuffer soll erstellt werden
        iattributes[niattribs  ] = WGL_DRAW_TO_PBUFFER_ARB;
        iattributes[++niattribs] = GL_TRUE;
    
    	//PBuffer muss als RGBA gebinden werden
        iattributes[++niattribs] = WGL_BIND_TO_TEXTURE_RGBA_ARB;
        iattributes[++niattribs] = GL_TRUE;
    
        if (!wglChoosePixelFormatARB(hdc, iattributes, fattributes, 256, pformat, &nformats))
        {
    		Log->Err ("PBuffer konnte nicht erstellt werden (wglChoosePixelFormatARB())");
    		return false;
        }
    
    	if (nformats <= 0)
        {
    		Log->Err ("PBuffer konnte nicht erstellt werden, kein passendes Pixelformat gefunden");
            return false;
        }
        format = pformat[0];
    
        //Attribute setzten
        memset(iattributes,0,sizeof(int)*2*256);
        niattribs = 0;
        //Render Texture Format ist RGBA
        iattributes[niattribs] = WGL_TEXTURE_FORMAT_ARB;
        iattributes[++niattribs] = WGL_TEXTURE_RGBA_ARB;
        //Render Texture Target ist ein normales Texture2D
        iattributes[++niattribs] = WGL_TEXTURE_TARGET_ARB;
        iattributes[++niattribs] = WGL_TEXTURE_2D_ARB;
        //Platz für Mipmaps freihalten
        iattributes[++niattribs] = WGL_MIPMAP_TEXTURE_ARB;
        iattributes[++niattribs] = TRUE;
        //Wenn Breite bzw. Höhe zu groß gewählt wurde, den größt möglichen Buffer wählen
        iattributes[++niattribs] = WGL_PBUFFER_LARGEST_ARB;
        iattributes[++niattribs] = FALSE;
    
        glGenTextures(1, &mId);
        glBindTexture(GL_TEXTURE_2D, mId);
    
    	//PBuffer erzeugen
    	mPBuffer = wglCreatePbufferARB(hdc, format, mWidth, mHeight, iattributes);
        if (mPBuffer == 0)
        {
            Log->Err ("PBuffer konnte nicht erstellt werden (wglCreatePbufferARB())");
            return false;
        }
    
        //Device Context vom PBuffer holen.
        mHdc = wglGetPbufferDCARB(mPBuffer);
        if (mHdc == 0)
        {
            Log->Err ("PBuffer konnte nicht erstellt werden (wglGetPbufferDCARB())");
            return false;
        }
    
        //Rendering Context vom PBuffer holen.
        mHrc = wglCreateContext(mHdc);
        if (mHrc == 0)
        {
            Log->Err ("PBuffer konnte nicht erstellt werden (wglCreateContext())");
            return false;
        }
    
    	wglShareLists(gHrc, mHrc);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE_EXT);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE_EXT);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
        //Wie groß der Buffer sein soll
        wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_WIDTH_ARB, &mWidth);
        wglQueryPbufferARB(mPBuffer, WGL_PBUFFER_HEIGHT_ARB, &mHeight);
    	SetDefaults();
    	Log->Out ("PBuffer (%ix%i) erzeugt",mWidth,mHeight);
    	return true;
    }
    
    void CRenderTarget::SetDefaults()
    {
        MakeCurrent();
    
        glViewport(0, 0, mWidth, mHeight);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45.0f, mWidth/mHeight, 1.0f, 5000.0f);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        glShadeModel(GL_SMOOTH );
        glClearColor(0, 0, 0.5f, 1 );
    
        glClearDepth( 1.0f );
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
    
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    }
    
    bool CRenderTarget::Bind()
    {
    	return (wglBindTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB) == GL_TRUE);
    }
    
    bool CRenderTarget::Unbind()
    {
    	return (wglReleaseTexImageARB(mPBuffer, WGL_FRONT_LEFT_ARB) == GL_TRUE);
    }
    
    bool CRenderTarget::Destroy()
    {
    	wglDeleteContext(mHrc);
    	wglReleasePbufferDCARB(mPBuffer, mHdc);
    	wglDestroyPbufferARB(mPBuffer);
    	return true;
    }
    
    bool CRenderTarget::MakeCurrent()
    {
    	return (wglMakeCurrent(mHdc, mHrc) == GL_TRUE);
    }
    

    im eigentlichen programm erzeuge ich dann einen puffer mit "target->Create(512,512)"
    beim zeichnen der szene gehe ich so vor:

    target->MakeCurrent();
    	gpSceneManager->Render(Camera);
    
    	wglMakeCurrent(gHdc, gHrc);
    	gpSceneManager->Render(Camera);
    

    Anschließend wechsle ich in den Ortho Modus und "binde" den Puffer, wie schon gesagt, die Texture bleibt einfach weiß 😞

    target->Bind();
    	glBindTexture(GL_TEXTURE_2D , target->mId);
    	glBegin(GL_QUADS);
    	glTexCoord2f(0,0); glVertex2f(0,0);
    	glTexCoord2f(1,0); glVertex2f(400,0);
    	glTexCoord2f(1,1); glVertex2f(400,400);
    	glTexCoord2f(0,1); glVertex2f(0,400);
    	glEnd();
    

    Danke schon mal im vorraus



  • Hmm, ich habe noch nie mit PBuffern gearbeitet, mag die Dinger einfach net.
    Aber ich habe von Nvidia eine Klasse (Win32/Linux) die einen PBuffer
    erstellt/managed. Vielleicht kannst du mit dem Source was anfangen.
    Wenn du willst kann ich ihn dir mailen.



  • ja schick ih n mir mal bitte: troop2500@hotmail.com ist vielleicht auch ein bsp dabei wie man den pbufer dann als texture verwenden kann?


Anmelden zum Antworten