void NativeRenderLogic::destroy(WorldModel::WorldAccess *worldAccess) { worldAccess->removeObserver(this); clearLights(); view = NULL; }
void OpenGLScene::render(SupportCanvas3D *context) { // Clear the screen in preparation for the next frame. (Use a gray background instead of a // black one for drawing wireframe or normals so they will show up against the background.) if (settings.drawWireframe || settings.drawNormals) glClearColor(0.5f, 0.5f, 0.5f, 0.5f); else glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Get the active camera Camera *camera = context->getCamera(); assert(camera); glm::mat4 viewMatrix = camera->getViewMatrix(); glUseProgram(m_shader); // Set scene uniforms. clearLights(); setLights(viewMatrix); glUniform1i(m_uniformLocs["useLighting"], settings.useLighting); glUniform1i(m_uniformLocs["useArrowOffsets"], GL_FALSE); glUniformMatrix4fv(m_uniformLocs["p"], 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix())); glUniformMatrix4fv(m_uniformLocs["v"], 1, GL_FALSE, glm::value_ptr(viewMatrix)); glUniformMatrix4fv(m_uniformLocs["m"], 1, GL_FALSE, glm::value_ptr(glm::mat4())); glUniform3f(m_uniformLocs["allBlack"], 1, 1, 1); renderGeometry(); if (settings.drawWireframe) { glUniform3f(m_uniformLocs["allBlack"], 0, 0, 0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); renderGeometry(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } // Render normals if specified. if (settings.drawNormals) { glUseProgram(m_shader); glUniform3f(m_uniformLocs["allBlack"], 0, 0, 0); this->renderNormals(); } glUseProgram(0); }
// Play the color and sound for a pressed button until the button is released void playPressedButtonColorAndSound() { // Grab first color pressed by the user int pressedColor = getPressedColor(); // Light corresponding light lightUpColor(pressedColor); // Loop until the user releases that button while (isPressed(pressedColor)) { playSoundForColor(pressedColor); updateButtonStates(); } noTone(SPEAKER_PIN); clearLights(); }
void NativeRenderLogic::cleared() { clearLights(); }
void SceneRenderer::render( bool _lastFrame, bool _sameFrame, bool fullWindow) { static const GLfloat blindnessColor[4] = { 1.0f, 1.0f, 0.0f, 1.0f }; static const GLfloat dimnessColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; static const float dimDensity = 0.75f; bool lighting = BZDB.isTrue("lighting"); lastFrame = _lastFrame; sameFrame = _sameFrame; // avoid OpenGL calls as long as possible -- there's a good // chance we're waiting on the vertical retrace. // set the view frustum if (sceneIterator) sceneIterator->resetFrustum(&frustum); // get the important lights in the scene int i; int numLights = 0; if (!sameFrame) { clearLights(); if (sceneIterator && !blank && lighting) { // add lights sceneIterator->reset(); SceneNode* node; while ((node = sceneIterator->getNext()) != NULL) node->addLight(*this); numLights = lights.size(); // pick maxLights most important light sources // should go by full lighting function but we'll just go by distance if (numLights > maxLights) { const GLfloat* eye = frustum.getEye(); for (i = 0; i < maxLights; i++) { GLfloat maxImportance = lights[i]->getImportance(eye); for (int j = i + 1; j < numLights; j++) { GLfloat importance = lights[j]->getImportance(eye); if (importance > maxImportance) { OpenGLLight* temp = lights[i]; lights[j] = lights[i]; lights[i] = temp; maxImportance = importance; } } } numLights = maxLights; } } } // get the nodes to draw if (!blank) { // empty the render node lists in preparation for the next frame OpenGLGState::clearLists(); orderedList.clear(); shadowList.clear(); flareLightList.clear(); // make the lists of render nodes sorted in optimal rendering order if (sceneIterator) { sceneIterator->reset(); SceneNode* node; while ((node = sceneIterator->getNext()) != NULL) node->getRenderNodes(*this); } // sort ordered list in reverse depth order if (!inOrder) orderedList.sort(frustum.getEye()); } // prepare transforms // note -- lights should not be positioned before view is set frustum.executeDeepProjection(); glPushMatrix(); frustum.executeView(); // turn sunlight on -- the ground needs it if (lighting && sunOrMoonUp) { theSun.execute(SunLight); theSun.enableLight(SunLight); } // turn on fog for teleporter blindness if close to a teleporter float teleporterProximity = 0.0f; if (!blank && LocalPlayer::getMyTank() && (LocalPlayer::getMyTank()->getTeam() != ObserverTeam)) teleporterProximity = LocalPlayer::getMyTank()->getTeleporterProximity(); float worldSize = BZDB.eval(StateDatabase::BZDB_WORLDSIZE); bool reallyUseFogHack = useFogHack && (useQualityValue >= 2); if (reallyUseFogHack) { if (useDimming) { const float density = dimDensity; glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, -density * 1000.0f * worldSize); glFogf(GL_FOG_END, (1.0f - density) * 1000.0f * worldSize); glFogfv(GL_FOG_COLOR, dimnessColor); glEnable(GL_FOG); } else if (teleporterProximity > 0.0f && useFogHack) { const float density = (teleporterProximity > 0.75f) ? 1.0f : teleporterProximity / 0.75f; glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, -density * 1000.0f * worldSize); glFogf(GL_FOG_END, (1.0f - density) * 1000.0f * worldSize); glFogfv(GL_FOG_COLOR, blindnessColor); glEnable(GL_FOG); } } // set scissor glScissor(window.getOriginX(), window.getOriginY() + window.getHeight() - window.getViewHeight(), window.getWidth(), window.getViewHeight()); if (useDepthComplexityOn) { // glEnable(GL_STENCIL_TEST); // glClear(GL_STENCIL_BUFFER_BIT); // glStencilFunc(GL_ALWAYS, 0, 0xf); // glStencilOp(GL_KEEP, GL_INCR, GL_INCR); } if (useHiddenLineOn) { //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // glClear(GL_COLOR_BUFFER_BIT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } else if (useWireframeOn) { //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // glClear(GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } // prepare z buffer /* if (BZDB.isTrue("zbuffer")) { if (sameFrame && ++depthRange == numDepthRanges) depthRange = 0; if (exposed || useHiddenLineOn || --depthRange < 0) { depthRange = numDepthRanges - 1; glClear(GL_DEPTH_BUFFER_BIT); exposed = false; } if (!sameFrame && numDepthRanges != 1) { if (useHiddenLineOn) { glDepthRange(0.0, 1.0); } else { GLclampd x_near = (GLclampd)depthRange * depthRangeSize; glDepthRange(x_near, x_near + depthRangeSize); } } } */ // draw start of background (no depth testing) OpenGLGState::resetState(); if (background) { background->setBlank(blank); background->setInvert(invert); background->renderSkyAndGround(*this, fullWindow); } // prepare the other lights but don't turn them on yet -- // we may need to turn them on when drawing the background. if (lighting) { for (i = 0; i < numLights; i++) lights[i]->execute(i + reservedLights); } // draw rest of background if (background) background->render(*this); if (!blank) { if (lighting) { // now turn on the remaining lights for (i = 0; i < numLights; i++) OpenGLLight::enableLight(i + reservedLights); } frustum.executeProjection(); if (BZDB.isTrue("zbuffer")) glEnable(GL_DEPTH_TEST); if (useHiddenLineOn) { #if defined(GL_VERSION_1_1) glEnable(GL_POLYGON_OFFSET_FILL); #elif defined(GL_EXT_polygon_offset) glEnable(GL_POLYGON_OFFSET_EXT); #endif } // render the normal stuff doRender(); if (useHiddenLineOn) { #if defined(GL_VERSION_1_1) glDisable(GL_POLYGON_OFFSET_FILL); #elif defined(GL_EXT_polygon_offset) glDisable(GL_POLYGON_OFFSET_EXT); #endif glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); doRender(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } OpenGLGState::resetState(); // shut off lights if (lighting) { theSun.enableLight(SunLight, false); for (i = 0; i < numLights; i++) OpenGLLight::enableLight(i + reservedLights, false); } if (BZDB.isTrue("zbuffer")) glDisable(GL_DEPTH_TEST); // FIXME -- must do post-rendering: flare lights, etc. // flare lights are in world coordinates. trace ray to that world // position and calculate opacity. if opaque then don't render // flare, otherwise modulate input color by opacity and draw a // billboard texture (constant size in screen space). } // back to original state if (!useHiddenLineOn && useWireframeOn) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPopMatrix(); if ((reallyUseFogHack && (teleporterProximity > 0.0f || useDimming))) glDisable(GL_FOG); if (!reallyUseFogHack) { float density = 0.0f; const GLfloat* color = NULL; if (useDimming) { density = dimDensity; color = dimnessColor; } else if (teleporterProximity > 0.0f) { density = (teleporterProximity > 0.75f) ? 1.0f : teleporterProximity / 0.75f; color = blindnessColor; } if (density > 0.0f && color != NULL) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glColor4f(color[0], color[1], color[2], density); glRectf(-1.0f, -1.0f, 1.0f, 1.0f); } } if (useDepthComplexityOn) { static const GLfloat depthColors[][3] = { { 0.0f, 0.0f, 0.0f }, // black -- 0 times { 0.5f, 0.0f, 1.0f }, // purple -- 1 time { 0.0f, 0.0f, 1.0f }, // blue -- 2 times { 0.0f, 1.0f, 1.0f }, // cyan -- 3 times { 0.0f, 1.0f, 0.0f }, // green -- 4 times { 1.0f, 1.0f, 0.0f }, // yellow -- 5 times { 1.0f, 0.5f, 0.0f }, // orange -- 6 times { 1.0f, 0.0f, 0.0f } // red -- 7 or more }; static const int numColors = countof(depthColors); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); for (i = 0; i < numColors; i++) { glStencilFunc(i == numColors - 1 ? GL_LEQUAL : GL_EQUAL, i, 0xf); glColor3fv(depthColors[i]); glRectf(-1.0f, -1.0f, 1.0f, 1.0f); } glDisable(GL_STENCIL_TEST); } }