void Demo::onGraphics(RenderDevice* rd) { LightingParameters lighting(G3D::toSeconds(2, 00, 00, AM), false); rd->setProjectionAndCameraMatrix(app->debugCamera); // Cyan background rd->setColorClearValue(Color3(0.1f, 0.5f, 1.0f)); rd->clear(app->sky.isNull(), true, true); if (app->sky.notNull()) { app->sky->render(rd, lighting); } // Create a light Vector4 wsLight(1.0f, 2.5f, 2.0f, 1.0f); // Vector4 wsLight(0,1,0,0); // Setup lighting rd->enableLighting(); rd->setLight(0, GLight::directional(lighting.lightDirection, lighting.lightColor)); rd->setAmbientLightColor(lighting.ambient); CoordinateFrame cframe; // Rotate the quad cframe.rotation = Matrix3::fromAxisAngle(Vector3::unitY(), System::time() * 0.1); rd->pushState(); GPUProgram::ArgList vertexArgs; rd->setObjectToWorldMatrix(cframe); // Take the light to object space Vector4 osLight = cframe.toObjectSpace(wsLight); // Take the viewer to object space Vector3 osEye = cframe.pointToObjectSpace(app->debugCamera.getCoordinateFrame().translation); vertexArgs.set("MVP", rd->getModelViewProjectionMatrix()); vertexArgs.set("osLight", osLight); vertexArgs.set("osEye", osEye); rd->setVertexProgram(parallaxVP, vertexArgs); GPUProgram::ArgList pixelArgs; pixelArgs.set("texture", texture); pixelArgs.set("normalMap", normalMap); rd->setPixelProgram(parallaxPP, pixelArgs); model.render(rd); rd->popState(); rd->disableLighting(); Draw::sphere(Sphere(wsLight.xyz(), .1f), rd, Color3::white(), Color4::clear()); if (app->sky.notNull()) { app->sky->renderLensFlare(rd, lighting); } rd->push2D(); app->debugFont->draw2D(rd, "The surface is a single quad textured with parallax bump mapping and per-pixel shading.", Vector2(10, 10), 10, Color3::white(), Color3::black()); app->debugFont->draw2D(rd, "Press TAB to toggle to first person camera controls.", Vector2(10, 30), 10, Color3::white(), Color3::black()); rd->pop2D(); }
void drawFeatureEdges(RenderDevice* renderDevice, const PosedModelRef& model, float creaseAngle) { float dotThreshold = max(cosf(creaseAngle), 0.0f); bool drawCreases = (creaseAngle <= pi() / 2); const Vector3 wsEye = renderDevice->getCameraToWorldMatrix().translation; const Array<MeshAlg::Edge>& edgeArray = model->weldedEdges(); const Array<Vector3>& faceNormal = model->objectSpaceFaceNormals(drawCreases); const Array<MeshAlg::Face>& faceArray = model->weldedFaces(); const Array<Vector3>& vertexArray = model->objectSpaceGeometry().vertexArray; // Work in the object space of the model so we don't // have to transform the geometry. const CoordinateFrame cframe = model->coordinateFrame(); const Vector3 eye = cframe.pointToObjectSpace(wsEye); // Compute backfaces static Array<bool> backface; backface.resize(faceNormal.size(), DONT_SHRINK_UNDERLYING_ARRAY); for (int f = faceNormal.size() - 1; f >= 0; --f) { // View vector const Vector3 V = (eye - vertexArray[faceArray[f].vertexIndex[0]]); backface[f] = faceNormal[f].dot(V) < 0; } // Find contour edges static Array<Vector3> cpuVertexArray; cpuVertexArray.resize(0, DONT_SHRINK_UNDERLYING_ARRAY); for (int e = edgeArray.size() - 1; e >= 0; --e) { const MeshAlg::Edge& edge = edgeArray[e]; const int f0 = edge.faceIndex[0]; const int f1 = edge.faceIndex[1]; if ( // Boundaries: (f0 == MeshAlg::Face::NONE) || (f1 == MeshAlg::Face::NONE) || // Contours: (backface[f0] ^ backface[f1]) || // Front-face creases: (drawCreases && (faceNormal[f0].dot(faceNormal[f1]) <= dotThreshold) && ! (backface[f0] && backface[f1]))) { cpuVertexArray.append( vertexArray[edge.vertexIndex[0]], vertexArray[edge.vertexIndex[1]]); } } VARAreaRef varArea = VARArea::create(cpuVertexArray.size() * sizeof(Vector3)); VAR gpuVertexArray(cpuVertexArray, varArea); renderDevice->pushState(); renderDevice->setObjectToWorldMatrix(cframe); renderDevice->beginIndexedPrimitives(); renderDevice->setVertexArray(gpuVertexArray); renderDevice->sendSequentialIndices(RenderDevice::LINES, cpuVertexArray.size()); renderDevice->endIndexedPrimitives(); renderDevice->popState(); }