//! constructor CNullDriver::CNullDriver(IFileSystem* io, const dimension2d<u32>& screenSize) : FileSystem(io), ViewPort(0,0,0,0), ScreenSize(screenSize), PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false) { DriverAttributes = new CAttributes(); DriverAttributes->addInt("MaxTextures", _DREAM_MATERIAL_MAX_TEXTURES_); DriverAttributes->addInt("MaxSupportedTextures", _DREAM_MATERIAL_MAX_TEXTURES_); DriverAttributes->addInt("MaxLights", getMaximalDynamicLightAmount()); DriverAttributes->addInt("MaxAnisotropy", 1); // DriverAttributes->addInt("MaxUserClipPlanes", 0); // DriverAttributes->addInt("MaxAuxBuffers", 0); DriverAttributes->addInt("MaxMultipleRenderTargets", 1); DriverAttributes->addInt("MaxIndices", -1); DriverAttributes->addInt("MaxTextureSize", -1); // DriverAttributes->addInt("MaxGeometryVerticesOut", 0); // DriverAttributes->addFloat("MaxTextureLODBias", 0.f); DriverAttributes->addInt("Version", 1); // DriverAttributes->addInt("ShaderLanguageVersion", 0); // DriverAttributes->addInt("AntiAlias", 0); setFog(); setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true); setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, true); ViewPort = rectangle<s32>(position2d<s32>(0,0), dimension2di(screenSize)); if (FileSystem) FileSystem->addRef(); // create surface loader #ifdef _DREAM_COMPILE_WITH_BMP_LOADER_ SurfaceLoader.push_back(createImageLoaderBMP()); #endif #ifdef _DREAM_COMPILE_WITH_BMP_WRITER_ SurfaceWriter.push_back(createImageWriterBMP()); #endif // set ExposedData to 0 memset(&ExposedData, 0, sizeof(ExposedData)); for (u32 i=0; i<EVDF_COUNT; ++i) FeatureEnabled[i]=true; InitMaterial2D.AntiAliasing=EAAM_OFF; InitMaterial2D.Lighting=false; InitMaterial2D.ZWriteEnable=false; InitMaterial2D.ZBuffer=ECFN_NEVER; InitMaterial2D.UseMipMaps=false; for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) { InitMaterial2D.TextureLayer[i].BilinearFilter=false; InitMaterial2D.TextureLayer[i].TextureWrapU=ETC_REPEAT; InitMaterial2D.TextureLayer[i].TextureWrapV=ETC_REPEAT; } OverrideMaterial2D=InitMaterial2D; }
void GLWidget::initializeGL() { if(!getExtensions()) { fprintf(stderr,"Error: %s.\n","Open OpenGL Extensions Error!!!"); exit(-1); } qglClearColor(Qt::gray); glClearDepth(1.0); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); setLight(); setFog(); t = startTimer(50); }
int InitGL(GLvoid) // All Setup For OpenGL Goes Here { if (!LoadGLTexture()) // Jump To Texture Loading Routine ( NEW ) { return FALSE; // If Texture Didn't Load Return FALSE ( NEW ) } quadric = gluNewQuadric(); glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW ) glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations glEnable(GL_FOG); setFog(); return TRUE; // Initialization Went OK }
void ScratchPad::run() { const string path = "/Users/saburookita/Personal Projects/Three.cpp Rev.2/examples/assets/"; ForwardRenderer renderer; renderer.init( "Ex 001: Simple Primitives", 1600 * 2 / 4, 900 * 2 / 4 ); renderer.setCameraControl(Arcball::create(2.0f)); /* Create scene */ auto scene = Scene::create(); scene->setFog(Fog::create( 0x72645b / 2, 2.0, 10.0 )); scene->setViewport(0, 0, 1600 * 2 / 4, 900 * 2 / 4); /* Create camera */ auto camera = PerspectiveCamera::create( 50.0, renderer.getAspectRatio(), 0.001, 100.0 ); camera->position = glm::vec3(0.0, 0.0, 5.5); camera->lookAt( 0.0, 0.0, 0.0 ); /* A sphere, cube, and cylinder walk into a pub */ auto sphere = Mesh::create( SphereGeometry::create(30, 20, 0.66f ), PhongMaterial::create( 0xCC00CC, 0x0, 0x0, 0x222222, 130.0, true ) ); auto cube = Mesh::create( CubeGeometry::create( 1.0f ), PhongMaterial::create( 0x00CCCC, 0x0, 0x0, 0x111111, 150.0, false ) ); cube->translate(2.0f, 0.0f, 0.0f); auto cylinder = Mesh::create( CylinderGeometry::create(0.5, 0.3, 1.0, 30, 5, true), PhongMaterial::create( 0xCCCC00, 0x0, 0x0, 0x111111, 150.0, false ) ); cylinder->getMaterial()->setSide( SIDE::DOUBLE_SIDE ); cylinder->translate(-2.0f, 0.0f, 0.0f); scene->add( sphere ); scene->add( cube ); scene->add( cylinder ); auto plane = Mesh::create( PlaneGeometry::create(20.0f, 1), PhongMaterial::create(0x333333, 0x333333, 0x333333, 0x101010 ) ); plane->rotateX(-90.0); plane->translate( 0.0, -1.5, 0.0 ); scene->add( plane ); /* Create directional light */ auto dir_light = DirectionalLight::create(0x99CCFF, 1.35, glm::vec3(3.0, 1.0, 3.0) ); scene->add( dir_light ); scene->add(HemisphereLight::create(0xFFFFFF, 0x333333, 0.8)); /* Create an ambient light */ scene->add( AmbientLight::create(0x777777)); /* Create a post render callback for objects rotation */ bool rotate_objects = false; float light_rotation_1 = 0.0; renderer.setPostRenderCallbackHandler( [&](){ dir_light->position.x = ( 2.0 * cosf( light_rotation_1 ) ); dir_light->position.z = ( 2.0 * sinf( light_rotation_1 ) ); light_rotation_1 += 0.01; if( rotate_objects ) { sphere->rotateY (-1.0f); cube->rotateY (-1.0f); cylinder->rotateX(-1.0f); } }); /* Override key callback handler */ renderer.setKeyCallbackHandler([&](GLFWwindow *window, int key, int scancode, int action, int mod) { if( action == GLFW_PRESS ) { switch ( key) { case GLFW_KEY_R: /* Toggle rotation */ rotate_objects = !rotate_objects; break; default: break; } } }); renderer.setGamma( true, true ); renderer.setClearColor( scene->getFog()->getColor() ); renderer.render(scene, camera ); }
void Ex_006_BoundingBoxTest::run() { const string path = "/Users/saburookita/Personal Projects/Three.cpp Rev.2/examples/assets/"; ForwardRenderer renderer; renderer.init( "Ex 006: Bounding Box Tests", 1600 * 2 / 4, 900 * 2 / 4 ); renderer.setCameraControl(Arcball::create(2.0f)); /* Create scene */ auto scene = Scene::create(); scene->setFog(Fog::create( 0x72645b / 2, 2.0, 15.0 )); scene->setViewport( 0.0, 0.0, renderer.getWidth(), renderer.getHeight() ); scene->setShadowMapType( SHADOW_MAP::PCF ); /* Create camera */ auto camera = PerspectiveCamera::create( 50.0, renderer.getAspectRatio(), 0.001, 100.0 ); camera->translate(0.0, 1.5, 5.5); camera->lookAt( 0.0, 1.0, 0.0 ); /* Load our ply models */ vector<string> filenames = { "dragon_vrip_res3.ply", "happy_vrip_res3.ply", }; vector<ptr<Mesh>> statues; float x_offset = -1.0; for( string filename: filenames ) { auto statue = Loader::loadPLY(path + "/ply models/", filename, aiProcess_Triangulate | aiProcess_OptimizeMeshes | aiProcess_JoinIdenticalVertices | aiProcess_GenSmoothNormals | aiProcess_FlipWindingOrder ); statue->setMaterial(PhongMaterial::create(0xcccccc, 0x0, 0x000000, 0x999999, 10, true)); statue->getGeometry()->setScale(10.0f); statue->castShadow = true; statue->receiveShadow = true; auto bbox = statue->computeBoundingBox(); glm::vec3 center = bbox->center(); glm::vec3 size = bbox->size(); statue->translate(x_offset, -(center.y - size.y * 0.5), 0.0); cout << *bbox << endl; x_offset += 2.0f; scene->add( statue ); statues.push_back( statue ); } auto box = Mesh::create( CubeGeometry::create(1.0f, 3), PhongMaterial::create(0x777777, 0x777777, 0x0, 0x0, 0.0, true) ); box->setTexture( TextureUtils::loadAsTexture( path, "crate.tga") ); box->getGeometry()->rotateX(45.0f); box->getGeometry()->setScale(1.5f); box->translate(3.0f, 0.5, 0.0); box->castShadow = true; box->receiveShadow = true; scene->add( box ); auto cylinder = Mesh::create( CylinderGeometry::create(0.5, 0.5, 1.0, 30, 5, false), PhongMaterial::create( 0xDDDDDD, 0x0, 0x0, 0x111111, 150.0, true ) ); cylinder->translate(-3.0f, 0.5f, 0.0f); cylinder->castShadow = true; cylinder->receiveShadow = true; scene->add( cylinder ); /* And the ground plane */ auto plane = Mesh::create( PlaneGeometry::create(50.0f), PhongMaterial::create() ); plane->rotateX(-90.0f); plane->receiveShadow = true; scene->add( plane ); /* Cubemap */ // auto env = Mesh::create( CubeGeometry::create(50.0f), MeshCubeMapMaterial::create() ); // env->setTexture( TextureUtils::loadAsEnvMap( path + "cube/pisa", // "nx.png", "ny.png", "nz.png", // "px.png", "py.png", "pz.png")); // // cylinder->setEnvMap( env->getTexture() ); // scene->add( env ); /* Create a (rotating) directional light */ auto dir_light = DirectionalLight::create(0x99CCFF, 1.35, glm::vec3( 3.0, 1.0, 3.0 ) ); dir_light->castShadow = true; dir_light->shadowBias = -0.0001; dir_light->shadowCameraNear = -10.0; dir_light->shadowCameraFar = 10.0; dir_light->shadowMapSize = glm::vec2(512); scene->add( dir_light ); /* Create a spotlight, the shadow should be casted no the left hand side */ auto spot_light = SpotLight::create(0x99CCFF, 1.0, 20.0, 50.0, 1.0 ); spot_light->position = glm::vec3(3.0, 2.0, 3.0); spot_light->castShadow = true; scene->add( spot_light ); /* Create an ambient light */ scene->add( AmbientLight::create(0xCCCCCC)); /* Create a post render callback for objects rotation */ bool rotate_objects = false; float light_rotation_1 = 0.0; renderer.setPostRenderCallbackHandler( [&](){ dir_light->position.x = ( 3.0 * cosf( light_rotation_1 ) ); dir_light->position.z = ( 3.0 * sinf( light_rotation_1 ) ); light_rotation_1 += 0.01; if( rotate_objects ) { box->rotateY(-1.0f); statues[0]->rotateY(-0.5f); } }); renderer.setMouseButtonCallbackHandler([&] (GLFWwindow *, int button, int action, int mod){ auto descendants = scene->getDescendants(); /* Reset the color first */ for( auto obj: descendants ) { if( instance_of(obj, Mesh)) { auto mesh = downcast( obj, Mesh ); if( instance_of(mesh->getMaterial(), PhongMaterial)){ auto phong = downcast(mesh->getMaterial(), PhongMaterial); phong->setDiffuseColor( 0xDDDDDD ); } } } if( action == GLFW_PRESS ) { auto raycaster = Projector::pickingRay(renderer.getCursorPosition(), camera); /* Upon selected / ray picked, change the diffuse color to red */ for( auto obj: descendants ) { if( instance_of(obj, Geometry)) continue; auto bound = obj->getBoundingBox(); if(raycaster->ray->intersects(bound)) { if( instance_of(obj, Mesh)) { auto mesh = downcast( obj, Mesh ); if( instance_of(mesh->getMaterial(), PhongMaterial)){ auto phong = downcast(mesh->getMaterial(), PhongMaterial); phong->setDiffuseColor( 0xDD0000 ); } } } } } }); /* Override key callback handler */ renderer.setKeyCallbackHandler([&](GLFWwindow *, int key, int scancode, int action, int mod) { if( action == GLFW_PRESS ) { switch ( key) { case GLFW_KEY_R: /* Toggle rotation */ rotate_objects = !rotate_objects; break; default: break; } } }); renderer.setGamma( true, true ); renderer.setClearColor( scene->getFog()->getColor() ); renderer.render(scene, camera ); }
void Camera::prepareRender() { //Profile pr( "camera.prepareRender" ); // - update transform hierarchy // - find out front and back plane distances // - collect visible objects and lights // - update node visibility // - sort visible objects by ascending distance // - set viewport, view- and projection transformation // - add affecting lights to rendering device // - set fog and ambient if any // - update transform hierarchy Node* root = this->root(); Scene* scene = dynamic_cast<Scene*>( root ); root->validateHierarchy(); updateCachedTransforms(); Vector3 camWorldPos = cachedWorldTransform().translation(); Vector3 camWorldDir = cachedWorldTransform().rotation().getColumn(2); // - collect visible objects and lights s_objs.clear(); s_lights.clear(); for ( Node* obj = root ; obj ; ) { //assert( obj->name().length() > 0 ); obj->m_flags &= ~NODE_RENDEREDINLASTFRAME; if ( obj->enabled() ) { if ( obj->renderable() ) { Light* light = dynamic_cast<Light*>( obj ); if ( light ) { s_lights.add( light ); ++m_renderedLights; } else { obj->m_distanceToCamera = obj->boundSphere() + (obj->m_worldTransform.translation() - camWorldPos).dot( camWorldDir ); if ( obj->updateVisibility(this) ) { obj->m_flags |= NODE_RENDEREDINLASTFRAME; s_objs.add( obj ); ++m_renderedObjects; } } } } ++m_processedObjects; obj = obj->nextInHierarchy( Node::NODE_ENABLED ); } // - sort visible objects by ascending distance std::sort( s_objs.begin(), s_objs.end(), NodeDistanceToCameraLess() ); // - set viewport, view- and projection transformation gd::GraphicsDevice* dev = Context::device(); dev->setViewport( m_x, m_y, viewportWidth(), viewportHeight() ); dev->setViewTransform( m_worldToCamera ); dev->setProjectionTransform( projectionTransform() ); // - add affecting lights to rendering device dev->removeLights(); for ( int i = 0 ; i < (int)s_lights.size() ; ++i ) s_lights[i]->apply(); // - set fog and ambient if any if ( scene ) { setFog( dev, scene ); Colorf amb = Colorf( scene->ambientColor() ); dev->setAmbient( Color(amb) ); } }
void SkyDome::loadGradient(char* filename){ m_gradient = loadTextureBMP(filename); setFog(filename); }
void Ex_004_ShadowMapping::run() { const string path = "/Users/saburookita/Personal Projects/Three.cpp Rev.2/examples/assets/"; ForwardRenderer renderer; renderer.init( "Ex 004: Shadow Mapping", 1600 * 2 / 4, 900 * 2 / 4 ); renderer.setCameraControl(Arcball::create(2.0f)); /* Create scene */ auto scene = Scene::create(); scene->setFog(Fog::create( 0x72645b / 2, 2.0, 15.0 )); scene->setViewport( 0.0, 0.0, renderer.getWidth(), renderer.getHeight() ); scene->setShadowMapType( SHADOW_MAP::PCF_SOFT ); /* Create camera */ auto camera = PerspectiveCamera::create( 50.0, renderer.getAspectRatio(), 0.001, 100.0 ); camera->translate(0.0, 1.5, 5.5); camera->lookAt( 0.0, 0.0, 0.0 ); /* Create our objects */ auto sphere = Mesh::create( SphereGeometry::create(30, 20, 0.66f ), PhongMaterial::create(0x777777, 0x0, 0x0, 0x999999, 30, true) ); sphere->setNormalMap( TextureUtils::loadAsNormalMap ( path, "tutorial_normals07.gif" ) ); sphere->translate(-2.0, 0.66f, 0.0); sphere->castShadow = true; sphere->receiveShadow = true; auto cube = Mesh::create( CubeGeometry::create(1.0, 10), PhongMaterial::create(0x777777, 0x0, 0x0, 0x0, 30, false) ); cube->setTexture( TextureUtils::loadAsTexture( path, "four_shapes_color.tga" ) ); cube->translate(0.0, 0.5, 0.0); cube->castShadow = true; cube->receiveShadow = true; auto cylinder = Mesh::create( CylinderGeometry::create(0.5, 0.5, 1.0, 30, 5, true), PhongMaterial::create( 0xCCCCCC, 0x0, 0x0, 0x111111, 150.0, false ) ); cylinder->getMaterial()->setSide( SIDE::DOUBLE_SIDE ); cylinder->castShadow = true; cylinder->receiveShadow = true; cylinder->setTexture ( TextureUtils::loadAsTexture ( path, "rock_color.tga" ) ); cylinder->setNormalMap( TextureUtils::loadAsNormalMap ( path, "rock_normal.tga" ) ); cylinder->translate(+2.0f, 0.5f, -2.0f); scene->add( cylinder ); scene->add( cube ); scene->add( sphere ); /* And the ground plane */ auto plane = Mesh::create( PlaneGeometry::create(20.0f), PhongMaterial::create(0x777777, 0x777777, 0x0, 0x999999, 30) ); plane->name = "plane"; plane->rotateX(-90.0f); plane->translate(0.0, 0.0, 0.0); plane->receiveShadow = true; scene->add( plane ); /* Cubemap */ auto env = Mesh::create( CubeGeometry::create(20.0f), MeshCubeMapMaterial::create() ); env->setTexture( TextureUtils::loadAsEnvMap( path + "cube/pisa", "nx.png", "ny.png", "nz.png", "px.png", "py.png", "pz.png")); sphere->setEnvMap( downcast(env->getTexture(), EnvMap) ); scene->add( env ); /* Create a (rotating) directional light */ auto dir_light = DirectionalLight::create(0x99CCFF, 1.35, glm::vec3( 3.0, 1.0, 3.0 ) ); dir_light->castShadow = true; dir_light->shadowBias = -0.0005; dir_light->shadowMapSize = glm::vec2(512); scene->add( dir_light ); /* Create a spotlight, the shadow should be casted no the left hand side */ auto spot_light = SpotLight::create(0x99CCFF, 1.0, 20.0, 50.0, 1.0 ); spot_light->position = glm::vec3(3.0, 2.0, 3.0); spot_light->castShadow = true; scene->add( spot_light ); /* Create an ambient light */ scene->add( AmbientLight::create(0x777777)); /* Create a post render callback for objects rotation */ bool rotate_objects = false; float light_rotation_1 = 0.0; renderer.setPostRenderCallbackHandler( [&](){ dir_light->position.x = ( 3.0 * cosf( light_rotation_1 ) ); dir_light->position.z = ( 3.0 * sinf( light_rotation_1 ) ); light_rotation_1 += 0.01; if( rotate_objects ) { cube->rotateX(-1.0f); cylinder->rotateX(1.0f); } }); /* Override key callback handler */ renderer.setKeyCallbackHandler([&](GLFWwindow *window, int key, int scancode, int action, int mod) { if( action == GLFW_PRESS ) { switch ( key) { case GLFW_KEY_R: /* Toggle rotation */ rotate_objects = !rotate_objects; break; default: break; } } }); renderer.setGamma( true, true ); renderer.setClearColor( scene->getFog()->getColor() ); renderer.render(scene, camera ); }
void Ex_008_FontStashIntegration::run() { // const string path = "/Users/saburookita/Personal Projects/Three.cpp Rev.2/examples/assets/"; const string path = "../examples/assets/"; ForwardRenderer renderer; renderer.init( "Ex 008: FontStash integration test", 1600 * 2 / 4, 900 * 2 / 4 ); renderer.setCameraControl(Arcball::create(2.0f)); /* First load the fonts */ renderer.addFont("droid-regular", path + "fonts/DroidSerif-Regular.ttf"); renderer.addFont("droid-italic", path + "fonts/DroidSerif-Italic.ttf"); renderer.addFont("droid-bold", path + "fonts/DroidSerif-Bold.ttf"); renderer.addFont("droid-japanese", path + "fonts/DroidSansJapanese.ttf"); /*Then write on screen*/ renderer.addText( "Test FontStash", 100, 100, "droid-regular", 0x0, 32.0f ); renderer.addText( "writing in italic", 100, 130, "droid-italic", 0x00FF00, 24.0f ); renderer.addText( "... or bold", 250, 130, "droid-bold", 0xFF0000, 24.0f ); renderer.addText( "éßüä", 400, 90, "droid-regular", 0x0000FF, 24.0f ); renderer.addText( "日本語もできます。", 400, 120, "droid-japanese", 0xFFFFFF, 24.0f ); renderer.addText( "spacing = 1.0", 100, 200, "droid-italic", 0x00FF00, 20.0f, 1.0f ); renderer.addText( "spacing = 5.0", 100, 225, "droid-italic", 0xFFFF00, 20.0f, 5.0f ); renderer.addText( "spacing = 10.0", 100, 250, "droid-italic", 0x00FFFF, 20.0f, 10.0f ); renderer.addText( "blur = 1.0", 400, 200, "droid-bold", 0x99CCFF, 30.0f, 0.0f, 1.0f ); renderer.addText( "blur = 5.0", 400, 240, "droid-bold", 0xFFCC99, 30.0f, 0.0f, 5.0f ); renderer.addText( "blur = 10.0", 400, 280, "droid-bold", 0xCCFF99, 30.0f, 0.0f, 10.0f ); int cursor_pos_text = renderer.addText( "Cursor Position: ", 80, 400, "droid-regular", 0xFFFFFF, 20.0f ); /* Create scene */ auto scene = Scene::create(); scene->setFog(Fog::create( 0x72645b, 2.0, 15.0 )); scene->setViewport( 0.0, 0.0, renderer.getWidth(), renderer.getHeight() ); scene->setShadowMapType( SHADOW_MAP::PCF ); /* Create camera */ auto camera = PerspectiveCamera::create( 50.0, renderer.getAspectRatio(), 0.001, 100.0 ); camera->translate(0.0, 1.5, 5.5); camera->lookAt( 0.0, 1.0, 0.0 ); /* Load our ply models */ float x_offset = -1.0; auto statue = Loader::loadPLY(path + "/ply models/", "happy_vrip_res3.ply", aiProcess_JoinIdenticalVertices | aiProcess_GenSmoothNormals | aiProcess_FlipWindingOrder ); statue->setMaterial(PhongMaterial::create(0x777777, 0x0, 0x777777, 0x0, 0, true)); statue->getGeometry()->setScale(10.f); statue->castShadow = true; statue->receiveShadow = true; auto bounding_box = statue->computeBoundingBox(); glm::vec3 size = bounding_box->size(); glm::vec3 center = bounding_box->center(); statue->translate(x_offset, -(center.y - size.y * 0.5), 0.0); x_offset += 2.0f; scene->add( statue ); /* A sphere, cube, and cylinder walk into a pub */ auto sphere = Mesh::create( SphereGeometry::create(30, 20, 0.66f ), PhongMaterial::create( 0xCCCCCC, 0x0, 0x0, 0x222222, 130.0, true ) ); sphere->setTexture ( TextureUtils::loadAsTexture ( path + "planets", "earth_atmos_2048.jpg") ); sphere->setNormalMap ( TextureUtils::loadAsNormalMap ( path + "planets", "earth_normal_2048.jpg" ) ); sphere->setSpecularMap ( TextureUtils::loadAsSpecularMap( path + "planets", "earth_specular_2048.jpg" ) ); sphere->receiveShadow = true; sphere->castShadow = true; sphere->translate( x_offset, 0.66f, 0.0f ); scene->add( sphere ); auto plane = Mesh::create( PlaneGeometry::create(20.0f), PhongMaterial::create(0x777777, 0x777777, 0x0, 0x999999, 30) ); plane->name = "plane"; plane->rotateX(-90.0f); plane->receiveShadow = true; scene->add( plane ); /* Cubemap */ auto env = Mesh::create( CubeGeometry::create(50.0f), MeshCubeMapMaterial::create() ); env->setTexture( TextureUtils::loadAsEnvMap( path + "cube/pisa", "nx.png", "ny.png", "nz.png", "px.png", "py.png", "pz.png")); statue->setEnvMap( env->getTexture() ); scene->add( env ); /* Create a (rotating) directional light */ auto dir_light = DirectionalLight::create(0x99CCFF, 1.35, glm::vec3( 3.0, 1.0, 3.0 ) ); dir_light->castShadow = true; dir_light->shadowBias = -0.001; dir_light->shadowCameraNear = -10.0; dir_light->shadowCameraFar = 10.0; scene->add( dir_light ); /* Create a spotlight, the shadow should be casted no the left hand side */ auto spot_light = SpotLight::create(0x99CCFF, 1.0, 20.0, 50.0, 1.0 ); spot_light->position = glm::vec3(3.0, 2.0, 3.0); spot_light->castShadow = true; scene->add( spot_light ); /* Create an ambient light */ scene->add( AmbientLight::create(0x777777)); /* Create a post render callback for objects rotation */ bool rotate_objects = false; float light_rotation_1 = 0.0; renderer.setPostRenderCallbackHandler( [&](){ dir_light->position.x = ( 3.0 * cosf( light_rotation_1 ) ); dir_light->position.z = ( 3.0 * sinf( light_rotation_1 ) ); light_rotation_1 += 0.01; if( rotate_objects ) { statue->rotateY(1.0f); sphere->rotateY(-1.0f); } }); renderer.setCursorCallbackHandler([&](GLFWwindow *, double x, double y){ stringstream ss; ss.precision(4); ss << "Cursor Position: (" << x << ", " << y << ")"; renderer.setText(cursor_pos_text, ss.str() ); }); /* Override key callback handler */ renderer.setKeyCallbackHandler([&](GLFWwindow *window, int key, int scancode, int action, int mod) { if( action == GLFW_PRESS ) { switch ( key) { case GLFW_KEY_R: /* Toggle rotation */ rotate_objects = !rotate_objects; break; default: break; } } }); renderer.setGamma( true, true ); renderer.setClearColor( scene->getFog()->getColor() ); renderer.render(scene, camera ); }