Wyświetlenie menu w grze, czyli zmiana widoku na 2D

0

Witam, chciałbym w mojej grze 3d wyświetlić małe menu u dołu ekranu, które będzie pokazywało ile mamy życia.
Niestety okazało się, że nie do końca potrafię "przeskoczyć" z widoku 3d do 2d nie naruszając modeli 3d :/
Wiem że to trochę skomplikowane, ale liczę że mi pomożecie.
Z góry dzięki.

0

A jak to dotychczas robisz? I w czym to robisz? Jak chcesz rysować GUI to rysujesz je na końcu jako najwyższa warstwa. Możesz textury nakładać albo inaczej jak chcesz.

0
xeo545x39 napisał(a)

A jak to dotychczas robisz? I w czym to robisz? Jak chcesz rysować GUI to rysujesz je na końcu jako najwyższa warstwa. Możesz textury nakładać albo inaczej jak chcesz.

Naczy teraz zrobiłem tyle:

void Menu::Menuwgrze(){
    glLoadIdentity();
    std::cout << std::endl << zmienne::przycisk;
    glTranslatef(1.0f,2.0f,0.0f);
    glColor3f(0.0,1.0,1.0);
    glBegin(GL_TRIANGLES);         // Rysujemy kwadraty
        glVertex3f(-1.0f, 1.0f, 0.0f);         // górny lewy
        glVertex3f( 1.0f, 1.0f, 0.0f);         // górny prawy
        glVertex3f( 1.0f,-1.0f, 0.0f);         // dolny prawy
    glEnd();         // Koniec rysowania kwadratu
}

(Wiem, kod nie jest mistrzowski).
Miało to wyglądać tak, że ja się normalnie mogę rozglądać po świecie itp. a na ekranie widnieje sobie trójkąt w nienaruszonej pozycji.
Robię to w OpenGl'u, w GLUT'cie.

0

A konkretnie co się dzieje z tymi modelami?

0
xeo545x39 napisał(a)

A konkretnie co się dzieje z tymi modelami?

Nie ma ich :P Nie wyświetla się ten trójkąt.

0

Jak chcesz sobie zrobić rysowanie OSD to ważną rzeczą jest wyłączenie DEPTH_TEST. Czyli przed rysowaniem OSD piszesz:

glDisable(GL_DEPTH_TEST);

A po rysowaniu:

glEnable(GL_DEPTH_TEST);

To samo robisz z oświetleniem, żeby światło nie wpływało na OSD. No i to wszystko robisz po rysowaniu sceny, bo po wyłączeniu badania głębi ważna jest kolejność rysowania. Żeby OSD stało w miejscu, a nie było zależne od ruchów kamery, przed rysowaniem dopisz:

glLoadIdentity();
0
Spine napisał(a)

Jak chcesz sobie zrobić rysowanie OSD to ważną rzeczą jest wyłączenie DEPTH_TEST. Czyli przed rysowaniem OSD piszesz:

glDisable(GL_DEPTH_TEST);

A po rysowaniu:

glEnable(GL_DEPTH_TEST);

To samo robisz z oświetleniem, żeby światło nie wpływało na OSD. No i to wszystko robisz po rysowaniu sceny, bo po wyłączeniu badania głębi ważna jest kolejność rysowania. Żeby OSD stało w miejscu, a nie było zależne od ruchów kamery, przed rysowaniem dopisz:

glLoadIdentity();

Czy o to ci chodziło?

void Menu::Menuwgrze(){
    glDisable(GL_DEPTH_TEST);
    std::cout << std::endl << zmienne::przycisk;


    glTranslatef(1.0f,2.0f,0.0f);
    glColor3f(0.0,1.0,1.0);
    glLoadIdentity();
    glBegin(GL_TRIANGLES);         // Rysujemy kwadraty
        glVertex3f(-1.0f, 1.0f, 0.0f);         // górny lewy
        glVertex3f( 1.0f, 1.0f, 0.0f);         // górny prawy
        glVertex3f( 1.0f,-1.0f, 0.0f);         // dolny prawy
    glEnd();         // Koniec rysowania kwadratu
    glEnable(GL_DEPTH_TEST);
} 

Bo nie działa.

0

Pokaż funkcje rysujące resztę (i wywołującą metodę Menuwgrze).

0
Spine napisał(a)

Pokaż funkcje rysujące resztę (i wywołującą metodę Menuwgrze).

/* The main drawing function. */
void DrawGLScene()
{
    //Ukryj myszkę
    if(zm.ukrywaniemyszki == true){
        glutWarpPointer(zm.window_width / 2, zm.window_height / 2); //ustawiam na srodku ekranu
        glutSetCursor(GLUT_CURSOR_NONE); //ukrycie myszki
    }

    glutSetWindow(zm.window);        //Ustala aktywne okno

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);        // Czyści okno i bufor głebokości
    glLoadIdentity();                                // Restartuje widok


    //Funckje Rotate pozwalają rozglądać się.
    glRotatef(zm.lookUpDown,1.0f,0.0f,0.0f); //Obrot w osi X
    glRotatef(zm.lookLeftRight,0.0f,1.0f,0.0f); //Obrot w osi Y

    glTranslatef(0.0+zm.playerX, 0.0 + zm.playerY, 0.0 + zm.playerZ); //przesuwa obraz :)

    //Ustawiam kolor
    glColor3f(0.0f, 1.0f, 1.0f);

    //Wczytuję wierzchołki.
    //v.UstawDane();
    //Wyświetlam wierzchołki.
    v.ShowVertices();
    //Wyświetlam celownik
    c.MainCelownik();

    //Wczytuję kolor z pixela.
    //unsigned char pixel[3];
    //glReadPixels(zm.mouse_x, zm.mouse_y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
    //std::cout << "R: " << (int)pixel[0] << std::endl;
    //std::cout << "G: " << (int)pixel[1] << std::endl;
    //std::cout << "B: " << (int)pixel[2] << std::endl;
    //std::cout << std::endl;
    m.Menuwgrze(); //TUTAJ!!!! -----------------------------------------------
    update();
    glFlush();
    glutSwapBuffers();
} 
0

Na początek powinieneś oddzielić od siebie przekształcenia rysowania.

Te funkcje, cytuję "Funckje Rotate pozwalają rozglądać się.", działają na wszystko co rysujesz poniżej, Translate też. Musisz te przekształcenia razem z rysowaniem opakować w blok glPushMatrix(), glPopMatrix();

glPushMatrix();
    //Funckje Rotate pozwalają rozglądać się.
    glRotatef(zm.lookUpDown,1.0f,0.0f,0.0f); //Obrot w osi X
    glRotatef(zm.lookLeftRight,0.0f,1.0f,0.0f); //Obrot w osi Y
 
    glTranslatef(0.0+zm.playerX, 0.0 + zm.playerY, 0.0 + zm.playerZ); //przesuwa obraz :)
 
    //Ustawiam kolor
    glColor3f(0.0f, 1.0f, 1.0f);
 
    //Wczytuję wierzchołki.
    //v.UstawDane();
    //Wyświetlam wierzchołki.
    v.ShowVertices();
    //Wyświetlam celownik
    c.MainCelownik();
glPopMatrix();

To samo robisz z m.Menuwgrze(); tak na zaś ;)

Nie wiem czy od razu zobaczysz to co chciałeś, ale powinieneś zrobić to co napisałem. To glLoadIdentity w metodzie Menuwgrze myślę, że możesz wywalić.

0

niestety :/ Nadal nie jest tak jak chciałem. Ciągle nie widać tego trójkąta.

0

Może on ciągle nie znajduje się w obszarze widzenia kamery?

w DrawGLScene pod glClear... i glLoadIdentity wpisz: gluLookAt(0, 0.1, 1, 0, 0.0, -1, 0, 1, 0);
Oczywiście jak nie używałeś w projekcie glu, musisz podlinkować bibliotekę glu i dołączyć plik nagłówkowy.

