Seite 1 von 9

Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 12:04
von HeinzK
Ich mach gerade meine ersten Schritte in OpenGL. So weit .. so gut.

Bisher habe ich unter DDraw auf folgende Weise gearbeitet:
- Vollbild mit Width und Height des aktuellen Desktop
- Alle Objekte (Linien, Bögen, Ellipsen, etc.) selber Pixelweise ins VRAM geschrieben
- Zoom und Pan über eine eigene Skalierung erzeugt
- 2D Sicht von Oben

Nun ich möchte ich das so effektiv wie möglich unter OpenGL nachahmen.

1. Problem: Eine EINHEIT soll ein Fenster-PIXEL groß sein.
Wie mach' ich das am Besten?
glViewport(...)
gluPerspective(.....)
glTanslatef(....)
Sind das die richtigen Funktionen, oder habe ich hierzu andere, bessere Möglichkeiten?

Nach ersten Test stelle ich mir vor, dass ich unter OpenGL Zoom und Pan über
die Kamera (gluPerspective) löse und mein Modell nicht mehr selbst skaliere! Richtig?

Ich hoffe auf eure Hilfe ..

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 12:16
von Aramis
Problem: Eine EINHEIT soll ein Fenster-PIXEL groß sein.
Dafuer bietet sich eine entsprechende Projektionsmatrix an. Nach Anwendung selbiger muessen alle Koordinaten im Bereich -1 … 1 sein (NDC). OpenGl macht dann das gleiche rueckwaerts, womit du wieder bei Fensterkoordinaten landest.

Also in etwa folgende Matrix:

Code: Alles auswählen

2.f/width,  0.f,  0.f, 0.f,
0.f, 2.f/height,  0.f, 0.f,
0.f,  0.f,  1.f, 0.f,
1.f, 1.f,  0.f, 1.f);
(Skalierung mit 1/Fenstergroeße und Verschiebung des Koordinatenursprunges). Eventuell muss an der einen oder andere Stelle noch ein ‘-’, abhaengig davon wo du deinen Ursprung haben willst. Wenn du nun ein Dreieck zeichnest, kannst du Fensterkoordinaten angeben (z-Wert zwischen -1 und 1).

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 12:22
von zwergmulch
Da du früher DDraw verwendet hast gehe ich mal davon aus dass du 2D-Grafik machst.
Also... ich würde keine der 4 Funktionen verwenden, sondern gluOrtho2D nehmen.
Das sieht dann wie folgt aus:

Code: Alles auswählen

glMatrixMode (GL_PROJECTION);
glLoadIdenty();
gluOrtho2D (0.0f, 800.0f, 600.0f, 0.0f);// left, right, bottom, top
Mfg Fabian

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 13:09
von Alexander Kornrumpf
Also ich hab seit alten DirectDraw Zeiten auch immer gedacht, dass ein Pixel eine natürliche Einheit wäre. Als ich für den aktuellen Contest aber mal wieder in 2D eingestiegen bin, ist mir klar geworden, dass das keinen Sinn ergibt, und man genau wie in 3D besser Einheiten verwendet, die von der Auflösung unabhängig sind. Ist jetzt nicht die Antwort die du hören wolltest, aber wenn du schon dabei bist, wäre es "Zukunftssicherer" sich von der Idee eines Pixels zu verabschieden.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 13:59
von HeinzK
Ich will alles hören .. aber mein Problem ist nicht, dass ich an den Pixels hänge, sondern
meine vorhandene Modellgröße ist so eingestellt, dass bei einer Fenstergröße
von 1280/1024, eine Einheit gleich einem Pixel ist. Diesen Zustand möchte ich gern als
Basis (1.0) für die Skalierung behalten.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 14:33
von HeinzK
Hallo Zwergmulch.
Dein Tipp mit gluOrtho2D ist 'gigangtisch'. Skalierung ist da! Gleiche Orientierung wie unter DDraw. Super!
Nächstes Problem:
Bild
Während ich das Bild 'vergrößere', sind diese unschönen Rahmen zu sehen.
Abgefangen habe ich nur WM_SIZE:

