[ogl] OGL - Menu

S

suxx-

HI

Da es sicher Leute unter uns gibt die nicht wissen wie man ein OGL Menu baut es aber gerne wüssten hab ich mir gedacht schreib ich ein Tutorial für ein recht komfortables Menu.

Als erstes überlegen wir uns was wir brauchen und wie wir es umsetzten wollen. An sich gibt es zwei Methoden ein Menu umzusetzen einmal ein reines Textmenu oder ein Menu mit Zellen (also gemalten Boxen). Ich habe mich für das reine Textmenu entschieden weil es einfach besser rüber kommt.

Bevor wir mit einer Funktion Anfangen brauchen wir globale Variablen und zwar:

Code:
//Für die Das erstellen und ausgeben der Schrift
GLuint base;
HDC hDC;
bool FirstInit = false;
int viewportcount=0;

// Für die Keyverwaltung
int Last_Key=0;

// Informationen über die Bildschirm
static GLint	vp[4];

// Init Der Strukturen
menu_s	menu;
draw_s	draw;

Dann geht es auch gleich zur ersten Funktion los glPrint()

Code:
void glPrint(float x, float y, float z, float r, float g, float b, const char *fmt, ...)
{
	char		text[256];								
	va_list		ap;										
	if (fmt == NULL)									
		return;											
	va_start(ap, fmt);									
	vsprintf(text, fmt, ap);						
	va_end(ap);

	GLfloat  curcolor[4], position[4];
	(*orig_glPushAttrib)(GL_ALL_ATTRIB_BITS);
	(*orig_glGetFloatv)(GL_CURRENT_COLOR, curcolor);
	(*orig_glGetFloatv)(GL_CURRENT_RASTER_POSITION, position);

	(*orig_glDisable)(GL_TEXTURE_2D); 
	(*orig_glColor4f)(r,g,b,1.0f); // Setzen der Schriftfarbe
	(*orig_glRasterPos3f)(x,y,z); // glRasterPos3f  damit wir uns im 3 dimensionalen Raum bewegen

	(*orig_glPushAttrib)(GL_LIST_BIT);							
	(*orig_glListBase)(base - 32);								
	(*orig_glCallLists)(strlen(text), GL_UNSIGNED_BYTE, text);	
	(*orig_glPopAttrib)();										
	(*orig_glEnable)(GL_TEXTURE_2D); 

(*orig_glPopAttrib)();
    	(*orig_glColor4fv)(curcolor);
    	(*orig_glRasterPos2f)(position[0],position[1]);
}

wobei ich auf die Grundfunktionen hier nicht weiter eingehen möchte wer daran Interesse hat kann hier alles nachlesen.

Doch bevor wir die Funktion glPrint benutzten können müssen wir erst eine Schrift in den Speicher laden.

Das geschieht mit der Funktion BuildFont:

Code:
GLvoid BuildFont(GLvoid)
{
	hDC=wglGetCurrentDC();
	HFONT	font;										
	HFONT	oldfont;									
	base = (*orig_glGenLists)(96);								
	font = CreateFont(14,0,0,0,FW_BOLD,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,FF_DONTCARE|DEFAULT_PITCH,
	"Tahoma");
	oldfont = (HFONT)SelectObject(hDC, font);           
	wglUseFontBitmaps(hDC, 32, 96, base);				
	SelectObject(hDC, oldfont);							
	DeleteObject(font);									
}

Das Aussehen der Schrift beeinflussen wir mit CreateFont da können wir auch sagen welchen Schrifttype ob normal oder bold usw. aber ach alle anderen Einstellungen.
Dazu hier und hier mehr.

Nun kommen wir zu unserem eigentlich Menu und zwar mit der Funktion DrawMenu:

