LibGL+LibSoftGPU+3DFileViewer: Implement Specular highlighting :^)

This commit is contained in:
Jesse Buhagiar 2022-01-15 16:16:01 +11:00 committed by Idan Horowitz
parent 5bb8c14c8f
commit 865e7bbe5e
Notes: sideshowbarker 2024-07-17 20:41:56 +09:00
4 changed files with 35 additions and 4 deletions

View File

@ -187,16 +187,26 @@ void GLContextWidget::timer_event(Core::TimerEvent&)
// Disco time ;)
GLfloat const light0_position[4] = { -4.0f, 0.0f, 0.0f, 0.0f };
GLfloat const light0_diffuse[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
GLfloat const light0_specular[4] = { 0.75f, 0.75f, 0.75f };
GLfloat const light1_position[4] = { 4.0f, 0.0f, 0.0f, 0.0f };
GLfloat const light1_diffuse[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
GLfloat const light1_specular[4] = { 0.75f, 0.75f, 0.75f };
GLfloat const light2_position[4] = { 0.0f, 5.0f, 0.0f, 0.0f };
GLfloat const light2_diffuse[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
GLfloat const light2_specular[4] = { 0.75f, 0.75f, 0.75f };
glLightfv(GL_LIGHT0, GL_POSITION, &light0_position[0]);
glLightfv(GL_LIGHT0, GL_DIFFUSE, &light0_diffuse[0]);
glLightfv(GL_LIGHT0, GL_SPECULAR, &light0_specular[0]);
glLightfv(GL_LIGHT1, GL_POSITION, &light1_position[0]);
glLightfv(GL_LIGHT1, GL_DIFFUSE, &light1_diffuse[0]);
glLightfv(GL_LIGHT1, GL_SPECULAR, &light1_specular[0]);
glLightfv(GL_LIGHT2, GL_POSITION, &light2_position[0]);
glLightfv(GL_LIGHT2, GL_DIFFUSE, &light2_diffuse[0]);
glLightfv(GL_LIGHT2, GL_SPECULAR, &light2_specular[0]);
GLfloat const material_specular_color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
glMaterialf(GL_FRONT, GL_SHININESS, 45.0f);
glMaterialfv(GL_FRONT, GL_SPECULAR, &material_specular_color[0]);
glPopMatrix();
if (m_texture_enabled) {

View File

@ -260,6 +260,7 @@ extern "C" {
// Lighting related defines
#define GL_LIGHTING 0x0B50
#define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51
#define GL_LIGHT_MODEL_TWO_SIDE 0x0B52
#define GL_LIGHT_MODEL_AMBIENT 0x0B53

View File

@ -2764,6 +2764,12 @@ void SoftwareGLContext::gl_light_model(GLenum pname, GLfloat x, GLfloat y, GLflo
lighting_params.two_sided_lighting = x;
update_lighting_model = true;
break;
case GL_LIGHT_MODEL_LOCAL_VIEWER:
// 0 means the viewer is at infinity
// 1 means they're in local (eye) space
lighting_params.viewer_at_infinity = (x != 1.0f);
update_lighting_model = true;
break;
default:
VERIFY_NOT_REACHED();
}

View File

@ -856,9 +856,6 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
spotlight_factor = 0.0f;
}
// FIXME: Specular. The math for it doesn't quite make sense...
(void)m_lighting_model.viewer_at_infinity;
// FIXME: The spec allows for splitting the colors calculated here into multiple different colors (primary/secondary color). Investigate what this means.
(void)m_lighting_model.single_color;
@ -870,10 +867,27 @@ void Device::draw_primitives(PrimitiveType primitive_type, FloatMatrix4x4 const&
// Diffuse
auto const normal_dot_vertex_to_light = sgi_dot_operator(vertex.normal, vertex_to_light);
auto const diffuse_component = ((diffuse * light.diffuse_intensity) * normal_dot_vertex_to_light).clamped(0.0f, 1.0f);
auto const diffuse_component = ((diffuse * light.diffuse_intensity) * normal_dot_vertex_to_light);
// Specular
FloatVector4 specular_component = { 0.0f, 0.0f, 0.0f, 0.0f };
if (normal_dot_vertex_to_light > 0.0f) {
FloatVector3 half_vector_normalized;
if (!m_lighting_model.viewer_at_infinity) {
half_vector_normalized = (vertex_to_light + FloatVector3(0.0f, 0.0f, 1.0f)).normalized();
} else {
auto const vertex_to_eye_point = sgi_arrow_operator(vertex.eye_coordinates.normalized(), FloatVector4(0.0f, 0.0f, 0.0f, 1.0f), vector_length);
half_vector_normalized = vertex_to_light + vertex_to_eye_point;
}
auto const normal_dot_half_vector = sgi_dot_operator(vertex.normal.normalized(), half_vector_normalized);
auto const specular_coefficient = AK::pow(normal_dot_half_vector, material.shininess);
specular_component = (specular * light.specular_intensity) * specular_coefficient;
}
FloatVector4 color = ambient_component;
color += diffuse_component;
color += specular_component;
color = color * light_attenuation_factor * spotlight_factor;
result_color += color;
}