Jump to content
  • Advertisement
Sign in to follow this  
Seroja

Problem with render to texture

This topic is 4852 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

I've spent a couple of hours on this, without success :( I'm trying to render to a texture. Only experimenting now, I'm not rendering anything particular. The problem is that all I get is a black rectangle. glGetError returns 0 (well, it tends to do so even if errors occur), but it seems like the code works without errors. In the beginning when I had errors, it rendered a white rectangle - e.g. the quad without texture. When I eliminated these, it became black. But that was all I could do. No rendering code worked, not even clearing the window with a different color (not black, red). The pixel format of my window supports both render to texture and pixel buffers (set with wglChoosePixelFormatARB - wouldn't return unsuitable formats). Here is the code for setting up the pixel buffer:
        MyPixBuf = CreatePixBuf(1024, 1024) ' This creates my pixel buffer
        wSetContext(MyPixBuf.hDC, MyPixBuf.hRC)

        glClearColor(1, 0, 0, 0) ' Should be red, but remains black
        glShadeModel(GL_SMOOTH)
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LEQUAL)
        glClearDepth(1)

        glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT)

        glViewport(0, 0, 1024, 1024)
        ' ViewPerspective
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        OffY = wFrustum(PerspectiveAngle, 1, FRUSTUM_NEAR, FRUSTUM_FAR)
        OffX = OffY
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        ' Here are different drawing attempts. None successful

        'glTranslated(0, 0, -FRUSTUM_NEAR * 10)

        CameraOff = JumperPosZ + Landings(JumperLanding).AbsZ - CAMERA_DIST
        glTranslated(0, 0, CameraOff * OffY)
        DrawLandings()
        DrawDiamonds()
        DrawSurfaces()

        wSetContext(hDC, hGLRC)

        glGenTextures(1, MyTex)
        glBindTexture(GL_TEXTURE_2D, MyTex)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ' Linear filtering on smaller
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ' Linear filtering on bigger
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) ' Texture repeats over S
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) ' Texture repeats over T
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)

Here is how I set up my pixel buffer (pixel format already set):
        Dim PixBuf As PixelBuf

        Dim IntAttribs As Integer() = New Integer() { _
            WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGB_ARB, _
            WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, _
            0, 0}

        ' Handle
        PixBuf.Handle = wglCreatePbufferARB(hDC, PixelFmt, Width, Height, IntAttribs(0))
        If PixBuf.Handle = IntPtr.Zero Then Return PixBuf ' Couldn't create pixel buffer

        ' Sizes
        wglQueryPbufferARB(PixBuf.Handle, WGL_PBUFFER_WIDTH_ARB, PixBuf.Width)
        wglQueryPbufferARB(PixBuf.Handle, WGL_PBUFFER_WIDTH_ARB, PixBuf.Height)
        If PixBuf.Width <> Width Or PixBuf.Height <> Height Then ' Wrong size
            wglDestroyPbufferARB(PixBuf.Handle)
            PixBuf.Handle = IntPtr.Zero
            Return PixBuf
        End If

        ' Contexts
        PixBuf.hDC = wglGetPbufferDCARB(PixBuf.Handle)
        PixBuf.hRC = wCreateContext(PixBuf.hDC)
        If PixBuf.hDC = IntPtr.Zero Or PixBuf.hRC = IntPtr.Zero Then ' Bad context
            wglDestroyPbufferARB(PixBuf.Handle)
            PixBuf.Handle = IntPtr.Zero
            Return PixBuf
        End If

Here is the code for rendering the quad on which I wanted to put the texture:
        glBindTexture(GL_TEXTURE_2D, MyTex)
        wglBindTexImageARB(MyPixBuf.Handle, WGL_FRONT_LEFT_ARB)
        glPushMatrix()
        glPushAttrib(GL_ALL_ATTRIB_BITS)
        glLoadIdentity()
        glTranslated(0, 0, -5 * OffY)
        glEnable(GL_TEXTURE_2D)
        glDisable(GL_LIGHTING)
        glColor3d(1, 1, 1)
        glBegin(GL_QUADS)
        glTexCoord2d(0, 0)
        glVertex2d(-OffX / 2, -OffY / 2)
        glTexCoord2d(1, 0)
        glVertex2d(OffX / 2, -OffY / 2)
        glTexCoord2d(1, 1)
        glVertex2d(OffX / 2, OffY / 2)
        glTexCoord2d(0, 1)
        glVertex2d(-OffX / 2, OffY / 2)
        glEnd()
        glPopAttrib()
        glPopMatrix()
        wglReleaseTexImageARB(MyPixBuf.Handle, WGL_FRONT_LEFT_ARB)

