Beispiel #1
0
void
Canvas::text_clipped(int x, int y, unsigned width, const TCHAR *text)
{
#ifdef HAVE_GLES
  assert(x_offset == OpenGL::translate_x);
  assert(y_offset == OpenGL::translate_y);
#endif

  if (font == NULL)
    return;

  GLTexture *texture = TextCache::get(font, COLOR_BLACK, COLOR_WHITE, text);
  if (texture == NULL)
    return;

  GLEnable scope(GL_TEXTURE_2D);
  texture->bind();
  GLLogicOp logic_op(GL_AND_INVERTED);

  unsigned height = texture->get_height();
  if (texture->get_width() < width)
    width = texture->get_width();

  /* cut out the shape in black */
  OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  texture->draw(x, y, width, height, 0, 0, width, height);

  if (text_color != COLOR_BLACK) {
    /* draw the text color on top */
    OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    logic_op.set(GL_OR);
    text_color.set();
    texture->draw(x, y, width, height, 0, 0, width, height);
  }
}
Beispiel #2
0
void GL::GLProgram::setUniform(const char* name, const GLTexture& tex, int iTextureSlot)
{
  int loc = getUniformByName(name);
  //assert(loc > -1);
  tex.bind(iTextureSlot);
  glUniform1i(loc, iTextureSlot);
}
Beispiel #3
0
/* MCAThingSelection::draw
 * Draws the animation
 *******************************************************************/
void MCAThingSelection::draw()
{
	// Setup colour
	rgba_t col;
	if (select)
		col.set(255, 255, 255, 255*fade, 1);
	else
	{
		col = ColourConfiguration::getColour("map_selection");
		col.a *= fade;
	}
	OpenGL::setColour(col);

	// Get texture if needed
	if (!thing_overlay_square)
	{
		// Get thing selection texture
		GLTexture* tex = NULL;
		if (thing_drawtype == TDT_ROUND || thing_drawtype == TDT_SPRITE)
			tex = MapEditor::textureManager().getEditorImage("thing/hilight");
		else
			tex = MapEditor::textureManager().getEditorImage("thing/square/hilight");

		if (!tex)
			return;

		// Bind the texture
		glEnable(GL_TEXTURE_2D);
		tex->bind();
	}

	// Animate radius
	double r = radius;
	if (select) r += radius*0.2*fade;

	// Draw
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f);	glVertex2d(x - r, y - r);
	glTexCoord2f(0.0f, 1.0f);	glVertex2d(x - r, y + r);
	glTexCoord2f(1.0f, 1.0f);	glVertex2d(x + r, y + r);
	glTexCoord2f(1.0f, 0.0f);	glVertex2d(x + r, y - r);
	glEnd();
}
Beispiel #4
0
void
Canvas::text(int x, int y, const TCHAR *text)
{
#ifdef HAVE_GLES
  assert(x_offset == OpenGL::translate_x);
  assert(y_offset == OpenGL::translate_y);
#endif

  if (font == NULL)
    return;

  GLTexture *texture = TextCache::get(font, COLOR_BLACK, COLOR_WHITE, text);
  if (texture == NULL)
    return;

  if (background_mode == OPAQUE)
    /* draw the opaque background */
    fill_rectangle(x, y, x + texture->get_width(), y + texture->get_height(),
                   background_color);

  GLEnable scope(GL_TEXTURE_2D);
  texture->bind();
  GLLogicOp logic_op(GL_AND_INVERTED);

  if (background_mode != OPAQUE || background_color != COLOR_BLACK) {
    /* cut out the shape in black */
    OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    texture->draw(x, y);
  }

  if (text_color != COLOR_BLACK) {
    /* draw the text color on top */
    OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    logic_op.set(GL_OR);
    text_color.set();
    texture->draw(x, y);
  }
}
void StartupFeedbackEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data)
{
    effects->paintScreen(mask, region, data);
    if (m_active) {
        GLTexture* texture;
        switch(m_type) {
        case BouncingFeedback:
            texture = m_bouncingTextures[ FRAME_TO_BOUNCE_TEXTURE[ m_frame ]];
            break;
        case BlinkingFeedback: // fall through
        case PassiveFeedback:
            texture = m_texture;
            break;
        default:
            return; // safety
        }
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        texture->bind();
        bool useShader = false;
        if (m_type == BlinkingFeedback) {
            const QColor& blinkingColor = BLINKING_COLORS[ FRAME_TO_BLINKING_COLOR[ m_frame ]];
            if (m_blinkingShader && m_blinkingShader->isValid()) {
                useShader = true;
                ShaderManager::instance()->pushShader(m_blinkingShader);
                m_blinkingShader->setUniform("u_color", blinkingColor);
            } else {
#ifndef KWIN_HAVE_OPENGLES
                // texture transformation
                float color[4] = { blinkingColor.redF(), blinkingColor.greenF(), blinkingColor.blueF(), 1.0f };
                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
                glColor4fv(color);
                glActiveTexture(GL_TEXTURE1);
                texture->bind();
                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
                glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
                glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
                glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
                glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_CONSTANT);
                glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
                glActiveTexture(GL_TEXTURE0);
                glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
#endif
            }
        } else if (ShaderManager::instance()->isValid()) {
            useShader = true;
            ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
        }
        texture->render(m_currentGeometry, m_currentGeometry);
        if (useShader) {
            ShaderManager::instance()->popShader();
        }
        if (m_type == BlinkingFeedback && !useShader) {
#ifndef KWIN_HAVE_OPENGLES
            // resture states
            glActiveTexture(GL_TEXTURE1);
            texture->unbind();
            glActiveTexture(GL_TEXTURE0);
            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
            glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
#endif
        }
        texture->unbind();
        glDisable(GL_BLEND);
    }
}
void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data)
{
    if (effects->compositingType() == KWin::OpenGLCompositing && (data.xScale() < 0.9 || data.yScale() < 0.9) &&
            KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) {
        if (!m_inited)
            init();
        const QRect screenRect = Workspace::self()->clientArea(ScreenArea, w->screen(), w->desktop());
        // window geometry may not be bigger than screen geometry to fit into the FBO
        if (m_shader && w->width() <= screenRect.width() && w->height() <= screenRect.height()) {
            double left = 0;
            double top = 0;
            double right = w->width();
            double bottom = w->height();
            foreach (const WindowQuad & quad, data.quads) {
                // we need this loop to include the decoration padding
                left   = qMin(left, quad.left());
                top    = qMin(top, quad.top());
                right  = qMax(right, quad.right());
                bottom = qMax(bottom, quad.bottom());
            }
            double width = right - left;
            double height = bottom - top;
            if (width > screenRect.width() || height > screenRect.height()) {
                // window with padding does not fit into the framebuffer
                // so cut of the shadow
                left = 0;
                top = 0;
                width = w->width();
                height = w->height();
            }
            int tx = data.xTranslation() + w->x() + left * data.xScale();
            int ty = data.yTranslation() + w->y() + top * data.yScale();
            int tw = width * data.xScale();
            int th = height * data.yScale();
            const QRect textureRect(tx, ty, tw, th);
            const bool hardwareClipping = !(QRegion(textureRect)-region).isEmpty();

            int sw = width;
            int sh = height;

            GLTexture *cachedTexture = static_cast< GLTexture*>(w->data(LanczosCacheRole).value<void*>());
            if (cachedTexture) {
                if (cachedTexture->width() == tw && cachedTexture->height() == th) {
                    cachedTexture->bind();
                    if (hardwareClipping) {
                        glEnable(GL_SCISSOR_TEST);
                    }
                    if (ShaderManager::instance()->isValid()) {
                        glEnable(GL_BLEND);
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

                        const qreal rgb = data.brightness() * data.opacity();
                        const qreal a = data.opacity();

                        GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
                        shader->setUniform(GLShader::Offset, QVector2D(0, 0));
                        shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
                        shader->setUniform(GLShader::Saturation, data.saturation());
                        shader->setUniform(GLShader::AlphaToOne, 0);

                        cachedTexture->render(region, textureRect, hardwareClipping);

                        ShaderManager::instance()->popShader();
                        glDisable(GL_BLEND);
                    } else {
                        prepareRenderStates(cachedTexture, data.opacity(), data.brightness(), data.saturation());
                        cachedTexture->render(region, textureRect, hardwareClipping);
                        restoreRenderStates(cachedTexture, data.opacity(), data.brightness(), data.saturation());
                    }
                    if (hardwareClipping) {
                        glDisable(GL_SCISSOR_TEST);
                    }
                    cachedTexture->unbind();
                    m_timer.start(5000, this);
                    return;
                } else {
                    // offscreen texture not matching - delete
                    delete cachedTexture;
                    cachedTexture = 0;
                    w->setData(LanczosCacheRole, QVariant());
                }
            }

            WindowPaintData thumbData = data;
            thumbData.setXScale(1.0);
            thumbData.setYScale(1.0);
            thumbData.setXTranslation(-w->x() - left);
            thumbData.setYTranslation(-w->y() - top);
            thumbData.setBrightness(1.0);
            thumbData.setOpacity(1.0);
            thumbData.setSaturation(1.0);

            // Bind the offscreen FBO and draw the window on it unscaled
            updateOffscreenSurfaces();
            GLRenderTarget::pushRenderTarget(m_offscreenTarget);

            glClearColor(0.0, 0.0, 0.0, 0.0);
            glClear(GL_COLOR_BUFFER_BIT);
            w->sceneWindow()->performPaint(mask, infiniteRegion(), thumbData);

            // Create a scratch texture and copy the rendered window into it
            GLTexture tex(sw, sh);
            tex.setFilter(GL_LINEAR);
            tex.setWrapMode(GL_CLAMP_TO_EDGE);
            tex.bind();

            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, sw, sh);

            // Set up the shader for horizontal scaling
            float dx = sw / float(tw);
            int kernelSize;
            m_shader->createKernel(dx, &kernelSize);
            m_shader->createOffsets(kernelSize, sw, Qt::Horizontal);

            m_shader->bind();
            m_shader->setUniforms();

            // Draw the window back into the FBO, this time scaled horizontally
            glClear(GL_COLOR_BUFFER_BIT);
            QVector<float> verts;
            QVector<float> texCoords;
            verts.reserve(12);
            texCoords.reserve(12);

            texCoords << 1.0 << 0.0; verts << tw  << 0.0; // Top right
            texCoords << 0.0 << 0.0; verts << 0.0 << 0.0; // Top left
            texCoords << 0.0 << 1.0; verts << 0.0 << sh;  // Bottom left
            texCoords << 0.0 << 1.0; verts << 0.0 << sh;  // Bottom left
            texCoords << 1.0 << 1.0; verts << tw  << sh;  // Bottom right
            texCoords << 1.0 << 0.0; verts << tw  << 0.0; // Top right
            GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
            vbo->reset();
            vbo->setData(6, 2, verts.constData(), texCoords.constData());
            vbo->render(GL_TRIANGLES);

            // At this point we don't need the scratch texture anymore
            tex.unbind();
            tex.discard();

            // create scratch texture for second rendering pass
            GLTexture tex2(tw, sh);
            tex2.setFilter(GL_LINEAR);
            tex2.setWrapMode(GL_CLAMP_TO_EDGE);
            tex2.bind();

            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, tw, sh);

            // Set up the shader for vertical scaling
            float dy = sh / float(th);
            m_shader->createKernel(dy, &kernelSize);
            m_shader->createOffsets(kernelSize, m_offscreenTex->height(), Qt::Vertical);
            m_shader->setUniforms();

            // Now draw the horizontally scaled window in the FBO at the right
            // coordinates on the screen, while scaling it vertically and blending it.
            glClear(GL_COLOR_BUFFER_BIT);

            verts.clear();

            verts << tw  << 0.0; // Top right
            verts << 0.0 << 0.0; // Top left
            verts << 0.0 << th;  // Bottom left
            verts << 0.0 << th;  // Bottom left
            verts << tw  << th;  // Bottom right
            verts << tw  << 0.0; // Top right
            vbo->setData(6, 2, verts.constData(), texCoords.constData());
            vbo->render(GL_TRIANGLES);

            tex2.unbind();
            tex2.discard();
            m_shader->unbind();

            // create cache texture
            GLTexture *cache = new GLTexture(tw, th);

            cache->setFilter(GL_LINEAR);
            cache->setWrapMode(GL_CLAMP_TO_EDGE);
            cache->bind();
            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th);
            GLRenderTarget::popRenderTarget();

            if (hardwareClipping) {
                glEnable(GL_SCISSOR_TEST);
            }
            if (ShaderManager::instance()->isValid()) {
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

                const qreal rgb = data.brightness() * data.opacity();
                const qreal a = data.opacity();

                GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
                shader->setUniform(GLShader::Offset, QVector2D(0, 0));
                shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a));
                shader->setUniform(GLShader::Saturation, data.saturation());
                shader->setUniform(GLShader::AlphaToOne, 0);

                cache->render(region, textureRect, hardwareClipping);

                ShaderManager::instance()->popShader();
                glDisable(GL_BLEND);
            } else {
                prepareRenderStates(cache, data.opacity(), data.brightness(), data.saturation());
                cache->render(region, textureRect, hardwareClipping);
                restoreRenderStates(cache, data.opacity(), data.brightness(), data.saturation());
            }
            if (hardwareClipping) {
                glDisable(GL_SCISSOR_TEST);
            }

            cache->unbind();
            w->setData(LanczosCacheRole, QVariant::fromValue(static_cast<void*>(cache)));

            // Delete the offscreen surface after 5 seconds
            m_timer.start(5000, this);
            return;
        }
    } // if ( effects->compositingType() == KWin::OpenGLCompositing )
