Passing from start menu to game scene

Hi, I create using GLUT and VBO a simple menu start (three rectangle with fonts inside) and I want that when user press the mouse button the game starts.
I don’t develop the game yet, so I’m trying to load a simple game scene with a shape after pressing mouse button.
But I don’t know how I sould design the code and implement it.

Start menu is rendered in a StartMenu class. After the mouse click I call the GameScene render() function using a pointer to GameScene object, so GameScene is a new class to render and manage the game itself.
Is it correct or I should manage the two renderings (start menu and game scene) in a unique class?

My second question is how render the game scene using VBO, if I try to use VBO I get a bad_exc_error.
This is my actual code:

bool StartMenu::drawButtons()
{
    m_vertices.push_back(Vertex(-button1->x,button1->y,-1));
    m_vertices.push_back(Vertex(button1->x,button1->y,-1));
    m_vertices.push_back(Vertex(button1->x,button1->y+button1->h,-1));
    m_vertices.push_back(Vertex(-button1->x,button1->y+button1->h,-1));
    
    m_vertices.push_back(Vertex(-button2->x,button2->y,-1));
    m_vertices.push_back(Vertex(button2->x,button2->y,-1));
    m_vertices.push_back(Vertex(button2->x,button2->y+button2->h,-1));
    m_vertices.push_back(Vertex(-button2->x,button2->y+button2->h,-1));
    
    m_vertices.push_back(Vertex(-button3->x,button3->y,-1));
    m_vertices.push_back(Vertex(button3->x,button3->y,-1));
    m_vertices.push_back(Vertex(button3->x,button3->y+button3->h,-1));
    m_vertices.push_back(Vertex(-button3->x,button3->y+button3->h,-1));
    
    m_indices.push_back(0);
    m_indices.push_back(1);
    m_indices.push_back(2);
    m_indices.push_back(3);
    
    m_indices.push_back(4);
    m_indices.push_back(5);
    m_indices.push_back(6);
    m_indices.push_back(7);
    
    m_indices.push_back(8);
    m_indices.push_back(9);
    m_indices.push_back(10);
    m_indices.push_back(11);
    
    //glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); //Bind the vertex buffer
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * m_vertices.size(), &m_vertices[0], GL_STATIC_DRAW);
    
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); //Bind the vertex buffer
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * m_indices.size(), &m_indices[0], GL_STATIC_DRAW);
    
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexPointer(3, GL_FLOAT, 0, 0);
    
    Font(GLUT_BITMAP_HELVETICA_18,button1->label,-0.3f,1.9f);
    Font(GLUT_BITMAP_HELVETICA_18,button2->label,-0.4f,0.15f);
    Font(GLUT_BITMAP_HELVETICA_18,button3->label,-0.3f,-1.6f);
    
    return true;
}

void StartMenu::renderMenu()
{
    drawButtons();
    glDrawElements(GL_QUADS, m_indices.size(), GL_UNSIGNED_INT, 0);
}

void StartMenu::mouse(int btn, int state, int x, int y)
{
    int posx, posy;
    if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
        posx = x;
        posy = y;
        //store the x,y value where the click happened
        std::cout << "premuto " << posx << " " << posy << std::endl;
        scene->render();
    }	
}

and the GameScene code:

void GameScene::render()
{
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_CULL_FACE);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(0.0f, 0.0f, 7.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    
    glBegin(GL_TRIANGLES);
    glVertex3f(-2.0f,2.0f,-1.0f);
    glVertex3f(2.0f,2.0f,-1.0f);
    glVertex3f(0.0f,4.0f,-1.0f);
    glEnd();
    
    glFlush();
               
}

The GameScene render() draw a Triangle using immediate mode, but I want to use VBO

Thank you

One way to do it is to have an abstract base class GamePhase and derive the different phases of your game from it. Your glut callbacks then simply forward to the currently active GamePhase object. When you go from one phase to the next you change the global activePhase pointer to point to an instance of the new phase.


class GamePhase
{
    virtual void render (void) = 0;
    virtual void reshape(int w, int h) = 0;
};

class StartMenu : public GamePhase
{
    virtual void render(void);
    virtual void reshape(int w, int h);
};

class GameScene : public GamePhase
{
    virtual void render(void);
    virtual void reshape(int w, int h);
}

GamePhase *activePhase;

// GLUT callbacks

void display(void)
{
    activePhase->render();
}

void reshape(int w, int h)
{
    activePhase->reshape(w, h);
}

if I try to use VBO I get a bad_exc_error.

Can you post the complete error message and the relevant code it refers to?
Have you read http://www.opengl.org/wiki/Vertex_Buffer_Object for example?

Thank you for your answer. I’ll implement the virtual base class and I’ll see if I have the same VBO error

Thank you! Now the program works.

I have only one problem. If I click the mouse button the GameScene is not rendered, it’s rendered only if I resize the window (so reshape function is called).
How can I rendered the new scene immediatly after the mouse button click?

Here is the new main code:

#include <iostream>
#include "myWindow.h"
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <vector>
#include "StartMenu.h"
#include "GameScene.h"

#include "globals.h"

using namespace std;

//#define BUFFER_OFFSET(i) ((char *)NULL + (i))
void display();
void animate();
void reshape(int width, int height);
void mouseFunc(int,int,int,int);

StartMenu start;
extern GamePhase *g_game;

int main (int argc, char ** argv) 
{
    g_game = &start;
    myWindow window1;
	window1.init(argc, argv);
    glutReshapeFunc(reshape);
    //window1.onResize();
	window1.render(&display);
    window1.mouse(&mouseFunc);
    
	//glutIdleFunc(&animate);
	//app.timeprec = glutGet(GLUT_ELAPSED_TIME);
    
	glutMainLoop();
	
    return 0;
}

void display()
{
	//printf("vers OpenGL: %s
", glGetString(GL_VERSION));
	//printf("vers GLSL: %s

", glGetString(GL_SHADING_LANGUAGE_VERSION));

	if(g_game->initialize()) {
		g_game->render();
	}

	glFlush();
	
}
void reshape(int width, int height)
{
    g_game->reshape(width,height);
}

void animate()
{
	//app.animate();
}

void mouseFunc(int btn, int state, int x, int y)
{
    g_game->mouse(btn, state, x, y);
}

The StartMenu mouse func:

void StartMenu::mouse(int btn, int state, int x, int y)
{
    int posx, posy;
    if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
        posx = x;
        posy = y;
        //store the x,y value where the click happened
        std::cout << "premuto " << posx << " " << posy << std::endl;
        g_game = &scene;
    }	
}