I have no idea what could go wrong here. My graphics card supports rendering to pixel buffers (ran a demo which worked fine), and I previously succeeded in "rendering to texture" with glCopyTexImage2D. Any help would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement
glClearColor(1, 0, 0, 0) ' Should be red, but remains black

- here you're clearing with an alpha of 0, so it doesn't really matter what the color is.

glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT)

- should be a bitwise OR
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


The basic steps to render to texture are:

1) set the pbuffer context current (so that you are actually rendering to it)
2) ensure you are rendering to the same resolution as the target(i.e. the pbuffer dimensions and the texture dimensions must match)
3) render stuff.
4) switch context again to the default drawing context.
5) bind the pbuffer as a texture.
6) draw full screen quad using the pbuffer texture.

It's unclear if you're following these steps from your code snippets.

Also, note that you can't render to a pbuffer context while it is bound as texture. So ensure that the pbuffer is released from the texture object before step 4.

One final note: you must declare a pixel format descriptor for your pbuffer with flags allowing it to be bound to a texture object. With the format you've described in your pbuffer you'll want to check out WGL_BIND_TO_TEXTURE_RGB_ARB.

Share this post


Link to post
Share on other sites
Quote:
Original post by Aeluned
glClearColor(1, 0, 0, 0) ' Should be red, but remains black

- here you're clearing with an alpha of 0, so it doesn't really matter what the color is.

I tried both with alpha of 1 and 0, it doesn't matter. Moreover, I removed the change context commands (tried to render the same thing to my window context) and it indeed became red.
Quote:

glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT)

- should be a bitwise OR
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

It's in VB, not C (notice, no ;). And I don't think it actually matters, tried with Or (there isn't | in VB) and no difference.
Quote:

The basic steps to render to texture are:

1) set the pbuffer context current (so that you are actually rendering to it)
2) ensure you are rendering to the same resolution as the target(i.e. the pbuffer dimensions and the texture dimensions must match)

Now that might be something. Do I have to allocate texture space? All I did was:

glGenTextures(1, MyTex)
glBindTexture(GL_TEXTURE_2D, MyTex)
wglBindTexImageARB(MyPixBuf.Handle, WGL_FRONT_LEFT_ARB)
...render a quad here...
wglReleaseTexImageARB(MyPixBuf.Handle, WGL_FRONT_LEFT_ARB)

What are texture dimensions? Isn't the information actually taken from the pixel buffer itself? My viewport is the same size as the pixel buffer, and the quad I draw isn't fullscreen (why should it be?).
Quote:

3) render stuff.
4) switch context again to the default drawing context.
5) bind the pbuffer as a texture.
6) draw full screen quad using the pbuffer texture.

It's unclear if you're following these steps from your code snippets.

Also, note that you can't render to a pbuffer context while it is bound as texture. So ensure that the pbuffer is released from the texture object before step 4.

Well, basically I was following these steps. I actually created the pbuffer, set it current, draw to it, set window current, only once (first frame). I wanted to get some kind of "printscreen" of the first frame. Later, I only bind the texture, bind the pbuffer, draw the quad, and release it.

Quote:

One final note: you must declare a pixel format descriptor for your pbuffer with flags allowing it to be bound to a texture object. With the format you've described in your pbuffer you'll want to check out WGL_BIND_TO_TEXTURE_RGB_ARB.


I did the correct pixel format. Otherwise wouldn't glGetError return an error (or maybe it doesn't return extension errors?).

Just to make sure, called wglGetPixelFormatAttribivARB ant it returned true (so it does support binding to texture).


My only idea for now is that I might have to allocate space for the texture. Something with glTexImage2D?

Share this post


Link to post
Share on other sites
Figured out the problem myself. Turns out that my pbuffer was double-buffered (I took a short-cut and used the same pixel format as my window instead of choosing a new one). Adding SwapBuffers fixed the whole thing.

I should've guessed it right away when I was getting a black (not white) rectangle whatever I rendered :S

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!