A przed rysowaniem trójkąta przesuń go sobie na widok tak dla pewności ;) - glTranslatef(0,0.0,-4);

0

Udało się!
Dziękuję wszystkim za pomoc! Oto jak ma wyglądać prawidłowy kod:

void Menu::Menuwgrze(){
    glPushMatrix();
    glDisable(GL_DEPTH_TEST);
    std::cout << std::endl << zmienne::przycisk;

    glTranslatef(0,0,-4);
    glColor3f(0.0,1.0,1.0);

    glBegin(GL_TRIANGLES);         // Rysujemy kwadraty
        glVertex3f(-1.0f, 1.0f, 0.0f);         // górny lewy
        glVertex3f( 1.0f, 1.0f, 0.0f);         // górny prawy
        glVertex3f( 1.0f,-1.0f, 0.0f);         // dolny prawy
    glEnd();         // Koniec rysowania kwadratu
    glEnable(GL_DEPTH_TEST);
    glPopMatrix();
}

Okazało się, że cały błąd polegał na tym, że tuż przed glbegin był ten glLoadIdentity();. Po prostu zapomniałem go wykomentować.

0

Niestety, pojawił się inny problem. Mianowicie chodzi o to:
user image
user image
Jak doskonale widać (o ile obrazki działają) chciałem, żeby ten kwadrat był w prawym górnym rogu ekranu. Niestety po ustawieniu na fullscreen, kwadrat juz się tego rogu nie trzyma :/
Poradzilibyście mi co robić?

0

To nie jest full screen, tylko maksymalizacja okienka. Scena zachowuje swoje proporcje (nie rozciąga się na boki), więc dobrze działa. Jak dorobisz full screen, w rozdzielczości o takich proporcjach jak okienko przed maksymalizacją, to kwadrat będzie w odpowiednim miejscu. I pewnie chodziło Ci o lewy górny róg, a nie prawy jak napisałeś...

0
Spine napisał(a)

To nie jest full screen, tylko maksymalizacja okienka. Scena zachowuje swoje proporcje (nie rozciąga się na boki), więc dobrze działa. Jak dorobisz full screen, w rozdzielczości o takich proporcjach jak okienko przed maksymalizacją, to kwadrat będzie w odpowiednim miejscu. I pewnie chodziło Ci o lewy górny róg, a nie prawy jak napisałeś...

Uruchomiłem full screen tą funckją:

 glutFullScreen();

I jest tak samo jak po zmaksymalizowaniu okna :/

0

Masz gdzieś w kodzie funkcję wyglądającą mniej więcej tak?

