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

Aktuelle Zeit: Di Jul 15, 2025 11:14

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 22 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 19, 2005 18:05 
Offline
DGL Member
Benutzeravatar

Registriert: Do Feb 24, 2005 22:44
Beiträge: 29
Ich hätte auch noch eine kleine Frage.
Dadurch, dass ich meine Matrix so gestaltet habe: glOrtho(0, 800, 0, 600, -30000, 15000);
Ist dann der Wert Z = 30000 ganz vorne, der naheste also. Und -15000 ist der weit entfernteste Z-Wert (wo die Objekte am weitesten entfernt sind). Demnach müsste ich bei der Selektion auch den größten Z-Wert suchen und nicht vom größten herab den kleinsten, oder? Könnte da der Fehler liegen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 19, 2005 18:31 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Also die ZWerte die du bei der Selektion bekommen wirst werden mit Sicherheit nicht die sein, die du als ZWerte reinsteckst. OpenGL wird den Bereich 0..4294967295 auf den eingestellten Bereich für das Clipping mappen. Also sollte 0 irgendwo bei -30000 (zNear) und 4294967294 bei 15000 (zFar) anzusiedln sein. Zu mindest die Reihenfolge der Elemente wird so wieder gespiegelt werden. Normal sucht man immer nach dem kleinsten "Pseudo" ZWert, der dann das Element wiederspiegelt was am Nächsten am zNear liegt.

Wenn du es gerne anders magst kannst du auch alles zurückliefern lassen oder das Element was am weitesten entfernt ist. ;-)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 19, 2005 19:13 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Also der Z-Buffer wird meines Wissens nach gleich unterteilt, von Near bis Far. Ich wüsste nicht, wieso das anders sein sollte. :?

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Okt 19, 2005 19:34 
Offline
DGL Member
Benutzeravatar

Registriert: Do Feb 24, 2005 22:44
Beiträge: 29
Ok, ich dachte man erhält bei den Z-Werten genau den Wert den man per Translate angesteuert hat. Wenn dem aber nicht so ist und intern der höchste Integer-Z-Wert der weit entfernteste ist kann ich die Routine ja übernehmen ohne das zu drehen.

Trotzdem gibts noch immer Probleme mit der Projektion. Ich habe dazu mal ein Testprojekt in der Projektionsansicht gemacht, da hat alles geklappt (hab mich sehr genau ans Tutorial gehalten). Jetzt hab ich das alles auf Orthogonale Ansicht umgestellt, Koorinaten angepasst usw. aber nun erhalte ich wieder ganz konfuse Werte, wie in meinem anderen "richtigen" Projekt.

Hier mal der komplette Code des kleinen Beispielprogramms: (C/C++ und WinAPI)

