Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Mai 15, 2024 00:55

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Autor Nachricht
BeitragVerfasst: Mi Nov 17, 2010 16:24 
Offline
DGL Member

Registriert: Mi Nov 17, 2010 15:31
Beiträge: 14
Programmiersprache: C, ASM, C++
EDIT: Sehe grade das Einsteiger Forum. Hätte ich vielleicht da fragen sollen? Wenn so ist, wäre eine Verschiebung nett :D

Hallo Leute,

gleich in meinem 1. Posting habe ich ne Frage an euch :) .

Ich habe eine längerfristige Aufgabe, bei der am Ende ein OpenGl Programm entstehen soll, was Signale eines Gerätes (in einem Hubschrauber) grafisch darstellen soll. Dies beinhaltet vor allen Dingen die Erstellung einer Kompassrose. Programmiert wird in C (was aber für meine Frage keine Rolle spielen sollte) und mit FreeGlut. Zur Übung habe ich folgendes erstellt.

Code:
#include <GL/freeglut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/// Relevante Kreis-Daten
#define PI 3.1415926535898
#define circle_points 200   // Anzahl von Liniensegmenten zur Zeichnung eines Kreises -> Genauigkeit

/// Dimensionen des zugrundegelegten Koordinatensystems
#define Dy 2.5;                  // Dimension der Y-Achse
#define Dx 2.5;                  // Dimension der X-Achse

typedef struct
{
    float rotation;
}Input_t;

typedef struct
{
    double ScaleFactorX;            // Skalierungsfaktor in X-Richtung
    double ScaleFactorY;            // Skalierungsfaktor in Y-Richtung
    double ScaleFactor;             // Hilfsvariable
    double RightShift;              // Rechtsverschiebung
    double TopShift;                // Höhenverschiebung
}State_t;

Input_t input_t;
State_t state_t;





void MyInit()
{
    glClearColor (0.0, 0.0, 0.0, 0.0);  // Hintergrundfarbe schwarz bei "gecleartem" Bildschirm
    glShadeModel (GL_FLAT);
    glEnable(GL_LINE_SMOOTH);

    /// Anti-Aliasing der Linien -> Kreis, Markierungen, etc.
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}


void render_circle()
{
    int i;
    int j;
    double angle_start;
    double angle_cur;
    char *text = "Hallo";
    float length;


    angle_start = (2*PI) / circle_points;  // Winkel eines Linienelements des Kreises

    /// Einheitskreis
    glPushMatrix(); // damit Rotation sich nicht aufaddiert
        glRotatef(input_t.rotation*5, 0, 0, 1);

        glBegin(GL_LINE_LOOP);
        glEnable(GL_LINE_SMOOTH);
            glVertex2d(cos(0), sin(0));     // Startpunkt => Einheitskreis mit Radius 1
            for(i=0; i<circle_points; i++)
            {
                glVertex2d(cos(angle_cur), sin(angle_cur));
                angle_cur += angle_start;
            }
        glEnd();

    /// Liniensegmente
        glPushMatrix();
            for(j=0; j<12; j++)         // 12*30 Grad = 360 Grad
            {
                glRotated(30, 0, 0, 1);
                glBegin(GL_LINES);
                    glVertex2f(0, 1.05);
                    glVertex2f(0, 0.95);
                glEnd();
            }
        glPopMatrix();

    /// Beschriftung mit Strokes
        glPushMatrix();

            glTranslatef(0.5, 0.5, 0);
//           glScaled(state_t.ScaleFactor, state_t.ScaleFactor, 1);
            glutStrokeString(GLUT_STROKE_ROMAN, (unsigned char*) text);

    /// Beschriftung mit Bitmaps
//            glRasterPos2f(0.5, 0);
//            glutBitmapString(GLUT_BITMAP_HELVETICA_10, (unsigned char*) text);
        glPopMatrix();
    glPopMatrix();






}


void MyResize(int LocalWidth, int LocalHeight)
{

    glViewport(0, 0, LocalWidth, LocalHeight);

    state_t.ScaleFactorX = LocalWidth  / Dx;
    state_t.ScaleFactorY = LocalHeight / Dy;

    state_t.RightShift = LocalWidth/2;      // Rechtsverschiebung um die halbe Breite des momentan offenen Fensters
    state_t.TopShift   = LocalHeight/2;     // Höhenverschiebung um die halbe Höhe des momentan offenen Fensters



    if(state_t.ScaleFactorX < state_t.ScaleFactorY) // Wenn Breite kleiner als Höhe, dann muss Höhe skaliert werden mit dem Faktor der Breite
    {
        state_t.ScaleFactor = state_t.ScaleFactorX;
    }

    else
    {
        state_t.ScaleFactor = state_t.ScaleFactorY; // s.o.
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,LocalWidth, 0, LocalHeight, -1, 1);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslated(state_t.RightShift, state_t.TopShift, 0);
    glScaled(state_t.ScaleFactor, state_t.ScaleFactor,1);
}


void MyRender()
{
    glClear(GL_COLOR_BUFFER_BIT);   // Leeren des Farbbuffer

    render_circle();                // Rendern des Kreises

    glutSwapBuffers();
}