Beispiel #7
0
void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const float opacity)
{
    const QRect screen = effects->virtualScreenGeometry();
    const QRegion blurredRegion = blurRegion(w).translated(w->pos()) & screen;
    const QRegion expanded = expand(blurredRegion) & screen;
    const QRect r = expanded.boundingRect();

    // The background texture we get is only partially valid.

    CacheEntry it = windows.find(w);
    if (it == windows.end()) {
        BlurWindowInfo bwi;
        bwi.blurredBackground = GLTexture(r.width(),r.height());
        bwi.damagedRegion = expanded;
        bwi.dropCache = false;
        bwi.windowPos = w->pos();
        it = windows.insert(w, bwi);
    } else if (it->blurredBackground.size() != r.size()) {
        it->blurredBackground = GLTexture(r.width(),r.height());
        it->dropCache = false;
        it->windowPos = w->pos();
    } else if (it->windowPos != w->pos()) {
        it->dropCache = false;
        it->windowPos = w->pos();
    }

    GLTexture targetTexture = it->blurredBackground;
    targetTexture.setFilter(GL_LINEAR);
    targetTexture.setWrapMode(GL_CLAMP_TO_EDGE);
    shader->bind();
    QMatrix4x4 textureMatrix;
    QMatrix4x4 modelViewProjectionMatrix;

    /**
     * Which part of the background texture can be updated ?
     *
     * Well this is a rather difficult question. We kind of rely on the fact, that
     * we need a bigger background region being painted before, more precisely if we want to
     * blur region A we need the background region expand(A). This business logic is basically
     * done in prePaintWindow:
     *          data.paint |= expand(damagedArea);
     *
     * Now "data.paint" gets clipped and becomes what we receive as the "region" variable
     * in this function. In theory there is now only one function that does this clipping
     * and this is paintSimpleScreen. The clipping has the effect that "damagedRegion"
     * is no longer a subset of "region" and we cannot fully validate the cache within one
     * rendering pass. If we would now update the "damageRegion & region" part of the cache
     * we would wrongly update the part of the cache that is next to the "region" border and
     * which lies within "damagedRegion", just because we cannot assume that the framebuffer
     * outside of "region" is valid. Therefore the maximal damaged region of the cache that can
     * be repainted is given by:
     *          validUpdate = damagedRegion - expand(damagedRegion - region);
     *
     * Now you may ask what is with the rest of "damagedRegion & region" that is not part
     * of "validUpdate" but also might end up on the screen. Well under the assumption
     * that only the occlusion culling can shrink "data.paint", we can control this by reducing
     * the opaque area of every window by a margin of the blurring radius (c.f. prePaintWindow).
     * This way we are sure that this area is overpainted by a higher opaque window.
     *
     * Apparently paintSimpleScreen is not the only function that can influence "region".
     * In fact every effect's paintWindow that is called before Blur::paintWindow
     * can do so (e.g. SlidingPopups). Hence we have to make the compromise that we update
     * "damagedRegion & region" of the cache but only mark "validUpdate" as valid.
     **/
    const QRegion damagedRegion = it->damagedRegion;
    const QRegion updateBackground = damagedRegion & region;
    const QRegion validUpdate = damagedRegion - expand(damagedRegion - region);

    const QRegion horizontal = validUpdate.isEmpty() ? QRegion() : (updateBackground & screen);
    const QRegion vertical   = blurredRegion & region;

    const int horizontalOffset = 0;
    const int horizontalCount = horizontal.rectCount() * 6;

    const int verticalOffset = horizontalCount;
    const int verticalCount = vertical.rectCount() * 6;

    GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
    uploadGeometry(vbo, horizontal, vertical);

    vbo->bindArrays();

    if (!validUpdate.isEmpty()) {
        const QRect updateRect = (expand(updateBackground) & expanded).boundingRect();
        // First we have to copy the background from the frontbuffer
        // into a scratch texture (in this case "tex").
        tex.bind();

        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, updateRect.x(), displayHeight() - updateRect.y() - updateRect.height(),
                            updateRect.width(), updateRect.height());

        // Draw the texture on the offscreen framebuffer object, while blurring it horizontally
        target->attachTexture(targetTexture);
        GLRenderTarget::pushRenderTarget(target);

        shader->setDirection(Qt::Horizontal);
        shader->setPixelDistance(1.0 / tex.width());

        modelViewProjectionMatrix.ortho(0, r.width(), r.height(), 0 , 0, 65535);
        modelViewProjectionMatrix.translate(-r.x(), -r.y(), 0);
        shader->setModelViewProjectionMatrix(modelViewProjectionMatrix);

        // Set up the texture matrix to transform from screen coordinates
        // to texture coordinates.
        textureMatrix.scale(1.0 / tex.width(), -1.0 / tex.height(), 1);
        textureMatrix.translate(-updateRect.x(), -updateRect.height() - updateRect.y(), 0);
        shader->setTextureMatrix(textureMatrix);

        vbo->draw(GL_TRIANGLES, horizontalOffset, horizontalCount);

        GLRenderTarget::popRenderTarget();
        tex.unbind();
        // mark the updated region as valid
        it->damagedRegion -= validUpdate;
    }

    // Now draw the horizontally blurred area back to the backbuffer, while
    // blurring it vertically and clipping it to the window shape.
    targetTexture.bind();

    shader->setDirection(Qt::Vertical);
    shader->setPixelDistance(1.0 / targetTexture.height());

    // Modulate the blurred texture with the window opacity if the window isn't opaque
    if (opacity < 1.0) {
        glEnable(GL_BLEND);
        glBlendColor(0, 0, 0, opacity);
        glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);
    }

    modelViewProjectionMatrix.setToIdentity();
    const QSize screenSize = effects->virtualScreenSize();
    modelViewProjectionMatrix.ortho(0, screenSize.width(), screenSize.height(), 0, 0, 65535);
    shader->setModelViewProjectionMatrix(modelViewProjectionMatrix);

    // Set the up the texture matrix to transform from screen coordinates
    // to texture coordinates.
    textureMatrix.setToIdentity();
    textureMatrix.scale(1.0 / targetTexture.width(), -1.0 / targetTexture.height(), 1);
    textureMatrix.translate(-r.x(), -targetTexture.height() - r.y(), 0);
    shader->setTextureMatrix(textureMatrix);

    vbo->draw(GL_TRIANGLES, verticalOffset, verticalCount);
    vbo->unbindArrays();

    if (opacity < 1.0) {
        glDisable(GL_BLEND);
    }

    targetTexture.unbind();
    shader->unbind();
}
Beispiel #8
0
/* MCAVertexSelection::draw
 * Draws the animation
 *******************************************************************/
