Skip to content
Archive of posts filed under the Qt Development category.

iControlPad support libarary for Qt

The iControlPad didn’t work in keyboard mode with Symbian devices, so I decided to make my own support library for it. The iControlPad is working on SPP mode as default, and that mode support also the analog nubs, so I decided to write support for it.

You can get the support library from GitHub: https://github.com/Summeli/iCP4Qt

Integrating the library to your project

You only need to include the iCP4Qt pri file inside your project file

include (iCP4Qt.pri)

Connecting to the iControlPad

Connecting to the iControlPad is easy. Crete the iControlpad client, and then call connect:

client = new iControlPadClient(this); //the keyEvents will be delivered to the parent
client->discoverAndConnect( iControlPadClient::iCPReadDigital );

Once connected, whe library will emit singal:

void connectedToiControlPad();

And if the iControlPad was not found, then it’ll emit

void iControlPadNotFound();

Continue reading ‘iControlPad support libarary for Qt’ »

Fast blit with OpenGl ES and Qt

In my previous post I wrote about blit with opengl es 2.0 texture upload. However I noticed that using just Qt’s QGLWidget and implementing only the paintEvent is as fast as the texture upload with pure OpenGL ES API.

I guess that QGLWidget is making the drawing via OpenGL, since the performance seems to be equal to the texture blitting with the standard OpenGL ES API and texture uploading.

The whole blit is taking less than 6ms, so it’s good enough for my emulator ports. The memcopy could probably be optimized away from the blit, but that’s not the bottleneck at least in the current AntSnes implementation.

Here’s an example from the AntSnes how to blit with QGLWidget and paintevent.

void AntSnesQt::blit(int width, int height)
{
    if (buf != NULL)
    {
        delete buf;
        buf = NULL;
    }

    //memcopy into the new buffer, which will be blit to to screen in the paintEvent.
    buf = new QImage(GFX.Screen, width, height, GFX.RealPitch,
            QImage::Format_RGB16);

    //calling the repaint will cause a new paintEvent into the widget
    repaint();
}
void AntSnesQt::paintEvent(QPaintEvent *)
{
    QPainter painter;
    painter.begin(this);

    if (buf != NULL)
    {
        QRect target(96, 0, 448, 360);
        QRect source(0, 0, buf->width(), buf->height());
        painter.drawImage(target, *buf, source);
     }
     painter.end
}

Fast Blit with OpenGL ES 2.0 and texture uploading

OpenGL ES 2.0 is fully shader based, which means you can’t draw any geometry without having the appropriate shaders loaded and bound. This means there is more setup code required to render than there was in OpenGL ES 1.1 with fixed pipeline.

Setting up the OpenGL ES 2.0 pipeline.

void glBlitter::initializeGL ()
{
    GLuint fragmentShader;
    GLuint vertexShader;
    GLint linked;

    glDepthFunc(GL_ALWAYS);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_CULL_FACE);

    //Vertex shader
    QString srcVertShader =
        "attribute vec4 a_position; \n"
        "attribute vec2 a_texCoord; \n"
        "varying vec2 v_texCoord; \n"
        "void main() \n"
        "{ \n"
        " gl_Position = a_position; \n"
        " v_texCoord = a_texCoord; \n"
        "} \n";

    //fragment shader
    QString srcFragShader =
        "precision mediump float; \n"
        "varying vec2 v_texCoord; \n"
        "uniform sampler2D s_texture; \n"
        "void main() \n"
        "{ \n"
        " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
        "} \n";

    // Create the program object
    m_program = glCreateProgram();
    if(!m_program)
      return;

    // Load the shaders
    vertexShader = loadShader(qPrintable(srcVertShader), GL_VERTEX_SHADER);
    fragmentShader = loadShader(qPrintable(srcFragShader), GL_FRAGMENT_SHADER);

    glAttachShader(m_program, vertexShader);
    glAttachShader(m_program, fragmentShader);

    // Link the program
    glLinkProgram(m_program);

    // Check the link status
    glGetProgramiv(m_program, GL_LINK_STATUS, &linked);
    if(!linked){
      GLint infoLen = 0;
      glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &infoLen);
      if(infoLen > 1){
        char* infoLog = (char*)malloc(sizeof(char) * infoLen);
        glGetProgramInfoLog(m_program, infoLen, NULL, infoLog);
        qDebug() << infoLog;
        free(infoLog);
      }
      glDeleteProgram(m_program);
      return;
    }

    m_posLoc = glGetAttribLocation ( m_program, "a_position" );
    m_texLoc = glGetAttribLocation ( m_program, "a_texCoord" );

    // Get the sampler location
    m_samplerLoc = glGetUniformLocation ( m_program, "s_texture" );

    //Init textures to plot in the paintgl function
    InitTextures();

    glClearColor(.3,.4,.6,1);

}

