Esempio n. 1
0
//--------------------------------------------------------------------------------------------------
/// Render primitives in this primitive set using vertex arrays
/// 
/// \warning Requires at least OpenGL 1.5
//--------------------------------------------------------------------------------------------------
void PrimitiveSetIndexedUShort::render(OpenGLContext* oglContext) const
{
    CVF_CALLSITE_OPENGL(oglContext);
    CVF_TIGHT_ASSERT(BufferObjectManaged::supportedOpenGL(oglContext));

    if (m_indices.isNull())
    {
        return;
    }

    GLsizei numIndices = static_cast<GLsizei>(m_indices->size());
    if (numIndices <= 0) 
    {
        return;
    }

    const GLvoid* ptrOrOffset = 0;
    if (m_indicesBO.notNull() && m_indicesBO->isUploaded())
    {
        m_indicesBO->bindBuffer(oglContext);
    }
    else
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        ptrOrOffset = m_indices->ptr();
    }

#ifdef CVF_OPENGL_ES
    glDrawElements(primitiveTypeOpenGL(), numIndices, GL_UNSIGNED_SHORT, ptrOrOffset);
#else
    glDrawRangeElements(primitiveTypeOpenGL(), m_minIndex, m_maxIndex, numIndices, GL_UNSIGNED_SHORT, ptrOrOffset);
