【发布时间】:2014-02-04 17:51:10
【问题描述】:
我对 Qt OpenGL 编程的依赖关系或要求有一些问题。我正在使用带有 MSVC 2012 x64 的 OpenGL 的 Qt OpenGL 5.1
- 我的第一个问题是关于在运行时选择和使用正确的图形设备适配器。我的电脑有 2 个图形设备,其中一个是板载 Intel,另一个是高级 NVidia GeForce GT740M。我可以通过 NVidia 控制面板使用我的高级显卡来始终激活 Geforce。但我知道我必须用我的软件来做。我怎么能用 Qt OpenGL 做到这一点
- 我的第二个问题是关于 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);
}
【问题讨论】: