Results 1 to 6 of 6

Thread: Creating a texture from the front and backbuffer

  1. #1

    Creating a texture from the front and backbuffer

    How can I create a texture from the front or back buffer? I'm using Clootie's DX9 headers.

    The idea is to take a shot of the buffer in a texture, the process the texture with a pixel shader, and then place it in the buffer or draw it. What's the best method to acomplish that?

    Regards!

  2. #2

    Creating a texture from the front and backbuffer

    First look for IDirect3DDevice9:tretchRect. You scan StretchRect from backbuffer (rendertarget) to rendertarget-texture. ANd on second step use this texture as the source to the shader drawn with full-screen quad.

    Be warned: a lot of HW (probably except NV GF6 and up) have some restrictions on "non-power-of-two" textures.
    There are only 10 types of people in this world; those who understand binary and those who don't.

  3. #3

    Creating a texture from the front and backbuffer

    That's exactly what I was looking for.

  4. #4

    Creating a texture from the front and backbuffer

    Ok, I made it this way:

    Code:
    procedure dx9_cScene.Draw;
      const
        FILTER_FORMAT = D3DFVF_XYZRHW or D3DFVF_TEX1;
    
        FILTER: array[0..3] of TFilterVertex = (
          (Pos: (x: 000.0; y: 480.0; z: 0.5; w: 1.0); Tex1: (x: 0.0; y: 1.0)),
          (Pos: (x: 000.0; y: 000.0; z: 0.5; w: 1.0); Tex1: (x: 0.0; y: 0.0)),
          (Pos: (x: 640.0; y: 480.0; z: 0.5; w: 1.0); Tex1: (x: 1.0; y: 1.0)),
          (Pos: (x: 640.0; y: 000.0; z: 0.5; w: 1.0); Tex1: (x: 1.0; y: 0.0))
          );
    
      var
        Texture: IDirect3DTexture9;
        Backbuffer, Surface: IDirect3DSurface9;
        VertexBuffer: IDirect3DVertexBuffer9;
        Vertices: Pointer;
    
    begin
      if _Device = nil then Exit;
    
      if Failed(D3DXCreateTexture(_Device, 512, 512, 1, D3DUSAGE_RENDERTARGET,
        D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, Texture)) then Exit;
      Texture.GetSurfaceLevel(0, Surface);
    
      _Device.GetRenderTarget(0, Backbuffer);
      _Device.SetRenderTarget(0, Surface);
      _Device.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, _BackColor, 1.0,
        0);
    
      if Succeeded(_Device.BeginScene) then
      begin
    // Draw scene...
    
        _Device.EndScene;
      end;
    
      if Failed(_Device.CreateVertexBuffer(SizeOf(FILTER), 0,
        FILTER_FORMAT, D3DPOOL_DEFAULT, VertexBuffer, nil)) then Exit;
      if Failed(VertexBuffer.Lock(0, SizeOf(FILTER), Vertices, 0)) then Exit;
      CopyMemory(Vertices, @FILTER, SizeOf(FILTER));
      VertexBuffer.Unlock;
    
      _Device.SetRenderTarget(0, Backbuffer);
      _Device.Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, _BackColor, 1.0,
        0);
    
      if Succeeded(_Device.BeginScene) then
      begin
    
        _Device.SetTexture(0, Texture);
        _Device.SetStreamSource(0, VertexBuffer, 0,
          SizeOf(TFilterVertex));
        _Device.SetFVF(FILTER_FORMAT);
        _Device.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
    
        _Device.EndScene;
      end;
    
      _Device.Present(nil, nil, 0, nil);
    
      Texture := nil;
      Backbuffer := nil;
      Surface := nil;
      VertexBuffer := nil;
    End;
    It works, but I have 3 problems:
    1) There is a blinking white rectangle at the top-left corner of the screen. I found out white is the default color of the filter mesh. Maybe it's not drawing that zone from time to time, and that's why it's blinking, but I don't know how to correct that.
    2) A frame in the bottom of the screen is not being drawn, but it has the color of the scene background.
    3) The textures of the models I load are getting corrupted, some triangles become white. This is really weird.

    EDIT: I have just solved everything setting the texture size to 640x480 :

    Code:
    if Failed(D3DXCreateTexture(_Device, 640,480,...
    Probably the Device was corrupting memory when trying to draw to a surface smaller than the one it was set for. :lol:

  5. #5

    Creating a texture from the front and backbuffer

    It was probably related to some interaction [driver bug ?] of different sizes of original (640x480) DepthBuffer and your new (512x512) renderTarget.
    You can try to create and set new DepthBuffer with 512x512 size and assign at the same time with new renderTarget.

    PS. Creating / destroying VertexBuffer each frame is REALLY BAD!
    There are only 10 types of people in this world; those who understand binary and those who don't.

  6. #6

    Creating a texture from the front and backbuffer

    Quote Originally Posted by Clootie
    It was probably related to some interaction [driver bug ?] of different sizes of original (640x480) DepthBuffer and your new (512x512) renderTarget.
    You can try to create and set new DepthBuffer with 512x512 size and assign at the same time with new renderTarget.
    Ok.

    Quote Originally Posted by Clootie
    PS. Creating / destroying VertexBuffer each frame is REALLY BAD!
    Really?! Hmm, I will create a global mesh for my filters. Thanks

    By the way, I found out that it's better to disable texture smoothing when creating those filters.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •