Jump to content
  • Advertisement
Sign in to follow this  
xDarkice

OpenGL Porting from OpenGL to Directx

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

Hello,

recently I have been trying to port over the OpenGL interface due to some problems with Intel Graphic chips which have a bad OpenGL driver in Windows. I need help to port a Quad in OpenGL to DirectX. Heres what i have done in OpenGL:

GL.Begin(BeginMode.Quads);
GL.TexCoord2(x1, y1);
GL.Vertex3(rx1, ry1, rect.Z + CGraphics.ZOffset);

GL.TexCoord2(x1, y2);
GL.Vertex3(rx1, ry2, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x2, y2);
GL.Vertex3(rx2, ry2, rect.Z + CGraphics.ZOffset);
GL.TexCoord2(x2, y1);
GL.Vertex3(rx2, ry1, rect.Z + CGraphics.ZOffset);
GL.End();


And here is what I am doing for DirectX rx1 = ((rx1 * 2) / ClientSize.Width) -1f;
rx2 = ((rx2 * 2) / ClientSize.Width) - 1f;
ry1 = ((ry1 * 2) / ClientSize.Height) - 1f;
ry2 = ((ry2 * 2) / ClientSize.Height) - 1f;

DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.None);
stream.WriteRange(new[] {
new TexturedVertex(new Vector3(rx1, ry1, 0), new Vector2(x1, y1)),
new TexturedVertex(new Vector3(rx1, ry2, 0), new Vector2(x1, y2)),
new TexturedVertex(new Vector3(rx2, ry2, 0), new Vector2(x2, y2)),
new TexturedVertex(new Vector3(rx2, ry1, 0), new Vector2(x2, y1)),
});
_VertexBuffer.Unlock();
m_Device.SetTexture(0, _D3DTextures[Texture.index]);
m_Device.SetStreamSource(0, _VertexBuffer, 0, Marshal.SizeOf(typeof(TexturedVertex)));
m_Device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);


Unfortunetely the Textures are mirrored and the alpha Channel is displayed in black. I hope you can help me, I have been trying to get this working for 2 days now =/

Best regards xDarkice

Share this post


Link to post
Share on other sites
Advertisement
To mirror the texture, negate the v component of the texture coordinate. D3D and OpenGL consider the "up" direction differently in this case.

To blend with alpha channel, you need to enable the alphablend render state, and set the blend source and destination states accordingly.

As a side note, you don't want to be locking the vertex buffer at each frame if you don't need to. If you have a genuine need to do so, use a vertex buffer with dynamic usage flag specified. Excessive locking can cause stalling because the hardware can't use the buffer for rendering while it is locked to you. Requesting dynamic usage hints the driver to allocate the buffer to a physical memory resource that allows fast write usage at the expense of rendering performance (though choosing the actual allocation strategy is still up to the driver).

Share this post


Link to post
Share on other sites
Thanks for your answer! After setting m_Device.SetRenderState(RenderState.AlphaBlendEnable, true);
m_Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha);
m_Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha);

Alpha textures seem to render almost properly. But there are still some black blocks left.

Negating the y cords seems to work for the mirror part but the image is still some of sort of upset down. The main menu texture should be top. The ry1 and ry2 coordinates seem to be incorrect. Am I calculating them wrong? On top of that my Textures seem to be blurry and there might be a part missing ry1 = ((ry1 * 2) / CSettings.iRenderH) - 1f;
ry2 = ((ry2 * 2) / CSettings.iRenderH) - 1f;

I am multiplicating my coordinates by 2 and dividing them by the heigth and substracting 1.

I think I do not need to lock the buffer each frame. What should i initialize my DataStream with? Right now I am using DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.None);

The second picture shows how it is rendering in OpenGL. I disabled the background video in DirectX for testing purposes.

Now I just need to find a way to color the textures. But I think I can just add a new Color in my TexturedVertex struct.

Thanks for your help!

EDIT: I got the upside down fixed! I didnt had to negate y1 and y2, but ry1 and y2. But the blurry textures and texts arent fixed yet
EDIT2: The Black Bars seem to appear for a whitespace in a text

Share this post


Link to post
Share on other sites
OpenGL interprets screen-space positions as the centre of the pixel
DirectX interprets screen-space positions as the top-left corner of the pixel
(Or is it the other way round?)

Either way, to stop your textures from blurring, you need to subtract 0.5 from your screen-space positions when changing between OpenGL and DX. This is like shifting them up-left by 0.5 pixels. So they will still fill the same pixels, but it will affect how the texture coordinates are interpolated, and should stop the blurring

Share this post


Link to post
Share on other sites
I believe the black bars appear because your text rendering logic actually generates black rectangles with alpha of 1.0 to fill whitespace. Check your code that generates the triangles for the glyphs.

Share this post


Link to post
Share on other sites
Regarding locking, only do so when you actually change the text contents. You can't get the DataStream any other way than locking the buffer, nor can you keep the reference to it between frames (because it would keep the resource locked).

You can change the text color by modulating the rgb of the texture with a constant color factor, instead of locking the buffer. In fixed function pipeline, this is achieved by setting appropriate texture stage states, and in a pixel shader the operation is a single multiplication.

Share this post


Link to post
Share on other sites
I think the black bars appear because texture transparency is not drawn properly. For example my main menu bar should be drawn a little bit transparent like in the openGL pickture I included above.
My DrawGlyph function does render a transparent texture at whitespaces. This shouldnt be the problem because it is working in OpenGL aswell.

EDIT: I am providing my AddTexture and DrawTexture function:

public STexture AddTexture(Bitmap bmp, string TexturePath)
{
STexture texture = new STexture(-1);
if (bmp.Height == 0 || bmp.Width == 0)
return texture;
int MaxSize;
switch (CConfig.TextureQuality)
{
case ETextureQuality.TR_CONFIG_TEXTURE_LOWEST:
MaxSize = 128;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_LOW:
MaxSize = 256;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM:
MaxSize = 512;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_HIGH:
MaxSize = 1024;
break;
case ETextureQuality.TR_CONFIG_TEXTURE_HIGHEST:
MaxSize = 2048;
break;
default:
MaxSize = 512;
break;
}

int w = bmp.Width;
int h = bmp.Height;

if (h >= w && w > MaxSize)
{
h = (int)Math.Round((float)MaxSize / bmp.Width * bmp.Height);
w = MaxSize;
}

if (w >= h && h > MaxSize)
{
w = (int)Math.Round((float)MaxSize / bmp.Height * bmp.Width);
h = MaxSize;
}

Bitmap bmp2 = new Bitmap(w, h);
Graphics g = Graphics.FromImage(bmp2);
g.DrawImage(bmp, new Rectangle(0, 0, w, h));
g.Dispose();


texture.width = bmp2.Width;
texture.height = bmp2.Height;
texture.w2 = texture.width;
texture.h2 = texture.height;

texture.width_ratio = texture.width / texture.width;
texture.height_ratio = texture.height / texture.height;

BitmapData bmp_data = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (MemoryStream stream = new MemoryStream())
{
bmp2.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
//Texture t = Texture.FromStream(m_Device, stream);
Texture t = Texture.FromStream(m_Device, stream, 0, w, h, 0, Usage.None, Format.A8R8G8B8, Pool.Managed, Filter.Default, Filter.Linear, 0);
t.AutoMipGenerationFilter = TextureFilter.Linear;
t.GenerateMipSublevels();
//t = Texture.FromStream(m_Device, stream);
_D3DTextures.Add(t);
}
bmp2.UnlockBits(bmp_data);
bmp2.Dispose();

// Add to Texture List
texture.index = _D3DTextures.Count - 1;
texture.color = new SColorF(1f, 1f, 1f, 1f);
texture.rect = new SRectF(0f, 0f, texture.width, texture.height, 0f);
texture.TexturePath = String.Empty;
_Textures.Add(texture);

return texture;
}


public void DrawTexture(STexture Texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored)
{
if ((Texture.index >= 0) && (_Textures.Count > 0) && (_D3DTextures.Count > Texture.index))
{
float x1 = (bounds.X - rect.X) / rect.W * Texture.width_ratio;
float x2 = (bounds.X + bounds.W - rect.X) / rect.W * Texture.width_ratio;
float y1 = (bounds.Y - rect.Y) / rect.H * Texture.height_ratio;
float y2 = (bounds.Y + bounds.H - rect.Y) / rect.H * Texture.height_ratio;

if (x1 < 0)
x1 = 0f;

if (x2 > Texture.width_ratio)
x2 = Texture.width_ratio;

if (y1 < 0)
y1 = 0f;

if (y2 > Texture.height_ratio)
y2 = Texture.height_ratio;

float rx1 = rect.X;
float rx2 = rect.X + rect.W;
float ry1 = rect.Y;
float ry2 = rect.Y + rect.H;

if (rx1 < bounds.X)
rx1 = bounds.X;

if (rx2 > bounds.X + bounds.W)
rx2 = bounds.X + bounds.W;

if (ry1 < bounds.Y)
ry1 = bounds.Y;

if (ry2 > bounds.Y + bounds.H)
ry2 = bounds.Y + bounds.H;
rect.Z = 1f;
//y1 = y1*-1;

rx1 = (((rx1-0.5f) * 2) / 1280) - 1f;
rx2 = (((rx2 -0.5f) * 2) / 1280) - 1f;
ry1 = (((ry1-0.5f) * 2) / 720) - 1f;
ry2 = (((ry2-0.5f) * 2) / 720) - 1f;

DataStream stream = _VertexBuffer.Lock(0, 0, LockFlags.None);
Color c = Color.FromArgb((int)(color.A*255), (int)(color.R*255), (int)(color.G*255), (int)(color.B*255));
stream.WriteRange(new[] {
new TexturedColoredVertex(new Vector3(rx1, ry1*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x1, y1), c.ToArgb()),
new TexturedColoredVertex(new Vector3(rx1, ry2*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x1, y2), c.ToArgb()),
new TexturedColoredVertex(new Vector3(rx2, ry2*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x2, y2), c.ToArgb()),
new TexturedColoredVertex(new Vector3(rx2, ry1*-1f, rect.Z + CGraphics.ZOffset), new Vector2(x2, y1), c.ToArgb()),
});
_VertexBuffer.Unlock();
m_Device.VertexDeclaration= TexturedColoredVertex.GetDeclaration(m_Device);
m_Device.SetTexture(0, _D3DTextures[Texture.index]);
m_Device.SetStreamSource(0, _VertexBuffer, 0, Marshal.SizeOf(typeof(TexturedColoredVertex)));
m_Device.DrawPrimitives(PrimitiveType.TriangleFan, 0, 2);
}
}


I am looking for a way to make textures a bit transparent.

Share this post


Link to post
Share on other sites
The bmp format does not support alpha channels (universally). Png would be a better choice.

Share this post


Link to post
Share on other sites
...and you still lock the vertex buffer each time you draw it (which effectively means at least once per frame).

Share this post


Link to post
Share on other sites
Ok, thanks for your tip changing from BMP to PNG. This removed the black bars biggrin.png. Could you please provide a snippet how to not lock the Vertex buffer each frame, because I am not getting it? And i still need the textures to be a bit translucent.

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!