Code:
 void DrawMenu(int x, int y)
{
	char Entry[10][30]; // Initialisieren des zweidimensionalen Entry Arrays das später die einzelnen Menupunkte speichert. 
	// Belegen der einzelnen Elemente des Arrays mit Strings
	sprintf(Entry[1]," - Asus Hack %s",cvar.asus?"On":"Off");
	sprintf(Entry[2]," - XQZ Hack %s",cvar.xqz?"On":"Off");
	sprintf(Entry[3]," - White Walls %s",cvar.white?"On":"Off");
	sprintf(Entry[4]," - Lambert %s",cvar.lambert?"On":"Off");
	sprintf(Entry[5]," - Flash remove %s",cvar.flash?"On":"Off");
	sprintf(Entry[6]," - Smoke remove %s",cvar.smoke?"On":"Off");
	sprintf(Entry[7]," - Scope remove %s",cvar.scope?"On":"Off");
	sprintf(Entry[8]," - Sky remove %s",cvar.sky?"On":"Off");
	sprintf(Entry[9]," - Wireframe Hack %s",cvar.wire?"On":"Off");
	
        menu.maxcount = sizeof(Entry);

	// Ein Menukopf erzeugen
	glPrint(x,y-28,1.0f,0.5f,0.5f,1.0f,"------------------------");
	glPrint(x,y-17,1.0f,0.5f,0.5f,1.0f,"-       Suxx OGL        -");
	glPrint(x,y-6 ,1.0f,0.5f,0.5f,1.0f,"------------------------");
	
	// Die Schleife läuft solange bis menu.maxcount erreicht ist und somit keine weiteren Menuelemente mehr ausgegeben werden müssen.
	for (int i=1; i < menu.maxcount+1;i++) {
// Hier eine kleine besonderheit da wir ja den selektierten Punkt anders Darstellen möchte haben wir hier die If Abfrage wenn der Menupunkt den
// wir Ausgeben möchten gerade Selektiert ist bekommt er eine andere Farbe. Und noch etwas fällt hier auf und zwar y+(14 * i) +5 liegt einfach 
// daran das die Schrift 14 Pixel groß ist (definiert in CreateFont) und da wir ja nicht alle Punkte übereinander haben möchten multiplizieren wir  die 
// Schriftgröße mit dem Aktuellen menu.count – menu Punkt.
		if (menu.count == i) 
			glPrint(x,y+(14 * i)+5 ,1.0f,1.0f,0.2f,0.2f,Entry[i]); 
		else 
			glPrint(x,y+(14 * i)+5 ,1.0f,1.0f,1.0f,1.0f,Entry[i]);
	}
}

wie ihr sicher seht hab ich 9 Elemente in diesem kleinen Code im Menu dargestellt.
Und denkt daran das wenn ich z.b. 12 Elemente benötigt ihr das Array auf dem entsprechen erweitert.

Nun kommen wir auch schon zum Steuern durch das Menu mit den Pfeiltasten und aufgerufen wird das Menu mit „Del“ oder auch „Entf“.

Der Teil kommt in die Funktion glViewport

Code:
// Bei Jedem 5. Aufruf von glViewport wird draw.enable auf true gesetzt eine kleine maßnahme damit das ganze nicht so viele Frames zieht denn jedes 5. mal reicht vollkommen aus.
viewportcount++;
if (viewportcount > 4)
	draw.enable=true;

if (draw.enable) {
if ((GetAsyncKeyState(VK_UP) < 0) && (Last_Key != VK_UP) && (menu.active))
	{
		MenuUp();
		Last_Key = VK_UP;
	} 
	else if ((GetAsyncKeyState(VK_DELETE) < 0) && (Last_Key != VK_DELETE))
	{
		menu.active = !menu.active;
		draw.menu = !draw.menu;
		Last_Key = VK_DELETE;
	}
	else if ((GetAsyncKeyState(VK_LEFT) < 0) && (Last_Key != VK_LEFT) && (menu.active))
	{
		MenuSelect();
		Last_Key = VK_LEFT;
	}
	else if ((GetAsyncKeyState(VK_RIGHT) < 0) && (Last_Key != VK_LEFT) && (menu.active))
	{
		MenuSelect();
		Last_Key = VK_LEFT;
	}
	else if ((GetAsyncKeyState(VK_DOWN) < 0) && (Last_Key != VK_LEFT) && (menu.active))
	{
		MenuDown();
		Last_Key = VK_LEFT;
	}
	else if (!(GetAsyncKeyState(VK_DOWN) < 0) && 
			 !(GetAsyncKeyState(VK_RIGHT) < 0) && 
			 !(GetAsyncKeyState(VK_DELETE) < 0) && 
			 !(GetAsyncKeyState(VK_UP) < 0) && 
			 !(GetAsyncKeyState(VK_LEFT) < 0))
		Last_Key = 0;
}

Wobei sich der Code an sich selber erklärt demnach gehen wir auch nicht weiter darauf ein.
Nun aber ist uns aufgefallen das wir mit Funktionen Arbeiten die wir noch gar nicht kennen und zwar „MenuSelect()“, „MenuUp()“ und „MenuDown()“.
Damit wir auch diese Funktionen haben kommen sie nun auch gleich

Code:
void MenuUp()
{
	if(menu.count<2)
		menu.count=1;
	else
		menu.count--;
}

void MenuDown()
{
	if(menu.count>menu.maxcount-1)
		menu.count=menu.maxcount;
	else
		menu.count++;
}

