2013-04-19 7 views
5

Sono un principiante in OpenGL e sto cercando di creare un gioco in cui come sfondo ho un'immagine grezza. Quando il gioco inizia, visualizzo quell'immagine e voglio poterla cliccare sopra e visualizzare un'altra immagine in seguito. Ho provato a utilizzare la funzione glutMouseFunc ma quando provo a eseguire il programma, ricevo un messaggio che dice che il programma ha smesso di funzionare. Ecco alcune parti del mio codice: Ho una variabile globale onMouse; se faccio clic con il pulsante del mouse la variabile assume il valore 1 e se ha il valore 1, provo a caricare la seconda immagine.rileva i clic del mouse in OpenGL C++

int onMouse; 
void mouseClicks(int button, int state, int x, int y) { 
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { 
     onMouse = 1; 
    } 
} 

E questa è la funzione principale:

//load first texture 
texture = LoadTextureRAW("2 Lock screen.raw", TRUE); 
glutMouseFunc(mouseClicks); 
if(onMouse == 1){ 
    //load second texture 
    texture = LoadTextureRAW("in_game.raw", TRUE); 
} 

Che cosa sto facendo di sbagliato?

EDIT Ho apportato alcune modifiche al codice, ma l'immagine di sfondo continua a non cambiare. Ecco la nuova funzione principale:

glutCreateWindow("Game"); 
texture = LoadTextureRAW("2 Lock screen.raw", 1); 
glutDisplayFunc(display); 

glutMouseFunc(mouseClicks); 
glutKeyboardFunc(key); 

glutMainLoop(); 

if(onMouse == 1){ 
     texture = LoadTextureRAW("in_game.raw", 2); 
     glutDisplayFunc(display); 
} 

E questa è la funzione di visualizzazione in cui mappare la texture a un quad:

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

// setup texture mapping 
glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, texture); 

glPushMatrix(); 
glBegin(GL_QUADS); 
glTexCoord2d(1.0,0.0); glVertex3d(1.0,1.0, 1.0); 
glTexCoord2d(0.0,0.0); glVertex3d(-1.0,1.0,1.0); 
glTexCoord2d(0.0,1.0); glVertex3d(-1.0,-1.0, -1.0); 
glTexCoord2d(1.0,1.0); glVertex3d(1.0,-1.0, 1.0); 
glEnd(); 
glPopMatrix(); 
glutSwapBuffers(); 

// free the texture 
FreeTexture(texture); 
+0

La tua domanda riguarda GLUT, non OpenGL. – derpface

risposta

7

Avete l'ordine sbagliato.

glutMouseFunc(mouseClicks); 

Qui si registra la funzione da chiamare quando si fa clic con il mouse.

if(onMouse == 1) { 

Verificare immediatamente se il mouse è stato premuto. È impossibile che il mouse sia stato cliccato nel breve periodo tra queste due righe e che glutMainLoop non sia stato ancora inserito in modo che il tuo programma non abbia nemmeno la possibilità di ascoltare gli eventi del mouse.


Per quanto riguarda l'arresto anomalo, non posso aiutarti a eseguire il debug con solo il codice che hai fornito. Si prega di provare un debugger e trovare quale linea provoca l'arresto anomalo.

+0

Ho cambiato l'ordine e ora ho glutMouseFunc (mouseClicks) tra le funzioni DisplayFunc() e KeyboardFunc() e dopo la chiamata di glutMainLoop() controllo per vedere se onMouse ha il valore 1; il programma continua a non cambiare l'immagine ma almeno ora non si blocca – user1956190

5

Cosa sto facendo male?

Si aspetta che glutMouseFunc attenda il clic del mouse. Questo non è il modo in cui GLUT funziona (GLUT non fa parte di OpenGL BTW). Un altro callback da registrare è la funzione di disegno (solitamente chiamata display in programmi basati su GLUT).

Una volta inserito il ciclo principale GLUT (chiamata glutMainLoop()), gli eventi utente vengono elaborati e se viene richiesta una nuova visualizzazione viene richiamata la funzione di visualizzazione.

Quindi, ecco quello che fate (in pseudocodice semplificato)

// Define bitmasks for mouse status, we assume mice have less than 17 buttons 
#define MB_LEFT 0 
#define MB_MIDDLE 1 
#define MB_RIGHT 2 
#define LMB_PRESSED (1<<0) 
#define MMB_PRESSED (1<<1) 
#define RMB_PRESSED (1<<2) 
#define LMB_CLICKED (1<<16) 
#define MMB_CLICKED (1<<17) 
#define RMB_CLICKED (1<<18) 
#define MB_PRESSED(state, button) (1<<(button)) 
#define MB_CLICKED(state, button) (1<<((button)+16))) 
#define MB_MASK_PRESSED 0x0000ffffL 
#define MB_MASK_CLICKED 0xffff0000L 

uint32_t mouse_status = 0; 

void onMouseButton(int button, int state, int x, int y) 
{ 
    int b; 
    switch(button) { 
    case GLUT_LEFT_BUTTON: b=MB_LEFT; break; 
    case GLUT_MIDDLE_BUTTON: b=MB_MIDDLE; break; 
    case GLUT_RIGHT_BUTTON: b=MB_RIGHT; break; 
    } 

    if(mouse_status & MB_PRESSED(b) && GLUT_UP == state) { 
     mouse_status |= MB_CLICKED(b); 
    } 
    if(!(mouse_status & MB_PRESSED(b)) && GLUT_DOWN == state) { 
     mouse_status = (mouse_status & ~(0L | MB_CLICKED(b))) | MB_PRESSED(b); 
    } 

    glutPostRedisplay(); 
} 

void display(void) 
{ 
    if(mouse_status & MB_CLICKED(MB_LEFT)) { 
     /* do something */ 
     … 

     /* clear the click flag */ 
     mouse_status &= ~MB_MASK_CLICKED; 
    } 
} 

int main(…) 
{ 
    … 
    glutCreateWindow(…); 
    glutDisplayFunc(display); 
    glutMouseFunc(onMouseButton); 

    glutMainLoop(); 
} 

Ovviamente si può usare qualsiasi altro tipo di struttura che ti piace di passare dallo stato del pulsante del mouse tra le parti del programma. Preferisco le maschere di bit per tali. Altre persone potrebbero preferire gli array (personalmente non mi piacciono gli array per compiti come questo, perché non sono così facili da vedere in un debugger che in un semplice bitfield).

1

glutMouseFunc registra un callback: una funzione da richiamare su eventi specifici (qui eventi del mouse).Questi eventi vengono raccolti da glutMainLoop, che non è stato ancora chiamato quando si prova onMouse.

Un'altra cosa, anche se non posso dirlo con certezza dal piccolo estratto di codice che fornisci, è che è meglio caricare le risorse dall'inizio del programma, piuttosto che aspettare che un evento utente lo faccia. Caricali prima e cambia semplicemente texture a seconda di quale ID corrisponda alla trama che desideri visualizzare.

Problemi correlati