#endif
}
//--------------------------------------------------------------------------------------------------
/// Render primitives in this primitive set using vertex arrays
/// 
/// \warning Requires at least OpenGL 1.5
//--------------------------------------------------------------------------------------------------
void PrimitiveSetIndexedUShortScoped::render(OpenGLContext* oglContext) const
{
    CVF_CALLSITE_OPENGL(oglContext);
    CVF_ASSERT(BufferObjectManaged::supportedOpenGL(oglContext));
    
    if (m_indices.isNull())
    {
        return;
    }

    GLsizei numIndices = static_cast<GLsizei>(m_elementCount);
    if (numIndices <= 0) 
    {
        return;
    }

    const GLvoid* ptrOrOffset = 0;
    if (m_indicesBO.notNull() && m_indicesBO->isUploaded())
    {
        m_indicesBO->bindBuffer(oglContext);
        ptrOrOffset = reinterpret_cast<GLvoid*>(m_firstElement*sizeof(GLushort));
    }
    else
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        ptrOrOffset = m_indices->ptr() + m_firstElement;
    }
    
    glDrawElements(primitiveTypeOpenGL(), numIndices, GL_UNSIGNED_SHORT, ptrOrOffset);

    CVF_CHECK_OGL(oglContext);
}
Esempio n. 3
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RenderStateTextureMapping_FF::applyOpenGL(OpenGLContext* oglContext) const
{
    CVF_CALLSITE_OPENGL(oglContext);

    if (oglContext->capabilities()->supportsOpenGL2())
    {
        glActiveTexture(GL_TEXTURE0);
    }

    if (m_texture.notNull() && m_texture->textureOglId() != 0)
    {
        m_texture->bind(oglContext);
        m_texture->setupTextureParams(oglContext);

        cvfGLint oglTexFunc = GL_MODULATE;
        switch (m_textureFunction)
        {
            case MODULATE:  oglTexFunc = GL_MODULATE; break;
            case DECAL:     oglTexFunc = GL_DECAL; break;
        }

        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oglTexFunc);

        glEnable(GL_TEXTURE_2D);

        if (m_environmentMapping)
        {
            glEnable(GL_TEXTURE_GEN_S);
            glEnable(GL_TEXTURE_GEN_T);

            GLint piSphereMap[1];
            piSphereMap[0] = GL_SPHERE_MAP;
            glTexGeniv(GL_S, GL_TEXTURE_GEN_MODE, piSphereMap);
            glTexGeniv(GL_T, GL_TEXTURE_GEN_MODE, piSphereMap);
        }
        else
        {
            glDisable(GL_TEXTURE_GEN_S);
            glDisable(GL_TEXTURE_GEN_T);
        }
    }
    else
    {
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_TEXTURE_GEN_S);
        glDisable(GL_TEXTURE_GEN_T);
    }

    CVF_CHECK_OGL(oglContext);
}
Esempio n. 4
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RenderStateTextureMapping_FF::setupTexture(OpenGLContext* oglContext)
{
    CVF_CALLSITE_OPENGL(oglContext);

    if (m_texture.notNull())
    {
        if (m_texture->textureOglId() == 0)
        {
            if (oglContext->capabilities()->supportsOpenGL2())
            {
                glActiveTexture(GL_TEXTURE0);
            }

            m_texture->setupTexture(oglContext);

            CVF_CHECK_OGL(oglContext);
        }
    }
}
Esempio n. 5
0
//--------------------------------------------------------------------------------------------------
/// Explicitly generate mipmaps
/// 
/// \warning Requires the GENERATE_MIPMAP_FUNC capability. Will assert if this requirement is not met.
//--------------------------------------------------------------------------------------------------
void Texture::generateMipmap(OpenGLContext* oglContext)
{
    CVF_CALLSITE_OPENGL(oglContext);
    CVF_ASSERT(oglContext->capabilities()->hasCapability(OpenGLCapabilities::GENERATE_MIPMAP_FUNC));

    bind(oglContext);

    if (m_textureType == TEXTURE_2D)
    {
        glGenerateMipmap(GL_TEXTURE_2D);
        m_hasMipmaps = true;
    }
    else if (m_textureType == TEXTURE_CUBE_MAP)
    {
        glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
        m_hasMipmaps = true;
    }
    else
    {
        CVF_FAIL_MSG("Mipmap generation not supported for this texture type");
    }

    CVF_CHECK_OGL(oglContext);
}
Esempio n. 6
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void DrawableVectors::render(OpenGLContext* oglContext, ShaderProgram* shaderProgram, const MatrixState&)
{
    CVF_CALLSITE_OPENGL(oglContext);

    CVF_ASSERT(shaderProgram);
    CVF_ASSERT(shaderProgram->isProgramUsed(oglContext));
    CVF_ASSERT(m_vertexArray->size() == m_vectorArray->size());
    CVF_ASSERT(m_colorArray.isNull() || (m_colorArray->size() == m_vectorArray->size()));
    CVF_ASSERT(m_vectorGlyph.notNull());
    CVF_ASSERT(m_vectorGlyph->primitiveSetCount() == 1);

    // Setup Vertex Arrays/vbos 
    const GLvoid* ptrOrOffset = 0;

    if (m_renderWithVBO && m_glyphVerticesAndNormalsBO.notNull() && m_glyphVerticesAndNormalsBO->isUploaded())
    {
        // Bind VBO for vertex and normal data
        m_glyphVerticesAndNormalsBO->bindBuffer(oglContext);

        glVertexAttribPointer(ShaderProgram::NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(float)*6, (void*)(sizeof(float)*3));
        glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(float)*6, 0);
        glEnableVertexAttribArray(ShaderProgram::NORMAL);
        glEnableVertexAttribArray(ShaderProgram::VERTEX);

        m_indicesBO->bindBuffer(oglContext);
    }
    else
    {
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glVertexAttribPointer(ShaderProgram::NORMAL, 3, GL_FLOAT, GL_FALSE, 0, m_vectorGlyph->normalArray()->ptr()->ptr());
        glEnableVertexAttribArray(ShaderProgram::NORMAL);
        glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, m_vectorGlyph->vertexArray()->ptr()->ptr());
        glEnableVertexAttribArray(ShaderProgram::VERTEX);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        ptrOrOffset = m_vectorGlyphPrimSet->indices()->ptr();
    }

    // Must use manual uniform setting, as setting the uniform through the Uniform* class requires a lookup for location
    // every time, and this is always the same
    GLint vectorMatrixUniformLocation = shaderProgram->uniformLocation(m_vectorMatrixUniformName.toAscii().ptr());
    CVF_ASSERT(vectorMatrixUniformLocation != -1);
    GLint colorUniformLocation = shaderProgram->uniformLocation(m_colorUniformName.toAscii().ptr());
    CVF_ASSERT(colorUniformLocation != -1);

#ifndef CVF_OPENGL_ES
    uint minIndex = m_vectorGlyphPrimSet->minIndex();
    uint maxIndex = m_vectorGlyphPrimSet->maxIndex();
#endif
    GLsizei indexCount = static_cast<GLsizei>(m_vectorGlyphPrimSet->indexCount());

    // Set the single color to use
    if (m_colorArray.isNull())
    {
        glUniform3fv(colorUniformLocation, 1, m_singleColor.ptr());
    }

    float vectorMat[16];
    size_t numVectors = m_vectorArray->size();
    size_t i;
    for (i = 0; i < numVectors; i++)
    {
        // Compute the transformation matrix
        vectorMatrix(i, vectorMat);

        // Set this as a uniform to the shader program
        glUniformMatrix4fv(vectorMatrixUniformLocation, 1, GL_FALSE, vectorMat); 

        if (m_colorArray.notNull())
        {
            glUniform3fv(colorUniformLocation, 1, m_colorArray->get(i).ptr());
        }

        // Draw the arrow
#ifdef CVF_OPENGL_ES
        glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, ptrOrOffset);