void MyKeyboard (unsigned char C, int X, int Y)
{
    switch (C)
    {
      case 0x1b:          // Escape Taste beendet das OpenGL Fenster
           exit(1);
          break;
      default:
          printf ("Key: '%c' %i\n", C, (unsigned int)C);
          break;
    }
}


void MySpecial(int Key, int X, int Y)
{
    switch (Key)
    {
    case GLUT_KEY_RIGHT:

        input_t.rotation -= 1;
        break;

    case GLUT_KEY_LEFT:
        input_t.rotation += 1;
        break;
    default:

        break;
    }

}



int main(int argc, char **argv)
{
    int XPos;   // Fensterposition auf der X-Achse
    int YPos;   // Fensterposition auf der Y-Achse
    int XMax;   // Fenstergröße in X-Richtung
    int YMax;   // Fenstergröße in Y-Richtung


    /// Abfragen der Kommandozeilenparameter

//    sscanf(argv[1], "%d", &XPos);
//    sscanf(argv[2], "%d", &YPos);
//    sscanf(argv[3], "%d", &XMax);
//    sscanf(argv[4], "%d", &YMax);


    /// Wesentliche Glut Initialisierungen

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
//    glutInitWindowSize(XMax, YMax);
//    glutInitWindowPosition(XPos, YPos);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(1, 1);
    glutCreateWindow("Bewegbarer Kreis, etc.");


    MyInit();
    glutDisplayFunc(MyRender);
    glutReshapeFunc(MyResize);
    glutKeyboardFunc(MyKeyboard);
    glutSpecialFunc(MySpecial);
    glutIdleFunc(MyRender);       


    glutMainLoop();




    return 0;
}






Wie man sieht, erzeugt das Programm einen Einheitskreis mit Gradmarkierungen in 30er Schritten, welcher mit den Pfeiltasten drehbar und schön skalierbar ist und die Achsen die Länge 2.5 haben (natürlich in Pixeln, was ich mir ja aber festlegen kann, wie ich will).

Mein eigentliches Problem steckt nun in der Funktion render_circle().
Ich möchte nun nämlich Texte in Form von Strokes (Programm muss skalierbar sein) hinzufügen. Nun gibts es bei FreeGlut die Funktion GlutStrokeString, womit man das bewerkstelligen kann (funktioniert ja wie GlutStrokeCharacter, nur für Strings^^^). Das Problem ist nur, dass ich ja, im Gegensatz zu Bitmaps, glTranslate benutzen muss, um meinen Text zu platzieren. Ums kurz zu machen, mit Bitmaps arbeiten ist kein Problem, er legt mir den Text dahin, wo ich das will (im Quellcode ist diese Möglichkeit ausgegraut).
Mit den Strokes klappt das aber nicht. Er zeichnet den Text zwar, aber Riesengroß und an völlig andere Stellen, und ich sehe den Text auch nur, wenn ich meine Werte für Dx, Dy (Werte meiner neu festgelegten Koordinatenachsen) auf Werte wie 800*600 setze. Mir scheint es so, als ob die Skalierung, Verschiebung, Achsengröße, etc. der ModelView Matrix aus MyResize nicht registriert wird, oder sowas ähnliches. Vielleicht hat glTranslate auch andere Auswirkungen, die ich nicht überblicke, auf jeden Fall hält sich das Programm nicht mehr an meine durchgeführten Skalierungen. Ich habe schon probiert meine in MyResize ausgerechneten Skalierungsfaktoren nochmal neu auf den Text anzuwenden (ausgegraut), aber es funktioniert alles nicht.
Ich kanns leider schlecht erklären, aber vielleicht seht ihr da Problem ja im Quellcode, oder seid in der Lage das Programm auszuführen.

Ich hoffe mir kann da jmd. weiterhelfen, ich hab absolut keine Ideen mehr.
Wenn noch Fragen sind, stellt sie. Hab bestimmt nen Detail vergessen ;) .

Vielen Dank schonmal an dieser Stelle.

EDIT:

Nach weiterem rumprobieren steht fest, dass das Problem ausschließlich in der Skalierung des Textes lieggt. Anscheinend muss ich den Text nochmal unabhängig von meinen vorherigen Skalierungen skalieren (super Formulierung). Allerdings komme ich hier mit (aus meiner Sicht) logischen Werten nicht weiter. Auch mit willkürlichen Werten tut sich nichts. Hat an dieser Stelle jemand ne Idee?

EDIT":

Wenn ich Skalierungsfaktoren von 0.005 nehme, kommt der Text immerhin in Reichweite, ist aber immer noch vie zu groß. Dabei entspricht 0.005 ungefähr der Rechnung 1/ ScaleFactor (siehe Quellcode). Wie ich nun rechnerisch auf den richtigen Skalierungsfaktor komme, ist mir noch unklar.

EDIT3:

Jetzt hab ich die Lösung. Ich musste 1 durch die maximale Scriftgröße (in diesem Fall laut Freeglut Doku 119.05) teilen und dann mit einem Faktor multiplizieren, der mir die Schriftgröße im Verhälntnis zum Kreisradius liefert.


Andere Frage:

Nun möchte ich noch die Linienbreite mit der Größe des Fensterns skalieren. Wem da spontan was einfällt..... Ich probier erstmal rum.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 10 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.034s | 17 Queries | GZIP : On ]