Exemple #1
0
int main()
{
    initCrashSystem();
    initMemorySystem();

    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_Window *window = SDL_CreateWindow("",
                                          SDL_WINDOWPOS_UNDEFINED,
                                          SDL_WINDOWPOS_UNDEFINED,
                                          640,
                                          640,
                                           SDL_WINDOW_OPENGL
                                          |SDL_WINDOW_RESIZABLE
                                          |SDL_WINDOW_SHOWN);

    SDL_GLContext context = createContext(window);

    SDL_GL_SetSwapInterval(1);

    bool running = true;
    float frametime = 0.0f;

    Renderer *renderer = NEW(Renderer, NEW(GLBackend));
    ResourceManager *resMgr = renderer->getResourceManager();
    Scene *scene = NEW(Scene, renderer);
    Scene *quadScene = NEW(Scene, renderer);

    RenderTarget *target = NEW(RenderTarget, renderer);

    RenderTarget *textureTarget = NEW(RenderTarget, renderer);
    Framebuffer *framebuffer = textureTarget->addFramebuffer();
    framebuffer->addColor(resMgr->createTexture(Texture::Texture2D), Texture::RGBAU8_Norm_InternalFormat);
    framebuffer->addColor(resMgr->createTexture(Texture::Texture2D), Texture::Red32F_InternalFormat);
    framebuffer->addColor(resMgr->createTexture(Texture::Texture2D), Texture::RGBU8_Norm_InternalFormat);
    framebuffer->addColor(resMgr->createTexture(Texture::Texture2D), Texture::RGBAU8_Norm_InternalFormat);
    framebuffer->addColor(resMgr->createTexture(Texture::Texture2D), Texture::RGBU8_Norm_InternalFormat);
    framebuffer->addColor(resMgr->createTexture(Texture::Texture2D), Texture::RGBU8_Norm_InternalFormat);
    framebuffer->finish();

    ResPtr<Model> model = resMgr->load("res/models/dragon.json").cast<Model>();


    ResPtr<Mesh> quadMesh = resMgr->createMesh(resMgr->load("res/shaders/quad vertex.json").cast<Shader>(), Mesh::Triangles, 6);
    VertexBuffer *quadVB = quadMesh->addPositions(renderer, MeshComponent(2, MeshComponent::Float32))->getVertexBuffer();

    quadVB->alloc(sizeof(glm::vec2)*6);
    glm::vec2 *quadPositions = (glm::vec2 *)quadVB->map(false, true);
    quadPositions[0] = glm::vec2(-1.0f, -1.0f);
    quadPositions[1] = glm::vec2( 1.0f, -1.0f);
    quadPositions[2] = glm::vec2(-1.0f,  1.0f);
    quadPositions[3] = glm::vec2(-1.0f,  1.0f);
    quadPositions[4] = glm::vec2( 1.0f, -1.0f);
    quadPositions[5] = glm::vec2( 1.0f,  1.0f);
    quadVB->unmap();


    ResPtr<Material> quadMaterial = resMgr->createMaterial(
    resMgr->load("res/shaders/quad fragment.json").cast<Shader>());
    quadMaterial->mUniforms["colorTexture"] = framebuffer->getColorTexture(0);
    quadMaterial->mUniforms["depthTexture"] = framebuffer->getColorTexture(1);
    quadMaterial->mUniforms["normalTexture"] = framebuffer->getColorTexture(2);
    quadMaterial->mUniforms["materialTexture"] = framebuffer->getColorTexture(3);
    quadMaterial->mUniforms["ambientTexture"] = framebuffer->getColorTexture(4);
    quadMaterial->mUniforms["specularTexture"] = framebuffer->getColorTexture(5);
    quadMaterial->mUniforms["lightDirection"] = glm::vec3(0.0f);


    ResPtr<Model> quadModel = resMgr->createModel();
    quadModel->mLODs.push_back(LOD(quadMesh, quadMaterial, 0.0f));
    quadModel->sortLODs();

    quadScene->createEntity(quadModel);


    scene->mSkyboxTexture = resMgr->load("res/textures/enviroment texture.json").cast<Texture>();


    Entity *entity = scene->createEntity(model);

    float t = 0.0f;

    bool fullscreen = false;

    glm::vec3 cameraPosition(0.0f, 0.0f, 5.0f);
    glm::vec2 cameraAngle(3.1415f, 0.0f);
    float cameraSpeed = 3.0f;
    float cameraRotateSpeed = 1.0f;

    while (running)
    {
        Uint64 start = SDL_GetPerformanceCounter();

        SDL_Event event;

        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT:
                {
                    running = false;
                    break;
                }
                case SDL_KEYDOWN:
                {
                    switch (event.key.keysym.scancode)
                    {
                        case SDL_SCANCODE_ESCAPE:
                        {
                            running = false;
                            break;
                        }
                        case SDL_SCANCODE_F1:
                        {
                            fullscreen = not fullscreen;

                            SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP*fullscreen);
                        }
                        default: {}
                    }
                }
            }
        }

        const Uint8 *pressed = SDL_GetKeyboardState(NULL);

        glm::vec3 direction(std::cos(cameraAngle.y) * std::sin(cameraAngle.x),
                            std::sin(cameraAngle.y),
                            std::cos(cameraAngle.y) * std::cos(cameraAngle.x));

        glm::vec3 right(std::sin(cameraAngle.x - 3.1415f / 2.0f),
                        0.0f,
                        std::cos(cameraAngle.x - 3.1415f / 2.0f));

        glm::vec3 up = glm::cross(right, direction);

        if (pressed[SDL_SCANCODE_LEFT])
        {
            cameraAngle.x += cameraRotateSpeed * frametime;
        } else if (pressed[SDL_SCANCODE_RIGHT])
        {
            cameraAngle.x -= cameraRotateSpeed * frametime;
        } else if (pressed[SDL_SCANCODE_UP])
        {
            cameraAngle.y += cameraRotateSpeed * frametime;
        } else if (pressed[SDL_SCANCODE_DOWN])
        {
            cameraAngle.y -= cameraRotateSpeed * frametime;
        } else if (pressed[SDL_SCANCODE_A])
        {
            cameraPosition -= right * frametime * cameraSpeed;
        } else if (pressed[SDL_SCANCODE_D])
        {
            cameraPosition += right * frametime * cameraSpeed;
        } else if (pressed[SDL_SCANCODE_W])
        {
            cameraPosition += direction * frametime * cameraSpeed;
        } else if (pressed[SDL_SCANCODE_S])
        {
            cameraPosition -= direction * frametime * cameraSpeed;
        }

        scene->mProjectionTransform.reset();

        int windowWidth;
        int windowHeight;
        SDL_GetWindowSize(window, &windowWidth, &windowHeight);
        target->setWidthAndHeight(windowWidth, windowHeight);
        textureTarget->setWidthAndHeight(windowWidth, windowHeight);

        scene->mProjectionTransform.perspective(45.0f, float(windowWidth)/float(windowHeight), 0.1f, 100.0f);

        scene->mViewTransform.reset();
        scene->mViewTransform.lookAt(cameraPosition,
                                     cameraPosition+direction,
                                     up);

        t += frametime;

        entity->mTransform.reset();
        entity->mTransform.scale(glm::vec3(0.5f));

        entity->mTransform.rotate(45.0f*t, glm::vec3(0.0f, 1.0f, 0.0f));

        renderer->render(textureTarget, scene);

        quadMaterial->mUniforms["lightDirection"]
        = glm::mat3(scene->mViewTransform.getMatrix()) * glm::vec3(-1.0f, 1.0f, -1.0f);

        renderer->render(target, quadScene);

        SDL_GL_SwapWindow(window);

        resMgr->deleteUnusedResources();

        Uint64 end = SDL_GetPerformanceCounter();

        frametime = float(end - start) / float(SDL_GetPerformanceFrequency());

        char title[256];
        std::memset(title, 0, 256);
        std::snprintf(title, 256, "Frametime: %.4f, Framerate: %.0f", frametime, 1.0f/frametime);
        SDL_SetWindowTitle(window, title);
    }

    model = nullRes<Model>();
    quadMesh = nullRes<Mesh>();
    quadMaterial = nullRes<Material>();
    quadModel = nullRes<Model>();

    DELETE(RenderTarget, textureTarget);
    DELETE(RenderTarget, target);

    DELETE(Scene, quadScene);
    DELETE(Scene, scene);

    DELETE(Renderer, renderer);

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);

    SDL_Quit();

    deinitMemorySystem();

    return 0;
}
DemoScene raytracer::gui::constructDemoScene()
{
    /// Load resources
    ResourceManager* resourceManager = ResourceManager::getInstance();
    Texture* terrainTexture = new TerrainHeightTexture( // multitexture for terrain
	    resourceManager->createImage("terrainImage1", "resources/terrain_dirt.tga"),
	    resourceManager->createImage("terrainImage2", "resources/terrain_grass.tga"),
	    resourceManager->createImage("terrainImage3", "resources/terrain_rock.tga"),
	    resourceManager->createImage("terrainImage4", "resources/terrain_snow.tga")
    );
    std::vector<Image*> skyBoxImages(6);
    skyBoxImages[0] = resourceManager->createImage("skyboxFront", "resources/miramar_ft.tga");
    skyBoxImages[1] = resourceManager->createImage("skyboxRight", "resources/miramar_rt.tga");
    skyBoxImages[2] = resourceManager->createImage("skyboxBack", "resources/miramar_bk.tga");
    skyBoxImages[3] = resourceManager->createImage("skyboxLeft", "resources/miramar_lf.tga");
    skyBoxImages[4] = resourceManager->createImage("skyboxUp", "resources/miramar_up.tga");
    skyBoxImages[5] = resourceManager->createImage("skyboxDown", "resources/miramar_dn.tga");
    std::vector<Texture*> skyBoxTextures(6);
    skyBoxTextures[0] = resourceManager->createTexture("skyboxFrontTexture", "skyboxFront");
    skyBoxTextures[1] = resourceManager->createTexture("skyboxRightTexture", "skyboxRight");
	skyBoxTextures[2] = resourceManager->createTexture("skyboxBackTexture", "skyboxBack");
	skyBoxTextures[3] = resourceManager->createTexture("skyboxLeftTexture", "skyboxLeft");
	skyBoxTextures[4] = resourceManager->createTexture("skyboxUpTexture", "skyboxUp");
	skyBoxTextures[5] = resourceManager->createTexture("skyboxDownTexture", "skyboxDown");
    // Define scene
    AABB sceneBoundary(Vector3(-1000, -1000, -1000), Vector3(1000, 1000, 1000));
    ShapeList shapes;
    shapes.push_back(new Sphere(Vector3(0.0f, 8.0f, -25.0f), 2.0f,
        new Material(0.5f, 1.2f, 0.5f, 20.0f, Material::NO_REFLECTION,
        Material::NO_REFRACTION, Colour(0.4f, 0.4f, 0.8f), NULL)
    ));
    shapes.push_back(new Sphere(Vector3(-4.0f, 10.0f, -20.0f), 2.0f,
        new Material(0.5f, 3.0f, 1.0f, 20.0f, 1.0f,
        Material::NO_REFRACTION, Colour(), NULL)
    ));
    shapes.push_back(new Sphere(Vector3(0.0f, 5.0f, -15.0f), 2.0f,
        new Material(0.5f, 1.2f, 0.5f, 20.0f, 0.5f,
            1.6666, Colour(0.8f, 0.2f, 0.2f), NULL)
    ));
    shapes.push_back(new Sphere(Vector3(3.0f, 5.0f, -26.5f), 1.0f,
        new Material(5.0f, 0.0f, 0.0f, 0.0f, 0.4f,
        Material::NO_REFRACTION, Colour(0.9f, 0.65f, 0.0f), NULL)
    ));
    // Load skybox
    shapes.push_back(shapeloaders::getSkyBox(common::SKYBOX_SIZE, skyBoxTextures));

	// Define all possible viewpoints
	std::vector<Camera> cameras;
	cameras.reserve(3);
	cameras.push_back(Camera(
        Vector3(0, 5.0f, 0), Vector3(0, 0, -1), Vector3(0, 1, 0),
        Rect(-100, 100, -100, 100), 200, false));
	cameras.push_back(Camera(
        Vector3(-10, 3.0f, -10.0f), Vector3(1, 0.2f, -1), Vector3(0, 1, 0),
        Rect(-100, 100, -100, 100), 200, false));        
	cameras.push_back(Camera(
        Vector3(5.0f, 30.0f, -50.0f), Vector3(0.0f, -0.6f, 1), Vector3(0, 1, 0),
        Rect(-100, 100, -100, 100), 200, false));
        
    // Load all possible terrain
    std::vector<std::string> heightmapFilenames;
    heightmapFilenames.push_back("resources/heightmap.tga");
    heightmapFilenames.push_back("resources/heightmap2.tga");
    heightmapFilenames.push_back("resources/heightmap3.tga");
    std::vector<Image*> heightmaps;
    for (unsigned int i = 0; (i < heightmapFilenames.size()); i++)
    	heightmaps.push_back( resourceManager->createImage("heightmap", heightmapFilenames[i]) );
    std::vector<Vector3> terrainOffsets;
    for (unsigned int i = 0; (i < heightmaps.size()); i++)
    {
		terrainOffsets.push_back(Vector3(
			-((common::TERRAIN_CELL_SIZE * heightmaps[i]->getWidth()) / 2.0f),
			0.0f, -((common::TERRAIN_CELL_SIZE * heightmaps[i]->getHeight()) / 2.0f))
		);
	}
	ShapeList terrainVariants;
    for (unsigned int i = 0; (i < heightmaps.size()); i++)
    {
		Shape* unoptimisedTerrain = shapeloaders::getTerrainFromHeightmap(
			heightmapFilenames[i], common::TERRAIN_CELL_SIZE,
			common::TERRAIN_MAX_HEIGHT, terrainOffsets[i], terrainTexture, false);
		Shape* optimisedTerrain = shapeloaders::getTerrainFromHeightmap(
			heightmapFilenames[i], common::TERRAIN_CELL_SIZE,
			common::TERRAIN_MAX_HEIGHT, terrainOffsets[i], terrainTexture, true);
	    terrainVariants.push_back(unoptimisedTerrain);
        terrainVariants.push_back(optimisedTerrain);
    }
    
    // Construct test shapes (lines of each terrain's octree)
    ShapeList octreeLines;
    for (unsigned int i = 0; (i < terrainVariants.size()); i += 2) // go in 2s so unoptimised terrain is skipped
    {
        LineList lines = dynamic_cast<Octree*>(terrainVariants[i + 1])->getBoundingLines();
        ShapeList lineShapes = generateLines(lines, 0.4f, NULL);
        BoundingShape* rootOfLines = new BoundingShape(lineShapes, sceneBoundary);
        octreeLines.push_back(rootOfLines);
    }

	// Create renderer to render scene
	Raytracer* renderer = new Raytracer(cameras[0]);
    renderer->setRootShape(new BoundingShape(shapes, sceneBoundary));
    // Add light sources 
    std::vector<PointLight> pointLights;
    pointLights.push_back(PointLight(
        Vector3(-100, 70, 100),
        Colour(0.2f, 0.2f, 0.2f),
        Colour(0.4f, 0.4f, 0.4f),
        Colour(1.0f, 1.0f, 1.0f)
    ));
    pointLights.push_back(PointLight(
        Vector3(3.0f, 5.0f, -26.5f),
        Colour(0.0f, 0.0f, 0.0f),
        Colour(0.6f, 0.76f, 0.0f),
        Colour(1.0f, 0.3f, 0.0f)
    ));
    // Disable test shapes at start
    renderer->showTestShapes(false);
    
	// Return the entire scene
	DemoScene scene = { renderer, cameras, terrainVariants, octreeLines, pointLights };
	return scene;
}