void MenuSelect()
{
	switch(menu.count)
	{
		case 1:
			{
				cvar.asus=!cvar.asus;
				if (cvar.asus)
					cvar.sky = true;
				else
					cvar.sky = false;
				break;
			}
		case 2:
			{
				cvar.xqz=!cvar.xqz;
				break;
			}
		case 3:
			{
                			cvar.white=!cvar.white;
				break;
			}
		case 4:
			{
				cvar.lambert=!cvar.lambert;
				break;
			}
		case 5:
			{
				cvar.flash=!cvar.flash;
				break;
			}
		case 6:
			{
				cvar.smoke=!cvar.smoke;
				break;
			}
		case 7:
			{
				cvar.scope=!cvar.scope;
				break;
			}
		case 8:
			{
				cvar.sky=!cvar.sky;
				break;
			}
		case 9:
			{
				cvar.wire=!cvar.wire;
				if (cvar.asus)
					cvar.sky = true;
				else
					cvar.sky = false;
				break;
			}
	}
}

wobei sich das auch wieder alles selber erklärt und wir auch nicht weiter darauf eingehen müssen.

Nun noch ein kleiner Teil in glEnable und dann haben wir es auch schon fast geschafft.

Code:
if(!FirstInit) 
{
	BuildFont();						// Lädt die Schrift
	(*orig_glGetIntegerv)(GL_VIEWPORT,vp);	// Speichert Informationen über den Bildschirm in vp ab.
	FirstInit=true;
	InitHack();
}
	
if (draw.enable) {
	draw.enable = false;
	if (draw.menu)
		DrawMenu(50,(vp[3]/2)-60); // vp[3] enthält die Höhe unseres Screens (bei mir 1280) und dann teilen wir es durch zwei damit das Menu in der Mitte ist wobei wir noch 50 Pixel abziehen damit es etwas über der Hälfe des Screens liegt.
}

wo wir schon wieder eine neue Funktion sehen und zwar InitHack() wobei das nur eine kleine erleichterung für mich ist hier der Code

Code:
void InitHack() {
	menu.count = 1; 
	menu.active = false;
	draw.menu = false;
}

wie wir schon sehen setzt ich da nur die Werte die wir aber setzten müssen.

Nun noch die Strukturen und es ist geschafft.
Code:
typedef struct {
	int count;
	int maxcount;
	bool active;
}menu_s;

typedef struct {
	bool menu;
	bool chair;
	bool esp;
	bool info;
	bool enable;
}draw_s;

Und bevor ich es vergesse in wglSwapBuffers müssen wir den viewportcount wieder auf 0 setzten.

Ich hoffe dieses Tutorial hat hat euch geholfen.

Msg Suxx
 
thx... jetzt mach ich mir auchmaln menü :)
 
ps copy&past wird nich zwingend funktionieren :)
 
ok dann nehm ich das mit dem panzerGL zurück :rolleyes:

Es tut mir leid aber sicher hat C++ eine function mit der man zählen kann wieviele Array Elemente ein Array hat nur kenn ich sie nicht da ich erst seit ein paar Tagen mit C++ Arbeite also setzen wir hier die anzahl der Menupunkte fest

sizeof(array)
 
thx :) werd ich gleichmal einbauen

// Edit
so gemacht :)
 
Hmmm... sry aber klappt bei mir net :-/ muss aber net an dem tut liegen, vl stell ich mich auch einfach dumm an.
Code:
Kompilierung läuft...
opengl32.cpp
C:\lambert+wh+white walls\var.h(20) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'menu'
C:\lambert+wh+white walls\var.h(20) : error C2501: 'menu_s' : Fehlende Speicherklasse oder Typbezeichner
C:\lambert+wh+white walls\var.h(20) : fatal error C1004: Unerwartetes Dateiende gefunden
Fehler beim Ausführen von cl.exe.

opengl32.dll - 3 Fehler, 0 Warnung(en)

Code:
// Für die Keyverwaltung
int Last_Key=0;

// Informationen über die Bildschirm
static GLint	vp[4];

// Init Der Strukturen
menu_s	menu;
draw_s	draw;

Ich hab mein Source Code auchmal angehängt, wenn du dir den mal angucken könntest wäre das sehr lieb :-/
 
liegt sicher daran das du die strukturen nicht definiert hast das muss davor geschehen am besten in einem header file

Original von suxx-
Nun noch die Strukturen und es ist geschafft.
Code:
typedef struct {
	int count;
	int maxcount;
	bool active;
}menu_s;

typedef struct {
	bool menu;
	bool chair;
	bool esp;
	bool info;
	bool enable;
}draw_s;

Und bevor ich es vergesse in wglSwapBuffers müssen wir den viewportcount wieder auf 0 setzten.

Ich hoffe dieses Tutorial hat hat euch geholfen.

Msg Suxx

und noch etwas viel mir sofort auf

Original von suxx-

Nun noch ein kleiner Teil in glEnable und dann haben wir es auch schon fast geschafft.

