OpenGL Zoom mit glTranslatef funtkioniert nicht

Hm. Die Datei ist aus einem, mir unbekannten Grund, "ungültig". Vielleicht reicht ja erstmal der Code. Ich kümmere ich mal morgen um dieses Problem. Heute bin ich ein bisschen zu müde. ;)

Code:
// MAIN.CPP //

#include <Windows.h>
#include <glut.h>
#include <gl\GL.h>
#include <gl\GLU.h>
LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM );
HWND hWnd;
HINSTANCE hInstance;
HDC hDC;
HGLRC hRC;

float zoom = 0.0;

PIXELFORMATDESCRIPTOR pfd = {
	sizeof ( PIXELFORMATDESCRIPTOR ),
	1,
	PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
	PFD_TYPE_RGBA,
	32,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	16,
	0,
	0,
	PFD_MAIN_PLANE,
	0,
	0,
	0 };

int WINAPI WinMain ( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szCmdLine, int iCmdShow )
{
	hInstance = hInst;
	const char szClassname[] = "hWnd";
	MSG msg;
	WNDCLASS wc;

	wc.cbClsExtra		= NULL;
	wc.cbWndExtra		= NULL;
	wc.hbrBackground	= NULL;
	wc.hCursor			= LoadCursor ( NULL, IDC_ARROW );
	wc.hIcon			= LoadIcon ( NULL, IDI_APPLICATION );
	wc.hInstance		= hInst;
	wc.lpfnWndProc		= WndProc;
	wc.lpszClassName	= szClassname;
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

	if ( ! RegisterClass ( &wc ) )
	{
		MessageBox ( NULL, "Das Fenster konnte nicht erstellt werden.", "Fehler", MB_OK | MB_ICONERROR );
		return 1;
	}

	hWnd = CreateWindow ( szClassname, "Bewegung im Raum", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 800, 600, NULL, NULL, NULL, NULL );

	if ( ! hWnd )
	{
		MessageBox ( NULL, "Das Fenster konnte nicht erstellt werden.", "Fehler", MB_OK | MB_ICONERROR );
		return 1;
	}

	ShowWindow ( hWnd, SW_SHOW );
	UpdateWindow ( hWnd );

	while ( GetMessage ( &msg, NULL, 0, 0 ) )
	{
		TranslateMessage ( &msg );
		DispatchMessage ( &msg );
	}

	return 0;
}
LRESULT CALLBACK WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	int iPF;
	switch ( msg )
	{
	case WM_CREATE:
		hDC = GetDC ( hwnd );
		iPF = ChoosePixelFormat ( hDC, &pfd );
		SetPixelFormat ( hDC, iPF, &pfd );
		hRC = wglCreateContext ( hDC );
		wglMakeCurrent ( hDC, hRC );

		glViewport ( 0, 0, ( GLsizei ) 800 , ( GLsizei ) 600 );
		glMatrixMode ( GL_PROJECTION );
		glLoadIdentity ( );
		glFrustum ( -1.0, 1.0, -1.0f, 1.0f, -1.0f, 1.0f );
		glLoadIdentity ( );
		glMatrixMode ( GL_MODELVIEW );
		break;

	case WM_KEYDOWN:
		switch ( wParam )
		{
		case VK_ADD:
			zoom = zoom - 0.1;
			glTranslatef ( 0, 0, zoom );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_SUBTRACT:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 10.0, 0, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case 'X':
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 5, 0, 1, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case 'Y':
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 5, 1, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case 'Z':
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 5, 0, 0, 1 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_LEFT:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( 0.025, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_RIGHT:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( -0.025, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_UP:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( 0, 0.025, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_DOWN:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( 0, -0.025, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		}
		break;

	case WM_PAINT:
		glEnable(GL_DEPTH_TEST);
		glClearColor ( 1.0f, 1.0f, 1.0f, 1.0f );
		glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

		glBegin ( GL_QUADS );

			glColor3f ( 1, 0, 0 );
			glVertex3f ( -0.25, 0.25, 0 );
			glVertex3f ( -0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, 0 );
			glVertex3f ( 0.25, 0.25, 0 );

			glColor3f ( 0, 1, 0 );
			glVertex3f ( -0.25, 0.25, 0 );
			glVertex3f ( -0.25, -0.25, 0 );
			glVertex3f ( -0.25, -0.25, -0.25 );
			glVertex3f ( -0.25, 0.25, -0.25 );

			glColor3f ( 0, 0, 1 );
			glVertex3f ( 0.25, 0.25, 0 );
			glVertex3f ( 0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, -0.25 );
			glVertex3f ( 0.25, 0.25, -0.25 );

			glColor3f ( 1, 1, 0 );
			glVertex3f ( -0.25, 0.25, -0.25 );
			glVertex3f ( -0.25, -0.25, -0.25 );
			glVertex3f ( 0.25, -0.25, -0.25 );
			glVertex3f ( 0.25, 0.25, -0.25 );

			glColor3f ( 0, 1, 1 );
			glVertex3f ( -0.25, 0.25, 0 );
			glVertex3f ( 0.25, 0.25, 0 );
			glVertex3f ( 0.25, 0.25, -0.25 );
			glVertex3f ( -0.25, 0.25, -0.25 );

			glColor3f ( 1, 0, 1 );
			glVertex3f ( -0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, -0.25 );
			glVertex3f ( -0.25, -0.25, -0.25 );

		glEnd ( );

		glFlush ( );                             
		SwapBuffers ( hDC );                     

		ValidateRect ( hwnd, NULL );
		break;

	case WM_DESTROY:
		wglMakeCurrent ( hDC, NULL );
		wglDeleteContext ( hRC );

		PostQuitMessage ( 0 );
		break;
	}
	return DefWindowProc ( hwnd, msg, wParam, lParam );
}
 
Achso, das hab ich vergessen zu erwähnen. Auch das hab ich schon ausprobiert (Ich hab viel rumprobiert :) ). Hat aber leider nichts geändert. :(
 
Hallo,

Ich hab mich jetzt mal durch deinen Code durchgearbeitet, du verwendest nicht Visual Studio oder?
Aber egal, hier mal die wichtigsten Sachen damit das Programm mal läuft:

Projektionsmatrix:
C++:
glLoadIdentity ( );
glFrustum ( -1.0, 1.0, -1.0f, 1.0f, -1.0f, 1.0f );
glLoadIdentity ( );

Du lädtst dir als erstes eine Identitätsmatrix in den MatrixStack (glLoadIdentity), dann schreibst du eine Perspektivische Matrix drüber (wobei hier auch die Parameter nicht passen). Und zu guter letzt überschreibst du in der dritten Zeile alles was vorher was mit einer Identitätsmatrix --> im Matrixstack steht nur eine Identitätsmatrix. Das erklärt mal warum du keine Tiefenwahrnehmung hast.

zu glFrustrum: Ein bisschen selbst in der Doku nachschlagen wäre schon notwendig: Dort steht z.B.:
GL_INVALID_VALUE is generated if nearVal or farVal is not positive, ...

Fensterseitenverhältnis:
Da dein Fenster nicht rechteckig ist muss sich dies auch in der Projektionsmatrix wiederspiegeln, also musst du bottom und top Werte geben die das Seitenverhältnis von Höhe/Breite wiederspiegeln.

Gesammt sollte der Code für die Projektionsmatrix so aussehen
C++:
glMatrixMode ( GL_PROJECTION );
glLoadIdentity ( );
float aspectRatio = 600.0f/800.0f;
glFrustum ( -1.0, 1.0, -aspectRatio, aspectRatio, 0.1f, 10.0f );


Zoom:
glTranslatef multipliziert (genauso wie glRotatef) immer den aktuellen Wert zum bereits bestehenden dazu, daher kannst du nicht zuerst 0.1, dann 0.2 und dann 0.3 übergeben wenn du drei Schritte weg willst (ergibt ja gesammt 0.6), sondern musst jedes mal 0.1 verwenden. Anzumerken ist hier das du das bei den Rotationen ja auch schon so gemacht hast, indem du jedes mal 5 Grad übergibst.

Der Code sollte dann so ausschauen
C++:
case VK_ADD:
	glTranslatef ( 0, 0, -0.01f );
	glFlush ( );
	SwapBuffers ( hDC );
	InvalidateRect ( hwnd, NULL, true );
	break;

Ach ja nebenbei, der Würfel ist bei dir kein Würfel.

Edit: Wenn du schon mit OpenGL Fixed Function arbeiten möchtest, solltest du wenigstens auf GLUT verzichten, wie man auf der Homepage sieht wurde daran seit 2001 nicht mehr gearbeitet. 10 Jahre sind grad im Bereich der Spieleentwicklung einfach zu lange, vorallem da du bis jetzt keine GLUT Funktionalitäten nutzt.
 
Zuletzt bearbeitet von einem Moderator:
Hm. Irgendetwas stimmt da nicht. Die vordere (rote) Seite, fehlt und wenn ich den Quader rotiere, sieht das alles wirklich komisch aus. Es verschiebt sich - so sieht es zumindest aus - immer nur eine Seite.
Ach ja nebenbei, der Würfel ist bei dir kein Würfel.
Vielleicht hat dsa ja damit etwas zu tun. Und noch eine Frage:
Warum verschwindet alles, wenn ich "near" größer als 0.24 setzte? Nochmal vielen Dank.
 
Weil dir die near-Plane und die Far-Plane nach vorne und hinten den Bereich begrenzen in welchem Objekte gezeichnet werden. Wenn du die near-Plane auf 0.24 setzt werden keine Objekte dargestellt die näher als 0.24 an der Kamera sind. Die rote Seite vorne geht vielleicht auch deshalb verloren, weil sie vor der nearPlane ist.

Kannst du wieder deinen Code komplett posten? Dann schauen wir uns das mit dem Würfel noch an. Was mir aufgefallen ist, war nur, dass du sowohl 0, 0.25, und -0.25 als Koordinaten verwendest. Wenns ein Würfel wäre dürfte es aber z.B.: nur 0.25 und -0.25 geben.
 
Code:
// MAIN.CPP //

#include <Windows.h>
#include <glut.h>
#include <gl\GL.h>
#include <gl\GLU.h>
LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM );
HWND hWnd;
HINSTANCE hInstance;
HDC hDC;
HGLRC hRC;

float aspectRatio = 600.0f/800.0f;

PIXELFORMATDESCRIPTOR pfd = {
	sizeof ( PIXELFORMATDESCRIPTOR ),
	1,
	PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
	PFD_TYPE_RGBA,
	32,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	16,
	0,
	0,
	PFD_MAIN_PLANE,
	0,
	0,
	0 };

int WINAPI WinMain ( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szCmdLine, int iCmdShow )
{
	hInstance = hInst;
	const char szClassname[] = "hWnd";
	MSG msg;
	WNDCLASS wc;

	wc.cbClsExtra		= NULL;
	wc.cbWndExtra		= NULL;
	wc.hbrBackground	= NULL;
	wc.hCursor			= LoadCursor ( NULL, IDC_ARROW );
	wc.hIcon			= LoadIcon ( NULL, IDI_APPLICATION );
	wc.hInstance		= hInst;
	wc.lpfnWndProc		= WndProc;
	wc.lpszClassName	= szClassname;
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

	if ( ! RegisterClass ( &wc ) )
	{
		MessageBox ( NULL, "Das Fenster konnte nicht erstellt werden.", "Fehler", MB_OK | MB_ICONERROR );
		return 1;
	}

	hWnd = CreateWindow ( szClassname, "Bewegung im Raum", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 100, 100, 800, 600, NULL, NULL, NULL, NULL );

	if ( ! hWnd )
	{
		MessageBox ( NULL, "Das Fenster konnte nicht erstellt werden.", "Fehler", MB_OK | MB_ICONERROR );
		return 1;
	}

	ShowWindow ( hWnd, SW_SHOW );
	UpdateWindow ( hWnd );

	while ( GetMessage ( &msg, NULL, 0, 0 ) )
	{
		TranslateMessage ( &msg );
		DispatchMessage ( &msg );
	}

	return 0;
}
LRESULT CALLBACK WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	int iPF;
	switch ( msg )
	{
	case WM_CREATE:
		hDC = GetDC ( hwnd );
		iPF = ChoosePixelFormat ( hDC, &pfd );
		SetPixelFormat ( hDC, iPF, &pfd );
		hRC = wglCreateContext ( hDC );
		wglMakeCurrent ( hDC, hRC );

		glViewport ( 0, 0, ( GLsizei ) 800 , ( GLsizei ) 600 );
		glMatrixMode ( GL_PROJECTION );
		glLoadIdentity ( );
		glFrustum ( -1.0, 1.0, -aspectRatio, aspectRatio, 0.1f, 10.0f );
		break;

	case WM_KEYDOWN:
		switch ( wParam )
		{
		case VK_ADD:
			glTranslatef ( 0, 0, -0.01f );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_SUBTRACT:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 10.0, 0, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case 'X':
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 5, 0, 1, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case 'Y':
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 5, 1, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case 'Z':
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glRotatef ( 5, 0, 0, 1 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_LEFT:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( 0.025, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_RIGHT:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( -0.025, 0, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_UP:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( 0, 0.025, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		case VK_DOWN:
			glEnable(GL_DEPTH_TEST);
			glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
			glTranslatef ( 0, -0.025, 0 );
			glFlush ( );
			SwapBuffers ( hDC );
			InvalidateRect ( hwnd, NULL, true );
			break;
		}
		break;

	case WM_PAINT:
		glEnable(GL_DEPTH_TEST);
		glClearColor ( 1.0f, 1.0f, 1.0f, 1.0f );
		glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

		glBegin ( GL_QUADS );

			glColor3f ( 1, 0, 0 );
			glVertex3f ( -0.25, 0.25, 0 );
			glVertex3f ( -0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, 0 );
			glVertex3f ( 0.25, 0.25, 0 );

			glColor3f ( 0, 1, 0 );
			glVertex3f ( -0.25, 0.25, 0 );
			glVertex3f ( -0.25, -0.25, 0 );
			glVertex3f ( -0.25, -0.25, -0.25 );
			glVertex3f ( -0.25, 0.25, -0.25 );

			glColor3f ( 0, 0, 1 );
			glVertex3f ( 0.25, 0.25, 0 );
			glVertex3f ( 0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, -0.25 );
			glVertex3f ( 0.25, 0.25, -0.25 );

			glColor3f ( 1, 1, 0 );
			glVertex3f ( -0.25, 0.25, -0.25 );
			glVertex3f ( -0.25, -0.25, -0.25 );
			glVertex3f ( 0.25, -0.25, -0.25 );
			glVertex3f ( 0.25, 0.25, -0.25 );

			glColor3f ( 0, 1, 1 );
			glVertex3f ( -0.25, 0.25, 0 );
			glVertex3f ( 0.25, 0.25, 0 );
			glVertex3f ( 0.25, 0.25, -0.25 );
			glVertex3f ( -0.25, 0.25, -0.25 );

			glColor3f ( 1, 0, 1 );
			glVertex3f ( -0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, 0 );
			glVertex3f ( 0.25, -0.25, -0.25 );
			glVertex3f ( -0.25, -0.25, -0.25 );

		glEnd ( );

		glFlush ( );                             
		SwapBuffers ( hDC );                     

		ValidateRect ( hwnd, NULL );
		break;

	case WM_DESTROY:
		wglMakeCurrent ( hDC, NULL );
		wglDeleteContext ( hRC );

		PostQuitMessage ( 0 );
		break;
	}
	return DefWindowProc ( hwnd, msg, wParam, lParam );
}
 
Welchen Compiler verwendest du? Bei mir (Microsoft C++ Compiler 2010) kann ich z.B. bei CreateWindow nur eine LPCWSTR übergeben und keinen char*. Aber egal, ich schau mir den Code demnächst an.
 
Diesen Compiler verwende ich auch. Man muss die Projekteinstellungen ändern:
Projekt -> Name-des-Projekts-Eigentschaften -> Konfigurationseingentschaften -> Unten steht Zeichensatz, das auf "Nicht festgelegt" stellen. Dann hat man dieses Problem nicht mehr ;)
 
Zurück