Code: Alles auswählen

case WM_SIZE:
    {
      ReSizeGLSzene(LOWORD(lParam), HIWORD(lParam));
      return 0;
      break;
    }
Gibt es hiefür eine bessere (weitere) Möglichkeit?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 14:34
von Alexander Kornrumpf
Die Frage ist ob du bei einer anderen Auflösung weiterhin einen Pixel als Einheit haben willst, dann wird der sichtbare Ausschnitt der Welt halt größer oder kleiner, oder ob man den selben Teil der Welt größer/kleiner sehen soll. Meistens will man letzteres.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 14:42
von HeinzK
Hallo Alexander Kornrumpf.
Die sichtbare Welt wird bei mir größer oder kleiner. EINHEIT=PIXEL ist nur ein Ausgangswert.
Ich weiß, wie groß meine Modelle bei 1280/1024 in der Skalierung 1.0 sind.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 15:51
von eXile
Schau mal nach WM_ENTERSIZEMOVE, WM_SIZING und WM_EXITSIZEMOVE.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 22:42
von HeinzK
Vielen Dank eXile für diesen Hinweis. Ich hab' etwas rumprobiert und bin auf folgende Lösung gekommen:

Code: Alles auswählen

    
    case WM_SIZING:
    {
      RECT WindowRect;
      GetClientRect(g_hWnd, &WindowRect);
      
      ReSizeGLSzene
      (
        (WindowRect.right - WindowRect.left), 
        (WindowRect.bottom - WindowRect.top)
      );
      
      DrawGLSzene();
      SwapBuffers(g_hDC);
      
      return 0;
      break;
    }
Jetzt kann ich vergrößern, ohne das diese 'etwas häßlichen' Ränder sichtbar werden!

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 08.05.2010, 22:46
von HeinzK
Ich hab' gerade beim Debuggen gemerkt, dass ich WindowRect und ReSizeGLSzene()
hier nicht brauche. Neuer Code:

Code: Alles auswählen

case WM_SIZING:
    {
      DrawGLSzene();
	    SwapBuffers(g_hDC);
      
      return 0;
      break;
    }

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 09.05.2010, 11:02
von HeinzK
Eine Frage: Welche Präprozessorvariable verwende ich am Besten um
zu erkennen ob ich unter Linux/Ubuntu oder Windows arbeite, wenn ich
den gleichen Quelltext zum Compilieren verwenden will.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 09.05.2010, 11:14
von eXile
Man schaue hier nach: http://msdn.microsoft.com/en-us/library/b0084kay.aspx
Und man sehe: "_WIN32 - Defined for applications for Win32 and Win64. Always defined. "

Dementsprechend sollte ausreichen (wenn du nur Windows und Linux als Zielplattform anstrebst):

Code: Alles auswählen

#ifdef _WIN32
// Windows
#else
// Linux
#endif

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 09:35
von HeinzK
Ich entwickle aktuell mit C++ auf VS 2008 unter Windows.
Nun habe ich Linux (Ubuntu mit VMWare auf einem Windows-XP-Rechner) installiert.
Auf der Suche nach einer Entwicklungsumgebung für C++ unter Ubuntu bin ich auf den Compiler CB (Code-Blocks) gestossen.
Mit der IDE von CB käme ich zwar klar, aber ...
Sie ist VS sehr ähnlich, ich muss auf beiden Plattformen arbeiten, will nicht ständig umdenken (da F5 dort F8, etc.).
Und .. mal einfach so gesagt .. Entwicklungstechnisch wäre es eine gewaltiger Rückschritt.
Also, lange Rede, kurzer Sinn, hat jemand Erfahrung mit Visual Studio unter Linux?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 10:45
von Tobiking
HeinzK hat geschrieben:Also, lange Rede, kurzer Sinn, hat jemand Erfahrung mit Visual Studio unter Linux?
Nach http://appdb.winehq.org/objectManager.p ... on&iId=892 sieht es schlecht damit aus, da es sich nichtmals installieren lässt. Zudem wäre da auch noch das Problem, dass man die Toolchain auf die Linux Tools und Libs anpassen müsste. Da ist Visual Studio etwas weniger komfortabel als die meisten anderen IDEs, die dafür gedacht sind auf verschiedenen Betriebssystemen zu laufen.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 10:50
von HeinzK
Ich war der Meinung, es gibt Visual Studio für Linux .. ? (ohne WinE)

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 11:41
von Aramis
Nein, gibt es nicht. Auch wenn Microsoft schon mehrfach angekuendigt hat dass sie gerne Anwendungsentwickler unter Linux unterstuetzen wuerden. Weil der Pinguin ein tolles Betriebssystem ist, und vor allem ein so billiges.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 12:08
von kimmi
Man kann mittels CMake sich aber Projectfiles für das Visual-Studio unter Windows und für KDevelop unter Linux generieren, wenn man will.

Gruß Kimmi

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 18:18
von HeinzK
Linux/Ubuntu/CB/KonsolenAnwendung
Wenn ich folgende Code Erzeuge erhalte ich die nachfolgende Warnung:

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
void fatalError(char *message)
{
  fprintf(stderr, "Fehler: %s\n", message);
  exit(1);
}
int main(int argc, char **argv)
{
  fatalError("Text!");
  return 0;
}
13|warning: deprecated conversion from string constant to ‘char*’
Wenn ich Linux/Ubuntu/CB/OpenGL project öffne, ist der gleiche Codeteil enthalten,
aber es kommt beim kompilieren zu keiner Warnung.
In den 'Project build options' sehe ich aber keine Unterschiedlichen Einstellungen.
VS 2008 meldet bei Warnstufe Level 3 auch nichts.
Ich bin durch dieses unterschiedliche Verhalten 'etwas' verunsichert .. :-)

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 18:21
von Aramis
Das Problem ist, dass eine Zeichenkette (genauer, ein string-literal) zwar den Datentyp char* hat (bzw. zumindest in C hatte, der aktuelle C++ Sprachstandard definiert String-Literale als array of const char), aber dennoch nicht modifiziert werden darf, da der Compiler sie ueblicherweise in einer read-only Sektion ablegt. Vermutlich kompilierst du in einem der Projekte mit -wall – die Warnung ist gerechtfertigt.

Code: Alles auswählen

void fatalError(const char *message)

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 18:49
von Krishty
Wenn wir schon mit const anfangen, dann bitte richtig (in der Postfix-Variante):
void fatalError(char const *message)

