Qt OpenGL Programming Platform Dependencies

I've some problem about dependencies or requirements for Qt OpenGL Programming. I am using Qt OpenGL 5.1 with OpenGL with MSVC 2012 x64

  1. My first problem is about selecting and using the right graphics device adapter during runtime. My pc has 2 graphics devices, one of them is an onboard Intel and other one is an advanced NVidia GeForce GT740M. I can use my advanced graphics card using NVidia control panel to activate Geforce always. But I know I must do it my my software. How can I do it with Qt OpenGL
  2. My second problem is about OpenGl Extensions. I am using basic OpenGL functions but my software is only working on advanced graphics cards which has at least OpenGl 4.0 support. I am using these OpenGL Extensions below.

SHADERS

The Vertex Shader

uniform mat4 u_mat4_model;
uniform mat4 u_mat4_view;
uniform mat4 u_mat4_proj;

varying vec3 N;
varying vec3 v;

void main()
{
    mat4 model_view = u_mat4_view * u_mat4_model;
    mat4 model_view_proj = u_mat4_proj * model_view;

    v = model_view * gl_Vertex;
    N = normalize(gl_NormalMatrix * gl_Normal);

    gl_Position = model_view_proj * gl_Vertex;
}

The Fragment Shader

varying vec3 N;
varying vec3 v;

void main (void)
{
    vec3 L = normalize(gl_LightSource[0].position.xyz - v);
    vec3 E = normalize(-v);
    vec3 R = normalize(-reflect(L,N));

    vec4 Iambi = gl_FrontLightProduct[0].ambient;
    vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
    vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0), gl_FrontMaterial.shininess);

    gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iambi + Idiff + Ispec;
}

DRAWING

void Renderer::Render(Mesh *mesh, Material *material, RenderMode rm)
{
    material->Bind();

    if (mesh->GetVertexCount() > 0)
    {
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(3, GL_FLOAT, 0, mesh->GetVertices().constData());
    }
    else
    {
        return;
    }

    if (mesh->GetColorCount() > 0)
    {
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(3, GL_FLOAT, 0, mesh->GetColors().constData());
    }

    if (mesh->GetNormalCount() > 0)
    {
        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(GL_FLOAT, 0, mesh->GetNormals().constData());
    }

    if (m_rm.Dotted() && rm.Dotted())
    {
        glDrawArrays(GL_POINTS, 0, mesh->GetVertexCount());
    }

    if (m_rm.Wired() && rm.Wired())
    {
        glDrawElements(GL_LINES, mesh->GetLineCount(), GL_UNSIGNED_INT, mesh->GetLines().constData());
    }


    if (m_rm.Solid() && rm.Solid())
    {
        glDrawElements(GL_TRIANGLES, mesh->GetFaceCount(), GL_UNSIGNED_INT, mesh->GetFaces().constData());
    }

    material->Unbind();
}

MATERIAL

void Material::Bind()
{
    glEnable(GL_COLOR_MATERIAL);

    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,   m_ambient);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,   m_diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,  m_specular);
    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION,  m_emission);
    glMateriali(GL_FRONT_AND_BACK,  GL_SHININESS, m_shininess);
}

void Material::Unbind()
{
    glDisable(GL_COLOR_MATERIAL);
}

LIGHT

void Light::Bind()
{
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    // Işık Pozisyon ve Yönünü Transformation sınıfından al
    QVector3D pos_v = m_transform.GetPosition();
    QVector3D dir_v = m_transform.GetDirection();

    float l_position[] = { pos_v.x(), pos_v.y(), pos_v.z()};
    float l_direction[] = { dir_v.x(), dir_v.y(), dir_v.z()};

    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,     m_lm_ambient);
    glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0);
    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,     0.0);

    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, l_direction);
    glLighti(GL_LIGHT0,  GL_SPOT_EXPONENT,  m_spot_exponent);
    glLighti(GL_LIGHT0,  GL_SPOT_CUTOFF,    m_spot_cut_off);

    glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,  m_constant);
    glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION,    m_lineer);
    glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, m_quadratic);

    glLightfv(GL_LIGHT0, GL_POSITION, l_position);
    glLightfv(GL_LIGHT0, GL_AMBIENT,  m_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  m_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, m_specular);
}

void Light::Unbind()
{
    glDisable(GL_LIGHTING);
    glDisable(GL_LIGHT0);
}

Upvotes: 2

Views: 518

Answers (2)

Marco A.
Marco A.

Reputation: 43662

1) This is tricky, you'll have (in a Windows environment) to create a DC for your device (http://msdn.microsoft.com/en-us/library/windows/desktop/dd183490(v=vs.85).aspx) and then using the Windows API, get the HWND from the HDC.

HWND handle = WindowFromDC(hdc);
assert(handle != NULL);

Then subclass QWidget to get access to the protected member convert. Using this, create the QWidget using this member as described in this solution: How to create a qwidget with a hwnd as parent. In this example, I've called the subclass for QWidgetWrapper.

QWidgetWrapper *w = new QWidgetWrapper();
w->create((Wld)main_window);

Note that Wld is a typedef in Qt for "Platform dependent window identifier". (source: https://stackoverflow.com/a/10376968/1938163)

You can then finally create a QGLContext associated with it.

2) For your code I suppose you will need at least OpenGL 4.3, you can check this with http://qt-project.org/doc/qt-4.8/qglformat.html#OpenGLVersionFlag-enum

Upvotes: 1

Alex Telishev
Alex Telishev

Reputation: 2274

  1. There is no such functionality in Qt and probably never will - you cannot use one graphic card for one program and other for second program, so you need to change it globally.

  2. uniforms are in core OpenGL since 4.3, and as arb extension since 3.3, that means you'll need at least that version of opengl in order to use them.

Upvotes: 1

Related Questions