Porting from OpenGL to Directx

Started by
29 comments, last by xDarkice 12 years, 3 months ago
Simply don't do the lock->write->unlock in the same place where you draw. The buffer update should only be done when you actually want to change its contents, which is usually far more seldom than drawing it.

Niko Suni

Advertisement
And if you want "bit more translucent", you can adjust the alpha levels on the PNG files, or modulate the alpha of the texture by using texture stage states or (again) simple maths in the pixel shader.

Niko Suni

I do not need to adjust the alpha levels, because they should already be in the PNG. In OpenGL those textures are rendered translucent, but in DirectX they arent. Just compare the OpenGL and the DirectX one: In OpenGL you can see the snow falling behind the texture where "Main Menu" is drawn on. In DirectX you cant.
I think I am missing some parameters for alpha Blending, am I?
If you have alpha blending on, the alpha factor comes from the texture stage setup or the pixel shader. If either outputs alpha of 1.0 (independent of any source textures), the drawn geometry is opaque even though blending is enabled.

Niko Suni

Ok i got alpha working now. Now I am stuck at creating a texture out of a byte[], height and width is given. I am doing this:

Texture t = new Texture(m_Device, W, H, 0, Usage.Dynamic, Format.A8R8G8B8, Pool.Default);
DataRectangle rect = t.LockRectangle(0, LockFlags.None);
rect.Data.WriteRange(Data);
t.UnlockRectangle(0);

But i am not getting the result I want on screen. I need this to play a video, decoded by Acinerella, so creating a Bitmap out of the byte[] would not be a good idea due to the bad performance.
It looks like the pitch of the data is incorrect.

D3D textures have a "pitch" that is the number of bytes per line. It may or may not be equal to width * bytes per pixel, and you should not assume that it is.

The actual visible pixels are guaranteed to be at the beginning of the scanline (regardless of the pitch) so the most robust way to copy an image to a texture is to copy the data one line at a time, and shift the destination pointer by the pitch after each line until all the lines are copied. I don't know how to do this in SlimDX, though - I'm a native D3D user.

Also check that the source and destination formats are same (or at least have the same bit count per pixel).

Niko Suni

Also, do not create the texture each frame. This is very detrimental to performance. Instead, keep the texture reference in your code after you've created it, and merely update it when you want to change the contents.

Niko Suni

I am not recreating the texture each frame. I keep all textures stored in a List and they can be updated using my UpdateTexture methods. The textures are drawn in my DrawTexture methods.

Your post really helped me out. Instead of writing the data directly into the stream i am now doing this which works like a charm:

DataRectangle rect = t.LockRectangle(0, LockFlags.None);
for(int i = 0; i < Data.Length;) {
rect.Data.Write(Data, i, 4 * W);
i+= 4*W;
rect.Data.Position = rect.Data.Position - 4 * W;
rect.Data.Position += rect.Pitch;
}
t.UnlockRectangle(0);


The hopefully last minor bugs are that [s]my z-position isnt applied correctly [/s]and the textures are still a bit blurry.
The small album art should be rendered over the big one. It is working fine in OpenGL, but z-Positions can go beyond 1.0f in OpenGL. If I draw my z-Positions with values over 1f they wont show up. I am currently setting any positions over 1f to 1f which creates this bug i think.
The other thing is that the textures are not that good as in OpenGL. I experimented with some TextureFilters ending up using a linear filter, which is still not too fine. In OpenGL i am using MipMaps to have smooth textures. Can I do the same in DirectX?

EDIT: Fixed z-Positions, still need to examine why the textures are a bit blurry though I am shifting the Pixels by 0.5
You can use mipmaps in D3D too.

In the image attached to your last post, it seems that there is not a 1:1 size correspondence between the source and target. If this is intented, be sure to enable minification, magnification and mip filtering. For mip mapping, you need to allocate and fill the mip levels (I believe there is a D3DX helper function for filling them).

Niko Suni

Regarding the z range, you can control it by using the viewport of the device. The viewport structure represents a mapping between physical and logical dimensions of rendering.

The default viewport has a z-range of 0...1, as you noticed.

Niko Suni

This topic is closed to new replies.

Advertisement