Пример #1
0
PainterOGL2::PainterOGL2()
{
    m_drawProgram = nullptr;
    resetState();

    m_drawTexturedProgram = PainterShaderProgramPtr(new PainterShaderProgram);
    assert(m_drawTexturedProgram);
    m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
    m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader);
    m_drawTexturedProgram->link();

    m_drawSolidColorProgram = PainterShaderProgramPtr(new PainterShaderProgram);
    assert(m_drawSolidColorProgram);
    m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader);
    m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader);
    m_drawSolidColorProgram->link();

    PainterShaderProgram::release();
}
Пример #2
0
void Map::draw(const Rect& rect)
{
    if(!m_framebuffer) {
        m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));


        program = PainterShaderProgramPtr(new PainterShaderProgram);
        program->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
        program->addShaderFromSourceFile(Shader::Fragment, "/shadertest.frag");
        assert(program->link());
    }

    g_painter.setColor(Fw::white);
    m_framebuffer->bind();

    // draw offsets
    LocalPlayerPtr localPlayer = g_game.getLocalPlayer();
    if(localPlayer)
        m_drawOffset = localPlayer->getWalkOffset();

    //TODO: cache first/last visible floor
    // draw from bottom floors to top floors
    int firstFloor = getFirstVisibleFloor();
    const int lastFloor = MAX_Z-1;
    for(int iz = lastFloor; iz >= firstFloor; --iz) {
        // draw tiles like linus pauling's rule order
        const int numDiagonals = m_size.width() + m_size.height() - 1;
        for(int diagonal = 0; diagonal < numDiagonals; ++diagonal) {
            // loop through / diagonal tiles
            for(int ix = std::min(diagonal, m_size.width() - 1), iy = std::max(diagonal - m_size.width(), 0); ix >= 0 && iy < m_size.height(); --ix, ++iy) {
                // position on current floor
                Position tilePos(m_centralPosition.x + (ix - m_centralOffset.x), m_centralPosition.y + (iy - m_centralOffset.y), m_centralPosition.z);
                // adjust tilePos to the wanted floor
                tilePos.perspectiveUp(m_centralPosition.z - iz);
                //TODO: cache visible tiles, m_tiles[] has a high cost (50% fps decrease)
                if(const TilePtr& tile = m_tiles[tilePos]) {
                    // skip tiles that are behind another tile
                    //if(isCompletlyCovered(tilePos, firstFloor))
                    //    continue;
                    tile->draw(positionTo2D(tilePos) - m_drawOffset);
                }
            }
        }

        // after drawing all tiles, draw shots
        for(const MissilePtr& shot : m_missilesAtFloor[iz]) {
            Position missilePos = shot->getPosition();
            shot->draw(positionTo2D(missilePos) - m_drawOffset);
        }
    }

    m_framebuffer->release();


    g_painter.setCustomProgram(program);
    g_painter.setColor(Fw::white);
    m_framebuffer->draw(rect);
    g_painter.releaseCustomProgram();

    // calculate stretch factor
    float horizontalStretchFactor = rect.width() / (float)(m_visibleSize.width() * NUM_TILE_PIXELS);
    float verticalStretchFactor = rect.height() / (float)(m_visibleSize.height() * NUM_TILE_PIXELS);

    // draw player names and health bars
    //TODO: this must be cached with creature walks
    for(int x = 0; x < m_visibleSize.width(); ++x) {
        for(int y = 0; y < m_visibleSize.height(); ++y) {
            Position tilePos = Position(m_centralPosition.x + (x - m_centralOffset.x + 1), m_centralPosition.y + (y - m_centralOffset.y + 1), m_centralPosition.z);
            if(const TilePtr& tile = m_tiles[tilePos]) {
                auto creatures = tile->getCreatures();

                if(creatures.size() == 0)
                    continue;

                for(const CreaturePtr& creature : creatures) {
                    Point p((m_centralOffset.x - 1 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation(),
                            (m_centralOffset.y - 1 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation());

                    if(creature != localPlayer) {
                        p += creature->getWalkOffset() - m_drawOffset;
                    }

                    creature->drawInformation(rect.x() + p.x*horizontalStretchFactor, rect.y() + p.y*verticalStretchFactor, isCovered(tilePos, firstFloor), rect);
                }
            }
        }
    }
}
Пример #3
0
PainterShaderProgramPtr PainterShaderManager::createShader()
{
    if(!g_graphics.canUseShaders())
        return nullptr;
    return PainterShaderProgramPtr(new PainterShaderProgram);
}
Пример #4
0
void Creature::draw(const Point& p, const Rect&)
{
    if(m_showVolatileSquare) {
        g_painter.setColor(m_volatileSquareColor);
        g_painter.drawBoundingRect(Rect(p + m_walkOffset - Point(m_type->parameters[ThingType::DisplacementX], m_type->parameters[ThingType::DisplacementY]) + 3, Size(28, 28)), 2);
    }

    if(m_showStaticSquare) {
        g_painter.setColor(m_staticSquareColor);
        g_painter.drawBoundingRect(Rect(p + m_walkOffset - Point(m_type->parameters[ThingType::DisplacementX], m_type->parameters[ThingType::DisplacementY]) + 1, Size(32, 32)), 2);
    }

    g_painter.setColor(Fw::white);
    if(!outfitProgram) {
        outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
        outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
        outfitProgram->addShaderFromSourceFile(Shader::Fragment, "/game_shaders/outfit.frag");
        assert(outfitProgram->link());
        outfitProgram->bindUniformLocation(HEAD_COLOR_UNIFORM, "headColor");
        outfitProgram->bindUniformLocation(BODY_COLOR_UNIFORM, "bodyColor");
        outfitProgram->bindUniformLocation(LEGS_COLOR_UNIFORM, "legsColor");
        outfitProgram->bindUniformLocation(FEET_COLOR_UNIFORM, "feetColor");
        outfitProgram->bindUniformLocation(MASK_TEXTURE_UNIFORM, "maskTexture");
    }

    // Render creature
    if(m_outfit.getCategory() == ThingsType::Creature) {
        for(m_yPattern = 0; m_yPattern < m_type->dimensions[ThingType::PatternY]; m_yPattern++) {

            // continue if we dont have this addon.
            if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
                continue;

            g_painter.setCustomProgram(outfitProgram);

            outfitProgram->bind();
            outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
            outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
            outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
            outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());

            for(int h = 0; h < m_type->dimensions[ThingType::Height]; h++) {
                for(int w = 0; w < m_type->dimensions[ThingType::Width]; w++) {
                    int spriteId = m_type->getSpriteId(w, h, 0, m_xPattern, m_yPattern, m_zPattern, m_animation);
                    if(!spriteId)
                        continue;
                    TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
                    if(!spriteTex)
                        continue;

                    if(m_type->dimensions[ThingType::Layers] > 1) {
                        int maskId = m_type->getSpriteId(w, h, 1, m_xPattern, m_yPattern, m_zPattern, m_animation);
                        TexturePtr maskTex = g_sprites.getSpriteTexture(maskId);
                        outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
                    }

                    Rect drawRect(((p + m_walkOffset).x - w*32) - m_type->parameters[ThingType::DisplacementX],
                                ((p + m_walkOffset).y - h*32) - m_type->parameters[ThingType::DisplacementY],
                                32, 32);
                    g_painter.drawTexturedRect(drawRect, spriteTex);
                }
            }

            g_painter.releaseCustomProgram();
        }
    }
    else if(m_outfit.getCategory() == ThingsType::Item) {
        for(int l = 0; l < m_type->dimensions[ThingType::Layers]; l++)
            internalDraw(p + m_walkOffset, l);
    }
    else if(m_outfit.getCategory() == ThingsType::Effect)
        internalDraw(p + m_walkOffset, 0);
}
Пример #5
0
void Creature::draw(const Point& p)
{
    // TODO: activate on attack, follow, discover how 'attacked' works
    if(m_showSquareColor) {
        g_painter.setColor(Outfit::getColor(m_squareColor));
        g_painter.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2);
    }

    if(!outfitProgram) {
        outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
        outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
        outfitProgram->addShaderFromSourceFile(Shader::Fragment, "/outfit.frag");
        assert(outfitProgram->link());
        outfitProgram->bindUniformLocation(HEAD_COLOR_UNIFORM, "headColor");
        outfitProgram->bindUniformLocation(BODY_COLOR_UNIFORM, "bodyColor");
        outfitProgram->bindUniformLocation(LEGS_COLOR_UNIFORM, "legsColor");
        outfitProgram->bindUniformLocation(FEET_COLOR_UNIFORM, "feetColor");
        outfitProgram->bindUniformLocation(MASK_TEXTURE_UNIFORM, "maskTexture");
    }

    // Render creature
    for(m_yPattern = 0; m_yPattern < m_type->dimensions[ThingType::PatternY]; m_yPattern++) {

        // continue if we dont have this addon.
        if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
            continue;

        g_painter.setCustomProgram(outfitProgram);

        outfitProgram->bind();
        outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
        outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
        outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
        outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());

        for(int yi = 0; yi < m_type->dimensions[ThingType::Height]; yi++) {
            for(int xi = 0; xi < m_type->dimensions[ThingType::Width]; xi++) {
                int sprIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases])
                                * m_type->dimensions[ThingType::PatternZ] + m_zPattern)
                                * m_type->dimensions[ThingType::PatternY] + m_yPattern)
                                * m_type->dimensions[ThingType::PatternX] + m_xPattern)
                                * m_type->dimensions[ThingType::Layers] + 0)
                                * m_type->dimensions[ThingType::Height] + yi)
                                * m_type->dimensions[ThingType::Width] + xi;
                if(m_type->dimensions[ThingType::Layers] > 1) {
                    int maskIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases])
                                    * m_type->dimensions[ThingType::PatternZ] + m_zPattern)
                                    * m_type->dimensions[ThingType::PatternY] + m_yPattern)
                                    * m_type->dimensions[ThingType::PatternX] + m_xPattern)
                                    * m_type->dimensions[ThingType::Layers] + 1)
                                    * m_type->dimensions[ThingType::Height] + yi)
                                    * m_type->dimensions[ThingType::Width] + xi;
                    int spriteId = m_type->sprites[maskIndex];
                    if(!spriteId)
                        continue;
                    TexturePtr maskTex = g_sprites.getSpriteTexture(spriteId);
                    outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
                }

                int spriteId = m_type->sprites[sprIndex];
                if(!spriteId)
                    continue;

                TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);

                Rect drawRect(((p + m_walkOffset).x - xi*32) - m_type->parameters[ThingType::DisplacementX],
                            ((p + m_walkOffset).y - yi*32) - m_type->parameters[ThingType::DisplacementY],
                            32, 32);
                g_painter.drawTexturedRect(drawRect, spriteTex);
            }
        }

        g_painter.releaseCustomProgram();
    }
}