void Scene::rasterize(const gml::mat4x4_t &worldView, const gml::mat4x4_t &projection, const bool useShadows) { // Struct used to pass data values for GLSL uniform variables to // the shader program Shader::GLProgUniforms shaderUniforms; // Set up uniforms constant to the world shaderUniforms.m_lightPos = gml::extract3( gml::mul( worldView, m_lightPos ) ); shaderUniforms.m_lightRad = m_lightRad; shaderUniforms.m_ambientRad = m_ambientRad; shaderUniforms.m_projection = projection; for (GLuint i=0; i<m_nObjects; i++) { // Fetch the Shader object from the ShaderManager that will perform the // shading calculations for this object const Shader::Shader *shader = m_shaderManager.getShader(m_scene[i]->getMaterial()); if (shader->getIsReady(useShadows)) { shader->bindGL(useShadows); // Bind the shader to the OpenGL context if (isGLError()) return; // Object-specific uniforms shaderUniforms.m_modelView = gml::mul(worldView, m_scene[i]->getObjectToWorld()); shaderUniforms.m_normalTrans = gml::transpose( gml::inverse(shaderUniforms.m_modelView) ); // If the surface material is not using a texture for Lambertian surface reflectance if (m_scene[i]->getMaterial().getLambSource() == Material::CONSTANT) { shaderUniforms.m_surfRefl = m_scene[i]->getMaterial().getSurfRefl(); } else { m_scene[i]->getMaterial().getTexture()->bindGL(GL_TEXTURE0); // Set up texture } // Set up the specular components of the uniforms struct if the material // is specular if (m_scene[i]->getMaterial().hasSpecular()) { shaderUniforms.m_specExp = m_scene[i]->getMaterial().getSpecExp(); shaderUniforms.m_specRefl = m_scene[i]->getMaterial().getSpecRefl(); } // Set the shader uniform variables if ( !shader->setUniforms(shaderUniforms, useShadows) || isGLError() ) return; // Rasterize the object m_scene[i]->rasterize(); if (isGLError()) return; // Unbind the shader from the OpenGL context shader->unbindGL(); } } }
bool CombinerInfo::_loadShadersStorage() { wchar_t fileName[PLUGIN_PATH_SIZE]; getStorageFileName(fileName); m_configOptionsBitSet = _getConfigOptionsBitSet(); #ifdef OS_WINDOWS std::ifstream fin(fileName, std::ofstream::binary); #else char fileName_c[PATH_MAX]; wcstombs(fileName_c, fileName, PATH_MAX); std::ifstream fin(fileName_c, std::ofstream::binary); #endif if (!fin) return false; try { u32 version; fin.read((char*)&version, sizeof(version)); if (version != ShaderStorageFormatVersion) return false; u32 optionsSet; fin.read((char*)&optionsSet, sizeof(optionsSet)); if (optionsSet != m_configOptionsBitSet) return false; const char * strRenderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); u32 len; fin.read((char*)&len, sizeof(len)); std::vector<char> strBuf(len); fin.read(strBuf.data(), len); if (strncmp(strRenderer, strBuf.data(), len) != 0) return false; const char * strGLVersion = reinterpret_cast<const char *>(glGetString(GL_VERSION)); fin.read((char*)&len, sizeof(len)); strBuf.resize(len); fin.read(strBuf.data(), len); if (strncmp(strGLVersion, strBuf.data(), len) != 0) return false; fin.read((char*)&len, sizeof(len)); for (u32 i = 0; i < len; ++i) { m_pCurrent = new ShaderCombiner(); fin >> *m_pCurrent; m_pCurrent->update(true); m_pUniformCollection->bindWithShaderCombiner(m_pCurrent); m_combiners[m_pCurrent->getKey()] = m_pCurrent; } } catch (...) { m_shadersLoaded = 0; return false; } m_shadersLoaded = m_combiners.size(); fin.close(); return !isGLError(); }
Gouraud::Gouraud() { //printf("Vert shader:\n%s\n\nFrag shader:\n%s\n", vertShader, fragShader); if ( !m_program.init(vertShader, fragShader) || isGLError() ) { fprintf(stderr, "ERROR: Specular Gouraud failed to initialize\n"); } m_isReady = (m_program.getUniformID(UNIFORM_LIGHTPOS) >= 0) && (m_program.getUniformID(UNIFORM_LIGHTRAD) >= 0) && (m_program.getUniformID(UNIFORM_AMBIENT) >= 0) && (m_program.getUniformID(UNIFORM_SURFREF) >= 0) && (m_program.getUniformID(UNIFORM_SPECEXP) >= 0) && (m_program.getUniformID(UNIFORM_SPECREF) >= 0) && (m_program.getUniformID(UNIFORM_MODELVIEW) >= 0) && (m_program.getUniformID(UNIFORM_PROJECTION) >= 0) && (m_program.getUniformID(UNIFORM_NORMALTRANS) >= 0); m_isShadowReady = m_isReady; #if !defined(NDEBUG) if ( !m_isReady ) { fprintf(stderr, "ERROR: Specular Gouraud missing uniforms\n"); } #endif }
DirectionalLightPass::DirectionalLightPass() { // Try to create, compile, & link a GLSL program using the source // you give it. if ( !m_program.init(vertShader, fragShader) || isGLError() ) { fprintf(stderr, "ERROR: Depth failed to initialize\n"); } // Make sure that every uniform that you are using in your shader // is given a handle. // variable names that do not correspond with a uniform will have // been given the value -1 m_isReady = (m_program.getUniformID(UNIFORM_MODELVIEW) >= 0) && (m_program.getUniformID(UNIFORM_PROJECTION) >= 0) && (m_program.getUniformID(UNIFORM_LIGHTRAD) >= 0) && (m_program.getUniformID(UNIFORM_DS_AMBIENTINTENCITY) >= 0) && (m_program.getUniformID(UNIFORM_DS_DIFFUSEINTENSITY) >= 0) && (m_program.getUniformID(UNIFORM_DS_DLDIRECTION) >= 0) && (m_program.getUniformID(UNIFORM_DS_SCREENSIZE) >= 0) && (m_program.getUniformID(UNIFORM_DS_POSTEX) >= 0) && (m_program.getUniformID(UNIFORM_DS_DIFFTEX) >= 0) && (m_program.getUniformID(UNIFORM_DS_NORMTEX) >= 0) #if defined (DO_SHADOW) && (m_program.getUniformID(UNIFORM_SHADOWMAP) >= 0) && (m_program.getUniformID(UNIFORM_DS_LIGHT_PROJMAT) >= 0) #endif ; }
void neb::glsl::program::scanUniforms() { GLsizei len; GLint size; GLenum type; GLchar str_name[128]; for(int i = 0; i < 1000; i++) { glGetActiveUniform(o_, i, 128, &len, &size, &type, str_name); if(isGLError()) break; //printf("name=%32s type=%s\n", str_name, shaderTypeString(type)); // scalar or vector std::string name = str_name; size_t find_open = name.find("["); size_t find_close = name.find("]"); if(find_open != std::string::npos) { std::string name1 = name.substr(0, find_open); std::string name2 = name.substr(find_close + 2); auto it = uniform_vector_.find(name1 + "." + name2); if(it != uniform_vector_.end()) continue; add_uniform_vector(name1, name2, type); } else { add_uniform_scalar(name, type); } } }
void Mesh::rasterize() const { assert(m_vertArrayObj != 0); // To render/rasterize the object, we first have to bind the VAO // for the geometry. glBindVertexArray(m_vertArrayObj); if (!isGLError()) { // Tell OpenGL to render the geometry defined by the index array // using the data in the currently bound VAO glDrawElements(m_primitiveType, m_numIndices, GL_UNSIGNED_INT, m_indices); isGLError(); } glBindVertexArray(0); }
void Assignment6::rasterizeScene() { if (m_renderWireframe) { // Turn on wireframe rendering glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } // Turn on backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // Turn on the depth buffer glEnable(GL_DEPTH_TEST); // Clear the pixel data & depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (isGLError()) return; // Bind the shadowmap to texture unit 1 if (m_useShadowMap) { m_shadowmap.bindGL(GL_TEXTURE1); if (isGLError()) return; } m_scene.rasterize(m_camera.getWorldView(), m_camera.getProjection(), m_useShadowMap); if (m_useShadowMap) { m_shadowmap.unbindGL(GL_TEXTURE1); } // Put the render state back the way we found it glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); if (m_renderWireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // Force everything outstanding to complete glFinish(); }
void Assignment6::repaint() { /*member * Called automatically whenever the window needs to be * redrawn. * This will end up being called after any user event (keypress, etc), * and pretty much every time through the event loop. */ if (m_sRGBframebuffer) { //glEnable(GL_FRAMEBUFFER_SRGB_EXT); } if (m_isRayTracing) { glBindFramebuffer(GL_READ_FRAMEBUFFER, m_rtFBO); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rtTex, 0); if (isGLError()) return; glBlitFramebuffer( 0, 0, m_windowWidth, m_windowHeight, 0, 0, m_windowWidth, m_windowHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST); if (isGLError()) return; } else { if (m_useShadowMap) { m_shadowmap.create(m_scene, m_camera.getWorldView()); if ( isGLError() ) return; } // Bind the default framebuffer. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glViewport(0,0,m_windowWidth,m_windowHeight); rasterizeScene(); } if (m_sRGBframebuffer) { //glDisable(GL_FRAMEBUFFER_SRGB_EXT); } }
void RSP_ThreadProc(std::mutex * _pRspThreadMtx, std::mutex * _pPluginThreadMtx, std::condition_variable_any * _pRspThreadCv, std::condition_variable_any * _pPluginThreadCv, APICommand ** _pCommand) { _pRspThreadMtx->lock(); RSP_Init(); GBI.init(); Config_LoadConfig(); video().start(); assert(!isGLError()); while (true) { _pPluginThreadMtx->lock(); _pPluginThreadCv->notify_one(); _pPluginThreadMtx->unlock(); _pRspThreadCv->wait(*_pRspThreadMtx); if (*_pCommand != nullptr && !(*_pCommand)->run()) return; assert(!isGLError()); } }
bool Gouraud::setUniforms(const GLProgUniforms &uniforms, const bool usingShadow) const { glUniform3fv(m_program.getUniformID(UNIFORM_LIGHTPOS), 1, (GLfloat*)&uniforms.m_lightPos); glUniform3fv(m_program.getUniformID(UNIFORM_LIGHTRAD), 1, (GLfloat*)&uniforms.m_lightRad); glUniform3fv(m_program.getUniformID(UNIFORM_AMBIENT), 1, (GLfloat*)&uniforms.m_ambientRad); glUniform1i(m_program.getUniformID(UNIFORM_TEXTURE0), 0); glUniformMatrix4fv(m_program.getUniformID(UNIFORM_MODELVIEW), 1, GL_FALSE, (GLfloat*)&uniforms.m_modelView); glUniformMatrix4fv(m_program.getUniformID(UNIFORM_PROJECTION), 1, GL_FALSE, (GLfloat*)&uniforms.m_projection); glUniformMatrix4fv(m_program.getUniformID(UNIFORM_NORMALTRANS), 1, GL_FALSE, (GLfloat*)&uniforms.m_normalTrans); return !isGLError(); }
void RSP_ThreadProc(std::mutex * _pRspThreadMtx, std::mutex * _pPluginThreadMtx, std::condition_variable_any * _pRspThreadCv, std::condition_variable_any * _pPluginThreadCv, API_COMMAND * _pCommand) { _pRspThreadMtx->lock(); RSP_Init(); GBI.init(); Config_LoadConfig(); video().start(); assert(!isGLError()); while (true) { _pPluginThreadMtx->lock(); _pPluginThreadCv->notify_one(); _pPluginThreadMtx->unlock(); _pRspThreadCv->wait(*_pRspThreadMtx); switch (*_pCommand) { case acProcessDList: RSP_ProcessDList(); break; case acProcessRDPList: RDP_ProcessRDPList(); break; case acUpdateScreen: VI_UpdateScreen(); break; case acRomClosed: TFH.shutdown(); video().stop(); GBI.destroy(); *_pCommand = acNone; _pRspThreadMtx->unlock(); _pPluginThreadMtx->lock(); _pPluginThreadCv->notify_one(); _pPluginThreadMtx->unlock(); return; } assert(!isGLError()); *_pCommand = acNone; } }
Simple::Simple() { // Try to create, compile, & link a GLSL program using the source // you give it. if ( !m_program.init(vertShader, fragShader) || isGLError() ) { fprintf(stderr, "ERROR: Simple failed to initialize\n"); } // Make sure that every uniform that you are using in your shader // is given a handle. // variable names that do not correspond with a uniform will have // been given the value -1 m_isReady = (m_program.getUniformID(UNIFORM_AMBIENT) >= 0) && (m_program.getUniformID(UNIFORM_SURFREF) >= 0); }
bool ShadowMap::init(const unsigned int & smapSize, const Shader::Manager *manager) { glGenFramebuffers(1, &m_fbo); glGenTextures(1, &m_shadowmap); if (LT_POINT == m_type) { glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadowmap); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_NEAREST, GL_LINEAR glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_NEAREST, GL_LINEAR glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); for (unsigned short i = 0; i < 6; ++i) glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, smapSize, smapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); } else if (LT_DIRECTIONAL == m_type) { glBindTexture(GL_TEXTURE_2D, m_shadowmap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // TODO: Check two following options glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, smapSize, smapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); } m_manager = manager; m_shadowMapSize = smapSize; m_isReady = glIsTexture(m_shadowmap) == GL_TRUE; //printf("Is shadowmap ready:%s\n", m_isReady ? "True": "False"); return !isGLError(); //*/ }
void Scene::rasterizeDepth(const gml::mat4x4_t &worldView, const gml::mat4x4_t &projection) { const Shader::Shader *depthShader = m_shaderManager.getDepthShader(); Shader::GLProgUniforms shaderUniforms; shaderUniforms.m_projection = projection; depthShader->bindGL(false); for (GLuint i=0; i<m_nObjects; i++) { shaderUniforms.m_modelView = gml::mul(worldView, m_scene[i]->getObjectToWorld()); if ( !depthShader->setUniforms(shaderUniforms, false) ) return; m_scene[i]->rasterize(); if ( isGLError() ) return; } }
bool OGLVideoMupenPlus::_resizeWindow() { _setAttributes(); m_bFullscreen = false; m_width = m_screenWidth = m_resizeWidth; m_height = m_screenHeight = m_resizeHeight; if (CoreVideo_ResizeWindow(m_screenWidth, m_screenHeight) != M64ERR_SUCCESS) { printf("(EE) Error setting videomode %dx%d\n", m_screenWidth, m_screenHeight); m_width = m_screenWidth = config.video.windowedWidth; m_height = m_screenHeight = config.video.windowedHeight; CoreVideo_Quit(); return false; } _setBufferSize(); isGLError(); // reset GL error. return true; }
bool DirectionalLightPass::setUniforms(const GLProgUniforms &uniforms, const bool usingShadow) const { glUniformMatrix4fv(m_program.getUniformID(UNIFORM_MODELVIEW), 1, GL_FALSE, (GLfloat*)&uniforms.m_modelView); glUniformMatrix4fv(m_program.getUniformID(UNIFORM_PROJECTION), 1, GL_FALSE, (GLfloat*)&uniforms.m_projection); glUniform3fv(m_program.getUniformID(UNIFORM_LIGHTRAD), 1, (GLfloat*)&uniforms.m_lightRad); glUniform1f(m_program.getUniformID(UNIFORM_DS_AMBIENTINTENCITY), uniforms.m_ds_AmbientIntensity); glUniform1f(m_program.getUniformID(UNIFORM_DS_DIFFUSEINTENSITY), uniforms.m_ds_DiffuseIntensity); glUniform3fv(m_program.getUniformID(UNIFORM_DS_DLDIRECTION), 1, (GLfloat*)&uniforms.m_ds_DirectionalLightDirection); glUniform2fv(m_program.getUniformID(UNIFORM_DS_SCREENSIZE), 1, (GLfloat*)&uniforms.m_ds_ScreenSize); glUniform1i(m_program.getUniformID(UNIFORM_DS_POSTEX), 0); glUniform1i(m_program.getUniformID(UNIFORM_DS_DIFFTEX), 1); glUniform1i(m_program.getUniformID(UNIFORM_DS_NORMTEX), 2); #if defined (DO_SHADOW) glUniform1i(m_program.getUniformID(UNIFORM_SHADOWMAP), 3); glUniformMatrix4fv(m_program.getUniformID(UNIFORM_DS_LIGHT_PROJMAT), 1, GL_FALSE, (GLfloat*)&uniforms.m_ds_light_projection_mat); #endif return !isGLError(); }
bool Simple::setUniforms(const GLProgUniforms &uniforms) const { // This gets the values for the GLSL shader uniforms from 'uniforms' and // sets the program to use them. // // Different types of uniforms have different glUniform* functions to // be able to set their values. // // Note: OpenGL wants data for matrix uniforms supplied as an array in column-major // order. All of the matrix types in the supplied gml are stored in column-major // order. So, you can just take the address of the matrix, typecast the address to a GLfloat* // and pass the typecast pointer for the matrix data. // This isn't demonstrated here, but you will need to know it when you // implement your geometry transforms. glUniform3fv(m_program.getUniformID(UNIFORM_AMBIENT), 1, (GLfloat*)&uniforms.m_ambientRad); glUniform3fv(m_program.getUniformID(UNIFORM_SURFREF), 1, (GLfloat*)&uniforms.m_surfRefl); return !isGLError(); }
GLuint createTexture(const char* filename) { std::vector< unsigned char > rawImage; LodePNG::loadFile( rawImage, filename ); LodePNG::Decoder decoder; std::vector< unsigned char > image; decoder.decode( image, rawImage.empty() ? 0 : &rawImage[0], (unsigned)rawImage.size() ); // // Flip and invert the PNG image since OpenGL likes to load everything // backwards from what is considered normal! // unsigned char *imagePtr = &image[0]; int halfTheHeightInPixels = decoder.getHeight() / 2; int heightInPixels = decoder.getHeight(); // Assuming RGBA for 4 components per pixel. int numColorComponents = 4; // Assuming each color component is an unsigned char. int widthInChars = decoder.getWidth() * numColorComponents; unsigned char *top = NULL; unsigned char *bottom = NULL; unsigned char temp = 0; for( int h = 0; h < halfTheHeightInPixels; ++h ) { top = imagePtr + h * widthInChars; bottom = imagePtr + (heightInPixels - h - 1) * widthInChars; for( int w = 0; w < widthInChars; ++w ) { // Swap the chars around. temp = *top; *top = *bottom; *bottom = temp; ++top; ++bottom; } } GLuint texid; //glEnable(GL_TEXTURE_2D); glGenTextures( 1, &texid ); glActiveTexture(GL_TEXTURE0); glBindTexture( GL_TEXTURE_2D, texid ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &image[0] ); if (isGLError()) return -1; return texid; }
void Assignment3::idle() { // idle is called each time through the event loop when there is no // pending render call, or interaction event to process. // That makes it ideal for animation, and similar actions double currTime = UI::getTime(); // current time if (m_isRayTracing) { if (m_rtRow < m_windowHeight) { GLuint startRow = m_rtRow; // Ray trace rows for TIMEOUT s float timeout = 0.1f; // 100ms RayTracing::Ray_t ray; RayTracing::HitInfo_t hitinfo; double time = currTime; do { gml::vec3_t *imgPos = m_rtImage + m_rtRow*m_windowWidth; for (int c=0; c<m_windowWidth; c++, imgPos++) { gml::vec3_t clr(0.0, 0.0, 0.0); // (x,y) give the screen-space (aka: image-space, or window-space) coordinates of // the ray to be cast. const float x = c - 0.5 + rand() / ((float)RAND_MAX); const float y = m_rtRow - 0.5 + rand() / ((float)RAND_MAX); // TODO!! // Create the ray through (x,y) from the camera, then use the m_scene // object to find an intersection of the ray, and shade the ray if there // is an intersection. // Assign the shade of the ray to the 'clr' variable. // The recursive depth for shading the ray is given by the // constant MAX_RAY_DEPTH (found at top of this file) ray = m_camera.genViewRay(x, y); if (m_scene.rayIntersects(ray, m_camera.getNearClip(), m_camera.getFarClip(), hitinfo)) { clr = m_scene.shadeRay(ray, hitinfo, MAX_RAY_DEPTH); } // Use 'clr' to update the image if (m_rtPassNum == 0) { *imgPos = clr; } else { *imgPos = gml::scale(1.0f/(m_rtPassNum+1), gml::add( gml::scale(m_rtPassNum,*imgPos), clr ) ); } } m_rtRow += 1; time = UI::getTime(); } while (m_rtRow < m_windowHeight && (time-currTime)<timeout); // Copy the new image data to the texture for blitting to the screen. glBindTexture(GL_TEXTURE_2D, m_rtTex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, startRow, m_windowWidth, m_rtRow-startRow, GL_RGB, GL_FLOAT, m_rtImage+startRow*m_windowWidth); if (isGLError()) return; } else { if (m_rtPassNum < MAX_RT_PASSES) { m_rtRow = 0; m_rtPassNum += 1; fprintf(stdout, "Pass %d Complete\n", m_rtPassNum); } } } else { if (m_cameraMovement) // Is a camera movement key pressed? { // time since the last time we updated the camera double deltaT = currTime - m_lastCamMoveTime; if (deltaT > 0) { // Time has elapsed since the last time idle() was called // so, move the camera according to which key(s) are pressed. if (m_cameraMovement & CAMERA_FORWARD) m_camera.moveForward( m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_BACKWARD) m_camera.moveForward( -m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_STRAFE_RIGHT) m_camera.strafeRight( m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_STRAFE_LEFT) m_camera.strafeRight( -m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_UP) m_camera.moveUp( m_movementSpeed * deltaT); if (m_cameraMovement & CAMERA_DOWN) m_camera.moveUp( -m_movementSpeed * deltaT); if (m_cameraMovement & CAMERA_ROTATE_UP) m_camera.rotateUp( m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_ROTATE_DOWN) m_camera.rotateUp( -m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_ROTATE_LEFT) m_camera.rotateRight( m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_ROTATE_RIGHT) m_camera.rotateRight( -m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_SPIN_LEFT) m_camera.spinCamera( m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_SPIN_RIGHT) m_camera.spinCamera( -m_rotationSpeed * deltaT ); m_cameraChanged = true; m_lastCamMoveTime = currTime; } } } m_lastIdleTime = currTime; }
void ShadowMap::create(const ObjectVec & scene, const gml::mat4x4_t &worldview , const gml::vec3_t & position, const gml::vec3_t & target , const gml::vec3_t & up) { if ( !m_isReady ) { #if !defined(NDEBUG) fprintf(stderr, "Trying to create shadow map when cubemap not ready\n"); #endif return; } glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo); glViewport(0, 0, m_shadowMapSize, m_shadowMapSize); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glEnable(GL_DEPTH_TEST); if (isGLError()) return; if (LT_POINT == m_type) { gml::vec3_t _light_pos = gml::extract3(gml::mul(worldview, gml::vec4_t(position, 1.0))); for (unsigned short i = 0; i < 6; ++i) m_cameras[i]->setPosition(_light_pos); } else if (LT_DIRECTIONAL == m_type) { gml::vec3_t _light_pos = gml::extract3(gml::mul(worldview, gml::vec4_t(position, 1.0))); gml::vec3_t _light_target = gml::extract3(gml::mul(worldview, gml::vec4_t(target, 1.0))); gml::vec3_t _light_up = gml::extract3(gml::mul(worldview, gml::vec4_t(up, 1.0))); m_cameras[0]->lookAt(_light_pos, _light_target, _light_up); } const Shader::Shader* _pdptshdr = m_manager->getDepthShader(); if (LT_POINT == m_type) { for (unsigned short i = 0; i < 6; ++i) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, m_shadowmap, 0); if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) return; glClear(GL_DEPTH_BUFFER_BIT); if (isGLError()) return; if (_pdptshdr->getIsReady()) { _pdptshdr->bindGL(); if (isGLError()) return; Shader::GLProgUniforms shaderUniforms; shaderUniforms.m_projection = m_cameras[i]->getProjection(); for (ObjectVec::const_iterator itr = scene.begin(); itr != scene.end(); ++itr) { shaderUniforms.m_modelView = gml::mul(m_cameras[i]->getWorldView(), gml::mul(worldview, (*itr)->getObjectToWorld())); shaderUniforms.m_normalTrans = gml::transpose( gml::inverse(shaderUniforms.m_modelView) ); if ( !_pdptshdr->setUniforms(shaderUniforms, false) || isGLError() ) return; (*itr)->rasterize(); if (isGLError()) return; } _pdptshdr->unbindGL(); glFinish(); } } } else if (LT_DIRECTIONAL == m_type) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowmap, 0); if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) return; glClear(GL_DEPTH_BUFFER_BIT); if (isGLError()) return; if (_pdptshdr->getIsReady()) { _pdptshdr->bindGL(); if (isGLError()) return; Shader::GLProgUniforms shaderUniforms; shaderUniforms.m_projection = m_cameras[0]->getProjection(); for (ObjectVec::const_iterator itr = scene.begin(); itr != scene.end(); ++itr) { shaderUniforms.m_modelView = gml::mul(m_cameras[0]->getWorldView(), gml::mul(worldview, (*itr)->getObjectToWorld())); shaderUniforms.m_normalTrans = gml::transpose( gml::inverse(shaderUniforms.m_modelView) ); if ( !_pdptshdr->setUniforms(shaderUniforms, false) || isGLError() ) return; (*itr)->rasterize(); if (isGLError()) return; } _pdptshdr->unbindGL(); glFinish(); } } glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); }
void Assignment6::idle() { // idle is called each time through the event loop when there is no // pending render call, or interaction event to process. // That makes it ideal for animation, and similar actions double currTime = UI::getTime(); // current time if (m_isRayTracing) { RayTracing::Ray_t *rays; RayTracing::HitInfo_t *hitinfos; m_isProcessingRayTracing = true; clock_t start, finish; start = clock(); for(int pass = 0; pass < MAX_RT_PASSES; pass++) { rays = m_camera.genViewRayInParallel(m_windowWidth,m_windowHeight); hitinfos = m_scene.rayIntersectsInParallel(rays, 0.0001, 300.0, m_windowWidth, m_windowHeight, NULL); gml::vec3_t *tempClrs = m_scene.shadeRaysInParallel(rays,hitinfos,MAX_RAY_DEPTH,m_windowWidth,m_windowHeight); memcpy(m_rtImage, tempClrs, m_windowWidth * m_windowHeight * sizeof(gml::vec3_t)); delete[] tempClrs; // Copy the new image data to the texture for blitting to the screen. glBindTexture(GL_TEXTURE_2D, m_rtTex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_windowWidth, m_windowHeight, GL_RGB, GL_FLOAT, m_rtImage); if (isGLError()) return; m_cameraChanged = false; //fprintf(stdout, "Pass %d Complete\n", pass); } finish = clock(); double exeTime = ( (finish - start)/1000.0 ); printf("Took %lf to render a frame\n", exeTime); m_isProcessingRayTracing = false; } if (m_cameraMovement) // Is a camera movement key pressed? { // time since the last time we updated the camera double deltaT = currTime - m_lastCamMoveTime; if (deltaT > 0) { // Time has elapsed since the last time idle() was called // so, move the camera according to which key(s) are pressed. if (m_cameraMovement & CAMERA_FORWARD) m_camera.moveForward( m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_BACKWARD) m_camera.moveForward( -m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_STRAFE_RIGHT) m_camera.strafeRight( m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_STRAFE_LEFT) m_camera.strafeRight( -m_movementSpeed * deltaT ); if (m_cameraMovement & CAMERA_UP) m_camera.moveUp( m_movementSpeed * deltaT); if (m_cameraMovement & CAMERA_DOWN) m_camera.moveUp( -m_movementSpeed * deltaT); if (m_cameraMovement & CAMERA_ROTATE_UP) m_camera.rotateUp( m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_ROTATE_DOWN) m_camera.rotateUp( -m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_ROTATE_LEFT) m_camera.rotateRight( m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_ROTATE_RIGHT) m_camera.rotateRight( -m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_SPIN_LEFT) m_camera.spinCamera( m_rotationSpeed * deltaT ); if (m_cameraMovement & CAMERA_SPIN_RIGHT) m_camera.spinCamera( -m_rotationSpeed * deltaT ); m_cameraChanged = true; m_lastCamMoveTime = currTime; } } gml::mat3x3_t rotateMat = gml::rotateAxis(0.01f, gml::vec3_t(0.0,1.0,0.0)); m_scene.setLightPos(gml::mul(rotateMat,gml::extract3(m_scene.getLightPos()))); Object::Object **o = m_scene.getObjects(); /* gml::mat4x4_t b; gml::vec4_t t = gml::mul(o[1]->getObjectToWorld(),gml::vec4_t(0.0,0.0,0.0,1.0)); if(flag) { b = gml::mul(gml::translate(gml::vec3_t(0.0,0.01,0.0)),o[1]->getObjectToWorld()); if(t.y > 2.0) flag = false; }else { b = gml::mul(gml::translate(gml::vec3_t(0.0,-0.01,0.0)),o[1]->getObjectToWorld()); if(t.y < 0.5) flag = true; } o[1]->setTransform(b); */ for(int i=4; i<m_nGeometry;i++) { o[i]->setTransform(getObjectPosition(o[i])); } m_lastIdleTime = currTime; }
Texture::Texture(const char *filename, FilterType minFilter, FilterType magFilter, WrapMode wrap) { #if defined (PNG_LOADER_LIBPNG) m_filename = strdup(filename); m_minFilter = minFilter; m_magFilter = magFilter; m_wrapMode = wrap; m_image = 0; m_handle = 0; m_isReady = false; // Try to read in the image file FILE *infile = fopen(filename, "r"); if (!infile) { return; } Image::PNGDecoder decoder; if ( !decoder.checkSig(infile) ) { fprintf(stderr, "ERROR! Texture file not a png\n"); fclose(infile); return; } void *m_image = decoder.decode(infile, m_width, m_height, m_nChannels, m_bitDepth, m_rowBytes); if ( !m_image ) { return; } // Upload the texture to the GL context glGenTextures(1, &m_handle); if ( isGLError() || (0==m_handle) ) { return; } glBindTexture(GL_TEXTURE_2D, m_handle); if ( isGLError() ) { fprintf(stderr, "ERROR!! 1\n"); return; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapMode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapMode); if ( isGLError() ) { fprintf(stderr, "ERROR!! 1\n"); return; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter); if ( isGLError() ) { fprintf(stderr, "ERROR!! 1\n"); return; } // Each row of image data is 4-byte aligned. glPixelStorei(GL_UNPACK_ALIGNMENT, 4); if ( isGLError() ) { fprintf(stderr, "ERROR!! 1\n"); return; } //fprintf(stderr, "Channels = %u\nwidth = %u\nheight = %u\nbitdepth = %u\n", m_nChannels, m_width, m_height, m_bitDepth); glTexImage2D(GL_TEXTURE_2D, 0, (m_nChannels==1)?GL_RED:GL_RGB8, m_width, m_height, 0, (m_nChannels==1)?GL_RED:GL_RGB, (m_bitDepth==8)?GL_UNSIGNED_BYTE:GL_UNSIGNED_SHORT, m_image); if ( isGLError() ) { fprintf(stderr, "ERROR!! 1\n"); return; } m_isReady = glIsTexture(m_handle) == GL_TRUE; #elif defined (PNG_LOADER_LODEPNG) m_handle = createTexture(filename); m_isReady = glIsTexture(m_handle) == GL_TRUE; #endif }
bool Mesh::init(GLenum primitive, GLuint numVerts, const gml::vec3_t *positions, const gml::vec3_t *normals, const gml::vec2_t *texcoords, GLuint numIndices, const GLuint *indices) { assert(positions != 0); assert(normals != 0); assert(texcoords != 0); assert(indices != 0); destroy(); m_primitiveType = primitive; // Create storage for vertex positions, normals, texture coordinates, and triangle indices m_vertPositions = (gml::vec3_t*)malloc((2*sizeof(gml::vec3_t)+sizeof(gml::vec2_t))*numVerts + sizeof(GLuint)*numIndices); if (m_vertPositions == 0) { fprintf(stderr, "ERROR(Mesh): Out of memory\n"); return false; } m_vertNormals = m_vertPositions + numVerts; m_vertTexcoords = (gml::vec2_t*)(m_vertNormals + numVerts); m_indices = (GLuint*)(m_vertTexcoords + numVerts); // Copy the given data into a local storage memcpy(m_vertPositions, positions, sizeof(gml::vec3_t)*numVerts); memcpy(m_vertNormals, normals, sizeof(gml::vec3_t)*numVerts); memcpy(m_vertTexcoords, texcoords, sizeof(gml::vec2_t)*numVerts); memcpy(m_indices, indices, sizeof(GLuint)*numIndices); m_numIndices = numIndices; // To render objects in OpenGL you first create a "Vertex Array Object" (VAO) // The VAO is basically a container for the object's geometry // So, create one VAO glGenVertexArrays(1, &m_vertArrayObj); if (isGLError()) { return false; } // To set up the VAO, we have to bind it glBindVertexArray(m_vertArrayObj); if (isGLError()) { return false; } // Each vertex attribute that is going to be passed to a GLSL shader must be passed // in a buffer. There are many different forms these buffers can take; this // is just one of them // We're going to use one buffer per vertex attribute. // So, ask OpenGL to create a buffer per attribute for us, and store it // in the array m_vertBuffers // These buffers are also called 'Vertex Buffer Objects' (VBO) glGenBuffers(Shader::NUM_VERTEX_ATTRIBS, m_vertBuffers); // Bind the attribute buffer that we'll use for vertex positions // Binding makes the buffer the active buffer glBindBuffer(GL_ARRAY_BUFFER, m_vertBuffers[Shader::VERTEX_POSITION]); // Copy the vertex position data into the active buffer glBufferData(GL_ARRAY_BUFFER, sizeof(gml::vec3_t)*numVerts, m_vertPositions, GL_STATIC_DRAW); // Tell OpenGL that this buffer should be mapped to the vertex attribute // at location 'Shader::VERTEX_POSITION' glVertexAttribPointer(Shader::VERTEX_POSITION, 3, GL_FLOAT, GL_FALSE, 0, 0); // We have to enable attributes at the location 'Shader::VERTEX_POSITION' // If we don't, then the data will not actually be passed to the GLSL shader. glEnableVertexAttribArray(Shader::VERTEX_POSITION); if (isGLError()) { return false; } // Same as above, but for the vertex normals glBindBuffer(GL_ARRAY_BUFFER, m_vertBuffers[Shader::VERTEX_NORMAL]); glBufferData(GL_ARRAY_BUFFER, sizeof(gml::vec3_t)*numVerts, m_vertNormals, GL_STATIC_DRAW); glVertexAttribPointer(Shader::VERTEX_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(Shader::VERTEX_NORMAL); if (isGLError()) { return false; } // Same as above, but for the texture coordinates. // Not all of our objects will use texture coordinates, but we still // have to bind them for the objects that will. glBindBuffer(GL_ARRAY_BUFFER, m_vertBuffers[Shader::VERTEX_TEXCOORDS]); glBufferData(GL_ARRAY_BUFFER, sizeof(gml::vec2_t)*numVerts, m_vertTexcoords, GL_STATIC_DRAW); glVertexAttribPointer(Shader::VERTEX_TEXCOORDS, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(Shader::VERTEX_TEXCOORDS); if (isGLError()) { return false; } // Binding VAO 0 will unbind whatever VAO is currently bound glBindVertexArray(0); return true; }
void Assignment6::specialKeyboard(UI::KeySpecial_t key, UI::ButtonState_t state) { /* * Called automatically when the user presses a key on the keyboard * key will be a code indicating which key was pressed * state will be one of UI::BUTTON_UP or UI::BUTTON_DOWN * indicating whether the key was released, or pressed */ switch (key) { case UI::KEY_ESC: if (state == UI::BUTTON_UP) { UI::exitMainLoop(); } break; case UI::KEY_W: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_FORWARD); break; case UI::KEY_S: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_BACKWARD); break; case UI::KEY_A: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_STRAFE_LEFT); break; case UI::KEY_D: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_STRAFE_RIGHT); break; case UI::KEY_Q: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_UP); break; case UI::KEY_E: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_DOWN); break; case UI::KEY_KP_8: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_ROTATE_UP); break; case UI::KEY_KP_5: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_ROTATE_DOWN); break; case UI::KEY_KP_4: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_ROTATE_LEFT); break; case UI::KEY_KP_6: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_ROTATE_RIGHT); break; case UI::KEY_KP_7: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_SPIN_LEFT); break; case UI::KEY_KP_9: //if (m_isProcessingRayTracing) break; toggleCameraMoveDirection(state == UI::BUTTON_DOWN, CAMERA_SPIN_RIGHT); break; case UI::KEY_F1: //if (m_isProcessingRayTracing) break; if (state == UI::BUTTON_DOWN) m_useShadowMap = !m_useShadowMap; break; case UI::KEY_F2: if (state == UI::BUTTON_DOWN) { m_isRayTracing = !m_isRayTracing; if (m_isRayTracing && m_cameraChanged) { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_rtFBO); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rtTex, 0); isGLError(); glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0, 0.0, 0.0, 1.0); isGLError(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); m_cameraChanged = true; // Zero(black)-out the image memset(m_rtImage, 0x00, sizeof(gml::vec3_t)*m_windowHeight*m_windowWidth); } } break; case UI::KEY_G: if (m_isRayTracing) break; if (state == UI::BUTTON_DOWN) { m_sRGBframebuffer = !m_sRGBframebuffer; if (m_sRGBframebuffer) { printf("sRGB framebuffer enabled\n"); } else { printf("sRGB framebuffer disabled\n"); } } break; case UI::KEY_F: if (m_isRayTracing) break; if (state == UI::BUTTON_DOWN) { m_renderWireframe = !m_renderWireframe; } break; case UI::KEY_O: if (m_isRayTracing) break; m_camera.setCameraProjection(CAMERA_PROJECTION_ORTHOGRAPHIC); break; case UI::KEY_P: if (m_isRayTracing) break; m_camera.setCameraProjection(CAMERA_PROJECTION_PERSPECTIVE); break; default: break; } }
bool Assignment6::init() { /* * This function is called by main() when the program is starting up. * It should initialize whatever data the assignment requires. */ if ( !m_scene.init() ) { fprintf(stderr, "Could not initialize scene object\n"); return false; } // Create the geometry. const int SPHERE_LOC = 0; const int OCTAHEDRON_LOC = 1; const int PLANE_LOC = 2; m_nGeometry = 11; m_geometry = new Object::Geometry*[m_nGeometry]; memset(m_geometry, 0x00, sizeof(Object::Geometry*)*m_nGeometry); m_geometry[SPHERE_LOC] = new Object::Models::Sphere(); if ( !m_geometry[SPHERE_LOC] || !((Object::Models::Sphere*)m_geometry[SPHERE_LOC])->init(3) || isGLError() ) { return false; } m_geometry[OCTAHEDRON_LOC] = new Object::Models::Octahedron(); if ( !m_geometry[OCTAHEDRON_LOC] || !((Object::Models::Octahedron*)m_geometry[OCTAHEDRON_LOC])->init() || isGLError()) { return false; } m_geometry[PLANE_LOC] = new Object::Models::Plane(); if ( !m_geometry[PLANE_LOC] || !((Object::Models::Plane*)m_geometry[PLANE_LOC])->init() || isGLError()) { return false; } const float pi2 = (90.0f * M_PI) / 180.0f; m_scene.setAmbient(gml::vec3_t(0.0, 0.0, 0.0)); m_scene.setLightPos(gml::vec4_t(4.5f, 4.5, 0.0 , 1.0)); m_scene.setLightRad(gml::vec3_t(1.0, 1.0, 1.0)); m_camera.lookAt(gml::vec3_t(0.0,2.0,3.0), gml::vec3_t(0.0,0.0,0.0) ); m_camera.setDepthClip(0.5f, 30.0f); Material::Material mat; mat.setShaderType(Material::PHONG); gml::vec3_t beige(0.76, 0.75, 0.5); gml::vec3_t red(0.63, 0.06, 0.04); gml::vec3_t green(0.15, 0.48, 0.09); mat.setSpecExp(-1.0f); // turn off specular mat.setSurfReflectance(beige); // Ground plane mat.setTexture(0); m_scene.addObject(new Object::Object(m_geometry[PLANE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(0.0,0.0,0.0)), gml::scaleh(5.0, 1.0, 5.0)) ) ); gml::mat4x4_t rotScale = gml::mul( gml::rotateYh((25.0f * M_PI)/180.0), gml::scaleh(0.5,0.5,0.5) ); // Some other objects mat.setSurfReflectance(beige); /* m_scene.addObject(new Object::Object(m_geometry[OCTAHEDRON_LOC], mat, gml::mul(gml::translate(gml::vec3_t(0.0,0.75,0.0)), rotScale)) ); */ // "Box" walls mat.setSurfReflectance(green); m_scene.addObject(new Object::Object(m_geometry[PLANE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(5.0,2.5,0.0)), gml::mul(gml::rotateZh(pi2),gml::scaleh(2.5, 1.0, 5.0))) ) ); m_scene.addObject(new Object::Object(m_geometry[PLANE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(-5.0,2.5,0.0)), gml::mul(gml::rotateZh(-pi2),gml::scaleh(2.5, 1.0, 5.0))) )); mat.setSurfReflectance(red); // m_scene.addObject(new Object::Object(m_geometry[PLANE_LOC], mat, // gml::mul(gml::translate(gml::vec3_t(0.0,2.5,5.0)), gml::mul(gml::rotateXh(-pi2),gml::scaleh(5.0, 1.0, 2.5))) )); m_scene.addObject(new Object::Object(m_geometry[PLANE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(0.0,2.5,-5.0)), gml::mul(gml::rotateXh(pi2),gml::scaleh(5.0, 1.0, 2.5))) )); mat.setSpecExp(10.5f); mat.setSurfReflectance(gml::vec3_t(0.2,1.0,0.0)); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(0.0,0.75,-2.0)), rotScale)) ); mat.setSpecExp(10.5f); mat.setSurfReflectance(gml::vec3_t(0.8,1.0,0.0)); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(2.0,0.75,-2.0)), rotScale)) ); mat.setSpecExp(10.5f); mat.setSurfReflectance(gml::vec3_t(1.0,0.0,1.0)); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(3.0,0.75,-2.0)), rotScale)) ); mat.setSpecExp(10.5f); mat.setSurfReflectance(gml::vec3_t(1.0,0.0,0.2)); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(-1.0,0.75,-2.0)), rotScale)) ); mat.setSpecExp(10.5f); mat.setSurfReflectance(gml::vec3_t(0.4,1.0,1.0)); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(4.0,0.75,-2.0)), rotScale)) ); mat.setSpecExp(10.5f); mat.setSurfReflectance(gml::vec3_t(1.0,0.0,0.0)); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(-2.0,0.75,-2.0)), rotScale)) ); mat.setSpecExp(0.0f); mat.setShaderType(Material::MIRROR); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(1.0,0.75,-2.0)), rotScale)) ); mat.setSurfReflectance(beige); /* // Ground plane mat.setTexture(0); m_scene.addObject(new Object::Object(m_geometry[PLANE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(0.0,0.0,0.0)), gml::scaleh(5.0, 1.0, 5.0)) ) ); mat.setSpecExp(0.0f); mat.setShaderType(Material::MIRROR); m_scene.addObject(new Object::Object(m_geometry[SPHERE_LOC], mat, gml::mul(gml::translate(gml::vec3_t(-2.0,0.75,-2.0)), rotScale)) ); */ // ============================================================================================= if ( !m_shadowmap.init(m_shadowmapSize) ) { fprintf(stderr, "Failed to initialize shadow mapping members.\n"); return false; } // Ray tracing inits if (m_rtFBO) glDeleteFramebuffers(1, &m_rtFBO); glGenFramebuffers(1, &m_rtFBO); if (m_rtTex) glDeleteTextures(1, &m_rtTex); glGenTextures(1, &m_rtTex); printf( "Camera movement:\n" " [w] -- Camera forward\n" " [s] -- Camera backward\n" " [q] -- Camera up\n" " [e] -- Camera down\n" " [a] -- Camera strafe left\n" " [d] -- Camera strafe right\n" "Camera rotation:\n" " [keypad 8] -- Rotate camera up\n" " [keypad 5] -- Rotate camera down\n" " [keypad 4] -- Rotate camera right\n" " [keypad 6] -- Rotate camera left\n" " [keypad 7] -- Spin camera left\n" " [keypad 9] -- Spin camera right\n" "Other Controls:\n" " [F1] -- Toggle shadows\n" " [F2] -- Toggle ray tracing\n" " [g] -- Toggle sRGB framebuffer\n" " [f] -- Toggle wireframe rendering\n" " [o] -- Set to orthographic camera\n" " [p] -- Set to perspective camera\n" " [ESC] -- Quit\n" ); return true; }