Code:
  1. //9.10.05 | Stefan Hof
  2.  
  3. #include <iostream>
  4. #include <windows.h>
  5. #include <gl/gl.h>
  6. #include <gl/glu.h>
  7.  
  8. #define NICHTS      0
  9. #define DREIECK     1
  10. #define QUADRAT     2
  11.  
  12. using namespace std;
  13.  
  14. MSG msg;
  15. HDC hdc;
  16. HGLRC hrc;
  17. int pixelformat;
  18.  
  19.  
  20. LRESULT CALLBACK wndproc(HWND, UINT, WPARAM, LPARAM);
  21.  
  22.  
  23. void set_gl_view( int size_x, int size_y)
  24. {
  25.     glViewport(0, 0, size_x, size_y);
  26.     glMatrixMode(GL_PROJECTION);
  27.     glLoadIdentity();
  28.     glOrtho(0, 800, 0, 600, -300, 300);    
  29. }
  30.  
  31. void int_gl( void )
  32. {
  33.     glShadeModel(GL_SMOOTH);
  34.     glClearColor(0.0f, 0.5f, 0.5f, 0.0f);
  35.     glClearDepth(1.0f);
  36.     glEnable(GL_DEPTH_TEST);
  37.     glDepthFunc(GL_LEQUAL);
  38.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  39. }
  40.  
  41. void render_ogl( void )
  42. {
  43.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  44.     glMatrixMode(GL_PROJECTION);
  45.     glLoadIdentity();
  46.     glOrtho(0, 800, 0, 600, -300, 300);
  47.     glMatrixMode(GL_MODELVIEW);
  48.     glLoadIdentity();
  49.     glTranslatef(400,300,0);
  50.  
  51.     glLoadName(DREIECK);
  52.     glBegin(GL_TRIANGLES);
  53.         glVertex3f(0, 0, 0);
  54.         glVertex3f(50, 50, 0);
  55.         glVertex3f(100, 0, 0);
  56.     glEnd();
  57.  
  58.     glTranslatef(-200,0,0);
  59.  
  60.     glLoadName(QUADRAT);
  61.     glBegin(GL_QUADS);
  62.         glVertex3f(0, 0, 0);
  63.         glVertex3f(50, 0, 0);
  64.         glVertex3f(50, -50, 0);
  65.         glVertex3f(0, -50, 0);
  66.     glEnd();
  67. }
  68.  
  69.  
  70. int selection( int mouse_x, int mouse_y)
  71. {
  72.     unsigned int SelectBuffer[513];
  73.     int Viewport[4];
  74.     int Hits, i;
  75.     unsigned int HitZValue;
  76.     unsigned int Hit;
  77.  
  78.     glGetIntegerv(GL_VIEWPORT, Viewport);
  79.     glSelectBuffer(512, SelectBuffer);
  80.     glRenderMode(GL_SELECT);
  81.     glInitNames();
  82.     glPushName(NICHTS);
  83.     glMatrixMode(GL_PROJECTION);
  84.     glPushMatrix();
  85.     glLoadIdentity();
  86.     gluPickMatrix(mouse_x, Viewport[3]-mouse_y, 1.0, 1.0, Viewport);
  87.     glMatrixMode(GL_PROJECTION);
  88.     glLoadIdentity();
  89.     glOrtho(0,800,0,600, -300, 300);
  90.     render_ogl();
  91.     glMatrixMode(GL_PROJECTION);
  92.     glPopMatrix();
  93.     Hits = glRenderMode(GL_RENDER);
  94.  
  95.     Hit = 4294967295;
  96.     HitZValue = 4294967295;
  97.    
  98.     for (i = 0; i <= Hits -1; i++)
  99.     {
  100.         if (SelectBuffer[(i*4)+1] <= HitZValue)
  101.         {
  102.             Hit = SelectBuffer[(i*4)+3];
  103.             HitZValue = SelectBuffer[(i*4)+1];
  104.         }
  105.     }
  106.     return Hit;
  107. }
  108.  
  109.  
  110. int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE pre, PSTR commandline, int showflag)
  111. {
  112.     WNDCLASS wndclass;
  113.     wndclass.style = 0;
  114.     wndclass.lpfnWndProc = &wndproc;
  115.     wndclass.cbClsExtra = 0;
  116.     wndclass.cbWndExtra = 0;
  117.     wndclass.hInstance = hinstance;
  118.     wndclass.hIcon = NULL;
  119.     wndclass.hCursor = LoadCursor(hinstance, IDC_ARROW);
  120.     wndclass.hbrBackground = (HBRUSH) 3;
  121.     wndclass.lpszMenuName = NULL;
  122.     wndclass.lpszClassName = "classname";
  123.  
  124.     RegisterClass(&wndclass);
  125.     HWND hwnd = CreateWindow("classname",
  126.                              "no name",
  127.                              WS_CAPTION | WS_BORDER | WS_SYSMENU,
  128.                              100, 100, 800, 632,
  129.                              NULL, NULL, hinstance, NULL);
  130.  
  131.     static  PIXELFORMATDESCRIPTOR pfd=                  // pfd Tells Windows How We Want Things To Be
  132.     {
  133.         sizeof(PIXELFORMATDESCRIPTOR),                  // Size Of This Pixel Format Descriptor
  134.         1,                              // Version Number
  135.         PFD_DRAW_TO_WINDOW |                        // Format Must Support Window
  136.         PFD_SUPPORT_OPENGL |                        // Format Must Support OpenGL
  137.         PFD_DOUBLEBUFFER,                       // Must Support Double Buffering
  138.         PFD_TYPE_RGBA,                          // Request An RGBA Format
  139.         32,                             // Select Our Color Depth
  140.         0, 0, 0, 0, 0, 0,                       // Color Bits Ignored
  141.         0,                              // No Alpha Buffer
  142.         0,                              // Shift Bit Ignored
  143.         0,                              // No Accumulation Buffer
  144.         0, 0, 0, 0,                         // Accumulation Bits Ignored
  145.         16,                             // 16Bit Z-Buffer (Depth Buffer)
  146.         0,                              // No Stencil Buffer
  147.         0,                              // No Auxiliary Buffer
  148.         PFD_MAIN_PLANE,                         // Main Drawing Layer
  149.         0,                              // Reserved
  150.         0, 0, 0                             // Layer Masks Ignored
  151.     };
  152.    
  153.     hdc = GetDC(hwnd);
  154.     pixelformat = ChoosePixelFormat(hdc, &pfd);
  155.     SetPixelFormat(hdc, pixelformat, &pfd);
  156.     hrc = wglCreateContext(hdc);
  157.     wglMakeCurrent(hdc, hrc);
  158.  
  159.     set_gl_view(800,600);
  160.     int_gl();
  161.  
  162.     ShowWindow(hwnd, SW_SHOWNORMAL);
  163.  
  164.  
  165.     bool done = false;
  166.     while( done == false )
  167.     {
  168.         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  169.         {
  170.             if (msg.message == WM_QUIT)
  171.             {
  172.                 done = true;
  173.             }
  174.             else
  175.             {
  176.                 TranslateMessage(&msg);
  177.                 DispatchMessage(&msg);
  178.             }
  179.         }
  180.         else
  181.         {
  182.             render_ogl();
  183.             SwapBuffers(hdc);
  184.         }
  185.     }
  186.     return msg.wParam;
  187. }
  188.  
  189. LRESULT CALLBACK wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  190. {
  191.     switch (message)
  192.     {
  193.         case WM_DESTROY:
  194.             PostQuitMessage(0);
  195.             return 0;
  196.  
  197.         case WM_LBUTTONUP:
  198. //            cout<<"Y-pos: "<<HIWORD(lParam)<<endl;
  199.             cout<<"Selektion:  "<<selection(LOWORD(lParam), HIWORD(lParam))<<endl;
  200.             return 0;
  201.  
  202.     }
  203.     return DefWindowProc(hwnd, message, wParam, lParam);
  204. }