#else
        glDrawRangeElements(GL_TRIANGLES, minIndex, maxIndex, indexCount, GL_UNSIGNED_SHORT, ptrOrOffset);
#endif
    }

    // Cleanup
    glDisableVertexAttribArray(ShaderProgram::VERTEX);
    glDisableVertexAttribArray(ShaderProgram::NORMAL);

    CVF_CHECK_OGL(oglContext);

    // Things to consider for performance:

    // 1) Uniform arrays evt. Uniform buffer objects
    // 2) Texture
    // 3) Texture array

    // GL_ARB_draw_instanced();
    // glDrawElementsInstanced
}
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::applyOpenGL(OpenGLContext* oglContext) const
{
    CVF_CALLSITE_OPENGL(oglContext);

    /// As we do not care about specific support for OpenGL 1.4, 1.3 etc., everything that is not in 1.1
    /// will require at least support for our baseline (currently OpenGL 2.0)
    bool openGL2Support = oglContext->capabilities()->supportsOpenGL2();

    if (m_enableBlending)
    {
        glEnable(GL_BLEND);
    }
    else
    {
        glDisable(GL_BLEND);
    }

    if ((m_funcSourceRGB == m_funcSourceAlpha) && (m_funcDestinationRGB == m_funcDestinationAlpha))
    {
        glBlendFunc(blendFuncOpenGL(m_funcSourceRGB), blendFuncOpenGL(m_funcDestinationRGB));
    }
    else
    {
        if (openGL2Support)
        {
            glBlendFuncSeparate(blendFuncOpenGL(m_funcSourceRGB), blendFuncOpenGL(m_funcDestinationRGB), blendFuncOpenGL(m_funcSourceAlpha), blendFuncOpenGL(m_funcDestinationAlpha));
        }
        else
        {
            CVF_LOG_RENDER_ERROR(oglContext, "Context does not support separate blend functions.");
        }
    }

    if (openGL2Support)
    {
        if (m_equationRGB == m_equationAlpha)
        {
            glBlendEquation(blendEquationOpenGL(m_equationRGB));
        }
        else
        {
            glBlendEquationSeparate(blendEquationOpenGL(m_equationRGB), blendEquationOpenGL(m_equationAlpha));
        }

        glBlendColor(m_blendColor.r(), m_blendColor.g(), m_blendColor.b(), m_blendColor.a());
    }
    else
    {
        // Only error reporting here
        if (m_equationRGB != FUNC_ADD ||
            m_equationRGB != m_equationAlpha)
        {
            CVF_LOG_RENDER_ERROR(oglContext, "Context does not support blend equations.");
        }

        if (m_blendColor != Color4f(0, 0, 0, 0))
        {
            CVF_LOG_RENDER_ERROR(oglContext, "Context does not support blend color.");
        }
    }
}
Esempio n. 8
0
//--------------------------------------------------------------------------------------------------
/// 
//--------------------------------------------------------------------------------------------------
void OverlayImage::render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size, bool software)
{
    CVF_CALLSITE_OPENGL(oglContext);

    Camera projCam;
    projCam.setViewport(position.x(), position.y(), size.x(), size.y());
    projCam.setProjectionAsPixelExact2D();
    projCam.setViewMatrix(Mat4d::IDENTITY);

    // Turn off depth test
    RenderStateDepth depth(false, RenderStateDepth::LESS, false);
    depth.applyOpenGL(oglContext);

    float vertexArray[12];
    float textureCoords[] = {0.0f, 0.0f,
                            1.0f, 0.0f,
                            1.0f, 1.0f,
                            0.0f, 1.0f};
    
    projCam.viewport()->applyOpenGL(oglContext, Viewport::DO_NOT_CLEAR);

    if (software)
    {
        // Create a POW2 texture for software rendering if needed
        if (m_image.notNull() && m_pow2Image.isNull() && (!Math::isPow2(m_image->width()) || !Math::isPow2(m_image->height())))
        {
            m_pow2Image = new TextureImage;
            m_pow2Image->allocate(Math::roundUpPow2(m_image->width()), Math::roundUpPow2(m_image->height()));
            m_pow2Image->fill(Color4ub(Color3::BLACK));

            for (uint y = 0; y < m_image->height(); ++y)
            {
                for (uint x = 0; x < m_image->width(); ++x)
                {
                    m_pow2Image->setPixel(x, y, m_image->pixel(x, y));
                }
            }
        }


        if (ShaderProgram::supportedOpenGL(oglContext))
        {
            ShaderProgram::useNoProgram(oglContext);
        }

#ifndef CVF_OPENGL_ES
        RenderStateMaterial_FF mat;
        mat.enableColorMaterial(true);
        mat.applyOpenGL(oglContext);

        RenderStateLighting_FF light(false);
        light.applyOpenGL(oglContext);

        if (m_textureBindings.isNull())
        {
            // Use fixed function texture setup
            ref<Texture2D_FF> texture = new Texture2D_FF(m_pow2Image.notNull() ? m_pow2Image.p() : m_image.p());
            texture->setWrapMode(Texture2D_FF::CLAMP);
            texture->setMinFilter(Texture2D_FF::NEAREST);
            texture->setMagFilter(Texture2D_FF::NEAREST);
            texture->setupTexture(oglContext);
            texture->setupTextureParams(oglContext);

            ref<RenderStateTextureMapping_FF> textureMapping = new RenderStateTextureMapping_FF(texture.p());
            textureMapping->setTextureFunction(m_blendMode == TEXTURE_ALPHA ? RenderStateTextureMapping_FF::MODULATE : RenderStateTextureMapping_FF::DECAL);

            m_textureBindings = textureMapping;
        }
#endif
        // Adjust texture coordinates
        if (m_pow2Image.notNull())
        {
            float xMax = static_cast<float>(m_image->width())/static_cast<float>(m_pow2Image->width());
            float yMax = static_cast<float>(m_image->height())/static_cast<float>(m_pow2Image->height());
            textureCoords[2] = xMax;
            textureCoords[4] = xMax;
            textureCoords[5] = yMax;
            textureCoords[7] = yMax;
        }

        projCam.applyOpenGL();
    }
    else
    {
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glEnableVertexAttribArray(ShaderProgram::VERTEX);
        glEnableVertexAttribArray(ShaderProgram::TEX_COORD_2F_0);
        glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);
        glVertexAttribPointer(ShaderProgram::TEX_COORD_2F_0, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);

        if (m_shaderProgram.isNull())
        {
            ShaderProgramGenerator gen("OverlayImage_Shader", ShaderSourceProvider::instance());
            gen.addVertexCode(ShaderSourceRepository::vs_MinimalTexture);
            
            if (m_blendMode == GLOBAL_ALPHA)
            {
                gen.addFragmentCode(ShaderSourceRepository::src_TextureGlobalAlpha);
            }
            else
            {
                gen.addFragmentCode(ShaderSourceRepository::src_Texture);
            }

            gen.addFragmentCode(ShaderSourceRepository::fs_Unlit);
            m_shaderProgram = gen.generate();
            m_shaderProgram->linkProgram(oglContext);
        }

        if (m_shaderProgram->useProgram(oglContext))
        {
            MatrixState projMatrixState(projCam);
            m_shaderProgram->clearUniformApplyTracking();
            m_shaderProgram->applyFixedUniforms(oglContext, projMatrixState);
        }

        if (m_texture->textureOglId() == 0)
        {
            m_texture->setupTexture(oglContext);
        }

        if (m_textureBindings.isNull())
        {
            cvf::RenderStateTextureBindings* textureBindings = new cvf::RenderStateTextureBindings;
            textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D");
            m_textureBindings = textureBindings;
        }
    }

    float offset = 0.0f;
    Vec3f min(offset, offset, 0.0f);
    Vec3f max(static_cast<float>(size.x()) + offset, static_cast<float>(size.y()) + offset, 0.0f);

    // Setup the vertex array
    float* v1 = &vertexArray[0]; 
    float* v2 = &vertexArray[3];
    float* v3 = &vertexArray[6];
    float* v4 = &vertexArray[9];
    v1[0] = min.x(); v1[1] = min.y(); v1[2] = 0.0f;
    v2[0] = max.x(); v2[1] = min.y(); v2[2] = 0.0f;
    v3[0] = max.x(); v3[1] = max.y(); v3[2] = 0.0f;
    v4[0] = min.x(); v4[1] = max.y(); v4[2] = 0.0f;

    if (m_blendMode != NO_BLENDING)
    {
        RenderStateBlending blend;
        blend.configureTransparencyBlending();
        blend.applyOpenGL(oglContext);
    }

    m_textureBindings->applyOpenGL(oglContext);

    if (software)
    {
#ifndef CVF_OPENGL_ES
        glColor4f(1.0f, 1.0f, 1.0f, m_blendMode == GLOBAL_ALPHA ? m_alpha : 1.0f);
        glBegin(GL_TRIANGLE_FAN);
        glTexCoord2f(textureCoords[0], textureCoords[1]);
        glVertex3fv(v1);
        glTexCoord2f(textureCoords[2], textureCoords[3]);
        glVertex3fv(v2);
        glTexCoord2f(textureCoords[4], textureCoords[5]);
        glVertex3fv(v3);
        glTexCoord2f(textureCoords[6], textureCoords[7]);
        glVertex3fv(v4);
        glEnd();
#endif
    }
    else
    {
        if (m_blendMode == GLOBAL_ALPHA)
        {
            UniformFloat alphaUniform("u_alpha", m_alpha);
            m_shaderProgram->applyUniform(oglContext, alphaUniform);
        }

        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }

    if (m_blendMode != NO_BLENDING)
    {
        RenderStateBlending blend;
        blend.applyOpenGL(oglContext);
    }

    RenderStateDepth resetDepth;
    resetDepth.applyOpenGL(oglContext);

    if (software)
    {
#ifndef CVF_OPENGL_ES
        RenderStateTextureMapping_FF resetTextureMapping;
        resetTextureMapping.applyOpenGL(oglContext);
#endif
    }

    if (!software)
    {
        glDisableVertexAttribArray(ShaderProgram::VERTEX);
        glDisableVertexAttribArray(ShaderProgram::TEX_COORD_2F_0);
    }
}
Esempio n. 9
0
//--------------------------------------------------------------------------------------------------
/// Draw the legend using shader programs
//--------------------------------------------------------------------------------------------------
void OverlayColorLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLegendLayoutInfo* layout, const MatrixState& matrixState)
{
    CVF_CALLSITE_OPENGL(oglContext);

    CVF_TIGHT_ASSERT(layout);
    CVF_TIGHT_ASSERT(layout->size.x() > 0);
    CVF_TIGHT_ASSERT(layout->size.y() > 0);

    Depth depth(false);
    depth.applyOpenGL(oglContext);

    // All vertices. Initialized here to set Z to zero once and for all.
    static float vertexArray[] = 
    {
        0.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 0.0f
    };

    // Per vector convenience pointers
    float* v0 = &vertexArray[0]; 
    float* v1 = &vertexArray[3]; 
    float* v2 = &vertexArray[6]; 
    float* v3 = &vertexArray[9]; 
    float* v4 = &vertexArray[12];

    // Constant coordinates
    v0[0] = v3[0] = layout->x0;
    v1[0] = v4[0] = layout->x1;

    // Connects
    static const ushort trianglesConnects[] = { 0, 1, 4, 0, 4, 3 };

    ref<ShaderProgram> shaderProgram = oglContext->resourceManager()->getLinkedUnlitColorShaderProgram(oglContext);
    CVF_TIGHT_ASSERT(shaderProgram.notNull());

    if (shaderProgram->useProgram(oglContext))
    {
        shaderProgram->clearUniformApplyTracking();
        shaderProgram->applyFixedUniforms(oglContext, matrixState);
    }

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glEnableVertexAttribArray(ShaderProgram::VERTEX);
    glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);

    // Render color bar as one colored quad per pixel

    int legendHeightPixelCount = static_cast<int>(layout->tickPixelPos->get(m_tickValues.size()-1) - layout->tickPixelPos->get(0) + 0.01);
    if (m_scalarMapper.notNull())
    {
        int iPx;
        for (iPx = 0; iPx < legendHeightPixelCount; iPx++)
        {
            const Color3ub& clr = m_scalarMapper->mapToColor(m_scalarMapper->domainValue((iPx+0.5)/legendHeightPixelCount));
            float y0 = static_cast<float>(layout->legendRect.min().y() + iPx);
            float y1 = static_cast<float>(layout->legendRect.min().y() + iPx + 1);

            // Dynamic coordinates for rectangle
            v0[1] = v1[1] = y0;
            v3[1] = v4[1] = y1;

            // Draw filled rectangle elements
            {
                UniformFloat uniformColor("u_color", Color4f(Color3f(clr)));
                shaderProgram->applyUniform(oglContext, uniformColor);

#ifdef CVF_OPENGL_ES
                glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, trianglesConnects);
#else
                glDrawRangeElements(GL_TRIANGLES, 0, 4, 6, GL_UNSIGNED_SHORT, trianglesConnects);
#endif
            }
        }
    }

    // Render frame

    // Dynamic coordinates for  tickmarks-lines
    bool isRenderingFrame = true;
    if (isRenderingFrame)
    {
        v0[0] = v2[0] = layout->legendRect.min().x()-0.5f;
        v1[0] = v3[0] = layout->legendRect.max().x()-0.5f;
        v0[1] = v1[1] = layout->legendRect.min().y()-0.5f;
        v2[1] = v3[1] = layout->legendRect.max().y()-0.5f;
        static const ushort frameConnects[] = { 0, 1, 1, 3, 3, 2, 2, 0};

        UniformFloat uniformColor("u_color", Color4f(m_color));
        shaderProgram->applyUniform(oglContext, uniformColor);

#ifdef CVF_OPENGL_ES
        glDrawElements(GL_LINES, 8, GL_UNSIGNED_SHORT, frameConnects);
#else
        glDrawRangeElements(GL_LINES, 0, 3, 8, GL_UNSIGNED_SHORT, frameConnects);
#endif
    }

    // Render tickmarks
    bool isRenderingTicks = true;

    if (isRenderingTicks)
    {
        // Constant coordinates
        v0[0] = layout->x0;
        v1[0] = layout->x1 - 0.5f*(layout->tickX - layout->x1) - 0.5f;
        v2[0] = layout->x1;
        v3[0] = layout->tickX - 0.5f*(layout->tickX - layout->x1) - 0.5f;
        v4[0] = layout->tickX;

        static const ushort tickLinesWithLabel[] = { 0, 4 };
        static const ushort tickLinesWoLabel[] = { 2, 3 };

        size_t ic;
        for (ic = 0; ic < m_tickValues.size(); ic++)
        {
                float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic) - 0.5f);

                // Dynamic coordinates for  tickmarks-lines
                v0[1] = v1[1] = v2[1] = v3[1] = v4[1] = y0;

                UniformFloat uniformColor("u_color", Color4f(m_color));
                shaderProgram->applyUniform(oglContext, uniformColor);
                const ushort * linesConnects;

                if ( m_visibleTickLabels[ic])
                {
                    linesConnects = tickLinesWithLabel;
                }
                else
                {
                    linesConnects = tickLinesWoLabel;
                }

