Ahojte, snažím se naučit pracovat v OpenGL a jdu podle tohoto tutoriálu http://ogldev.atspace.co.uk/. Teď konkrétně používám kód tohoto http://ogldev.atspace.co.uk/www/tutorial32/tutorial32.html. Trochu jsem upravil kód hlavního cpp souboru tak, aby bylo možné inicializovat více nezávislých scén najednou (aktuálně scény obsahují jen SkyBox). Chtěl bych docílit toho, že při stisku klávesy '1' se na obrazovku vykreslí scéna 1, při stisku '2' scéna 2 atd. Problém ale je, že program vykresluje jen poslední inicializovanou scénu (což je samozřejmě špatně, protože by měl vykreslit první), a při stisku kláves se scéna nezmění. Tady posílám svůj kód (snad není moc dlouhý - každopádně by neměl být těžký, ale týká se opravdu zbývajícího kódu toho tutoriálu):
#include <vector>
#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "util.h"
#include "pipeline.h"
#include "camera.h"
#include "texture.h"
#include "lighting_technique.h"
#include "glut_backend.h"
#include "mesh.h"
#include "skybox.h"
using namespace std;
#define WINDOW_WIDTH 1680
#define WINDOW_HEIGHT 1050
#define SCENES_COUNT 2
class OpenGLApp : public ICallbacks
{
private:
struct OpenGLScene {
LightingTechnique* m_pLightingTechnique;
DirectionalLight m_directionalLight;
Camera* m_pGameCamera;
SkyBox* m_pSkyBox;
PersProjInfo m_persProjInfo;
vector<Mesh*> m_models;
OpenGLScene(int modelsCount)
{
m_pLightingTechnique = NULL;
m_directionalLight.AmbientIntensity = 0.2f;
m_directionalLight.DiffuseIntensity = 0.8f;
m_directionalLight.Color = Vector3f(1.0f, 1.0f, 1.0f);
m_directionalLight.Direction = Vector3f(1.0f, -1.0f, 0.0f);
m_pGameCamera = NULL;
m_pSkyBox = NULL;
m_persProjInfo.FOV = 60.0f;
m_persProjInfo.Height = WINDOW_HEIGHT;
m_persProjInfo.Width = WINDOW_WIDTH;
m_persProjInfo.zNear = 1.0f;
m_persProjInfo.zFar = 100.0f;
m_models.resize(modelsCount, NULL);
}
~OpenGLScene()
{
SAFE_DELETE(m_pLightingTechnique);
SAFE_DELETE(m_pGameCamera);
SAFE_DELETE(m_pSkyBox);
for (int i = 0; i < m_models.size(); i++)
{
SAFE_DELETE(m_models[i]);
}
}
};
int m_currentScene;
vector<OpenGLScene*> m_pScenes;
public:
OpenGLApp()
{
m_currentScene = 0;
m_pScenes.resize(SCENES_COUNT, new OpenGLScene(1));
}
~OpenGLApp()
{
for (int i = 0; i < m_pScenes.size(); i++)
{
SAFE_DELETE(m_pScenes[i]);
}
}
bool InitScene1()
{
int scene = 0;
m_pScenes[scene]->m_pSkyBox = new SkyBox(m_pScenes[scene]->m_pGameCamera, m_pScenes[scene]->m_persProjInfo);
if (!m_pScenes[scene]->m_pSkyBox->Init("skybox/skybox-elbrus", "elbrus_front.jpg", "elbrus_back.jpg", "elbrus_top.jpg", "sand_grass_02.jpg", "elbrus_left.jpg", "elbrus_right.jpg"))
{
return false;
}
return true;
}
bool InitScene2()
{
int scene = 1;
m_pScenes[scene]->m_pSkyBox = new SkyBox(m_pScenes[scene]->m_pGameCamera, m_pScenes[scene]->m_persProjInfo);
if (!m_pScenes[scene]->m_pSkyBox->Init("skybox/skybox-countrypaths", "skybox_country_paths_right.jpg", "skybox_country_paths_left.jpg", "skybox_country_paths_top.jpg", "skybox_country_paths_bottom.jpg", "skybox_country_paths_front.jpg", "skybox_country_paths_back.jpg"))
{
return false;
}
return true;
}
bool Init()
{
for (int i = 0; i < m_pScenes.size(); i++)
{
Vector3f Pos(0.0f, 1.0f, -20.0f);
Vector3f Target(0.0f, 0.0f, 1.0f);
Vector3f Up(0.0, 1.0f, 0.0f);
m_pScenes[i]->m_pGameCamera = new Camera(WINDOW_WIDTH, WINDOW_HEIGHT, Pos, Target, Up);
m_pScenes[i]->m_pLightingTechnique = new LightingTechnique();
if (!m_pScenes[i]->m_pLightingTechnique->Init())
{
printf("Error initializing the lighting technique of the %d. scene.\n", i + 1);
return false;
}
m_pScenes[i]->m_pLightingTechnique->Enable();
m_pScenes[i]->m_pLightingTechnique->SetDirectionalLight(m_pScenes[i]->m_directionalLight);
m_pScenes[i]->m_pLightingTechnique->SetColorTextureUnit(0);
switch(i)
{
case 0:
if (!InitScene1())
{
printf("Error initializing the scene %d.\n", i + 1);
return false;
}
break;
case 1:
if (!InitScene2())
{
printf("Error initializing the scene %d.\n", i + 1);
return false;
}
break;
default:
m_pScenes[i]->m_pSkyBox = new SkyBox(m_pScenes[i]->m_pGameCamera, m_pScenes[i]->m_persProjInfo);
if (!m_pScenes[i]->m_pSkyBox->Init("skybox/skybox-elbrus",
"elbrus_front.jpg", "elbrus_back.jpg", "elbrus_top.jpg", "sand_grass_02.jpg", "elbrus_left.jpg", "elbrus_right.jpg"))
{
printf("Error initializing the scene %d.\n", i + 1);
return false;
}
break;
}
}
return true;
}
void Run()
{
GLUTBackendRun(this);
}
virtual void RenderSceneCB()
{
m_pScenes[m_currentScene]->m_pGameCamera->OnRender();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_pScenes[m_currentScene]->m_pLightingTechnique->Enable();
Pipeline p;
p.Rotate(0.0f, 180.0f, 0.0f);
p.SetCamera(m_pScenes[m_currentScene]->m_pGameCamera->GetPos(),
m_pScenes[m_currentScene]->m_pGameCamera->GetTarget(),
m_pScenes[m_currentScene]->m_pGameCamera->GetUp());
p.SetPerspectiveProj(m_pScenes[m_currentScene]->m_persProjInfo);
m_pScenes[m_currentScene]->m_pLightingTechnique->SetWVP(p.GetWVPTrans());
m_pScenes[m_currentScene]->m_pLightingTechnique->SetWorldMatrix(p.GetWorldTrans());
m_pScenes[m_currentScene]->m_pSkyBox->Render();
glutSwapBuffers();
}
virtual void IdleCB()
{
RenderSceneCB();
}
virtual void SpecialKeyboardCB(int Key, int x, int y)
{
m_pScenes[m_currentScene]->m_pGameCamera->OnKeyboard(Key);
}
virtual void KeyboardCB(unsigned char Key, int x, int y)
{
switch (Key) {
case 'q':
case 27:
glutLeaveMainLoop();
break;
case '1': m_currentScene = 0; break;
case '2': m_currentScene = 1; break;
case 'w': m_pScenes[m_currentScene]->m_pGameCamera->OnKeyboard(GLUT_KEY_UP); break;
case 'd': m_pScenes[m_currentScene]->m_pGameCamera->OnKeyboard(GLUT_KEY_RIGHT); break;
case 's': m_pScenes[m_currentScene]->m_pGameCamera->OnKeyboard(GLUT_KEY_DOWN); break;
case 'a': m_pScenes[m_currentScene]->m_pGameCamera->OnKeyboard(GLUT_KEY_LEFT); break;
}
}
virtual void PassiveMouseCB(int x, int y)
{
m_pScenes[m_currentScene]->m_pGameCamera->OnMouse(x, y);
}
virtual void MouseCB(int Button, int State, int x, int y)
{
}
};
int main(int argc, char** argv)
{
GLUTBackendInit(argc, argv);
if (!GLUTBackendCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, 32, true, "OpenGL Application")) {
return 1;
}
OpenGLApp* pApp = new OpenGLApp();
if (!pApp->Init()) {
return 1;
}
pApp->Run();
delete pApp;
return 0;
}
Nějaký nápad, kde bych mohl mít chybu? Díky :-)