【问题标题】:Qt OpenGL Programming Platform DependenciesQt OpenGL 编程平台依赖
【发布时间】:2014-02-04 17:51:10
【问题描述】:

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

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

着色器

顶点着色器

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

灯光

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

【问题讨论】:

    标签: c++ qt opengl


    【解决方案1】:
    1. Qt 中没有这样的功能,而且可能永远不会 - 您不能将一张显卡用于一个程序而另一张用于第二个程序,因此您需要全局更改它。

    2. uniforms 自 4.3 起在核心 OpenGL 中,自 3.3 起作为 arb 扩展,这意味着您至少需要该版本的 opengl 才能使用它们。

    【讨论】:

    • 实际上我在问“我的程序刚刚启动时如何在全球范围内更改它?”。例如,高级绘图应用程序或电脑游戏为自己启用了我的高级显卡,如何?他们是否在安装期间/之后、运行之前在设备上创建配置文件?
    • @CahitBurakKüçüksütcü 我猜你应该使用developer.nvidia.com/nvapi
    【解决方案2】:

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

    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 进行检查

    【讨论】:

    • 实际上我的目标是在所有支持 Qt 的平台上运行我的应用程序,如 android、raspberry、iOs、PC、Mac 等等……所以我需要建议来使我的代码跨平台。
    • 这与您在描述中提到的 NVIDIA GeForce 有什么关系?在其他设备上,您只需要检查 OpenGL 功能,不必担心使用 openGL 的设备
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-04-09
    • 2020-02-04
    • 2011-05-27
    • 1970-01-01
    相关资源
    最近更新 更多