void GemShape :: render(GemState *state) { if (m_drawType == GL_LINE_LOOP || m_drawType == GL_LINE_STRIP || m_drawType == GL_LINES) glLineWidth(m_linewidth); if (m_blend) { glEnable(GL_POLYGON_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE); glHint(GL_POLYGON_SMOOTH_HINT,GL_DONT_CARE); } m_texType=0; m_texNum =0; m_texCoords=NULL; m_lighting=false; state->get(GemState::_GL_TEX_COORDS, m_texCoords); state->get(GemState::_GL_TEX_TYPE, m_texType); state->get(GemState::_GL_TEX_NUMCOORDS, m_texNum); state->get(GemState::_GL_LIGHTING, m_lighting); renderShape(state); // LATER try to restore the original state if (m_blend) { glDisable(GL_POLYGON_SMOOTH); glDisable(GL_BLEND); } if (m_drawType == GL_LINE_LOOP || m_drawType == GL_LINE_STRIP || m_drawType == GL_LINES) glLineWidth(1.0); }
//******************************************************************************* void HapticObject::renderShapeAtPosition() { glPushMatrix(); glMultMatrixd(m_transformMatrix); renderShape(); glPopMatrix(); }
static void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); if(csg_mode)renderInCSGMode(); else renderShape(); char string[20]; glLoadIdentity(); sprintf(string,"FPS: %02.0f",fps); glPrint(string,5,15); if(crystal > 0.0){ sprintf(string,"C: %.2f%%",crystal); glPrint(string,5,30); } if(animation){ sprintf(string,"Frame: %03d",ani_frame); if(crystal > 0.0) glPrint(string,5,45); else glPrint(string,5,30); } if(renderdiff){ renderDiffraction(); } glutSwapBuffers(); }
void OpenGLRenderer::render(const shared_ptr<Scene>& _scene,Body::id_t selection){ gilLock lockgil; if(!initDone) init(); assert(initDone); selId = selection; scene=_scene; // assign scene inside functors boundDispatcher.updateScenePtr(); geomDispatcher.updateScenePtr(); physDispatcher.updateScenePtr(); shapeDispatcher.updateScenePtr(); // stateDispatcher.updateScenePtr(); // just to make sure, since it is not initialized by default if(!scene->bound) scene->bound=shared_ptr<Aabb>(new Aabb); // recompute emissive light colors for highlighted bodies Real now=TimingInfo::getNow(/*even if timing is disabled*/true)*1e-9; highlightEmission0[0]=highlightEmission0[1]=highlightEmission0[2]=.8*normSquare(now,1); highlightEmission1[0]=highlightEmission1[1]=highlightEmission0[2]=.5*normSaw(now,2); // clipping assert(clipPlaneNormals.size()==(size_t)numClipPlanes); for(size_t i=0;i<(size_t)numClipPlanes; i++){ // someone could have modified those from python and truncate the vectors; fill those here in that case if(i==clipPlaneSe3.size()) clipPlaneSe3.push_back(Se3r(Vector3r::Zero(),Quaternionr::Identity())); if(i==clipPlaneActive.size()) clipPlaneActive.push_back(false); if(i==clipPlaneNormals.size()) clipPlaneNormals.push_back(Vector3r::UnitX()); // end filling stuff modified from python if(clipPlaneActive[i]) clipPlaneNormals[i]=clipPlaneSe3[i].orientation*Vector3r(0,0,1); /* glBegin(GL_LINES);glVertex3v(clipPlaneSe3[i].position);glVertex3v(clipPlaneSe3[i].position+clipPlaneNormals[i]);glEnd(); */ } // set displayed Se3 of body (scaling) and isDisplayed (clipping) setBodiesDispInfo(); glClearColor(bgColor[0],bgColor[1],bgColor[2],1.0); // set light sources glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,1); // important: do lighting calculations on both sides of polygons const GLfloat pos[4] = {(float) light1Pos[0], (float) light1Pos[1], (float) light1Pos[2],1.0}; const GLfloat ambientColor[4]={0.2,0.2,0.2,1.0}; const GLfloat specularColor[4]={1,1,1,1.f}; const GLfloat diffuseLight[4] = { (float) light1Color[0], (float) light1Color[1], (float) light1Color[2], 1.0f }; glLightfv(GL_LIGHT0, GL_POSITION,pos); glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor); glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight); if (light1) glEnable(GL_LIGHT0); else glDisable(GL_LIGHT0); const GLfloat pos2[4] = {(float) light2Pos[0], (float) light2Pos[1], (float) light2Pos[2],1.0}; const GLfloat ambientColor2[4]={0.0,0.0,0.0,1.0}; const GLfloat specularColor2[4]={1,1,0.6,1.f}; const GLfloat diffuseLight2[4] = { (float) light2Color[0], (float) light2Color[1], (float) light2Color[2], 1.0f }; glLightfv(GL_LIGHT1, GL_POSITION,pos2); glLightfv(GL_LIGHT1, GL_SPECULAR, specularColor2); glLightfv(GL_LIGHT1, GL_AMBIENT, ambientColor2); glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseLight2); if (light2) glEnable(GL_LIGHT1); else glDisable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_CULL_FACE); // http://www.sjbaker.org/steve/omniv/opengl_lighting.html glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); //Shared material settings resetSpecularEmission(); drawPeriodicCell(); if (dof || id) renderDOF_ID(); if (bound) renderBound(); if (shape) renderShape(); if (intrAllWire) renderAllInteractionsWire(); if (intrGeom) renderIGeom(); if (intrPhys) renderIPhys(); FOREACH(const shared_ptr<GlExtraDrawer> d, extraDrawers){ if(d->dead) continue; glPushMatrix(); d->scene=scene.get(); d->render(); glPopMatrix(); } }
void draw() { // Attempting to draw before we're visible and have a valid size will // produce GL errors. if (!isVisible() || _size.width() <= 0 || _size.height() <= 0) { return; } makeCurrent(); gpu::Batch batch; batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLORS, { 0.0f, 0.0f, 0.0f, 1.0f }); batch.clearDepthFramebuffer(1e4); batch.setViewportTransform({ 0, 0, _size.width() * devicePixelRatio(), _size.height() * devicePixelRatio() }); batch.setProjectionTransform(_projectionMatrix); float t = _time.elapsed() * 1e-3f; glm::vec3 unitscale { 1.0f }; glm::vec3 up { 0.0f, 1.0f, 0.0f }; float distance = 3.0f; glm::vec3 camera_position{ distance * sinf(t), 0.0f, distance * cosf(t) }; static const vec3 camera_focus(0); static const vec3 camera_up(0, 1, 0); glm::mat4 camera = glm::inverse(glm::lookAt(camera_position, camera_focus, up)); batch.setViewTransform(camera); batch.setPipeline(_pipeline); batch.setModelTransform(Transform()); auto geometryCache = DependencyManager::get<GeometryCache>(); // Render grid on xz plane (not the optimal way to do things, but w/e) // Note: GeometryCache::renderGrid will *not* work, as it is apparenly unaffected by batch rotations and renders xy only { static const std::string GRID_INSTANCE = "Grid"; static auto compactColor1 = toCompactColor(vec4{ 0.35f, 0.25f, 0.15f, 1.0f }); static auto compactColor2 = toCompactColor(vec4{ 0.15f, 0.25f, 0.35f, 1.0f }); static std::vector<glm::mat4> transforms; static gpu::BufferPointer colorBuffer; if (!transforms.empty()) { transforms.reserve(200); colorBuffer = std::make_shared<gpu::Buffer>(); for (int i = 0; i < 100; ++i) { { glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i)); transform = glm::scale(transform, vec3(100, 1, 1)); transforms.push_back(transform); colorBuffer->append(compactColor1); } { glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0))); transform = glm::translate(transform, vec3(0, -1, -50 + i)); transform = glm::scale(transform, vec3(100, 1, 1)); transforms.push_back(transform); colorBuffer->append(compactColor2); } } } auto pipeline = geometryCache->getSimplePipeline(); for (auto& transform : transforms) { batch.setModelTransform(transform); batch.setupNamedCalls(GRID_INSTANCE, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { batch.setViewTransform(camera); batch.setPipeline(_pipeline); geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count(), colorBuffer); }); } } { static const size_t ITEM_COUNT = 1000; static const float SHAPE_INTERVAL = (PI * 2.0f) / ITEM_COUNT; static const float ITEM_INTERVAL = SHAPE_INTERVAL / TYPE_COUNT; static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA }; static const gpu::Element TRANSFORM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW }; static std::vector<Transform> transforms; static std::vector<vec4> colors; static gpu::BufferPointer indirectBuffer; static gpu::BufferPointer transformBuffer; static gpu::BufferPointer colorBuffer; static gpu::BufferView colorView; static gpu::BufferView instanceXfmView; if (!transformBuffer) { transformBuffer = std::make_shared<gpu::Buffer>(); colorBuffer = std::make_shared<gpu::Buffer>(); indirectBuffer = std::make_shared<gpu::Buffer>(); static const float ITEM_RADIUS = 20; static const vec3 ITEM_TRANSLATION{ 0, 0, -ITEM_RADIUS }; for (size_t i = 0; i < TYPE_COUNT; ++i) { GeometryCache::Shape shape = SHAPE[i]; GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape]; { gpu::Batch::DrawIndexedIndirectCommand indirectCommand; indirectCommand._count = (uint)shapeData._indexCount; indirectCommand._instanceCount = ITEM_COUNT; indirectCommand._baseInstance = (uint)(i * ITEM_COUNT); indirectCommand._firstIndex = (uint)shapeData._indexOffset / 2; indirectCommand._baseVertex = 0; indirectBuffer->append(indirectCommand); } //indirectCommand._count float startingInterval = ITEM_INTERVAL * i; for (size_t j = 0; j < ITEM_COUNT; ++j) { float theta = j * SHAPE_INTERVAL + startingInterval; auto transform = glm::rotate(mat4(), theta, Vectors::UP); transform = glm::rotate(transform, (randFloat() - 0.5f) * PI / 4.0f, Vectors::UNIT_X); transform = glm::translate(transform, ITEM_TRANSLATION); transform = glm::scale(transform, vec3(randFloat() / 2.0f + 0.5f)); transformBuffer->append(transform); transforms.push_back(transform); auto color = vec4{ randomColorValue(64), randomColorValue(64), randomColorValue(64), 255 }; color /= 255.0f; colors.push_back(color); colorBuffer->append(toCompactColor(color)); } } colorView = gpu::BufferView(colorBuffer, COLOR_ELEMENT); instanceXfmView = gpu::BufferView(transformBuffer, TRANSFORM_ELEMENT); } #if 1 GeometryCache::ShapeData shapeData = geometryCache->_shapes[GeometryCache::Icosahedron]; { batch.setViewTransform(camera); batch.setModelTransform(Transform()); batch.setPipeline(_pipeline); batch.setInputFormat(getInstancedSolidStreamFormat()); batch.setInputBuffer(gpu::Stream::COLOR, colorView); batch.setIndirectBuffer(indirectBuffer); shapeData.setupBatch(batch); batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES); } #else batch.setViewTransform(camera); batch.setPipeline(_pipeline); for (size_t i = 0; i < TYPE_COUNT; ++i) { GeometryCache::Shape shape = SHAPE[i]; for (size_t j = 0; j < ITEM_COUNT; ++j) { int index = i * ITEM_COUNT + j; batch.setModelTransform(transforms[index]); const vec4& color = colors[index]; batch._glColor4f(color.r, color.g, color.b, 1.0); geometryCache->renderShape(batch, shape); } } #endif } // Render unlit cube + sphere static auto startUsecs = usecTimestampNow(); float seconds = getSeconds(startUsecs); seconds /= 4.0f; int shapeIndex = ((int)seconds) % TYPE_COUNT; bool wire = (seconds - floorf(seconds) > 0.5f); batch.setModelTransform(Transform()); batch._glColor4f(0.8f, 0.25f, 0.25f, 1.0f); if (wire) { geometryCache->renderWireShape(batch, SHAPE[shapeIndex]); } else { geometryCache->renderShape(batch, SHAPE[shapeIndex]); } batch.setModelTransform(Transform().setScale(2.05f)); batch._glColor4f(1, 1, 1, 1); geometryCache->renderWireCube(batch); _context->render(batch); _qGlContext.swapBuffers(this); fps.increment(); if (fps.elapsed() >= 0.5f) { qDebug() << "FPS: " << fps.rate(); fps.reset(); } }