Die Problemzone dabei ist wohl die Selektionsfunktion. Diese gibt immer als Treffer die Anzahl der insgesamt vorhandenen Objekte raus. In dem Fall 2, also 2 als Treffer zurück. Egal wo man hinklickt. Vielleicht findet ihr ja den Fehler? Im Orthogonalen Modus möchte es plötzlich nicht mehr so klappen wie vorher.
Dabei stelle ich in der Selektionsfunktion auch eine Orthogonale Matrix bereit (mit der Projektionsmatrix multipliziert) und lasse dann dort rendern. Doch irgendwas will nicht so ganz.

Wo wir gerade beim Thema sind. Warum ist es eigentlich immer zwingend notwendig, in jedem Schleifendurchlauf vor dem Rendern wieder glOrtho aufzurufen und die Projektionsmatrix mit dieser Sicht zu versehen? Ich dachte OpenGL behält solche Einstellungen immer bei. Jedenfalls, wenn ich das Ortho rauslasse in der "render_ogl" Funktion dann wird nix mehr angezeigt. Jeder Schleifendurchlauf erfordert also immer diesen Code:
Code:
  1.     glMatrixMode(GL_PROJECTION);
  2.     glLoadIdentity();
  3.     glOrtho(0, 800, 0, 600, -300, 300);
  4.  

Die Frage ist, ob das nur ein Fehler meinerseits ist oder ob man tatsächlich immer dieses Ortho einbinden muss vor dem Rendern der Objekte?

EDIT: Gibt es vielleicht ein Tutorial welches den Ortho-Modus genauer beschreibt, vielleicht mit Beispielprogramm oder so?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 20, 2005 08:09 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Wir haben doch zu so ziemlich alles ein Tutorial ;-)

Aber ich kann dir versichern. In einer reinen 2D Anwendung ist es nicht nötig bei jedem Rendern glOrtho neu aufzurufen. Unnötige aufrufe kosten schließlich auch Performance. Hier dazu mal ein Codeschnippsel von mir.

