Qt OpenGL编程平台依赖

时间:2014-02-04 17:51:10

标签: c++ qt opengl

我对Qt OpenGL编程的依赖性或要求有一些问题。我正在使用带有OpenGL和MSVC 2012 x64的Qt OpenGL 5.1

  1. 我的第一个问题是在运行时选择和使用正确的图形设备适配器。我的电脑有2个图形设备,其中一个是板载英特尔,另一个是高级NVidia GeForce GT740M。我可以使用我的高级显卡使用NVidia控制面板来激活Geforce。但我知道我必须使用我的软件。我怎么能用Qt OpenGL
  2. 来做
  3. 我的第二个问题是关于OpenGl Extensions。我使用的是基本的OpenGL功能,但我的软件仅适用于至少支持OpenGl 4.0的高级显卡。我在下面使用这些OpenGL扩展。
  4. 着色

    顶点着色器

    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;
    }
    

    片段着色器

    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;
    }
    

    附图说明

    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();
    }
    

    材料

    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);
    }
    

2 个答案:

答案 0 :(得分:1)

  1. Qt中没有这样的功能,可能永远不会 - 你不能将一个图形卡用于一个程序而另一个用于第二个程序,所以你需要全局更改它。

  2. 制服自4.3以来一直在核心OpenGL中,并且从3.3开始作为arb扩展,这意味着你至少需要那个版本的opengl才能使用它们。

答案 1 :(得分:1)

1)这很棘手,您(在Windows环境中)为您的设备创建DC(http://msdn.microsoft.com/en-us/library/windows/desktop/dd183490(v=vs.85).aspx),然后使用Windows API从HDC获取HWND。 / p>

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

然后继承QWidget以获取受保护成员转换的访问权限。使用此方法,使用此成员创建QWidget,如此解决方案中所述:如何使用hwnd作为父级创建qwidget。在这个例子中,我调用了QWidgetWrapper的子类。

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

请注意,Wld是Qt中的typedef,用于"平台相关的窗口标识符"。 (来源:https://stackoverflow.com/a/10376968/1938163

然后,您最终可以创建与之关联的QGLContext。

2)对于您的代码,我认为您至少需要OpenGL 4.3,您可以使用http://qt-project.org/doc/qt-4.8/qglformat.html#OpenGLVersionFlag-enum

进行检查