PDA

View Full Version : [OpenGL 1.X] Drawing 2D Texture with custom Transparency



XamlDdev
07-17-2013, 10:51 AM
Good morning.

I am an ex XNA developer and i start to migrate to OpenGL 1.X to begin.

My goal is to make a very simple 2D drawing library which could draw primitives (circles, boxes, lines) and texture. with parametrized alpha value and color.

I use C# language and OpenGL wrapper called TAO which provide me 1-1 mapping to OpenGL functions.

I have some problems on displaying a texture with both invisible part (it's some background not to be drawn) and a custom transparency value.

I have a second problem which is (i think) is linked to the first one : i could not change the color of primitives to be drawn, it always keep the same value.

This is my code below :

First i used a class called Texture containing some information for my 2d resource :




public sealed class Texture
{
#region Fields

private Color _alphaColor;
private int _width;
private int _height;
private int _index;

#endregion

#region Properties

public Color GetAlphaColor()
{
return _alphaColor;
}

public int GetWidth()
{
return _width;
}

public int GetHeight()
{
return _height;
}

public int GetIndex()
{
return _index;
}

#endregion

#region Ctors

public Texture(int width, int height, int index, ref Color alphaColor)
{
_alphaColor = alphaColor;
_width = width;
_height = height;
_index = index;
}

#endregion
}



I load my texture from my own type file containing the color of background, height, width and a bytes list figuring RGB datas.




private static Texture LoadTexture(string path)
{
Texture surface;

using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open)))
{
byte rValue = reader.ReadByte();
byte gValue = reader.ReadByte();
byte bValue = reader.ReadByte();

Color alphaColor = Color.FromArgb(rValue, gValue, bValue);

int width = reader.ReadInt32();
int height = reader.ReadInt32();

int colorCount = reader.ReadInt32() / 3;

byte[] bytes = new byte[colorCount * 4];
int indexBytes = 0, indexColor;

byte aValue;

for (indexColor = 0; indexColor < colorCount; ++indexColor)
{
bValue = reader.ReadByte();
gValue = reader.ReadByte();
rValue = reader.ReadByte();

aValue = 255;

if (rValue == alphaColor.R && gValue == alphaColor.G && bValue == alphaColor.B)
{
aValue = 0;
}

bytes[indexBytes] = rValue; ++indexBytes;
bytes[indexBytes] = gValue; ++indexBytes;
bytes[indexBytes] = bValue; ++indexBytes;
bytes[indexBytes] = aValue; ++indexBytes;
}

reader.Close();

Gl.glBindTexture(Gl.GL_TEXTURE_2D, _textureIds[0]);

Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);

Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, 4, width, height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, bytes);

surface = new Texture(width, height, _textureIds[0], ref alphaColor);
}

return surface;
}



In initialization process i used a PIXELFORMATDESCRIPTOR with default values :




Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();
pfd.nSize = (short)Marshal.SizeOf(pfd);
pfd.nVersion = 1;
pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW | Gdi.PFD_SUPPORT_OPENGL | Gdi.PFD_DOUBLEBUFFER;
pfd.iPixelType = (byte)Gdi.PFD_TYPE_RGBA;
pfd.cColorBits = (byte)bits;
pfd.cRedBits = 0;
pfd.cRedShift = 0;
pfd.cGreenBits = 0;
pfd.cGreenShift = 0;
pfd.cBlueBits = 0;
pfd.cBlueShift = 0;
pfd.cAlphaBits = 0;
pfd.cAlphaShift = 0;
pfd.cAccumBits = 0;
pfd.cAccumRedBits = 0;
pfd.cAccumGreenBits = 0;
pfd.cAccumBlueBits = 0;
pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = 16;
pfd.cStencilBits = 0;
pfd.cAuxBuffers = 0;
pfd.iLayerType = (byte)Gdi.PFD_MAIN_PLANE;
pfd.bReserved = 0;
pfd.dwLayerMask = 0;
pfd.dwVisibleMask = 0;
pfd.dwDamageMask = 0;



I initialize OpenGl wuth those flags.




