Hallo,
meine beiden Ausgangs-Probleme sind im groben gelöst. Ein ganz herzliches Dankeschön für die Hilfe, besonders an TheLordFerada.
Die Sache mit OpenGL-Polygonen innerhalb eines bestehenden Dialogs funktioniert und auch das „Packstück-Tiefenproblem“ ist gelöst.
Anliegender Code ergibt das entsprechende Ergebnis.
Nun sind aber noch ein paar Details dazu zu erledigen. Ich habe mich selbst daran versucht, durch „Ausprobieren“, d.h. durch Verändern mancher Parameter das zu erreichen, aber ohne zufrieden stellenden Erfolg.
Ich bin dafür ganz offensichtlich einfach noch zu sehr Anfänger.
Daher meine Hoffnung, dass von Euch Experten mir jemand genau die Werte bzw. Veränderungen nennen kann, die genau zur gewünschten Darstellung führen.
Ich muss zur Problemschilderung nun notgedungen etwas ausholen:
Man stelle sich das nun bitte nicht mehr als Lkw vor, sondern als „hoher Haufen von rechteckigen Packstücken, die auf eine Palette geladen sind“. Die Abmessungen über alles (des gesamten Haufens bzw. der verwendeten Palette) können je nach Beladung variieren.
Um eine konkretes Beispiel zu haben, nehmen wir hier bitte einmal eine Breite von 120cm, eine Tiefe von 100cm und eine Höhe von 250cm an.
Jedem Interessenten sende ich per email gerne einen Snapshot zu, der visuell das Ergebnis verdeutlicht (den Dialog, in dem die OpenGL-Quads angezeigt werden). Ich kenne bisher keine Möglichkeiten, erläuternde Bilddateien an Forum-Artikel anzuhängen.
Es bestehen noch folgende offene Probleme:
-
Wie kann ich erreichen, dass ein jeweiliger Packstück-Haufen mit seinen Abmessungen über alles, beim Öffnen des Dialogs in der Größe dargestellt wird, dass er ideal in den Graph-Bereich passt (d.h. dass an den Rändern nur ca. 10% Rand verbleibt) ?
-
Hierbei kommt hinzu, dass der Haufen derzeit immer nur in der oberen Hälfte angezeigt wird, da der Ursprung ja in die Mitte des Graphen gelegt ist.
Ich habe versucht, den mittleren Wert von glTranslatef(-0.0f, -0.0f, -m_fZoom) in InDraw mit einem negativen Wert zu belegen, aber ohne brauchbare Ergebnisse. Zwar rutscht dann das Gebilde nach unten, aber nie in die ideale Position wie es soll. Es fehlt mir an der genauen Abstimmung aller Parameter untereinander, die mir mangels ausreichender Kenntnisse bisher nicht gelingen will.
-
Wie man sieht, werden die Ergebnis-Werte von meinem Berechnungs-Algorithmus in integer-Werten geliefert (nämlich genau in Zentimetern).
Die Werte (jeweils in integers) befinden sich in folgenden Variablen:
pLength, pHeight, pWidth: Abmessungen des jeweiligen Packstücks
&xi, &yi, &zi: Lage-Koordinate der unteren linken Ecke des jeweiligen Packstücks
pallength, pallwidth, palheight: Abmessungen der Palette, auf welche die Packstücke verladen sind (= Abmessungen über alles des „Packstück-Haufens“).
Bei der Umrechnung in float (hier einfach salopp per /100 von mir realisiert) gibt es wohl gelegentlich üble Rundungsfehler, so dass in der Darstellung manchmal Packstücke sich im Volumen überlappen (was nicht sein darf). Die Berechnungsergebnisse meines Algorithmus sind stets korrekt, das habe ich geprüft.
Zudem bin ich im Zweifel immer „Performance-Fetischist“. Das heißt es ist mir an sich ein Dorn im Auge, dass überhaupt in float umgerechnet werden muss.
Viel schöner wäre es, einfach bei den Vertex-Deklarationen im int-Bereich zu bleiben.
Ich habe es per glVertex3i anstatt glVertex3d versucht, allerdings ohne die Packstück-Ergebnis-Werte des Berechnungs-Algorithmus per Division zu verkleinern (die Kanten-Längen der Packstücke liegen stets so zwischen 30 und 70 cm).
Das hatte zum Ergebnis, dass die Werte für die Anzeige so groß waren, dass man vom Gesamtgebilde (Haufen) gar nichts erkennen konnte, sondern nur noch den Oberflächen-Ausschnitt irgendeines Packstücks.
Das liegt wiederum daran, dass die anderen Werte (ich vermute die in OnSize und oglInitialize) nicht auf diese int-Werte von der Größenordnung her abgestimmt sind (im Prinzip das gleiche Grundproblem wie unter 1. und 2.).
Ich bin mir sicher, dass man die in OnSize und oglInitialize nur entsprechend geschickt verändern muss, nur eben bitte wie ? Auf das Zusammenspiel kommt es hier an und ich bin zugegebenermaßen derzeit noch „zu doof“ bzw. zu „Betriebsblind“ um das hinzubekommen.
Welcher „OpenGL-Volldurchblicker“ kann mir am besten gleich den Parameter-technisch überarbeiteten Code nennen ?
#include „stdafx.h“
#include „palletdefinition.h“
#include „OpenGLControl.h“
#include „.\openglcontrol.h“
COpenGLControl::COpenGLControl(void)
{
m_fZoom = 10.0f;
m_fRotX = 45.0f;
m_fRotY = 45.0f;
palnr = 0;
pallength = 0;
palwidth = 0;
palheight = 0;
gitterfill = TRUE;
packerg = NULL;
paldef = NULL;
}
COpenGLControl::~COpenGLControl(void)
{
}
BEGIN_MESSAGE_MAP(COpenGLControl, CWnd)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
void COpenGLControl:nPaint()
{
ValidateRect(NULL);
}
void COpenGLControl:nSize(UINT nType, int cx, int cy)
{
CWnd:nSize(nType, cx, cy);
if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;
// Map the OpenGL coordinates.
glViewport(0, 0, cx, cy);
// Projection view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set our current view perspective
gluPerspective(35.0f, (float)cx / (float)cy, 0.1f, 2000.0f);
// Model view
glMatrixMode(GL_MODELVIEW);
}
int COpenGLControl:nCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd:nCreate(lpCreateStruct) == -1) return -1;
oglInitialize();
return 0;
}
void COpenGLControl:nDraw(CDC *pDC)
{
// If the current view is perspective…
glLoadIdentity();
glTranslatef(-0.0f, -0.0f, -m_fZoom);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
}
void COpenGLControl:nTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 1:
{
// Clear color and depth buffer bits
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw OpenGL scene
oglDrawScene();
// Swap buffers
SwapBuffers(hdc);
break;
}
default:
break;
}
CWnd:nTimer(nIDEvent);
}
void COpenGLControl:nMouseMove(UINT nFlags, CPoint point)
{
int diffX = (int)(point.x - m_fLastX);
int diffY = (int)(point.y - m_fLastY);
m_fLastX = (float)point.x;
m_fLastY = (float)point.y;
// Left mouse button
if (nFlags & MK_LBUTTON)
{
m_fRotX += (float)0.5f * diffY;
if ((m_fRotX > 360.0f) || (m_fRotX 360.0f) || (m_fRotY m_hDC;
// Pixel format
m_nPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, m_nPixelFormat, &pfd);
// Create the OpenGL Rendering Context
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
// Set color to use when clearing the background
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClearDepth(1.0f);
// Turn on backface culling
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
// Turn on depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
// Send draw request
OnDraw(NULL);
}
void COpenGLControl::oglDrawScene(void)
{
float x, y, z, packLength, packWidth, packHeight;
unsigned short xi, yi, zi, packnr;
unsigned short pLength, pWidth, pHeight;
CString str;
int i = 0;
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(2.0);
glColor3f(0, 0, 0);
int palnr_view = packerg->GetOriginNumberOfPals() - palnr - 1;
for (i=0; i GetOriginNumberOfPacksOnPal(palnr_view); ++i)
{
packerg->GetPackPosition(palnr_view, i, &xi, &yi, &zi, &packnr);
x = ((float)xi) / 100;
y = ((float)zi) / 100;
z = ((float)yi) / 100;
packerg->GetOriginPacks(0, &str, &pLength, &pHeight, &pWidth, &xi, &yi);
packLength = ((float)pLength) / 100;
packWidth = ((float)pWidth) / 100;
packHeight = ((float)pHeight) / 100;
glBegin(GL_QUADS);
// Boden
glVertex3d(x, y, z);
glVertex3d(x, packWidth+y, z);
glVertex3d(packLength+x, packWidth+y, z);
glVertex3d(packLength+x, y, z);
// Deckel
glVertex3d(x, y, packHeight+z);
glVertex3d(packLength+x, y, packHeight+z);
glVertex3d(packLength+x, packWidth+y, packHeight+z);
glVertex3d(x, packWidth+y, packHeight+z);
// Mantel
glVertex3d(x, y, z);
glVertex3d(packLength+x, y, z);
glVertex3d(packLength+x, y, packHeight+z);
glVertex3d(x, y, packHeight+z);
glVertex3d(x, y, z);
glVertex3d(x, packWidth+y, z);
glVertex3d(x, packWidth+y, packHeight+z);
glVertex3d(x, y, packHeight+z);
glVertex3d(x, packWidth+y, z);
glVertex3d(x, packWidth+y, packHeight+z);
glVertex3d(packLength+x, packWidth+y, packHeight+z);
glVertex3d(packLength+x, packWidth+y, z);
glVertex3d(packLength+x, packWidth+y, z);
glVertex3d(packLength+x, packWidth+y, packHeight+z);
glVertex3d(packLength+x, y, packHeight+z);
glVertex3d(packLength+x, y, z);
glEnd();
}
if (gitterfill)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
for (i=0; i GetOriginNumberOfPacksOnPal(palnr_view); ++i)
{
packerg->GetPackPosition(palnr_view, i, &xi, &yi, &zi, &packnr);
x = ((float)xi) / 100;
y = ((float)zi) / 100;
z = ((float)yi) / 100;
packerg->GetOriginPacks(0, &str, &pLength, &pHeight, &pWidth, &xi, &yi);
packLength = ((float)pLength) / 100;
packWidth = ((float)pWidth) / 100;
packHeight = ((float)pHeight) / 100;
glColor3f(paldef->GetRGB1(yi),
paldef->GetRGB2(yi),
paldef->GetRGB3(yi));
glBegin(GL_QUADS);
// Boden
glVertex3d(x, y, z);
glVertex3d(x, packWidth+y, z);
glVertex3d(packLength+x, packWidth+y, z);
glVertex3d(packLength+x, y, z);
// Deckel
glVertex3d(x, y, packHeight+z);
glVertex3d(packLength+x, y, packHeight+z);
glVertex3d(packLength+x, packWidth+y, packHeight+z);
glVertex3d(x, packWidth+y, packHeight+z);
// Mantel
glVertex3d(x, y, z);
glVertex3d(packLength+x, y, z);
glVertex3d(packLength+x, y, packHeight+z);
glVertex3d(x, y, packHeight+z);
glVertex3d(x, y, z);
glVertex3d(x, packWidth+y, z);
glVertex3d(x, packWidth+y, packHeight+z);
glVertex3d(x, y, packHeight+z);
glVertex3d(x, packWidth+y, z);
glVertex3d(x, packWidth+y, packHeight+z);
glVertex3d(packLength+x, packWidth+y, packHeight+z);
glVertex3d(packLength+x, packWidth+y, z);
glVertex3d(packLength+x, packWidth+y, z);
glVertex3d(packLength+x, packWidth+y, packHeight+z);
glVertex3d(packLength+x, y, packHeight+z);
glVertex3d(packLength+x, y, z);
glEnd();
}
}
glDisable(GL_POLYGON_OFFSET_FILL);
}
void COpenGLControl::Up()
{
m_fRotX -= (float)10;
if (m_fRotX 360.0f)
{
m_fRotX = 0.0f;
}
OnDraw(NULL);
}
void COpenGLControl::Left()
{
m_fRotY -= (float)10;
if (m_fRotY 360.0f)
{
m_fRotY = 0.0f;
}
OnDraw(NULL);
}
void COpenGLControl:lus()
{
if (m_fZoom > 4.5)
{
m_fZoom -= (float)1;
}
OnDraw(NULL);
}
void COpenGLControl::Minus()
{
if (m_fZoom