#ifdef CVF_OPENGL_ES
                glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, linesConnects);
#else
                glDrawRangeElements(GL_LINES, 0, 4, 2, GL_UNSIGNED_SHORT, linesConnects);
#endif
        }
    }

    glDisableVertexAttribArray(ShaderProgram::VERTEX);

    CVF_TIGHT_ASSERT(shaderProgram.notNull());
    shaderProgram->useNoProgram(oglContext);

    // Reset render states
    Depth resetDepth;
    resetDepth.applyOpenGL(oglContext);

    CVF_CHECK_OGL(oglContext);
}
Esempio n. 10
0
//--------------------------------------------------------------------------------------------------
/// Do setup of the texture
/// 
/// \warning Requires at least OpenGL2 capability. Will assert if this condition is not met.
/// \warning Default unpack alignment (GL_UNPACK_ALIGNMENT) is 4 and 4 byte values is preferred, thus
///          we should always use RGBA when having byte textures as GPUs are optimized to 32 bit values
//--------------------------------------------------------------------------------------------------
bool Texture::setupTexture(OpenGLContext* oglContext)
{
    CVF_CALLSITE_OPENGL(oglContext);
    CVF_ASSERT(OglRc::safeOglId(m_oglRcTexture.p()) == 0);

    const OpenGLCapabilities* oglCaps = oglContext->capabilities();
    CVF_ASSERT(oglCaps->supportsOpenGL2());

    CVF_CLEAR_OGL_ERROR(oglContext);

    // Is manual generation of mipmaps through glGenerateMipmap() supported?
    bool supportsGenerateMipmapFunc = oglCaps->hasCapability(OpenGLCapabilities::GENERATE_MIPMAP_FUNC);
    
    m_hasMipmaps = false;
    
    m_oglRcTexture = oglContext->resourceManager()->createOglRcTexture(oglContext);
    
    bind(oglContext);

    CVF_ASSERT(m_image.isNull() || (m_image->width() == m_width && m_image->height() == m_height));

    switch (m_textureType)
    {
        case TEXTURE_2D:
        {
            if (m_internalFormat == DEPTH_COMPONENT16 || m_internalFormat == DEPTH_COMPONENT24 || m_internalFormat == DEPTH_COMPONENT32)
            {
                CVF_ASSERT(m_image.isNull());
                CVF_ASSERT(!m_enableMipmapGeneration);
                glTexImage2D(GL_TEXTURE_2D, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
            }
            else if (m_internalFormat == DEPTH24_STENCIL8)
            {
#ifndef CVF_OPENGL_ES
                
                CVF_ASSERT(m_image.isNull());
                CVF_ASSERT(!m_enableMipmapGeneration);
                glTexImage2D(GL_TEXTURE_2D, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
#else
                CVF_FAIL_MSG("Not supported on IOS");
#endif
            }
            else
            {
#ifndef CVF_OPENGL_ES
                if (!supportsGenerateMipmapFunc)
                {
                    // Explicit mipmap generation not supported so must configure before specifying texture image
                    if (m_enableMipmapGeneration && m_image.notNull())  
                    {
                        glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 
                        m_hasMipmaps = true;
                    }
                    else
                    {
                        glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); 
                    }
                }
#endif

                glTexImage2D(GL_TEXTURE_2D, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.notNull() ? m_image->ptr() : 0);

                if (supportsGenerateMipmapFunc && m_enableMipmapGeneration && m_image.notNull())
                {
                    glGenerateMipmap(GL_TEXTURE_2D);
                    m_hasMipmaps = true;
                }
            }

            break;
        }

        case TEXTURE_RECTANGLE:
        {
#ifndef CVF_OPENGL_ES
            CVF_ASSERT(!m_enableMipmapGeneration);

            if (m_internalFormat == DEPTH_COMPONENT16 || m_internalFormat == DEPTH_COMPONENT24 || m_internalFormat == DEPTH_COMPONENT32)
            {
                CVF_ASSERT(m_image.isNull());
                glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
            }
            else
            {
                glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_image.notNull() ? m_image->ptr() : 0);
            }
#else
            CVF_FAIL_MSG("Not supported on iOS");
#endif
            break;
        }

        case TEXTURE_CUBE_MAP:
        {
            if (m_cubeMapImages.size() == 0)
            {
                uint i;
                for (i = 0; i < 6; i++)
                {
                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
                }
            }
            else
            {
#ifndef CVF_OPENGL_ES
                if (!supportsGenerateMipmapFunc)
                {
                    if (m_enableMipmapGeneration)
                    {
                        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE); 
                        m_hasMipmaps = true;
                    }
                    else
                    {
                        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_FALSE); 
                    }
                }
#endif

                CVF_ASSERT(m_cubeMapImages.size() == 6);
                uint i;
                for (i = 0; i < 6; i++)
                {
                    ref<TextureImage> img = m_cubeMapImages[i];
                    CVF_ASSERT(img.notNull());

                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormatOpenGL(), static_cast<GLsizei>(m_width), static_cast<GLsizei>(m_height), 0, GL_RGBA, GL_UNSIGNED_BYTE, img->ptr());
                }

                if (supportsGenerateMipmapFunc && m_enableMipmapGeneration)
                {
                    glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
                    m_hasMipmaps = true;
                }
            }

            break;
        }
    }

    if (CVF_TEST_AND_REPORT_OPENGL_ERROR(oglContext, "Setup texture"))
    {
        deleteTexture(oglContext);
        return false;
    }

    m_versionTick++;

    return true;
}
Esempio n. 11
0
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayTextBox::renderBackgroundAndBorder(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software)
{
    CVF_CALLSITE_OPENGL(oglContext);

    // Prepare 2D pixel exact projection to draw texts
    Camera projCam;
    projCam.setViewport(position.x(), position.y(), size.x(), size.y());
    projCam.setProjectionAsPixelExact2D();
    projCam.setViewMatrix(Mat4d::IDENTITY);

    // Turn off depth test
    RenderStateDepth depth(false, RenderStateDepth::LESS, false);
    depth.applyOpenGL(oglContext);

    ref<ShaderProgram> backgroundShader;
    float vertexArray[12];

    projCam.viewport()->applyOpenGL(oglContext, Viewport::DO_NOT_CLEAR);

    if (software)
    {
        if (ShaderProgram::supportedOpenGL(oglContext))
        {
            ShaderProgram::useNoProgram(oglContext);
        }

#ifndef CVF_OPENGL_ES
        RenderStateMaterial_FF mat;
        mat.enableColorMaterial(true);
        mat.applyOpenGL(oglContext);

        RenderStateLighting_FF light(false);
        light.applyOpenGL(oglContext);
#endif
        projCam.applyOpenGL();
    }
    else
    {
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glEnableVertexAttribArray(ShaderProgram::VERTEX);
        glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);

        backgroundShader = oglContext->resourceManager()->getLinkedUnlitColorShaderProgram(oglContext);
        if (backgroundShader->useProgram(oglContext))
        {
            MatrixState projMatrixState(projCam);
            backgroundShader->clearUniformApplyTracking();
            backgroundShader->applyFixedUniforms(oglContext, projMatrixState);
        }
    }

    Vec3f min(1.0f, 1.0f, 0.0f);
    Vec3f max(static_cast<float>(size.x() - 1), static_cast<float>(size.y() - 1), 0.0f);

    // Setup the vertex array
    float* v1 = &vertexArray[0];
    float* v2 = &vertexArray[3];
    float* v3 = &vertexArray[6];
    float* v4 = &vertexArray[9];
    v1[0] = min.x();
    v1[1] = min.y();
    v1[2] = 0.0f;
    v2[0] = max.x();
    v2[1] = min.y();
    v2[2] = 0.0f;
    v3[0] = max.x();
    v3[1] = max.y();
    v3[2] = 0.0f;
    v4[0] = min.x();
    v4[1] = max.y();
    v4[2] = 0.0f;

    if (m_drawBackground)
    {
        if (software)
        {
#ifndef CVF_OPENGL_ES
            glColor4fv(m_backgroundColor.ptr());
            glBegin(GL_TRIANGLE_FAN);
            glVertex3fv(v1);
            glVertex3fv(v2);
            glVertex3fv(v3);
            glVertex3fv(v4);
            glEnd();
#endif
        }
        else
        {
            // Draw background
            UniformFloat backgroundColor("u_color", Color4f(m_backgroundColor));
            backgroundShader->applyUniform(oglContext, backgroundColor);
            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
        }
    }

    if (m_drawBorder)
    {
        if (software)
        {
#ifndef CVF_OPENGL_ES
            glColor3fv(m_borderColor.ptr());
            glBegin(GL_LINE_LOOP);
            glVertex3fv(v1);
            glVertex3fv(v2);
            glVertex3fv(v3);
            glVertex3fv(v4);
            glEnd();
#endif
        }
        else
        {
            UniformFloat borderColor("u_color", Color4f(m_borderColor));
            backgroundShader->applyUniform(oglContext, borderColor);

            RenderStateLine line(static_cast<float>(3));
            line.applyOpenGL(oglContext);

            // Draw border
            glDrawArrays(GL_LINE_LOOP, 0, 4);

            RenderStateLine resetLine;
            resetLine.applyOpenGL(oglContext);
        }
    }
}
//--------------------------------------------------------------------------------------------------
/// Render a semi transparent background frame
//--------------------------------------------------------------------------------------------------
void InternalLegendRenderTools::renderBackgroundUsingShaders(OpenGLContext* oglContext,
                                                     const MatrixState& matrixState,
                                                     const Vec2f& size,
                                                     const Color4f& backgroundColor,
                                                     const Color4f& backgroundFrameColor)
{
    CVF_CALLSITE_OPENGL(oglContext);

    RenderStateDepth depth(false);
    depth.applyOpenGL(oglContext);

    RenderStateLine line(1.0f);
    line.applyOpenGL(oglContext);

    RenderStateBlending blend;
    blend.configureTransparencyBlending();
    blend.applyOpenGL(oglContext);

    // Shader program

    ref<ShaderProgram> shaderProgram = oglContext->resourceManager()->getLinkedUnlitColorShaderProgram(oglContext);
    CVF_TIGHT_ASSERT(shaderProgram.notNull());

    if (shaderProgram->useProgram(oglContext))
    {
        shaderProgram->clearUniformApplyTracking();
        shaderProgram->applyFixedUniforms(oglContext, matrixState);
    }

    std::array<Vec3f, 4> vertexArray ={
        Vec3f(1       ,        1, 0.0f),
        Vec3f(size.x(),        1, 0.0f),
        Vec3f(size.x(), size.y(), 0.0f),
        Vec3f(1       , size.y(), 0.0f),
    };


    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glEnableVertexAttribArray(ShaderProgram::VERTEX);
    glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray.data());

    // Draw frame background

    UniformFloat backgroundColorUniform("u_color", backgroundColor);
    shaderProgram->applyUniform(oglContext, backgroundColorUniform);

    // Triangle indices for the frame background

    static const ushort backgroundTriangleIndices[] = { 0, 1, 2,  2, 3, 0};

    glDrawRangeElements(GL_TRIANGLES, 0, 3, 6, GL_UNSIGNED_SHORT, backgroundTriangleIndices);


    // Draw frame border lines

    UniformFloat uniformColor("u_color", backgroundFrameColor);
    shaderProgram->applyUniform(oglContext, uniformColor);

    static const ushort frameLineIndices[] = { 0, 1,
                                               1, 2,
                                               2, 3,
                                               3, 0 };

    glDrawRangeElements(GL_LINES, 0, 3, 8, GL_UNSIGNED_SHORT, frameLineIndices);

    glDisableVertexAttribArray(ShaderProgram::VERTEX);

    CVF_TIGHT_ASSERT(shaderProgram.notNull());
    shaderProgram->useNoProgram(oglContext);

    // Reset render states
    RenderStateDepth resetDepth;
    resetDepth.applyOpenGL(oglContext);

    RenderStateLine resetLine;
    resetLine.applyOpenGL(oglContext);

    RenderStateBlending resetblend;
    resetblend.applyOpenGL(oglContext);

    CVF_CHECK_OGL(oglContext);
}