void resize(int width, int height)
{
  if (height==0)
   height=1;

  glViewport(0,0,width,height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

Po fullscreenie pewnie ta funkcja jest wywoływana dla nowych wymiarów obszaru rysowania. Zmień wstępny rozmiar okna na taki, żeby odpowiadał proporcjom Twojego ekranu. Np. jeśli masz ekran 16:9, to pomnóż pożądaną wysokość okienka przez 16/9, np. width=int(1.78f*float(height));
Do takiego rozmiaru dopasuj ten prostokąt, który jest w lewym górnym rogu.

0
Spine napisał(a)

Masz gdzieś w kodzie funkcję wyglądającą mniej więcej tak?

void resize(int width, int height)
{
  if (height==0)
   height=1;

  glViewport(0,0,width,height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

Po fullscreenie pewnie ta funkcja jest wywoływana dla nowych wymiarów obszaru rysowania. Zmień wstępny rozmiar okna na taki, żeby odpowiadał proporcjom Twojego ekranu. Np. jeśli masz ekran 16:9, to pomnóż pożądaną wysokość okienka przez 16/9, np. width=int(1.78f*float(height));
Do takiego rozmiaru dopasuj ten prostokąt, który jest w lewym górnym rogu.

Nie działa ten twój sposób. Dzielę 1920 na 1080, wychodzi mi 1.78. Potem ten wynik mnożę przez to co chę powiększyć (czyli jak zmieniam szerokość to mnożę przez szerokość). Zamiast ekran się wyrównać to jest za wielki :/

0

gdzieś w kodzie napisz:

glutReshapeWindow(854,480);

Najlepiej gdzieś jak tworzysz okienko glut'a.

Funkcją resize chyba nic nie musisz robić, ewentualnie wpisz jej te same parametry co w ReshapeWindow.

0
Spine napisał(a)

gdzieś w kodzie napisz:

glutReshapeWindow(854,480);

Najlepiej gdzieś jak tworzysz okienko glut'a.

Funkcją resize chyba nic nie musisz robić, ewentualnie wpisz jej te same parametry co w ReshapeWindow.

Wstawiłem to ReshapeWindow do funckji main (tam gdzie odbywa się tworzenie okna).
Nie wiem w czym ma mi to pomóc, w każdym razie efekt jest żaden (chyba że na pierwszy rzut oka się tego nie widzi).
Myślę, że trzeba by było załatwić to w inny sposób:
W tej chwili układ osi mam mniej więcej taki:
user image
Czyli punkt 0 jest na środku ekranu.
A jakbym chciał coś takiego:
user image
To jak to zmienić? Tylko chwilowo oczywiście :)

0

Chyba potrzebujesz tej funkcji: http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

0
Spine napisał(a)

Chyba potrzebujesz tej funkcji: http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml

Help. Naprawdę nie wiem co jest źle:

#include <GL/glut.h>    // Header File For The GLUT Library
#include "..\zmienne.cpp"
#include <iostream>
#include "..\include\Menu.h"


void Menu::InitMenu(){
    float w = zmienne::window_width;
    float h = zmienne::window_height;

    gluOrtho2D(0.0f, w, 0.0f, h);
}

void Menu::Menuwgrze(){

    glPushMatrix();
    InitMenu();

    glDisable(GL_DEPTH_TEST);
    std::cout << std::endl << zmienne::przycisk;

    glTranslatef(0.0f,0.0f,-3.0f);
    glColor3f(0.0,1.0,1.0);

    glBegin(GL_QUADS);         // Rysujemy kwadraty
        glVertex2f(-20.0f, 20.0f);         // górny lewy
        glVertex2f( 20.0f, 20.0f);         // górny prawy
        glVertex2f( 20.0f,-20.0f);         // dolny prawy
        glVertex2f(-20.0f,-20.0f);         // dolny lewy
    glEnd();         // Koniec rysowania kwadratu
    glEnable(GL_DEPTH_TEST);
    glPopMatrix();
}
 

Dokładnie chodzi o to, że się ten kwadrat nie wyświetla :/

0

W moich gierkach 2D z użyciem OpenGL ortho mam w funkcji resize :D

	def resize(self,(width, height)):
		if height==0:
			height=1
		glViewport(0, 0, width, height)
		glMatrixMode(GL_PROJECTION)
		glLoadIdentity()
		gluOrtho2D(self.OrthoX[0], self.OrthoX[1], self.OrthoY[0], self.OrthoY[1])
		glMatrixMode(GL_MODELVIEW)
		glLoadIdentity()

Może ten kawałek kodu Ci pomoże...

0
Spine napisał(a)

W moich gierkach 2D z użyciem OpenGL ortho mam w funkcji resize :D

	def resize(self,(width, height)):
		if height==0:
			height=1
		glViewport(0, 0, width, height)
		glMatrixMode(GL_PROJECTION)
		glLoadIdentity()
		gluOrtho2D(self.OrthoX[0], self.OrthoX[1], self.OrthoY[0], self.OrthoY[1])
		glMatrixMode(GL_MODELVIEW)
		glLoadIdentity()

Może ten kawałek kodu Ci pomoże...

No tak, ale w funckji ReSize mam już tworzenie widoku 3D. jak zamienię tworzenie perspektywy na ortho, to znowu 2D będzie działać a 3D nie :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1