The actual drawing is done in the QGLWidget’s paintGL function. The OpenGL ES 2.0 guild line says that you should use upload textures with sizes of power of two. However you don’t have blit the whole texture. You can create a texCoords matrix for using only a part of the uploaded texture. There’s a really good tutorial for texturemapping in iPhone Development Blog. It’s for iPhone and it’s for OpenGL ES 1.1 or so, but the vector math in binding the textures etc. is still valid with OpenGL ES 2.0.

Continue reading ‘Fast Blit with OpenGL ES 2.0 and texture uploading’ »

Building Symbian Projects with QtSDK

All new Symbian SDKs are now distributed inside the new QtSDK, so that should be my primary build environment. The new QtSDK also includes an updated version of GCCE (4.x), and new sbsv2 build, which is a lot better than the old symbian abld-build. With this tutorial you can still build your old symbian projects from mmp-files.

Configuring the new sbsv2 build to the QtSDK

Here’s an example of my setEnv.bat. In this case the QtSDK was installed into c-drive

SET PATH=C:\QtSDK\Symbian\tools\sbs\bin;C:\QtSDK\Symbian\tools\perl\bin;C:\QtSDK\Symbian\SDKs\Symbian3Qt473\epoc32\gcc\bin;C:\QtSDK\Symbian\SDKs\Symbian3Qt473\epoc32\tools;%PATH%
SET EPOCROOT=\QtSDK\Symbian\SDKs\Symbian3Qt473\
SET SBS_MINGW=C:\QtSDK\Symbian\tools\sbs\win32\mingw
SET SBS_HOME=C:\QtSDK\Symbian\tools\sbs
SET SBS_GCCE441BIN=C:\QtSDK\Symbian\tools\gcce4\bin

call C:\QtSDK\Symbian\SDKs\Symbian3Qt473\bin\qtenvS3.bat

Modifying bld.inf

The sbsv2 does not understand PRJ_PLATFORMS lists, so you’ll have to remove those. I left only PRJ_MMPFILES definitions in the bld.inf files.

Building with sbsv2

Here’s a list of couple of useful sbsv2 build command

sbs -c armv5_udeb_gcce                       - debug build with GCCE
sbs reallyclean                                    - cleans everthing
sbs clean

Continue reading ‘Building Symbian Projects with QtSDK’ »

Implementing AntSnes with Qt part 6: Final touch, using stylesheets

The Qt’s default style tries to look as much your original S60 theme as possible. The big problem is that each phone can have very different theme, and then your application might look really bad.

The good news is that you can write your own style, and use it in your own application.

Here’s a “before image” with my Symbian foundation default theme and AtnSnes:

AntSnes with Symbian default theme

AntSnes with default theme

The default theme has a lot of problems. For example the default blue color is used, when Qt doesn’t know what color to use.  The donw arrow is also way too big in the default Qt theme.

AntSnes with style sheet

The Style sheet makes a huge difference in here. Now I can add some nice application logo’s etc, and I know that the color fits the application style. For example using that black and green AntSnes text wouldn’t really work with my default theme ;-)

Continue reading ‘Implementing AntSnes with Qt part 6: Final touch, using stylesheets’ »