Ist nur ein Detail, aber das macht es jedem, der den Umgang mit const erst lernt, einfacher – spätestens, wenn es denn zu const-Zeigern und const-Memberfunktionen kommt.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 19:02
von HeinzK
Ok, kapiert. Der Unterschied liegt also an C und C++.
Wenn genauer hingesehen hätte .. das Beispiel, das mir als Vorlage dient ist eine *.c und meine
Konsolenanwendung habe ich als C++ gestartet.
Außerdem bin ich den Umgang mit char nicht gewöhnt, bisher habe ich immer CString benutzt.
Da kommt wohl auch noch einiges an Arbeit auf mich zu?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 19:20
von Aramis
dann bitte richtig
Beides ist richtig, wie du genau weißt :-) Die Postfix-Variante hat nur die genannten Vorteile wenn mehrere const's im Spiel sind. Die Praefix-Variante ist in allen anderen Faellen (imho!) intuitiver zu lesen. Eine Auffassung, die der C++ – Sprachstandard teilt.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 19:27
von Krishty
Kritisierst mir sogar den 777sten Post kaputt … :( Wird dir bei deinem 555sten heimgezahlt werden!

Stimmt schon, richtig ist auch 3["blubb"];, aber eben richtig scheiße. Man sollte sich – wieder imho – angewöhnen, alle Typen rückwärts zu lesen … selbst ohne const liest man char * ja als „Zeiger auf Buchstabe“ und nicht als „Buchstabe in Zeiger“.


Für die, die nicht mitreden können: const hinten anzuhängen ist bei vielen consts konsistenter, weil man Typen von hinten liest, also
char const * * const * &
als
& * const * * const char
d.h.
„Referenz von Zeiger auf konstanten Zeiger auf Zeiger auf konstanten Buchstaben“

const landet bei Zeigern und Member-Funktionen eh immer hinten, warum also für die restlichen Typen eine Ausnahme machen? … frage ich mich auch beim Standardkommitee.


Sorry, Heinz, für’s Sprengen des Topics …

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 22:48
von HeinzK
Alles OK, Krishty. Ich bin für alle Informationen dankbar!

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 22:57
von HeinzK
Hurra, mein erstes Fenster unter Linux/Ubuntu/OpenGL ist gerendert :P.
Ich hätte da eine bescheidene Bitte. Könnt ihr den prinzipiellen Ablauf begutachten und bewerten.
http://www.zwianer.de/Probleme/TestOpenGL.zip
Inhalt:
KHilfen.cpp
KHilfen.h
KOpenGL.cpp
KOpenGL.h
main.cpp
main.h
TestOpenGL.cbp
TestOpenGL.depend
TestOpenGL.laylout

Es gehr mir nur darum, habe ich etwas entscheidendes Übersehen, oder etwas doppelt gemoppelt?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 10.05.2010, 23:13
von Aramis
Sieht gut aus. Einzig der glLoadIdentity–Aufruf in der Hauptschleife ist eigentlich ueberfluessig, denke ich (erstens zeichnest du ja nichts, der Matrixstack wird also gar nicht benoetigt, zweitens behaelt er seinen Status auch ueber mehrere Frames bei).

Jetzt wuerde ich an deiner Stelle mal anfangen was zu zeichnen - fuer 2D wirst du vermutlich den Tiefenbuffer deaktivieren wollen (GL_DEPTH_TEST), außerdem musst du dann natuerlich die eingangs besprochene Projektion nutzen wollen.

Ansonsten koenntest du natuerlich auch ein Framework wie glfw verwenden um dir das Vergnuegen, mit dem XServer zu kommunizieren, zu ersparen und auf allen Plattformen die gleiche Codebasis benutzen zu koennen. Haengt aber natuerlich von deinen Anforderungen ab.

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 11.05.2010, 09:24
von HeinzK
Wenn ich das Programm (s.o.) debugge, dann erscheint ein Fenster 'Program Console' mit dem Hinweis:
warning: GDB: Failed to set controlling terminal: Operation not permitted
Darüber dann mein 'main'-Fenster.
Was mache ich da falsch?
Wenn ich das Programm im Release-Modus starte, erscheint die 'Program Console' nicht nur das 'main'-Fenster!?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 11.05.2010, 09:40
von HeinzK
Frage:
Windows:

Code: Alles auswählen

gluOrtho2D(0.0f, width, height, 0.0f);
Linux: ?

Re: Auf dem Weg von DDraw nach OpenGL ..

Verfasst: 11.05.2010, 10:36
von Tobiking
HeinzK hat geschrieben:Frage:
Windows:

Code: Alles auswählen

gluOrtho2D(0.0f, width, height, 0.0f);
Linux: ?
Das Gleiche. Glu gibt es auch unter Linux. Also GL/glu.h includieren und GLU mitlinken (-lGLU als ld Parameter). Wahrscheinlich musst du dafür aber noch das Entwicklerpaket für die Header installieren. Unter Ubuntu müsste das libglu1-mesa-dev sein.