Mercurial > octave
comparison libinterp/corefcn/gl-render.cc @ 22192:20b225a3ebf8
Update to light (patch #8943)
* gl-render.h, gl-render.cc (get_maxlights): New static function.
(opengl_renderer::max_lights): New data member.
(opengl_renderer::opengl_renderer): Use get_maxlights to initialize
max_lights data member.
(opengl_renderer::draw_all_lights): New function. Support local
light sources.
(opengl_renderer::draw_axes_children): Call draw_all_lights instead
of doing the work here.
(opengl_renderer::draw_surface): Remove warning for "phong".
* scripts/plot/draw/light.m: Update docstring. Add and update demos.
* doc/interpreter/genpropdoc.m: Update docstring.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sat, 23 Jul 2016 17:45:32 +0200 |
parents | 3f5f1234c619 |
children | 553490ffc203 |
comparison
equal
deleted
inserted
replaced
22191:8971508e21c8 | 22192:20b225a3ebf8 |
---|---|
585 // Dummy class. | 585 // Dummy class. |
586 }; | 586 }; |
587 | 587 |
588 #endif | 588 #endif |
589 | 589 |
590 static int | |
591 get_maxlights (void) | |
592 { | |
593 #if defined (HAVE_OPENGL) | |
594 | |
595 static int max_lights = 0; | |
596 | |
597 // Check actual maximum number of lights possible | |
598 if (max_lights == 0) | |
599 { | |
600 for (max_lights = 0; max_lights < GL_MAX_LIGHTS; max_lights++) | |
601 { | |
602 glDisable (GL_LIGHT0 + max_lights); | |
603 if (glGetError ()) | |
604 break; | |
605 } | |
606 } | |
607 | |
608 return max_lights; | |
609 #else | |
610 | |
611 err_disabled_feature ("opengl_renderer", "OpenGL"); | |
612 | |
613 #endif | |
614 | |
615 } | |
616 | |
590 opengl_renderer::opengl_renderer (void) | 617 opengl_renderer::opengl_renderer (void) |
591 : toolkit (), xform (), xmin (), xmax (), ymin (), ymax (), | 618 : toolkit (), xform (), xmin (), xmax (), ymin (), ymax (), |
592 zmin (), zmax (), xZ1 (), xZ2 (), marker_id (), filled_marker_id (), | 619 zmin (), zmax (), xZ1 (), xZ2 (), marker_id (), filled_marker_id (), |
593 camera_pos (), camera_dir (), interpreter ("none"), txt_renderer () | 620 camera_pos (), camera_dir (), interpreter ("none"), txt_renderer () |
594 { | 621 { |
603 | 630 |
604 static bool ok = (sizeof (int) <= sizeof (GLsizei)); | 631 static bool ok = (sizeof (int) <= sizeof (GLsizei)); |
605 | 632 |
606 if (! ok) | 633 if (! ok) |
607 error ("the size of GLsizei is smaller than the size of int"); | 634 error ("the size of GLsizei is smaller than the size of int"); |
635 | |
636 // Check actual maximum number of lights possible | |
637 max_lights = get_maxlights (); | |
608 | 638 |
609 #else | 639 #else |
610 | 640 |
611 err_disabled_feature ("opengl_renderer", "OpenGL"); | 641 err_disabled_feature ("opengl_renderer", "OpenGL"); |
612 | 642 |
1616 else | 1646 else |
1617 gh_manager::get_object (props.get_zlabel ()).set ("visible", "off"); | 1647 gh_manager::get_object (props.get_zlabel ()).set ("visible", "off"); |
1618 } | 1648 } |
1619 | 1649 |
1620 void | 1650 void |
1621 opengl_renderer::draw_axes_children (const axes::properties& props) | 1651 opengl_renderer::draw_all_lights (const base_properties& props, std::list<graphics_object>& obj_list) |
1622 { | 1652 { |
1623 #if defined (HAVE_OPENGL) | |
1624 | |
1625 // Children | |
1626 | |
1627 Matrix children = props.get_all_children (); | 1653 Matrix children = props.get_all_children (); |
1628 std::list<graphics_object> obj_list; | |
1629 std::list<graphics_object>::iterator it; | |
1630 | |
1631 // 1st pass: draw light objects | |
1632 | |
1633 // Start with the last element of the array of child objects to | |
1634 // display them in the order they were added to the array. | |
1635 | |
1636 num_lights = 0; | |
1637 | 1654 |
1638 for (octave_idx_type i = children.numel () - 1; i >= 0; i--) | 1655 for (octave_idx_type i = children.numel () - 1; i >= 0; i--) |
1639 { | 1656 { |
1640 graphics_object go = gh_manager::get_object (children(i)); | 1657 graphics_object go = gh_manager::get_object (children(i)); |
1641 | 1658 |
1642 if (go.get_properties ().is_visible ()) | 1659 if (go.get_properties ().is_visible ()) |
1643 { | 1660 { |
1644 if (go.isa ("light")) | 1661 if (go.isa ("light")) |
1645 { | 1662 { |
1646 if (num_lights < GL_MAX_LIGHTS) | 1663 if (num_lights < max_lights) |
1647 { | 1664 { |
1648 current_light = GL_LIGHT0 + num_lights; | 1665 current_light = GL_LIGHT0 + num_lights; |
1649 set_clipping (go.get_properties ().is_clipping ()); | 1666 set_clipping (go.get_properties ().is_clipping ()); |
1650 draw (go); | 1667 draw (go); |
1651 num_lights++; | 1668 num_lights++; |
1652 } | 1669 } |
1670 else | |
1671 warning_with_id ("Octave:max-lights-exceeded", | |
1672 "light: Maximum number of lights (%d) in these axes is " | |
1673 "exceeded.", max_lights); | |
1653 } | 1674 } |
1675 else if (go.isa ("hggroup")) | |
1676 draw_all_lights (go.get_properties (), obj_list); | |
1654 else | 1677 else |
1655 obj_list.push_back (go); | 1678 obj_list.push_back (go); |
1656 } | 1679 } |
1657 } | 1680 } |
1681 } | |
1682 | |
1683 void | |
1684 opengl_renderer::draw_axes_children (const axes::properties& props) | |
1685 { | |
1686 #if defined (HAVE_OPENGL) | |
1687 // list for non-light child objects | |
1688 std::list<graphics_object> obj_list; | |
1689 std::list<graphics_object>::iterator it; | |
1690 | |
1691 // 1st pass: draw light objects | |
1692 | |
1693 // Start with the last element of the array of child objects to | |
1694 // display them in the order they were added to the array. | |
1695 | |
1696 num_lights = 0; | |
1697 draw_all_lights (props, obj_list); | |
1658 | 1698 |
1659 // disable other OpenGL lights | 1699 // disable other OpenGL lights |
1660 for (int i = num_lights; i < GL_MAX_LIGHTS; i++) | 1700 for (int i = num_lights; i < max_lights; i++) |
1661 glDisable (GL_LIGHT0 + i); | 1701 glDisable (GL_LIGHT0 + i); |
1662 | 1702 |
1663 // save camera position and set ambient light color before drawing | 1703 // save camera position and set ambient light color before drawing |
1664 // other objects | 1704 // other objects |
1665 view_vector = props.get_cameraposition ().matrix_value (); | 1705 view_vector = props.get_cameraposition ().matrix_value (); |
1941 const NDArray n = props.get_vertexnormals ().array_value (); | 1981 const NDArray n = props.get_vertexnormals ().array_value (); |
1942 | 1982 |
1943 // FIXME: handle transparency | 1983 // FIXME: handle transparency |
1944 Matrix a; | 1984 Matrix a; |
1945 | 1985 |
1946 if (props.facelighting_is ("phong") || props.edgelighting_is ("phong")) | |
1947 warning ("opengl_renderer: phong light model not supported"); | |
1948 | |
1949 int fc_mode = (props.facecolor_is_rgb () ? 0 : | 1986 int fc_mode = (props.facecolor_is_rgb () ? 0 : |
1950 (props.facecolor_is ("flat") ? 1 : | 1987 (props.facecolor_is ("flat") ? 1 : |
1951 (props.facecolor_is ("interp") ? 2 : | 1988 (props.facecolor_is ("interp") ? 2 : |
1952 (props.facecolor_is ("texturemap") ? 3 : -1)))); | 1989 (props.facecolor_is ("texturemap") ? 3 : -1)))); |
1953 int fl_mode = (props.facelighting_is ("none") ? 0 : | 1990 int fl_mode = (props.facelighting_is ("none") ? 0 : |
2294 { | 2331 { |
2295 for (int k = 0; k < 3; k++) | 2332 for (int k = 0; k < 3; k++) |
2296 cb[k] = c(j-1, i, k); | 2333 cb[k] = c(j-1, i, k); |
2297 glColor3fv (cb); | 2334 glColor3fv (cb); |
2298 | 2335 |
2299 if (fl_mode > 0) | 2336 if (el_mode > 0) |
2300 { | 2337 { |
2301 for (int k = 0; k < 3; k++) | 2338 for (int k = 0; k < 3; k++) |
2302 cb[k] *= as; | 2339 cb[k] *= as; |
2303 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); | 2340 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); |
2304 | 2341 |
2321 { | 2358 { |
2322 for (int k = 0; k < 3; k++) | 2359 for (int k = 0; k < 3; k++) |
2323 cb[k] = c(j, i, k); | 2360 cb[k] = c(j, i, k); |
2324 glColor3fv (cb); | 2361 glColor3fv (cb); |
2325 | 2362 |
2326 if (fl_mode > 0) | 2363 if (el_mode > 0) |
2327 { | 2364 { |
2328 for (int k = 0; k < 3; k++) | 2365 for (int k = 0; k < 3; k++) |
2329 cb[k] *= as; | 2366 cb[k] *= as; |
2330 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); | 2367 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); |
2331 | 2368 |
2391 { | 2428 { |
2392 for (int k = 0; k < 3; k++) | 2429 for (int k = 0; k < 3; k++) |
2393 cb[k] = c(j, i-1, k); | 2430 cb[k] = c(j, i-1, k); |
2394 glColor3fv (cb); | 2431 glColor3fv (cb); |
2395 | 2432 |
2396 if (fl_mode > 0) | 2433 if (el_mode > 0) |
2397 { | 2434 { |
2398 for (int k = 0; k < 3; k++) | 2435 for (int k = 0; k < 3; k++) |
2399 cb[k] *= as; | 2436 cb[k] *= as; |
2400 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); | 2437 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); |
2401 | 2438 |
2418 { | 2455 { |
2419 for (int k = 0; k < 3; k++) | 2456 for (int k = 0; k < 3; k++) |
2420 cb[k] = c(j, i, k); | 2457 cb[k] = c(j, i, k); |
2421 glColor3fv (cb); | 2458 glColor3fv (cb); |
2422 | 2459 |
2423 if (fl_mode > 0) | 2460 if (el_mode > 0) |
2424 { | 2461 { |
2425 for (int k = 0; k < 3; k++) | 2462 for (int k = 0; k < 3; k++) |
2426 cb[k] *= as; | 2463 cb[k] *= as; |
2427 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); | 2464 glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb); |
2428 | 2465 |
3013 | 3050 |
3014 // enable light source | 3051 // enable light source |
3015 glEnable (current_light); | 3052 glEnable (current_light); |
3016 | 3053 |
3017 // light position | 3054 // light position |
3018 float pos[4] = { 0, 0, 0, 0 }; // X,Y,Z,attenuation | 3055 float pos[4] = { 0, 0, 0, 0 }; // X,Y,Z,infinite/local |
3019 Matrix lpos = props.get_position ().matrix_value (); | 3056 Matrix lpos = props.get_position ().matrix_value (); |
3020 for (int i = 0; i < 3; i++) | 3057 for (int i = 0; i < 3; i++) |
3021 pos[i] = lpos(i); | 3058 pos[i] = lpos(i); |
3059 if (props.style_is ("local")) | |
3060 pos[3] = 1; | |
3022 glLightfv (current_light, GL_POSITION, pos); | 3061 glLightfv (current_light, GL_POSITION, pos); |
3023 | 3062 |
3024 // light color | 3063 // light color |
3025 float col[4] = { 1, 1, 1, 1 }; // R,G,B,ALPHA (the latter has no meaning) | 3064 float col[4] = { 1, 1, 1, 1 }; // R,G,B,ALPHA (the latter has no meaning) |
3026 Matrix lcolor = props.get_color ().matrix_value (); | 3065 Matrix lcolor = props.get_color ().matrix_value (); |