Im OnShow meines Formulares erstelle ich den Kontext. Zum Initialisieren der Ansicht rufe ich die untere Methode auf.
Code:
  1. procedure TForm1.FormResize(Sender: TObject);
  2. var
  3.   VP: array[0..1] of Integer;
  4.   newWidth, newHeight: Integer;
  5. begin
  6.   if (FInitialised) then begin
  7.     // Set the viewport for the OpenGL window
  8.     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, @VP);
  9.  
  10.     // Dont make the Window to large
  11.     newWidth :=  Min(VP[0], ClientWidth);
  12.     newHeight := Min(VP[1], Max(1, ClientHeight));
  13.  
  14.     // Viewport von OpenGL setzen
  15.     glViewport(
  16.       (ClientWidth div 2)  - (newWidth div 2),
  17.       (ClientHeight div 2) - (newHeight div 2),
  18.       newWidth,
  19.       newHeight);
  20.  
  21.     // Projection matrix
  22.     glMatrixMode(GL_PROJECTION);
  23.     glLoadIdentity();
  24.  
  25.     // Perspektive setzen
  26.     glOrtho(0, newWidth, newHeight, 0, -1, 1);
  27.  
  28.     // Modelview Matrix
  29.     glMatrixMode(GL_MODELVIEW);
  30.     glLoadIdentity();
  31.   end;
  32. end;

Beim Zeichnen mache ich dann nichts weiter als.
Code:
  1. var
  2.   Error: Cardinal;
  3.   RenderMode: Cardinal;
  4. begin
  5.   // Go to the model view matrix mode
  6.   glMatrixMode(GL_MODELVIEW);
  7.  
  8.   // Replaces the current matrix with the identity matrix
  9.   glLoadIdentity();
  10.  
  11.   // Clear the color and depth buffers
  12.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  13.  
  14.   glGetIntegerv(GL_RENDER_MODE, @RenderMode);
  15.  
  16.   glPushName(0);
  17.   glLoadName(10);
  18.   // Zeichnen
  19.   glPopName;
  20.  
  21.   Error := glGetError;
  22.   if Error <> 0 then
  23.     Caption := gluErrorString(Error);
  24.  
  25.   if (RenderMode = GL_RENDER)
  26.     then SwapBuffers (FDC);
  27. end;

Die Selection habe ich gerade mal Tesweise implementiert und das sieht so aus.
Code:
  1. var
  2.   Puffer       : array[0..256] of GLUInt;
  3.   Viewport     : TGLVectori4;
  4.   Treffer,i    : Integer;
  5.   Z_Wert       : GLUInt;
  6.   Getroffen    : GLUInt;
  7. begin
  8.   glGetIntegerv(GL_VIEWPORT, @viewport);
  9.   glSelectBuffer(256, @Puffer);
  10.   glRenderMode(GL_SELECT);
  11.  
  12.   glMatrixMode(GL_PROJECTION);
  13.   glLoadIdentity;
  14.  
  15.   gluPickMatrix(X, Viewport[3] - Y, 1.0, 1.0, Viewport);
  16.   glOrtho(0, ClientWidth, ClientHeight, 0, -1, 1);
  17.  
  18.   FormPaint(Self);
  19.  
  20.   glMatrixMode(GL_PROJECTION);
  21.  
  22.   treffer := glRenderMode(GL_RENDER);
  23.  
  24.   if treffer > 0 then begin
  25.     Getroffen := High(GLUInt);
  26.     Z_Wert := High(GLUInt);
  27.     for i := 0 to Treffer-1 do
  28.       if Puffer[(i*4)+1] < Z_Wert then begin
  29.         getroffen := Puffer[(i*4)+3];
  30.         Z_Wert := Puffer[(i*4)+1];
  31.       end;
  32.  
  33.     ShowMessage(IntToStr(Getroffen));
  34.   end;
  35.  
  36.   FormResize(Self);
  37. end;


Habe es auch getestet und geht so weit auch. Hoffe es hilft.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 20, 2005 13:55 
Offline
DGL Member
Benutzeravatar

Registriert: Do Feb 24, 2005 22:44
Beiträge: 29
Aaaah, die Selektion funktioniert. :)
Ich kann dir garnicht sagen wie froh ich da bin. Das hat mich schon einige Tage aufgehalten und wollte einfach nicht klappen. Ich bin froh, dass es hier ein Forum gibt wo solche Fragen geklärt werden können. :wink:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Okt 20, 2005 18:32 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Ich habe den Code mal ins Wiki übernommne. Zu finden im Artikel "Selektion".

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 22 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: Google [Bot], Majestic-12 [Bot] und 1 Gast


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:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]