Sign in to follow this  
Bucky32

Non Power of Two Texture Rendertarget

Recommended Posts

Bucky32    138
I'm having som troubles using non power of two textures. But when I try to create a texture using new Texture i get a D3DERR_INVALIDCALL. The caps says that NPOT-textures are supported. This is how I create the texture:
//Checks if NPOT-textures are supported
Caps caps = device.DeviceCaps;
bool nonPower2Supported = caps.TextureCaps.SupportsNonPower2Conditional; 
            
if(nonPower2Supported)
{
    renderTargetTexture = new Texture(device, 640, 480, 0, Usage.RenderTarget,   Format.X8R8G8B8, Pool.Default);
    renderTargetSurface = renderTargetTexture.GetSurfaceLevel(0);
}

The texture is supposed to be used as a rendertarget. All help appreciated... =) [Edited by - Bucky32 on December 3, 2005 3:35:17 PM]

Share this post


Link to post
Share on other sites
__ODIN__    479
Support for non-pow2 TEXTURES isn't the same as support for non-pow2 offscreen render-targets. In general, using pow2 RT's is the only sane thing to do.

Allan

Share this post


Link to post
Share on other sites
Bucky32    138
Okey, so if I have a 640x480 window I need to render to a 1024x1024 rendertarget texture? And then somehow access parts of that texture that contains my pixelvalues?

The thing is that I have done an application in OpenGL using framebuffer objects and rectangular textures with several shader passes that I now want to convert to C# and DirectX.

Share this post


Link to post
Share on other sites
Bucky32    138
Aha, it worked a bit better... It doesnt crash at the texture creation.

But it seems like i only get one correct frame each time I reset the device. All frames thereafter are black.


This is how i create the rendertarget now:
renderTargetTexture = new Texture(device, device.Viewport.Width, device.Viewport.Height, 1, Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
renderTargetSurface = renderTargetTexture.GetSurfaceLevel(0);



And here i render to the texture:
renderTargetSurface = renderTargetTexture.GetSurfaceLevel(0);
Surface oldRenderTarget = device.GetRenderTarget(0);
device.SetRenderTarget(0, renderTargetSurface);

device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);

device.BeginScene();
//Begin HLSL shader
effect.Technique = "simple";
effect.Begin(0);
effect.BeginPass(0);

//Draw cube
device.VertexFormat = CustomVertex.PositionOnly.Format;
device.SetStreamSource(0, vertexBuffer, 0);
device.Indices = indexBuffer;
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 8, 0, 12);

//End HLSL shader
effect.EndPass();
effect.End();

device.EndScene();

//Reset the render target.
device.SetRenderTarget(0, oldRenderTarget);
oldRenderTarget.Dispose();



Then i render the resulting rendertarget a full screen quad:
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.WhiteSmoke, 1.0f, 0);

//Reset world, view and projection matrix
device.Transform.World = device.Transform.View = device.Transform.Projection = Matrix.Identity;

device.BeginScene();

device.SetTexture(0, renderTargetTexture);
device.VertexFormat = CustomVertex.TransformedTextured.Format;
device.SetStreamSource(0, quadVertexBuffer, 0);
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
device.EndScene();


[Edited by - Bucky32 on December 3, 2005 3:05:21 PM]

Share this post


Link to post
Share on other sites
Try SetTexture(0, 0) after the quad render. When you make the rendertarget active on the next frame, it's still bound to texture stage 0, and D3D might be blocking the SetRenderTarget since a texture cannot be both a texture and a rendertarget at the same time. This would cause it to work for 1 frame.

Try the debug runtimes (ControlPanel/DirectX then Direct3D then the debug runtime radio button) to see if D3D is trying to tell you what it doesn't like.

Another thing you may need to do is SetPixelShader(0), and SetVertexShader(0) to undo what your effect file has set up. I'm not sure if you need this, as you say it works for 1 frame, and if this was a problem it would cause problems even on frame 0.

Share this post


Link to post
Share on other sites
Bucky32    138
Quote:
Original post by Namethatnobodyelsetook
Try SetTexture(0, 0) after the quad render. When you make the rendertarget active on the next frame, it's still bound to texture stage 0, and D3D might be blocking the SetRenderTarget since a texture cannot be both a texture and a rendertarget at the same time. This would cause it to work for 1 frame.


Thanks Namethatnobodyelsetook! That was exactly the problem... now its working perfectly. Don't know thou if this is the fastest way to do this.

Will have to check out those debug runtimes also...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this