Ray PinholeCamera::GenerateRay(const Vector2ui &pixel, const Vector2f &sample) const { // Compute point on view plane Vector3f s = Vector3f(left + (right - left) * (pixel.x() + sample.x()) / (float) width, bottom + (top - bottom) * (pixel.y() + sample.y()) / (float) height, -1.f); return Ray(eye_world, TransformPoint(look_at, s) - eye_world); }
bool BoxFilterFilm::AddSample(const rose::Spectrum &s, const Vector2ui &pixel, const Vector2f &sample) { // Check we are inside pixel boundaries if (sample.x() < 0.f || sample.x() > 1.f || sample.y() < 0.f || sample.y() > 1.f) { return false; } // Add sample raster[pixel.y() * width + pixel.x()] += s; // Increase number of samples of the pixel num_samples[pixel.y() * width + pixel.x()]++; return true; }
void reshape( const Vector2ui& frameSize ) { CameraPtr camera = _engine->getCamera(); FrameBufferPtr frameBuffer = _engine->getFrameBuffer(); if( frameBuffer->getSize() == frameSize ) return; frameBuffer->resize( frameSize ); camera->setAspectRatio( static_cast< float >( frameSize.x()) / static_cast< float >( frameSize.y())); }
void LineRenderer::draw() { boost::lock_guard<boost::mutex> lock(mMutex); // For all input data boost::unordered_map<uint, LineSet::pointer>::iterator it; for(it = mLineSetsToRender.begin(); it != mLineSetsToRender.end(); it++) { LineSet::pointer points = it->second; LineSetAccess::pointer access = points->getAccess(ACCESS_READ); AffineTransformation::pointer transform = SceneGraph::getAffineTransformationFromData(points); glPushMatrix(); glMultMatrixf(transform->data()); ProcessObjectPort port = getInputPort(it->first); if(mInputWidths.count(port) > 0) { glLineWidth(mInputWidths[port]); } else { glLineWidth(mDefaultLineWidth); } if(mInputColors.count(port) > 0) { Color c = mInputColors[port]; glColor3f(c.getRedValue(), c.getGreenValue(), c.getBlueValue()); } else { Color c = mDefaultColor; glColor3f(c.getRedValue(), c.getGreenValue(), c.getBlueValue()); } bool drawOnTop; if(mInputDrawOnTop.count(port) > 0) { drawOnTop = mInputDrawOnTop[port]; } else { drawOnTop = mDefaultDrawOnTop; } if(drawOnTop) glDisable(GL_DEPTH_TEST); glBegin(GL_LINES); for(uint i = 0; i < access->getNrOfLines(); i++) { Vector2ui line = access->getLine(i); Vector3f a = access->getPoint(line.x()); Vector3f b = access->getPoint(line.y()); glVertex3f(a.x(), a.y(), a.z()); glVertex3f(b.x(), b.y(), b.z()); } glEnd(); if(drawOnTop) glEnable(GL_DEPTH_TEST); glPopMatrix(); } glColor3f(1.0f, 1.0f, 1.0f); // Reset color }
void AbstractOpenGLRenderer::setScissor(const Vector2ui& topLeft, const Vector2ui& bottomRight) { GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); OpenGL::checkError(); glScissor(topLeft.X(), viewport[3] - bottomRight.Y(), bottomRight.X() - topLeft.X(), bottomRight.Y() - topLeft.Y()); OpenGL::checkError(); }
void MeshRenderer::draw2D( cl::BufferGL PBO, uint width, uint height, Eigen::Transform<float, 3, Eigen::Affine> pixelToViewportTransform, float PBOspacing, Vector2f translation ) { boost::lock_guard<boost::mutex> lock(mMutex); OpenCLDevice::pointer device = getMainDevice(); cl::CommandQueue queue = device->getCommandQueue(); std::vector<cl::Memory> v; v.push_back(PBO); queue.enqueueAcquireGLObjects(&v); // Map would probably be better here, but doesn't work on NVIDIA, segfault surprise! //float* pixels = (float*)queue.enqueueMapBuffer(PBO, CL_TRUE, CL_MAP_WRITE, 0, width*height*sizeof(float)*4); boost::shared_array<float> pixels(new float[width*height*sizeof(float)*4]); queue.enqueueReadBuffer(PBO, CL_TRUE, 0, width*height*4*sizeof(float), pixels.get()); boost::unordered_map<uint, Mesh::pointer>::iterator it; for(it = mMeshToRender.begin(); it != mMeshToRender.end(); it++) { Mesh::pointer mesh = it->second; if(mesh->getDimensions() != 2) // Mesh must be 2D continue; Color color = mDefaultColor; ProcessObjectPort port = getInputPort(it->first); if(mInputColors.count(port) > 0) { color = mInputColors[port]; } MeshAccess::pointer access = mesh->getMeshAccess(ACCESS_READ); std::vector<VectorXui> lines = access->getLines(); std::vector<MeshVertex> vertices = access->getVertices(); // Draw each line for(int i = 0; i < lines.size(); ++i) { Vector2ui line = lines[i]; Vector2f a = vertices[line.x()].getPosition(); Vector2f b = vertices[line.y()].getPosition(); Vector2f direction = b - a; float lengthInPixels = ceil(direction.norm() / PBOspacing); // Draw the line for(int j = 0; j <= lengthInPixels; ++j) { Vector2f positionInMM = a + direction*((float)j/lengthInPixels); Vector2f positionInPixels = positionInMM / PBOspacing; int x = round(positionInPixels.x()); int y = round(positionInPixels.y()); y = height - 1 - y; if(x < 0 || y < 0 || x >= width || y >= height) continue; pixels[4*(x + y*width)] = color.getRedValue(); pixels[4*(x + y*width) + 1] = color.getGreenValue(); pixels[4*(x + y*width) + 2] = color.getBlueValue(); } } } //queue.enqueueUnmapMemObject(PBO, pixels); queue.enqueueWriteBuffer(PBO, CL_TRUE, 0, width*height*4*sizeof(float), pixels.get()); queue.enqueueReleaseGLObjects(&v); }
bool GuillotineImageAtlas::Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) { if (m_layers.empty()) // On créé une première couche s'il n'y en a pas m_layers.resize(1); // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après for (unsigned int i = 0; i < m_layers.size(); ++i) { Layer& layer = m_layers[i]; // Une fois qu'un certain nombre de rectangles ont étés libérés d'une couche, on fusionne les rectangles libres if (layer.freedRectangles > 10) // Valeur totalement arbitraire { while (layer.binPack.MergeFreeRectangles()); // Tant qu'une fusion est possible layer.freedRectangles = 0; // Et on repart de zéro } if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic)) { // Insertion réussie dans l'une des couches, on place le glyphe en file d'attente layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1); QueuedGlyph& glyph = layer.queuedGlyphs.back(); glyph.flipped = *flipped; glyph.image = image; // Merci le Copy-On-Write glyph.rect = *rect; *layerIndex = i; return true; } else if (i == m_layers.size() - 1) // Dernière itération ? { // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? Vector2ui newSize = layer.binPack.GetSize()*2; if (newSize == Vector2ui::Zero()) newSize.Set(s_atlasStartSize); if (ResizeLayer(layer, newSize)) { // Oui on peut ! layer.binPack.Expand(newSize); // On ajuste l'atlas virtuel // Et on relance la boucle sur la nouvelle dernière couche i--; } else { // On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle newSize.Set(s_atlasStartSize); Layer newLayer; if (!ResizeLayer(newLayer, newSize)) { // Impossible d'allouer une nouvelle couche, nous manquons probablement de mémoire (ou le glyphe est trop grand) NazaraError("Failed to allocate new layer, we are probably out of memory"); return false; } newLayer.binPack.Reset(newSize); m_layers.emplace_back(std::move(newLayer)); // Insertion du layer // On laisse la boucle insérer toute seule le rectangle à la prochaine itération } } } NazaraInternalError("Unknown error"); // Normalement on ne peut pas arriver ici return false; }