void MCAVertexSelection::draw()
{
	// Setup colour
	rgba_t col;
	if (select)
		col.set(255, 255, 255, 255*fade, 1);
	else
	{
		col = ColourConfiguration::getColour("map_selection");
		col.a *= fade;
	}
	OpenGL::setColour(col);

	// Setup point sprites if supported
	bool point = false;
	if (OpenGL::pointSpriteSupport())
	{
		// Get appropriate vertex texture
		GLTexture* tex;
		//if (vertex_round) tex = MapEditor::textureManager().getEditorImage("vertex_r");
		//else tex = MapEditor::textureManager().getEditorImage("vertex_s");

		if (select)
		{
			if (vertex_round) tex = MapEditor::textureManager().getEditorImage("vertex/round");
			else tex = MapEditor::textureManager().getEditorImage("vertex/square");
		}
		else
		{
			if (vertex_round) tex = MapEditor::textureManager().getEditorImage("vertex/hilight_r");
			else tex = MapEditor::textureManager().getEditorImage("vertex/hilight_s");
		}

		// If it was found, enable point sprites
		if (tex)
		{
			glEnable(GL_TEXTURE_2D);
			tex->bind();
			glEnable(GL_POINT_SPRITE);
			glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
			point = true;
		}
	}

	// No point sprites, use regular points
	if (!point)
	{
		if (vertex_round)	glEnable(GL_POINT_SMOOTH);
		else				glDisable(GL_POINT_SMOOTH);
	}

	// Draw points
	if (select)
		glPointSize(size+(size*fade));
	else
		glPointSize(size);
	glBegin(GL_POINTS);
	for (unsigned a = 0; a < vertices.size(); a++)
		glVertex2d(vertices[a].x, vertices[a].y);
	glEnd();

	if (point)
	{
		glDisable(GL_POINT_SPRITE);
		glDisable(GL_TEXTURE_2D);
	}
}