Code:
if(!FirstInit) 
{
	BuildFont();						// Lädt die Schrift
	(*orig_glGetIntegerv)(GL_VIEWPORT,vp);	// Speichert Informationen über den Bildschirm in vp ab.
	FirstInit=true;
	InitHack();
}
	
if (draw.enable) {
	draw.enable = false;
	if (draw.menu)
		DrawMenu(50,(vp[3]/2)-60); // vp[3] enthält die Höhe unseres Screens (bei mir 1280) und dann teilen wir es durch zwei damit das Menu in der Mitte ist wobei wir noch 50 Pixel abziehen damit es etwas über der Hälfe des Screens liegt.
}
 
is im m3nu.h. Hab ich dass denn am anfang richtig gemacht mit glPrint und GLvoid BuildFont(GLvoid) ?
Thx, dass du mal nachguckst :D
 
jojo ich glaube hab was vergessen ^^

#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <math.h>
#include <Winbase.h>
#include <Stdlib.h>

und die errors

C:\lambert+wh+white walls\var.h(20) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'menu'
C:\lambert+wh+white walls\var.h(20) : error C2501: 'menu_s' : Fehlende Speicherklasse oder Typbezeichner

liegen daran das du menu_s menu und draw_s draw in der opengl32.cpp haben musst
 
die sind doch standartmässig im opengl32.h ... ich glaub ich hab in meinen funktioenen, die dauf menu zugreifen was falsch gemacht :-/

Edit:
Ich sollte mal schneller abschicken ;) thx
 
jo thx :)
Aber ich hab da wohl zu viel fehler reingemacht :-/ ich dachte, dass ist egal, wo ich das reinmach. nu bekomm ich nochmehr fehler :D
Code:
C:\lambert+wh+white walls\m3nu.h(21) : error C2065: 'base' : nichtdeklarierter Bezeichner
C:\lambert+wh+white walls\m3nu.h(31) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'BuildFont'
C:\lambert+wh+white walls\m3nu.h(31) : error C2501: 'Glvoid' : Fehlende Speicherklasse oder Typbezeichner
C:\lambert+wh+white walls\m3nu.h(31) : fatal error C1004: Unerwartetes Dateiende gefunden
Edit: schre auf Antworten geklickt hab ich nurnet gemerkt
 
dizzy weisste wa sich up einfach kurz mein source dann kannste es dir nochmal in ruhe angucken :)
 
das is lieb :)
Edit: hängs doch einfach an :D
 
nice tut ....aber verstehn tu ich da leider net viel....werd mich auch ma bissl mit c++ beschäftigen!
 
deine cvars müssen auch mit denen aus dem hack übereinstimmen. sonst klappt es natürlich nicht.
 
so nun geht auch dieses Tutorial aus dem Vip-Bereich an die Öffentlichkeit ich wünsch euch viel Spaß damit :)
 
hehe nu können sich manche nen menü machen, aber keinen hack dazu :P ich behaupte mal nu kommen 40-50 fragen was damit machen und was es überhaupt ist (und mal ne frage die kommen wird) Nein, dass kann man nicht inne cfg schreiben.
 
kann man in so ein menü auch so sachen wie namen, nextmap, adminsachen, oder so says machen ??
 
Bobby schrieb:
kann man in so ein menü auch so sachen wie namen, nextmap, adminsachen, oder so says machen ??
kommt drauf an in was für einem Hack du das einbaust... in einem Pure OGL Hack wirst du es nicht können
 
Ich danke dir erstmal für dieses Tutorial. Nur ich habe ein Problem. Und zwar habe ich
// Init Der Strukturen
menu_s menu;
draw_s draw;

in die OpenGl32.cpp kopiert, nur ich bekomme dann trotzdem diese errors.

Code:
--------------------Konfiguration: opengl32 - Win32 Release--------------------
Kompilierung läuft...
opengl32.cpp
C:\Dokumente und Einstellungen\ischmael\Desktop\opengl32.cpp(248) : error C2146: Syntaxfehler : Fehlendes ';' vor Bezeichner 'menu'
C:\Dokumente und Einstellungen\ischmael\Desktop\opengl32.cpp(248) : error C2501: 'menu_s' : Fehlende Speicherklasse oder Typbezeichner
C:\Dokumente und Einstellungen\ischmael\Desktop\opengl32.cpp(248) : fatal error C1004: Unerwartetes Dateiende gefunden
Fehler beim Ausführen von cl.exe.

opengl32.dll - 3 Fehler, 0 Warnung(en)
 

Beliebte Schlagwörter

Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden.
Du solltest ein Upgrade durchführen oder einen alternativen Browser verwenden.

Zurück
Oben Unten