public static bool InitGL()
{
Gl.glClearColor(0, 0, 0, 1);
Gl.glGenTextures(1, _textureIds);

_currentTexture = LoadTexture("A.pof");

Gl.glEnable(Gl.GL_TEXTURE_2D);

Gl.glDisable(Gl.GL_DEPTH_TEST);
Gl.glDisable(Gl.GL_LIGHTING);
Gl.glDisable(Gl.GL_DITHER);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glOrtho(0, 640, 480, 0, 0, 1);
Gl.glMatrixMode(Gl.GL_MODELVIEW);

Gl.glTexEnvi(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);

return true;
}



Here come my drawing primitives :




public static void DrawPoint(int x, int y, Color color)
{
Gl.glColor3b(color.R, color.G, color.B);

Gl.glBegin(Gl.GL_POINTS);

Gl.glVertex2i(x, y);

Gl.glEnd();
}

public static void DrawLine(Point p1, Point p2, Color color)
{
Gl.glColor4b(color.R, color.G, color.B, 255);

Gl.glBegin(Gl.GL_LINES);

Gl.glVertex2i(p1.X, p1.Y);
Gl.glVertex2i(p2.X, p2.Y);

Gl.glEnd();
}

public static void DrawFilledRectangle(Rectangle rectangle, Color color, byte alpha)
{
int tempX = rectangle.X + rectangle.Width, tempY = rectangle.Y + rectangle.Height;


Gl.glBegin(Gl.GL_QUADS);

Gl.glColor4b(color.R, color.G, color.B, alpha);

Gl.glVertex2i(rectangle.X, rectangle.Y);
Gl.glVertex2i(tempX, rectangle.Y);
Gl.glVertex2i(tempX, tempY);
Gl.glVertex2i(rectangle.X, tempY);

Gl.glEnd();
}

public static void DrawRectangle(Rectangle rectangle, Color color)
{
int tempX = rectangle.X + rectangle.Width, tempY = rectangle.Y + rectangle.Height;

Gl.glColor4b(color.R, color.G, color.B, 255);

Gl.glBegin(Gl.GL_LINE_LOOP);

Gl.glVertex2i(rectangle.X, rectangle.Y);
Gl.glVertex2i(tempX, rectangle.Y);
Gl.glVertex2i(tempX, tempY);
Gl.glVertex2i(rectangle.X, tempY);

Gl.glEnd();
}




Now my texture drawing function :




public static void DrawTexture(Texture texture, Point point, byte alpha)
{
Gl.glEnable(Gl.GL_ALPHA_TEST);
Gl.glAlphaFunc(Gl.GL_GREATER, 0);

Gl.glEnable(Gl.GL_BLEND);

Gl.glColor4b(255, 255, 255, alpha);

Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);

Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture.GetIndex());

Gl.glBegin(Gl.GL_QUADS);

Gl.glTexCoord2d(0, 0);
Gl.glVertex2i(point.X, point.Y);

Gl.glTexCoord2d(1, 0);
Gl.glVertex2i(point.X + texture.GetWidth(), point.Y);

Gl.glTexCoord2d(1, 1);
Gl.glVertex2i(point.X + texture.GetWidth(), point.Y + texture.GetHeight());

Gl.glTexCoord2d(0, 1);
Gl.glVertex2i(point.X, point.Y + texture.GetHeight());

Gl.glEnd();

Gl.glDisable(Gl.GL_ALPHA_TEST);
Gl.glDisable(Gl.GL_BLEND);
}



I use this function to call drawings :




public static bool DrawGLScene()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Point p1 = new Point(0, 0);
Point p2 = new Point(30, 200);

DrawTexture(_currentTexture, p1, 255);

DrawTexture(_currentTexture, p2, 64);

DrawRectangle(new Rectangle(0, 0, 50, 60), Color.White);
DrawFilledRectangle(new Rectangle(0, 0, 50, 60), Color.Blue, 255);

DrawLine(p1, p2, Color.Blue);

DrawPoint(p2.X, p2.Y, Color.White);

return true;
}




But the second drawing texture 'DrawTexture(_currentTexture, p2, 64);) is not transparent ...