(Gelöst) Bitmap in C# via OpenGL darstellen.
-
Hallo.
Ich meinem Program arbeite ich mit OpenGL. Dabei möchte ich Texte im Grafikfenster ausgeben. Der Code, einen Text in ein Bitmap umzuwandeln - der funktioniert wunderbar.
Beim Darstellen - naja, funktioniert auch etwas - aber es funktioniert nicht wirklich. Wenn ich als Hintergrundfarbei z.B. Grün angebe, dann wird ein Bitmap mit grünem Hintergrund und dem Text darauf erstellt. Das kann ich mir ansehen, das passt (außer, dass es Spiegelverkehrt ist - aber erstmal das eine).
In meinem OpenGL Fenster wird mir ein Quadrat mit der Farbe des Hintergrunds - bzw. schwarz, wenn ich transparent wähle. Also, da kommt schon was an. Vielleicht habe ich mit der Farbcodierung oder mit dem Bitmapformat einen Fehler, ich weiß es nicht. Oder der Zoom ist total falsch, aber ich habe schon viele verschiedene Viewports versucht.Anbei der Code:
using Tao.OpenGl; using Tao.Platform.Windows; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D;
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; SimpleOpenGlControl MainOGL = new SimpleOpenGlControl(); MainOGL.Dock = DockStyle.Fill; MainOGL.BackColor = Color.Black; MainOGL.Paint += new System.Windows.Forms.PaintEventHandler(MainOGL_Paint); this.Controls.Add(MainOGL); MainOGL.InitializeContexts(); } private void MainOGL_Paint(object sender, EventArgs e) { int Size = Math.Min(this.Width, this.Height); //Size = 1000; Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); Gl.glClearColor((float)0.0, (float)0.0, (float)0.0, (float)0.0); //Background color Gl.glViewport(0, 0, Size, Size); Gl.glColor3f(0.0f, 0.0f, 1.0f); Glu.gluOrtho2D(-1.0, 1.0, -1.0, 1.0); OGL_Text.AddText("Hallo", System.Drawing.Color.Red, System.Drawing.Color.Green,(float)0.0, (float)0.0, (float)1.0); } }
Und hier die Klasse zur Darstellung des Textes:
unsafe static class OGL_Text { public static void AddText(string text, Color color, Color backcolor, float x, float y, float scale) { const int side = 256; Bitmap texture = new Bitmap(side, side, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(texture); using (Brush brush = new SolidBrush(backcolor)) { g.FillRectangle(brush, new Rectangle(Point.Empty, texture.Size)); } using (Font font = new Font(SystemFonts.DialogFont.FontFamily, 12f)) { SizeF sz = g.MeasureString(text, font); float f = 256 / Math.Max(sz.Width, sz.Height) * scale; g.TranslateTransform(256 / 2 + f * sz.Width / 2, 256 / 2 - f * sz.Height / 2); g.ScaleTransform(-f, f); using (Brush brush = new SolidBrush(color)){g.DrawString(text, font, brush, 0, 0);} } texture.Save("C:/HomeC/Test.bmp"); LoadTexture(texture, false); } private static int LoadTexture(Bitmap texture, bool mipmaped) { int id; Gl.glGenTextures(1, out id); Gl.glBindTexture(Gl.GL_TEXTURE_2D, id); int wt = texture.Width; int ht = texture.Height; Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT); Gl.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_MODULATE); Gl.glTexParameteri(Gl.GL_TEXTURE_2D,Gl.GL_TEXTURE_MIN_FILTER, (int)Gl.GL_NEAREST); Gl.glTexParameteri(Gl.GL_TEXTURE_2D,Gl.GL_TEXTURE_MAG_FILTER, (int)Gl.GL_NEAREST); System.Drawing.Imaging.BitmapData data = texture.LockBits( new Rectangle(0, 0, wt, ht), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb); Gl.glTexImage2D(Gl.GL_TEXTURE_2D,0,Gl.GL_RGBA,wt, ht, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, data.Scan0); texture.UnlockBits(data); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glColor3f(1.0f, 1.0f, 1.0f); Gl.glBegin(Gl.GL_QUADS); Gl.glVertex2d(0.0, 0.0); Gl.glVertex2d(wt, 0.0); Gl.glVertex2d(wt, ht); Gl.glVertex2d(0.0, ht); Gl.glEnd(); Gl.glDisable(Gl.GL_TEXTURE_2D); return id; } }
-
Also erstmal solltest du vermutlich glClearColor VOR glClear aufrufen. Was aber mit deinem Problem nix zu tun hat.
Und dann...
Wo übergibst du denn die Texturkoordinaten (glTexCoord2d
?)?
-
Hallo,
das habe ich auch schon erkannt und habe es eingebaut - ändert aber nichts.
Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glColor3f(1.0f, 1.0f, 1.0f); Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2d(0, 0); Gl.glVertex2d(0.0, 0.0); Gl.glTexCoord2d(1, 0); Gl.glVertex2d(wt, 0.0); Gl.glTexCoord2d(1, 1); Gl.glVertex2d(wt, ht); Gl.glTexCoord2d(0, 1); Gl.glVertex2d(0.0, ht); Gl.glEnd(); Gl.glFlush(); Gl.glDisable(Gl.GL_TEXTURE_2D);
-
Es ist der Befehl:
Glu.gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
Die Argumente sind keine Richtungen, sondern geben tatsächlich das Sichtfeld an.
Wenn ich statt dessen:
Glu.gluOrtho2D(-256, 256, -256, 256);
schreibe, kann ich das komplette Bitmap sehen - naja, noch Spiegelverkehrt und blaut statt rot, aber da muss man nur an den GL_RGBs etwas drehen und mit
texture.RotateFlip(RotateFlipType.RotateNoneFlipX);
texture.RotateFlip(RotateFlipType.RotateNoneFlipY);
kann man das Bitmap spiegeln.
Damit können wir das schließen.
-
Da man diese Frage bei Google häufiger findet, hier der Code für C# und das Tao Framework:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; SimpleOpenGlControl MainOGL = new SimpleOpenGlControl(); MainOGL.Dock = DockStyle.Fill; MainOGL.BackColor = Color.Black; MainOGL.Paint += new System.Windows.Forms.PaintEventHandler(MainOGL_Paint); this.Controls.Add(MainOGL); MainOGL.InitializeContexts(); } private void MainOGL_Paint(object sender, EventArgs e) { int Size = Math.Min(this.Width, this.Height); //Size = 1000; Gl.glClearColor((float)0.0, (float)0.0, (float)0.0, (float)0.0); //Background color Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); Gl.glViewport(-100, -200, Size, Size); Gl.glColor3f(0.0f, 0.0f, 1.0f); Glu.gluOrtho2D(-this.Width / 2, this.Width / 2, -this.Height / 2, this.Height / 2); OGL_Text.AddText("Hallo!", System.Drawing.Color.Blue, System.Drawing.Color.Transparent,(float)0.0, (float)0.0, (float)1.0); } }
Und eine Klasse für die String Ausgabe:
unsafe static class OGL_Text { public static void AddText(string text, Color color, Color backcolor, float x, float y, float scale) { const int side = 256; Bitmap texture = new Bitmap(side, side, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(texture); using (Brush brush = new SolidBrush(backcolor)) { g.FillRectangle(brush, new Rectangle(Point.Empty, texture.Size)); } using (Font font = new Font(SystemFonts.DialogFont.FontFamily, 12f)) { SizeF sz = g.MeasureString(text, font); float f = 256 / Math.Max(sz.Width, sz.Height) * scale; g.TranslateTransform(256 / 2 + f * sz.Width / 2, 256 / 2 - f * sz.Height / 2); g.ScaleTransform(-f, f); using (Brush brush = new SolidBrush(color)){g.DrawString(text, font, brush, 0, 0);} } texture.RotateFlip(RotateFlipType.RotateNoneFlipX); texture.RotateFlip(RotateFlipType.RotateNoneFlipY); LoadTexture(texture, false); } private static int LoadTexture(Bitmap texture, bool mipmaped) { int id; Gl.glGenTextures(1, out id); Gl.glBindTexture(Gl.GL_TEXTURE_2D, id); int wt = texture.Width; int ht = texture.Height; Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER,Gl.GL_LINEAR); Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER,Gl.GL_LINEAR); System.Drawing.Imaging.BitmapData data = texture.LockBits( new Rectangle(0, 0, wt, ht), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, wt,ht, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, data.Scan0); texture.UnlockBits(data); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glColor3f(1.0f, 1.0f, 1.0f); Gl.glBegin(Gl.GL_QUADS); Gl.glTexCoord2d(0, 0); Gl.glVertex2d(0.0, 0.0); Gl.glTexCoord2d(1, 0); Gl.glVertex2d(wt, 0.0); Gl.glTexCoord2d(1, 1); Gl.glVertex2d(wt, ht); Gl.glTexCoord2d(0, 1); Gl.glVertex2d(0.0, ht); Gl.glEnd(); Gl.glDisable(Gl.GL_TEXTURE_2D); return id; } }
-
für Lösung posten