diff options
author | Jacek Antonelli | 2009-08-29 17:44:38 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-08-29 22:49:51 -0500 |
commit | 6a5aab98892df74f60743f5b789959c9593d6647 (patch) | |
tree | 62da18f8540879ed01e12eeb0ce49375474272e4 /linden/indra/newview/pipeline.cpp | |
parent | Merge branch 'mac-openal-url' into next (diff) | |
parent | Converted 1.23 XUI files to unix line endings. (diff) | |
download | meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.zip meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.tar.gz meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.tar.bz2 meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.tar.xz |
Merged SL 1.23.4 into Imprudence.
Conflicts:
linden/doc/contributions.txt
linden/indra/CMakeLists.txt
linden/indra/cmake/APR.cmake
linden/indra/cmake/CopyWinLibs.cmake
linden/indra/cmake/OPENAL.cmake
linden/indra/develop.py
linden/indra/llaudio/audioengine.cpp
linden/indra/llcommon/indra_constants.h
linden/indra/llcommon/llversionviewer.h
linden/indra/llcrashlogger/llcrashlogger.cpp
linden/indra/llmedia/llmediaimplgstreamer.cpp
linden/indra/llmedia/llmediaimplgstreamer.h
linden/indra/llmedia/llmediaimplgstreamer_syms.cpp
linden/indra/llmedia/llmediaimplgstreamer_syms.h
linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
linden/indra/llmedia/llmediamanager.cpp
linden/indra/llmessage/llassetstorage.cpp
linden/indra/llui/lltexteditor.cpp
linden/indra/llvfs/lldir.cpp
linden/indra/newview/CMakeLists.txt
linden/indra/newview/English.lproj/InfoPlist.strings
linden/indra/newview/Info-Imprudence.plist
linden/indra/newview/app_settings/logcontrol.xml
linden/indra/newview/app_settings/settings.xml
linden/indra/newview/installers/windows/installer_template.nsi
linden/indra/newview/llagent.cpp
linden/indra/newview/llappviewer.cpp
linden/indra/newview/llcallingcard.cpp
linden/indra/newview/llfilepicker.cpp
linden/indra/newview/llfloateractivespeakers.cpp
linden/indra/newview/llfloateravatarpicker.cpp
linden/indra/newview/llfloaterbulkpermission.cpp
linden/indra/newview/llfloaterbulkpermission.h
linden/indra/newview/llfloaterchat.cpp
linden/indra/newview/llfloatergodtools.cpp
linden/indra/newview/llfloaterhtmlhelp.cpp
linden/indra/newview/llfloatertools.cpp
linden/indra/newview/llfloatertools.h
linden/indra/newview/llfloatertopobjects.cpp
linden/indra/newview/llinventorybridge.cpp
linden/indra/newview/llinventoryview.cpp
linden/indra/newview/llnetmap.cpp
linden/indra/newview/llnetmap.h
linden/indra/newview/llpanelland.cpp
linden/indra/newview/llpanellogin.cpp
linden/indra/newview/llpanelobject.cpp
linden/indra/newview/llprefsim.cpp
linden/indra/newview/lltexturecache.cpp
linden/indra/newview/lltoolbrush.cpp
linden/indra/newview/llvieweraudio.cpp
linden/indra/newview/llviewermenu.cpp
linden/indra/newview/llviewermessage.cpp
linden/indra/newview/llviewerparcelmedia.cpp
linden/indra/newview/llvoavatar.cpp
linden/indra/newview/llwebbrowserctrl.cpp
linden/indra/newview/llworldmapview.cpp
linden/indra/newview/pipeline.cpp
linden/indra/newview/res/viewerRes.rc
linden/indra/newview/skins/default/colors_base.xml
linden/indra/newview/skins/default/xui/de/floater_active_speakers.xml
linden/indra/newview/skins/default/xui/de/floater_instant_message_ad_hoc.xml
linden/indra/newview/skins/default/xui/de/floater_instant_message_group.xml
linden/indra/newview/skins/default/xui/de/floater_joystick.xml
linden/indra/newview/skins/default/xui/de/floater_mute_object.xml
linden/indra/newview/skins/default/xui/de/floater_sim_release_message.xml
linden/indra/newview/skins/default/xui/de/panel_media_controls.xml
linden/indra/newview/skins/default/xui/de/panel_preferences_voice.xml
linden/indra/newview/skins/default/xui/de/strings.xml
linden/indra/newview/skins/default/xui/de/teleport_strings.xml
linden/indra/newview/skins/default/xui/en-us/alerts.xml
linden/indra/newview/skins/default/xui/en-us/floater_about_land.xml
linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml
linden/indra/newview/skins/default/xui/en-us/floater_beacons.xml
linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml
linden/indra/newview/skins/default/xui/en-us/floater_buy_land.xml
linden/indra/newview/skins/default/xui/en-us/floater_chatterbox.xml
linden/indra/newview/skins/default/xui/en-us/floater_inventory_view_finder.xml
linden/indra/newview/skins/default/xui/en-us/floater_media_browser.xml
linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml
linden/indra/newview/skins/default/xui/en-us/floater_tools.xml
linden/indra/newview/skins/default/xui/en-us/menu_login.xml
linden/indra/newview/skins/default/xui/en-us/menu_mini_map.xml
linden/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml
linden/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml
linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml
linden/indra/newview/skins/default/xui/en-us/menu_pie_self.xml
linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml
linden/indra/newview/skins/default/xui/en-us/notify.xml
linden/indra/newview/skins/default/xui/en-us/panel_bars.xml
linden/indra/newview/skins/default/xui/en-us/panel_groups.xml
linden/indra/newview/skins/default/xui/en-us/panel_media_controls.xml
linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml
linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml
linden/indra/newview/skins/default/xui/en-us/strings.xml
linden/indra/newview/skins/default/xui/es/alerts.xml
linden/indra/newview/skins/default/xui/es/floater_about.xml
linden/indra/newview/skins/default/xui/es/floater_about_land.xml
linden/indra/newview/skins/default/xui/es/floater_animation_preview.xml
linden/indra/newview/skins/default/xui/es/floater_auction.xml
linden/indra/newview/skins/default/xui/es/floater_avatar_picker.xml
linden/indra/newview/skins/default/xui/es/floater_avatar_textures.xml
linden/indra/newview/skins/default/xui/es/floater_build_options.xml
linden/indra/newview/skins/default/xui/es/floater_bumps.xml
linden/indra/newview/skins/default/xui/es/floater_buy_contents.xml
linden/indra/newview/skins/default/xui/es/floater_buy_currency.xml
linden/indra/newview/skins/default/xui/es/floater_buy_land.xml
linden/indra/newview/skins/default/xui/es/floater_buy_object.xml
linden/indra/newview/skins/default/xui/es/floater_chat_history.xml
linden/indra/newview/skins/default/xui/es/floater_choose_group.xml
linden/indra/newview/skins/default/xui/es/floater_clothing.xml
linden/indra/newview/skins/default/xui/es/floater_color_picker.xml
linden/indra/newview/skins/default/xui/es/floater_critical.xml
linden/indra/newview/skins/default/xui/es/floater_customize.xml
linden/indra/newview/skins/default/xui/es/floater_directory.xml
linden/indra/newview/skins/default/xui/es/floater_gesture.xml
linden/indra/newview/skins/default/xui/es/floater_group_info.xml
linden/indra/newview/skins/default/xui/es/floater_html.xml
linden/indra/newview/skins/default/xui/es/floater_im.xml
linden/indra/newview/skins/default/xui/es/floater_image_preview.xml
linden/indra/newview/skins/default/xui/es/floater_import.xml
linden/indra/newview/skins/default/xui/es/floater_instant_message.xml
linden/indra/newview/skins/default/xui/es/floater_inventory.xml
linden/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml
linden/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml
linden/indra/newview/skins/default/xui/es/floater_land_holdings.xml
linden/indra/newview/skins/default/xui/es/floater_live_lsleditor.xml
linden/indra/newview/skins/default/xui/es/floater_moveview.xml
linden/indra/newview/skins/default/xui/es/floater_mute.xml
linden/indra/newview/skins/default/xui/es/floater_name_description.xml
linden/indra/newview/skins/default/xui/es/floater_new_im.xml
linden/indra/newview/skins/default/xui/es/floater_new_outfit_dialog.xml
linden/indra/newview/skins/default/xui/es/floater_openobject.xml
linden/indra/newview/skins/default/xui/es/floater_pay.xml
linden/indra/newview/skins/default/xui/es/floater_pay_object.xml
linden/indra/newview/skins/default/xui/es/floater_postcard.xml
linden/indra/newview/skins/default/xui/es/floater_preferences.xml
linden/indra/newview/skins/default/xui/es/floater_preview_animation.xml
linden/indra/newview/skins/default/xui/es/floater_preview_embedded_texture.xml
linden/indra/newview/skins/default/xui/es/floater_preview_gesture.xml
linden/indra/newview/skins/default/xui/es/floater_preview_notecard.xml
linden/indra/newview/skins/default/xui/es/floater_preview_notecard_keep_discard.xml
linden/indra/newview/skins/default/xui/es/floater_preview_sound.xml
linden/indra/newview/skins/default/xui/es/floater_preview_texture.xml
linden/indra/newview/skins/default/xui/es/floater_preview_texture_keep_discard.xml
linden/indra/newview/skins/default/xui/es/floater_price_for_listing.xml
linden/indra/newview/skins/default/xui/es/floater_profile.xml
linden/indra/newview/skins/default/xui/es/floater_report_abuse.xml
linden/indra/newview/skins/default/xui/es/floater_script_debug.xml
linden/indra/newview/skins/default/xui/es/floater_script_ed_panel.xml
linden/indra/newview/skins/default/xui/es/floater_script_preview.xml
linden/indra/newview/skins/default/xui/es/floater_script_queue.xml
linden/indra/newview/skins/default/xui/es/floater_script_search.xml
linden/indra/newview/skins/default/xui/es/floater_sell_land.xml
linden/indra/newview/skins/default/xui/es/floater_settings_debug.xml
linden/indra/newview/skins/default/xui/es/floater_snapshot.xml
linden/indra/newview/skins/default/xui/es/floater_sound_preview.xml
linden/indra/newview/skins/default/xui/es/floater_telehub.xml
linden/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
linden/indra/newview/skins/default/xui/es/floater_tools.xml
linden/indra/newview/skins/default/xui/es/floater_top_objects.xml
linden/indra/newview/skins/default/xui/es/floater_tos.xml
linden/indra/newview/skins/default/xui/es/floater_wearable_save_as.xml
linden/indra/newview/skins/default/xui/es/floater_world_map.xml
linden/indra/newview/skins/default/xui/es/menu_inventory.xml
linden/indra/newview/skins/default/xui/es/menu_pie_attachment.xml
linden/indra/newview/skins/default/xui/es/menu_pie_avatar.xml
linden/indra/newview/skins/default/xui/es/menu_pie_land.xml
linden/indra/newview/skins/default/xui/es/menu_pie_object.xml
linden/indra/newview/skins/default/xui/es/menu_pie_self.xml
linden/indra/newview/skins/default/xui/es/menu_viewer.xml
linden/indra/newview/skins/default/xui/es/notify.xml
linden/indra/newview/skins/default/xui/es/panel_avatar.xml
linden/indra/newview/skins/default/xui/es/panel_avatar_classified.xml
linden/indra/newview/skins/default/xui/es/panel_avatar_pick.xml
linden/indra/newview/skins/default/xui/es/panel_chat_bar.xml
linden/indra/newview/skins/default/xui/es/panel_classified.xml
linden/indra/newview/skins/default/xui/es/panel_event.xml
linden/indra/newview/skins/default/xui/es/panel_group.xml
linden/indra/newview/skins/default/xui/es/panel_group_finder.xml
linden/indra/newview/skins/default/xui/es/panel_group_general.xml
linden/indra/newview/skins/default/xui/es/panel_group_invite.xml
linden/indra/newview/skins/default/xui/es/panel_group_land_money.xml
linden/indra/newview/skins/default/xui/es/panel_group_notices.xml
linden/indra/newview/skins/default/xui/es/panel_group_roles.xml
linden/indra/newview/skins/default/xui/es/panel_group_voting.xml
linden/indra/newview/skins/default/xui/es/panel_land_covenant.xml
linden/indra/newview/skins/default/xui/es/panel_login.xml
linden/indra/newview/skins/default/xui/es/panel_overlaybar.xml
linden/indra/newview/skins/default/xui/es/panel_place.xml
linden/indra/newview/skins/default/xui/es/panel_place_small.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_audio.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_general.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_im.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_input.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_network.xml
linden/indra/newview/skins/default/xui/es/panel_preferences_popups.xml
linden/indra/newview/skins/default/xui/es/panel_region_covenant.xml
linden/indra/newview/skins/default/xui/es/panel_region_debug.xml
linden/indra/newview/skins/default/xui/es/panel_region_estate.xml
linden/indra/newview/skins/default/xui/es/panel_region_general.xml
linden/indra/newview/skins/default/xui/es/panel_region_terrain.xml
linden/indra/newview/skins/default/xui/es/panel_region_texture.xml
linden/indra/newview/skins/default/xui/es/panel_scrolling_param.xml
linden/indra/newview/skins/default/xui/es/panel_status_bar.xml
linden/indra/newview/skins/default/xui/es/panel_toolbar.xml
linden/indra/newview/skins/default/xui/es/panel_top_pick.xml
linden/indra/newview/skins/default/xui/fr/alerts.xml
linden/indra/newview/skins/default/xui/fr/floater_about.xml
linden/indra/newview/skins/default/xui/fr/floater_about_land.xml
linden/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml
linden/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml
linden/indra/newview/skins/default/xui/fr/floater_beacons.xml
linden/indra/newview/skins/default/xui/fr/floater_buy_contents.xml
linden/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
linden/indra/newview/skins/default/xui/fr/floater_buy_land.xml
linden/indra/newview/skins/default/xui/fr/floater_chat_history.xml
linden/indra/newview/skins/default/xui/fr/floater_clothing.xml
linden/indra/newview/skins/default/xui/fr/floater_customize.xml
linden/indra/newview/skins/default/xui/fr/floater_directory.xml
linden/indra/newview/skins/default/xui/fr/floater_god_tools.xml
linden/indra/newview/skins/default/xui/fr/floater_group_info.xml
linden/indra/newview/skins/default/xui/fr/floater_html.xml
linden/indra/newview/skins/default/xui/fr/floater_im.xml
linden/indra/newview/skins/default/xui/fr/floater_instant_message.xml
linden/indra/newview/skins/default/xui/fr/floater_instant_message_group.xml
linden/indra/newview/skins/default/xui/fr/floater_inventory.xml
linden/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
linden/indra/newview/skins/default/xui/fr/floater_joystick.xml
linden/indra/newview/skins/default/xui/fr/floater_land_holdings.xml
linden/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml
linden/indra/newview/skins/default/xui/fr/floater_media_browser.xml
linden/indra/newview/skins/default/xui/fr/floater_mem_leaking.xml
linden/indra/newview/skins/default/xui/fr/floater_name_description.xml
linden/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml
linden/indra/newview/skins/default/xui/fr/floater_profile.xml
linden/indra/newview/skins/default/xui/fr/floater_report_abuse.xml
linden/indra/newview/skins/default/xui/fr/floater_script_search.xml
linden/indra/newview/skins/default/xui/fr/floater_sell_land.xml
linden/indra/newview/skins/default/xui/fr/floater_snapshot.xml
linden/indra/newview/skins/default/xui/fr/floater_sound_preview.xml
linden/indra/newview/skins/default/xui/fr/floater_tools.xml
linden/indra/newview/skins/default/xui/fr/floater_top_objects.xml
linden/indra/newview/skins/default/xui/fr/floater_world_map.xml
linden/indra/newview/skins/default/xui/fr/menu_inventory.xml
linden/indra/newview/skins/default/xui/fr/menu_login.xml
linden/indra/newview/skins/default/xui/fr/menu_pie_attachment.xml
linden/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml
linden/indra/newview/skins/default/xui/fr/menu_pie_object.xml
linden/indra/newview/skins/default/xui/fr/menu_viewer.xml
linden/indra/newview/skins/default/xui/fr/notify.xml
linden/indra/newview/skins/default/xui/fr/panel_audio.xml
linden/indra/newview/skins/default/xui/fr/panel_avatar.xml
linden/indra/newview/skins/default/xui/fr/panel_avatar_classified.xml
linden/indra/newview/skins/default/xui/fr/panel_classified.xml
linden/indra/newview/skins/default/xui/fr/panel_event.xml
linden/indra/newview/skins/default/xui/fr/panel_friends.xml
linden/indra/newview/skins/default/xui/fr/panel_group_general.xml
linden/indra/newview/skins/default/xui/fr/panel_group_invite.xml
linden/indra/newview/skins/default/xui/fr/panel_group_land_money.xml
linden/indra/newview/skins/default/xui/fr/panel_group_roles.xml
linden/indra/newview/skins/default/xui/fr/panel_login.xml
linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml
linden/indra/newview/skins/default/xui/fr/panel_media_remote_expanded.xml
linden/indra/newview/skins/default/xui/fr/panel_overlaybar.xml
linden/indra/newview/skins/default/xui/fr/panel_place.xml
linden/indra/newview/skins/default/xui/fr/panel_place_small.xml
linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml
linden/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml
linden/indra/newview/skins/default/xui/fr/panel_preferences_input.xml
linden/indra/newview/skins/default/xui/fr/panel_preferences_network.xml
linden/indra/newview/skins/default/xui/fr/panel_preferences_voice.xml
linden/indra/newview/skins/default/xui/fr/panel_region_covenant.xml
linden/indra/newview/skins/default/xui/fr/panel_region_debug.xml
linden/indra/newview/skins/default/xui/fr/panel_region_general.xml
linden/indra/newview/skins/default/xui/fr/panel_voice_controls.xml
linden/indra/newview/skins/default/xui/fr/role_actions.xml
linden/indra/newview/skins/default/xui/fr/strings.xml
linden/indra/newview/skins/default/xui/fr/teleport_strings.xml
linden/indra/newview/skins/default/xui/ja/floater_active_speakers.xml
linden/indra/newview/skins/default/xui/ja/floater_html.xml
linden/indra/newview/skins/default/xui/ja/floater_instant_message_ad_hoc.xml
linden/indra/newview/skins/default/xui/ja/floater_instant_message_group.xml
linden/indra/newview/skins/default/xui/ja/floater_joystick.xml
linden/indra/newview/skins/default/xui/ja/floater_media_browser.xml
linden/indra/newview/skins/default/xui/ja/floater_windlight_options.xml
linden/indra/newview/skins/default/xui/ja/menu_login.xml
linden/indra/newview/skins/default/xui/ja/panel_friends.xml
linden/indra/newview/skins/default/xui/ja/panel_media_controls.xml
linden/indra/newview/skins/default/xui/ja/panel_media_remote_expanded.xml
linden/indra/newview/skins/default/xui/ja/panel_preferences_voice.xml
linden/indra/newview/skins/default/xui/ja/panel_speaker_controls.xml
linden/indra/newview/skins/default/xui/ja/strings.xml
linden/indra/newview/skins/default/xui/ja/teleport_strings.xml
linden/indra/newview/skins/default/xui/ko/panel_media_controls.xml
linden/indra/newview/skins/default/xui/pt/alerts.xml
linden/indra/newview/skins/default/xui/pt/floater_about.xml
linden/indra/newview/skins/default/xui/pt/floater_about_land.xml
linden/indra/newview/skins/default/xui/pt/floater_active_speakers.xml
linden/indra/newview/skins/default/xui/pt/floater_animation_preview.xml
linden/indra/newview/skins/default/xui/pt/floater_auction.xml
linden/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml
linden/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml
linden/indra/newview/skins/default/xui/pt/floater_beacons.xml
linden/indra/newview/skins/default/xui/pt/floater_build_options.xml
linden/indra/newview/skins/default/xui/pt/floater_bumps.xml
linden/indra/newview/skins/default/xui/pt/floater_buy_contents.xml
linden/indra/newview/skins/default/xui/pt/floater_buy_currency.xml
linden/indra/newview/skins/default/xui/pt/floater_buy_land.xml
linden/indra/newview/skins/default/xui/pt/floater_buy_object.xml
linden/indra/newview/skins/default/xui/pt/floater_chat_history.xml
linden/indra/newview/skins/default/xui/pt/floater_clothing.xml
linden/indra/newview/skins/default/xui/pt/floater_color_picker.xml
linden/indra/newview/skins/default/xui/pt/floater_critical.xml
linden/indra/newview/skins/default/xui/pt/floater_customize.xml
linden/indra/newview/skins/default/xui/pt/floater_day_cycle_options.xml
linden/indra/newview/skins/default/xui/pt/floater_directory.xml
linden/indra/newview/skins/default/xui/pt/floater_env_settings.xml
linden/indra/newview/skins/default/xui/pt/floater_gesture.xml
linden/indra/newview/skins/default/xui/pt/floater_god_tools.xml
linden/indra/newview/skins/default/xui/pt/floater_group_info.xml
linden/indra/newview/skins/default/xui/pt/floater_im.xml
linden/indra/newview/skins/default/xui/pt/floater_image_preview.xml
linden/indra/newview/skins/default/xui/pt/floater_inspect.xml
linden/indra/newview/skins/default/xui/pt/floater_instant_message.xml
linden/indra/newview/skins/default/xui/pt/floater_instant_message_ad_hoc.xml
linden/indra/newview/skins/default/xui/pt/floater_instant_message_group.xml
linden/indra/newview/skins/default/xui/pt/floater_inventory.xml
linden/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml
linden/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml
linden/indra/newview/skins/default/xui/pt/floater_joystick.xml
linden/indra/newview/skins/default/xui/pt/floater_lagmeter.xml
linden/indra/newview/skins/default/xui/pt/floater_land_holdings.xml
linden/indra/newview/skins/default/xui/pt/floater_landmark_ctrl.xml
linden/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml
linden/indra/newview/skins/default/xui/pt/floater_lsl_guide.xml
linden/indra/newview/skins/default/xui/pt/floater_media_browser.xml
linden/indra/newview/skins/default/xui/pt/floater_moveview.xml
linden/indra/newview/skins/default/xui/pt/floater_mute.xml
linden/indra/newview/skins/default/xui/pt/floater_mute_object.xml
linden/indra/newview/skins/default/xui/pt/floater_name_description.xml
linden/indra/newview/skins/default/xui/pt/floater_new_outfit_dialog.xml
linden/indra/newview/skins/default/xui/pt/floater_openobject.xml
linden/indra/newview/skins/default/xui/pt/floater_pay.xml
linden/indra/newview/skins/default/xui/pt/floater_postcard.xml
linden/indra/newview/skins/default/xui/pt/floater_preferences.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_animation.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_classified.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_event.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_notecard_keep_discard.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_sound.xml
linden/indra/newview/skins/default/xui/pt/floater_preview_url.xml
linden/indra/newview/skins/default/xui/pt/floater_price_for_listing.xml
linden/indra/newview/skins/default/xui/pt/floater_profile.xml
linden/indra/newview/skins/default/xui/pt/floater_report_abuse.xml
linden/indra/newview/skins/default/xui/pt/floater_script_debug.xml
linden/indra/newview/skins/default/xui/pt/floater_script_queue.xml
linden/indra/newview/skins/default/xui/pt/floater_script_search.xml
linden/indra/newview/skins/default/xui/pt/floater_sell_land.xml
linden/indra/newview/skins/default/xui/pt/floater_settings_debug.xml
linden/indra/newview/skins/default/xui/pt/floater_sim_release_message.xml
linden/indra/newview/skins/default/xui/pt/floater_snapshot.xml
linden/indra/newview/skins/default/xui/pt/floater_sound_preview.xml
linden/indra/newview/skins/default/xui/pt/floater_telehub.xml
linden/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
linden/indra/newview/skins/default/xui/pt/floater_tools.xml
linden/indra/newview/skins/default/xui/pt/floater_top_objects.xml
linden/indra/newview/skins/default/xui/pt/floater_tos.xml
linden/indra/newview/skins/default/xui/pt/floater_url_entry.xml
linden/indra/newview/skins/default/xui/pt/floater_water.xml
linden/indra/newview/skins/default/xui/pt/floater_wearable_save_as.xml
linden/indra/newview/skins/default/xui/pt/floater_windlight_options.xml
linden/indra/newview/skins/default/xui/pt/floater_world_map.xml
linden/indra/newview/skins/default/xui/pt/menu_inventory.xml
linden/indra/newview/skins/default/xui/pt/menu_pie_attachment.xml
linden/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml
linden/indra/newview/skins/default/xui/pt/menu_pie_land.xml
linden/indra/newview/skins/default/xui/pt/menu_pie_object.xml
linden/indra/newview/skins/default/xui/pt/menu_viewer.xml
linden/indra/newview/skins/default/xui/pt/notify.xml
linden/indra/newview/skins/default/xui/pt/panel_account_details.xml
linden/indra/newview/skins/default/xui/pt/panel_account_planning.xml
linden/indra/newview/skins/default/xui/pt/panel_account_transactions.xml
linden/indra/newview/skins/default/xui/pt/panel_audio_device.xml
linden/indra/newview/skins/default/xui/pt/panel_avatar.xml
linden/indra/newview/skins/default/xui/pt/panel_avatar_classified.xml
linden/indra/newview/skins/default/xui/pt/panel_avatar_pick.xml
linden/indra/newview/skins/default/xui/pt/panel_chat_bar.xml
linden/indra/newview/skins/default/xui/pt/panel_classified.xml
linden/indra/newview/skins/default/xui/pt/panel_event.xml
linden/indra/newview/skins/default/xui/pt/panel_friends.xml
linden/indra/newview/skins/default/xui/pt/panel_group.xml
linden/indra/newview/skins/default/xui/pt/panel_group_finder.xml
linden/indra/newview/skins/default/xui/pt/panel_group_general.xml
linden/indra/newview/skins/default/xui/pt/panel_group_invite.xml
linden/indra/newview/skins/default/xui/pt/panel_group_land_money.xml
linden/indra/newview/skins/default/xui/pt/panel_group_notices.xml
linden/indra/newview/skins/default/xui/pt/panel_group_roles.xml
linden/indra/newview/skins/default/xui/pt/panel_group_voting.xml
linden/indra/newview/skins/default/xui/pt/panel_land_covenant.xml
linden/indra/newview/skins/default/xui/pt/panel_login.xml
linden/indra/newview/skins/default/xui/pt/panel_overlaybar.xml
linden/indra/newview/skins/default/xui/pt/panel_place.xml
linden/indra/newview/skins/default/xui/pt/panel_place_small.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_audio.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_im.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_input.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_network.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_popups.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_voice.xml
linden/indra/newview/skins/default/xui/pt/panel_preferences_web.xml
linden/indra/newview/skins/default/xui/pt/panel_region_covenant.xml
linden/indra/newview/skins/default/xui/pt/panel_region_debug.xml
linden/indra/newview/skins/default/xui/pt/panel_region_estate.xml
linden/indra/newview/skins/default/xui/pt/panel_region_general.xml
linden/indra/newview/skins/default/xui/pt/panel_region_terrain.xml
linden/indra/newview/skins/default/xui/pt/panel_region_texture.xml
linden/indra/newview/skins/default/xui/pt/panel_scrolling_param.xml
linden/indra/newview/skins/default/xui/pt/panel_speaker_controls.xml
linden/indra/newview/skins/default/xui/pt/panel_status_bar.xml
linden/indra/newview/skins/default/xui/pt/panel_toolbar.xml
linden/indra/newview/skins/default/xui/pt/panel_top_pick.xml
linden/indra/newview/skins/default/xui/pt/panel_voice_controls.xml
linden/indra/newview/skins/default/xui/pt/panel_voice_enable.xml
linden/indra/newview/skins/default/xui/pt/panel_voice_options.xml
linden/indra/newview/skins/default/xui/pt/strings.xml
linden/indra/newview/skins/default/xui/pt/teleport_strings.xml
linden/indra/newview/skins/default/xui/zh/floater_env_settings.xml
linden/indra/newview/skins/default/xui/zh/floater_instant_message_ad_hoc.xml
linden/indra/newview/skins/default/xui/zh/floater_lagmeter.xml
linden/indra/newview/skins/default/xui/zh/floater_landmark_ctrl.xml
linden/indra/newview/skins/default/xui/zh/floater_post_process.xml
linden/indra/newview/skins/default/xui/zh/floater_settings_debug.xml
linden/indra/newview/skins/default/xui/zh/floater_windlight_options.xml
linden/indra/newview/skins/default/xui/zh/menu_pie_attachment.xml
linden/indra/newview/skins/default/xui/zh/menu_pie_avatar.xml
linden/indra/newview/skins/default/xui/zh/menu_pie_land.xml
linden/indra/newview/skins/default/xui/zh/menu_pie_object.xml
linden/indra/newview/skins/default/xui/zh/menu_viewer.xml
linden/indra/newview/skins/default/xui/zh/panel_avatar.xml
linden/indra/newview/skins/default/xui/zh/panel_friends.xml
linden/indra/newview/skins/default/xui/zh/panel_group_general.xml
linden/indra/newview/skins/default/xui/zh/panel_group_invite.xml
linden/indra/newview/skins/default/xui/zh/panel_group_land_money.xml
linden/indra/newview/skins/default/xui/zh/panel_group_notices.xml
linden/indra/newview/skins/default/xui/zh/panel_group_roles.xml
linden/indra/newview/skins/default/xui/zh/panel_preferences_audio.xml
linden/indra/newview/skins/default/xui/zh/panel_preferences_im.xml
linden/indra/newview/skins/default/xui/zh/panel_region_covenant.xml
linden/indra/newview/skins/default/xui/zh/panel_speaker_controls.xml
linden/indra/newview/skins/default/xui/zh/panel_voice_options.xml
linden/indra/newview/skins/default/xui/zh/strings.xml
linden/indra/newview/skins/silver/colors_base.xml
linden/indra/newview/skins/silver/xui/en-us/floater_about_land.xml
linden/indra/newview/skins/silver/xui/en-us/floater_directory.xml
linden/indra/newview/skins/silver/xui/en-us/floater_tools.xml
linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml
linden/indra/newview/viewer_manifest.py
linden/install.xml
Diffstat (limited to 'linden/indra/newview/pipeline.cpp')
-rw-r--r-- | linden/indra/newview/pipeline.cpp | 2402 |
1 files changed, 1796 insertions, 606 deletions
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 87b810c..d6bc6da 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -138,21 +139,22 @@ LLPipeline gPipeline; | |||
138 | const LLMatrix4* gGLLastMatrix = NULL; | 139 | const LLMatrix4* gGLLastMatrix = NULL; |
139 | 140 | ||
140 | //---------------------------------------- | 141 | //---------------------------------------- |
141 | |||
142 | std::string gPoolNames[] = | 142 | std::string gPoolNames[] = |
143 | { | 143 | { |
144 | // Correspond to LLDrawpool enum render type | 144 | // Correspond to LLDrawpool enum render type |
145 | "NONE", | 145 | "NONE", |
146 | "POOL_SIMPLE", | 146 | "POOL_SIMPLE", |
147 | "POOL_TERRAIN", | 147 | "POOL_TERRAIN", |
148 | "POOL_BUMP", | ||
148 | "POOL_TREE", | 149 | "POOL_TREE", |
149 | "POOL_SKY", | 150 | "POOL_SKY", |
150 | "POOL_WL_SKY", | 151 | "POOL_WL_SKY", |
151 | "POOL_GROUND", | 152 | "POOL_GROUND", |
152 | "POOL_BUMP", | ||
153 | "POOL_INVISIBLE", | 153 | "POOL_INVISIBLE", |
154 | "POOL_AVATAR", | 154 | "POOL_AVATAR", |
155 | "POOL_WATER", | 155 | "POOL_WATER", |
156 | "POOL_GRASS", | ||
157 | "POOL_FULLBRIGHT", | ||
156 | "POOL_GLOW", | 158 | "POOL_GLOW", |
157 | "POOL_ALPHA", | 159 | "POOL_ALPHA", |
158 | }; | 160 | }; |
@@ -230,11 +232,14 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE; | |||
230 | BOOL LLPipeline::sRenderSoundBeacons = FALSE; | 232 | BOOL LLPipeline::sRenderSoundBeacons = FALSE; |
231 | BOOL LLPipeline::sRenderBeacons = FALSE; | 233 | BOOL LLPipeline::sRenderBeacons = FALSE; |
232 | BOOL LLPipeline::sRenderHighlight = TRUE; | 234 | BOOL LLPipeline::sRenderHighlight = TRUE; |
235 | BOOL LLPipeline::sForceOldBakedUpload = FALSE; | ||
233 | S32 LLPipeline::sUseOcclusion = 0; | 236 | S32 LLPipeline::sUseOcclusion = 0; |
237 | BOOL LLPipeline::sDelayVBUpdate = TRUE; | ||
234 | BOOL LLPipeline::sFastAlpha = TRUE; | 238 | BOOL LLPipeline::sFastAlpha = TRUE; |
235 | BOOL LLPipeline::sDisableShaders = FALSE; | 239 | BOOL LLPipeline::sDisableShaders = FALSE; |
236 | BOOL LLPipeline::sRenderBump = TRUE; | 240 | BOOL LLPipeline::sRenderBump = TRUE; |
237 | BOOL LLPipeline::sUseFarClip = TRUE; | 241 | BOOL LLPipeline::sUseFarClip = TRUE; |
242 | BOOL LLPipeline::sShadowRender = FALSE; | ||
238 | BOOL LLPipeline::sSkipUpdate = FALSE; | 243 | BOOL LLPipeline::sSkipUpdate = FALSE; |
239 | BOOL LLPipeline::sWaterReflections = FALSE; | 244 | BOOL LLPipeline::sWaterReflections = FALSE; |
240 | BOOL LLPipeline::sRenderGlow = FALSE; | 245 | BOOL LLPipeline::sRenderGlow = FALSE; |
@@ -245,6 +250,8 @@ BOOL LLPipeline::sTextureBindTest = FALSE; | |||
245 | BOOL LLPipeline::sRenderFrameTest = FALSE; | 250 | BOOL LLPipeline::sRenderFrameTest = FALSE; |
246 | BOOL LLPipeline::sRenderAttachedLights = TRUE; | 251 | BOOL LLPipeline::sRenderAttachedLights = TRUE; |
247 | BOOL LLPipeline::sRenderAttachedParticles = TRUE; | 252 | BOOL LLPipeline::sRenderAttachedParticles = TRUE; |
253 | BOOL LLPipeline::sRenderDeferred = FALSE; | ||
254 | S32 LLPipeline::sVisibleLightCount = 0; | ||
248 | 255 | ||
249 | static LLCullResult* sCull = NULL; | 256 | static LLCullResult* sCull = NULL; |
250 | 257 | ||
@@ -260,6 +267,13 @@ static const U32 gl_cube_face[] = | |||
260 | 267 | ||
261 | void validate_framebuffer_object(); | 268 | void validate_framebuffer_object(); |
262 | 269 | ||
270 | void addDeferredAttachments(LLRenderTarget& target) | ||
271 | { | ||
272 | target.addColorAttachment(GL_RGBA16F_ARB); //specular | ||
273 | target.addColorAttachment(GL_RGBA16F_ARB); //normal+z | ||
274 | target.addColorAttachment(GL_RGBA16F_ARB); //position | ||
275 | } | ||
276 | |||
263 | LLPipeline::LLPipeline() : | 277 | LLPipeline::LLPipeline() : |
264 | mBackfaceCull(FALSE), | 278 | mBackfaceCull(FALSE), |
265 | mBatchCount(0), | 279 | mBatchCount(0), |
@@ -275,9 +289,6 @@ LLPipeline::LLPipeline() : | |||
275 | mGeometryChanges(0), | 289 | mGeometryChanges(0), |
276 | mNumVisibleFaces(0), | 290 | mNumVisibleFaces(0), |
277 | 291 | ||
278 | mCubeBuffer(NULL), | ||
279 | mCubeFrameBuffer(0), | ||
280 | mCubeDepth(0), | ||
281 | mInitialized(FALSE), | 292 | mInitialized(FALSE), |
282 | mVertexShadersEnabled(FALSE), | 293 | mVertexShadersEnabled(FALSE), |
283 | mVertexShadersLoaded(0), | 294 | mVertexShadersLoaded(0), |
@@ -292,6 +303,7 @@ LLPipeline::LLPipeline() : | |||
292 | mWaterPool(NULL), | 303 | mWaterPool(NULL), |
293 | mGroundPool(NULL), | 304 | mGroundPool(NULL), |
294 | mSimplePool(NULL), | 305 | mSimplePool(NULL), |
306 | mFullbrightPool(NULL), | ||
295 | mInvisiblePool(NULL), | 307 | mInvisiblePool(NULL), |
296 | mGlowPool(NULL), | 308 | mGlowPool(NULL), |
297 | mBumpPool(NULL), | 309 | mBumpPool(NULL), |
@@ -300,8 +312,7 @@ LLPipeline::LLPipeline() : | |||
300 | mLightMovingMask(0), | 312 | mLightMovingMask(0), |
301 | mLightingDetail(0) | 313 | mLightingDetail(0) |
302 | { | 314 | { |
303 | mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; | 315 | mNoiseMap = 0; |
304 | mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; | ||
305 | } | 316 | } |
306 | 317 | ||
307 | void LLPipeline::init() | 318 | void LLPipeline::init() |
@@ -320,6 +331,8 @@ void LLPipeline::init() | |||
320 | //create render pass pools | 331 | //create render pass pools |
321 | getPool(LLDrawPool::POOL_ALPHA); | 332 | getPool(LLDrawPool::POOL_ALPHA); |
322 | getPool(LLDrawPool::POOL_SIMPLE); | 333 | getPool(LLDrawPool::POOL_SIMPLE); |
334 | getPool(LLDrawPool::POOL_GRASS); | ||
335 | getPool(LLDrawPool::POOL_FULLBRIGHT); | ||
323 | getPool(LLDrawPool::POOL_INVISIBLE); | 336 | getPool(LLDrawPool::POOL_INVISIBLE); |
324 | getPool(LLDrawPool::POOL_BUMP); | 337 | getPool(LLDrawPool::POOL_BUMP); |
325 | getPool(LLDrawPool::POOL_GLOW); | 338 | getPool(LLDrawPool::POOL_GLOW); |
@@ -404,6 +417,8 @@ void LLPipeline::cleanup() | |||
404 | mGroundPool = NULL; | 417 | mGroundPool = NULL; |
405 | delete mSimplePool; | 418 | delete mSimplePool; |
406 | mSimplePool = NULL; | 419 | mSimplePool = NULL; |
420 | delete mFullbrightPool; | ||
421 | mFullbrightPool = NULL; | ||
407 | delete mInvisiblePool; | 422 | delete mInvisiblePool; |
408 | mInvisiblePool = NULL; | 423 | mInvisiblePool = NULL; |
409 | delete mGlowPool; | 424 | delete mGlowPool; |
@@ -455,52 +470,103 @@ void LLPipeline::resizeScreenTexture() | |||
455 | GLuint resY = gViewerWindow->getWindowDisplayHeight(); | 470 | GLuint resY = gViewerWindow->getWindowDisplayHeight(); |
456 | 471 | ||
457 | U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); | 472 | U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); |
458 | if (res_mod > 1) | 473 | if (res_mod > 1 && res_mod < resX && res_mod < resY) |
459 | { | 474 | { |
460 | resX /= res_mod; | 475 | resX /= res_mod; |
461 | resY /= res_mod; | 476 | resY /= res_mod; |
462 | } | 477 | } |
463 | 478 | ||
464 | mScreen.release(); | 479 | allocateScreenBuffer(resX,resY); |
465 | mScreen.allocate(resX, resY, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE); | ||
466 | 480 | ||
467 | llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; | 481 | llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; |
468 | } | 482 | } |
469 | } | 483 | } |
470 | 484 | ||
471 | 485 | void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) | |
472 | void LLPipeline::releaseGLBuffers() | ||
473 | { | 486 | { |
474 | assertInitialized(); | 487 | U32 samples = gSavedSettings.getU32("RenderFSAASamples"); |
475 | 488 | if (LLPipeline::sRenderDeferred) | |
476 | if (mCubeBuffer) | ||
477 | { | 489 | { |
478 | mCubeBuffer = NULL; | 490 | //allocate deferred rendering color buffers |
491 | mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); | ||
492 | addDeferredAttachments(mDeferredScreen); | ||
493 | mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); | ||
494 | |||
495 | for (U32 i = 0; i < 2; i++) | ||
496 | { | ||
497 | mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); | ||
498 | } | ||
479 | } | 499 | } |
480 | 500 | else | |
481 | if (mCubeFrameBuffer) | ||
482 | { | 501 | { |
483 | glDeleteFramebuffersEXT(1, &mCubeFrameBuffer); | 502 | mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); |
484 | glDeleteRenderbuffersEXT(1, &mCubeDepth); | ||
485 | mCubeDepth = mCubeFrameBuffer = 0; | ||
486 | } | 503 | } |
504 | |||
487 | 505 | ||
488 | if (mBlurCubeBuffer[0]) | 506 | if (gGLManager.mHasFramebufferMultisample && samples > 1) |
489 | { | 507 | { |
490 | glDeleteFramebuffersEXT(3, mBlurCubeBuffer); | 508 | if (LLPipeline::sRenderDeferred) |
491 | mBlurCubeBuffer[0] = mBlurCubeBuffer[1] = mBlurCubeBuffer[2] = 0; | 509 | { |
510 | mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); | ||
511 | addDeferredAttachments(mSampleBuffer); | ||
512 | mDeferredScreen.setSampleBuffer(&mSampleBuffer); | ||
513 | } | ||
514 | else | ||
515 | { | ||
516 | mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); | ||
517 | } | ||
518 | |||
519 | mScreen.setSampleBuffer(&mSampleBuffer); | ||
520 | stop_glerror(); | ||
521 | } | ||
522 | else if (LLPipeline::sRenderDeferred) | ||
523 | { //share depth buffer between deferred targets | ||
524 | mDeferredScreen.shareDepthBuffer(mScreen); | ||
525 | for (U32 i = 0; i < 2; i++) | ||
526 | { | ||
527 | mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); | ||
528 | } | ||
492 | } | 529 | } |
493 | 530 | ||
494 | if (mBlurCubeTexture[0]) | 531 | gGL.getTexUnit(0)->disable(); |
532 | |||
533 | stop_glerror(); | ||
534 | |||
535 | } | ||
536 | |||
537 | //static | ||
538 | void LLPipeline::updateRenderDeferred() | ||
539 | { | ||
540 | BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") && | ||
541 | LLRenderTarget::sUseFBO && | ||
542 | gSavedSettings.getBOOL("VertexShaderEnable") && | ||
543 | gSavedSettings.getBOOL("RenderAvatarVP") && | ||
544 | gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE; | ||
545 | |||
546 | sRenderDeferred = deferred; | ||
547 | } | ||
548 | |||
549 | void LLPipeline::releaseGLBuffers() | ||
550 | { | ||
551 | assertInitialized(); | ||
552 | |||
553 | if (mNoiseMap) | ||
495 | { | 554 | { |
496 | glDeleteTextures(3, mBlurCubeTexture); | 555 | LLImageGL::deleteTextures(1, &mNoiseMap); |
497 | mBlurCubeTexture[0] = mBlurCubeTexture[1] = mBlurCubeTexture[2] = 0; | 556 | mNoiseMap = 0; |
498 | } | 557 | } |
499 | 558 | ||
500 | mWaterRef.release(); | 559 | mWaterRef.release(); |
501 | mWaterDis.release(); | 560 | mWaterDis.release(); |
502 | mScreen.release(); | 561 | mScreen.release(); |
503 | 562 | mSampleBuffer.releaseSampleBuffer(); | |
563 | mDeferredScreen.release(); | ||
564 | |||
565 | |||
566 | for (U32 i = 0; i < 4; i++) | ||
567 | { | ||
568 | mSunShadow[i].release(); | ||
569 | } | ||
504 | for (U32 i = 0; i < 3; i++) | 570 | for (U32 i = 0; i < 3; i++) |
505 | { | 571 | { |
506 | mGlow[i].release(); | 572 | mGlow[i].release(); |
@@ -513,72 +579,17 @@ void LLPipeline::createGLBuffers() | |||
513 | { | 579 | { |
514 | assertInitialized(); | 580 | assertInitialized(); |
515 | 581 | ||
582 | updateRenderDeferred(); | ||
583 | |||
516 | if (LLPipeline::sWaterReflections) | 584 | if (LLPipeline::sWaterReflections) |
517 | { //water reflection texture | 585 | { //water reflection texture |
518 | U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); | 586 | U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); |
519 | 587 | ||
520 | mWaterRef.allocate(res,res,GL_RGBA,TRUE); | 588 | mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); |
521 | mWaterDis.allocate(res,res,GL_RGBA,TRUE); | 589 | mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE); |
522 | |||
523 | #if 0 //cube map buffers (keep for future work) | ||
524 | { | ||
525 | //reflection map generation buffers | ||
526 | if (mCubeFrameBuffer == 0) | ||
527 | { | ||
528 | glGenFramebuffersEXT(1, &mCubeFrameBuffer); | ||
529 | glGenRenderbuffersEXT(1, &mCubeDepth); | ||
530 | |||
531 | U32 res = REFLECTION_MAP_RES; | ||
532 | |||
533 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, mCubeDepth); | ||
534 | |||
535 | glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,res,res); | ||
536 | |||
537 | glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); | ||
538 | } | ||
539 | |||
540 | if (mCubeBuffer.isNull()) | ||
541 | { | ||
542 | res = 128; | ||
543 | mCubeBuffer = new LLCubeMap(); | ||
544 | mCubeBuffer->initGL(); | ||
545 | mCubeBuffer->setReflection(); | ||
546 | |||
547 | for (U32 i = 0; i < 6; i++) | ||
548 | { | ||
549 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | if (mBlurCubeBuffer[0] == 0) | ||
554 | { | ||
555 | glGenFramebuffersEXT(3, mBlurCubeBuffer); | ||
556 | } | ||
557 | |||
558 | if (mBlurCubeTexture[0] == 0) | ||
559 | { | ||
560 | glGenTextures(3, mBlurCubeTexture); | ||
561 | } | ||
562 | |||
563 | res = (U32) gSavedSettings.getS32("RenderReflectionRes"); | ||
564 | |||
565 | for (U32 j = 0; j < 3; j++) | ||
566 | { | ||
567 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, mBlurCubeTexture[j]); | ||
568 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
569 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
570 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | ||
571 | glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | ||
572 | |||
573 | for (U32 i = 0; i < 6; i++) | ||
574 | { | ||
575 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | #endif | ||
580 | } | 590 | } |
581 | 591 | ||
592 | |||
582 | stop_glerror(); | 593 | stop_glerror(); |
583 | 594 | ||
584 | if (LLPipeline::sRenderGlow) | 595 | if (LLPipeline::sRenderGlow) |
@@ -588,14 +599,41 @@ void LLPipeline::createGLBuffers() | |||
588 | 599 | ||
589 | for (U32 i = 0; i < 3; i++) | 600 | for (U32 i = 0; i < 3; i++) |
590 | { | 601 | { |
591 | mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE); | 602 | mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); |
592 | } | 603 | } |
593 | 604 | } | |
594 | 605 | ||
595 | GLuint resX = gViewerWindow->getWindowDisplayWidth(); | 606 | GLuint resX = gViewerWindow->getWindowDisplayWidth(); |
596 | GLuint resY = gViewerWindow->getWindowDisplayHeight(); | 607 | GLuint resY = gViewerWindow->getWindowDisplayHeight(); |
597 | 608 | ||
598 | mScreen.allocate(resX, resY, GL_RGBA, TRUE, LLTexUnit::TT_RECT_TEXTURE); | 609 | allocateScreenBuffer(resX,resY); |
610 | |||
611 | if (sRenderDeferred) | ||
612 | { | ||
613 | mSunShadow[0].allocate(1024,1024, 0, TRUE, FALSE); | ||
614 | mSunShadow[1].allocate(1024,1024, 0, TRUE, FALSE); | ||
615 | mSunShadow[2].allocate(1024,1024, 0, TRUE, FALSE); | ||
616 | mSunShadow[3].allocate(1024,1024, 0, TRUE, FALSE); | ||
617 | |||
618 | if (!mNoiseMap) | ||
619 | { | ||
620 | const U32 noiseRes = 128; | ||
621 | LLVector3 noise[noiseRes*noiseRes]; | ||
622 | |||
623 | F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f; | ||
624 | for (U32 i = 0; i < noiseRes*noiseRes; ++i) | ||
625 | { | ||
626 | noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f); | ||
627 | noise[i].normVec(); | ||
628 | noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f; | ||
629 | } | ||
630 | |||
631 | LLImageGL::generateTextures(1, &mNoiseMap); | ||
632 | |||
633 | gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); | ||
634 | LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); | ||
635 | gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); | ||
636 | } | ||
599 | } | 637 | } |
600 | } | 638 | } |
601 | 639 | ||
@@ -626,7 +664,8 @@ void LLPipeline::restoreGL() | |||
626 | 664 | ||
627 | BOOL LLPipeline::canUseVertexShaders() | 665 | BOOL LLPipeline::canUseVertexShaders() |
628 | { | 666 | { |
629 | if (!gGLManager.mHasVertexShader || | 667 | if (sDisableShaders || |
668 | !gGLManager.mHasVertexShader || | ||
630 | !gGLManager.mHasFragmentShader || | 669 | !gGLManager.mHasFragmentShader || |
631 | !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") || | 670 | !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") || |
632 | (assertInitialized() && mVertexShadersLoaded != 1) ) | 671 | (assertInitialized() && mVertexShadersLoaded != 1) ) |
@@ -784,6 +823,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) | |||
784 | poolp = mSimplePool; | 823 | poolp = mSimplePool; |
785 | break; | 824 | break; |
786 | 825 | ||
826 | case LLDrawPool::POOL_GRASS: | ||
827 | poolp = mGrassPool; | ||
828 | break; | ||
829 | |||
830 | case LLDrawPool::POOL_FULLBRIGHT: | ||
831 | poolp = mFullbrightPool; | ||
832 | break; | ||
833 | |||
787 | case LLDrawPool::POOL_INVISIBLE: | 834 | case LLDrawPool::POOL_INVISIBLE: |
788 | poolp = mInvisiblePool; | 835 | poolp = mInvisiblePool; |
789 | break; | 836 | break; |
@@ -963,19 +1010,61 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) | |||
963 | 1010 | ||
964 | U32 LLPipeline::addObject(LLViewerObject *vobj) | 1011 | U32 LLPipeline::addObject(LLViewerObject *vobj) |
965 | { | 1012 | { |
966 | LLMemType mt(LLMemType::MTYPE_DRAWABLE); | ||
967 | if (gNoRender) | 1013 | if (gNoRender) |
968 | { | 1014 | { |
969 | return 0; | 1015 | return 0; |
970 | } | 1016 | } |
971 | 1017 | ||
1018 | if (gSavedSettings.getBOOL("RenderDelayCreation")) | ||
1019 | { | ||
1020 | mCreateQ.push_back(vobj); | ||
1021 | } | ||
1022 | else | ||
1023 | { | ||
1024 | createObject(vobj); | ||
1025 | } | ||
1026 | |||
1027 | return 1; | ||
1028 | } | ||
1029 | |||
1030 | void LLPipeline::createObjects(F32 max_dtime) | ||
1031 | { | ||
1032 | LLFastTimer ftm(LLFastTimer::FTM_GEO_UPDATE); | ||
1033 | LLMemType mt(LLMemType::MTYPE_DRAWABLE); | ||
1034 | |||
1035 | LLTimer update_timer; | ||
1036 | |||
1037 | while (!mCreateQ.empty() && update_timer.getElapsedTimeF32() < max_dtime) | ||
1038 | { | ||
1039 | LLViewerObject* vobj = mCreateQ.front(); | ||
1040 | if (!vobj->isDead()) | ||
1041 | { | ||
1042 | createObject(vobj); | ||
1043 | } | ||
1044 | mCreateQ.pop_front(); | ||
1045 | } | ||
1046 | |||
1047 | //for (LLViewerObject::vobj_list_t::iterator iter = mCreateQ.begin(); iter != mCreateQ.end(); ++iter) | ||
1048 | //{ | ||
1049 | // createObject(*iter); | ||
1050 | //} | ||
1051 | |||
1052 | //mCreateQ.clear(); | ||
1053 | } | ||
1054 | |||
1055 | void LLPipeline::createObject(LLViewerObject* vobj) | ||
1056 | { | ||
972 | LLDrawable* drawablep = vobj->mDrawable; | 1057 | LLDrawable* drawablep = vobj->mDrawable; |
973 | 1058 | ||
974 | if (!drawablep) | 1059 | if (!drawablep) |
975 | { | 1060 | { |
976 | drawablep = vobj->createDrawable(this); | 1061 | drawablep = vobj->createDrawable(this); |
977 | } | 1062 | } |
978 | 1063 | else | |
1064 | { | ||
1065 | llerrs << "Redundant drawable creation!" << llendl; | ||
1066 | } | ||
1067 | |||
979 | llassert(drawablep); | 1068 | llassert(drawablep); |
980 | 1069 | ||
981 | if (vobj->getParent()) | 1070 | if (vobj->getParent()) |
@@ -989,7 +1078,14 @@ U32 LLPipeline::addObject(LLViewerObject *vobj) | |||
989 | 1078 | ||
990 | markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); | 1079 | markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); |
991 | 1080 | ||
992 | return 1; | 1081 | if (drawablep->getVOVolume() && gSavedSettings.getBOOL("RenderAnimateRes")) |
1082 | { | ||
1083 | // fun animated res | ||
1084 | drawablep->updateXform(TRUE); | ||
1085 | drawablep->clearState(LLDrawable::MOVE_UNDAMPED); | ||
1086 | drawablep->setScale(LLVector3(0,0,0)); | ||
1087 | drawablep->makeActive(); | ||
1088 | } | ||
993 | } | 1089 | } |
994 | 1090 | ||
995 | 1091 | ||
@@ -1194,6 +1290,65 @@ void LLPipeline::grabReferences(LLCullResult& result) | |||
1194 | sCull = &result; | 1290 | sCull = &result; |
1195 | } | 1291 | } |
1196 | 1292 | ||
1293 | BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) | ||
1294 | { | ||
1295 | for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); | ||
1296 | iter != LLWorld::getInstance()->getRegionList().end(); ++iter) | ||
1297 | { | ||
1298 | LLViewerRegion* region = *iter; | ||
1299 | |||
1300 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
1301 | { | ||
1302 | LLSpatialPartition* part = region->getSpatialPartition(i); | ||
1303 | if (part) | ||
1304 | { | ||
1305 | if (hasRenderType(part->mDrawableType)) | ||
1306 | { | ||
1307 | if (part->visibleObjectsInFrustum(camera)) | ||
1308 | { | ||
1309 | return TRUE; | ||
1310 | } | ||
1311 | } | ||
1312 | } | ||
1313 | } | ||
1314 | } | ||
1315 | |||
1316 | return FALSE; | ||
1317 | } | ||
1318 | |||
1319 | BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max) | ||
1320 | { | ||
1321 | min = LLVector3(F32_MAX, F32_MAX, F32_MAX); | ||
1322 | max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX); | ||
1323 | |||
1324 | |||
1325 | BOOL res = TRUE; | ||
1326 | |||
1327 | for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); | ||
1328 | iter != LLWorld::getInstance()->getRegionList().end(); ++iter) | ||
1329 | { | ||
1330 | LLViewerRegion* region = *iter; | ||
1331 | |||
1332 | for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) | ||
1333 | { | ||
1334 | LLSpatialPartition* part = region->getSpatialPartition(i); | ||
1335 | if (part) | ||
1336 | { | ||
1337 | if (hasRenderType(part->mDrawableType)) | ||
1338 | { | ||
1339 | if (!part->getVisibleExtents(camera, min, max)) | ||
1340 | { | ||
1341 | res = FALSE; | ||
1342 | } | ||
1343 | } | ||
1344 | } | ||
1345 | } | ||
1346 | } | ||
1347 | |||
1348 | return res; | ||
1349 | } | ||
1350 | |||
1351 | |||
1197 | void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) | 1352 | void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) |
1198 | { | 1353 | { |
1199 | LLFastTimer t(LLFastTimer::FTM_CULL); | 1354 | LLFastTimer t(LLFastTimer::FTM_CULL); |
@@ -1206,6 +1361,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl | |||
1206 | BOOL to_texture = LLPipeline::sUseOcclusion > 1 && | 1361 | BOOL to_texture = LLPipeline::sUseOcclusion > 1 && |
1207 | !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && | 1362 | !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && |
1208 | !sReflectionRender && | 1363 | !sReflectionRender && |
1364 | !sShadowRender && | ||
1209 | gPipeline.canUseVertexShaders() && | 1365 | gPipeline.canUseVertexShaders() && |
1210 | sRenderGlow; | 1366 | sRenderGlow; |
1211 | 1367 | ||
@@ -1216,6 +1372,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl | |||
1216 | 1372 | ||
1217 | glPushMatrix(); | 1373 | glPushMatrix(); |
1218 | gGLLastMatrix = NULL; | 1374 | gGLLastMatrix = NULL; |
1375 | //glLoadMatrixd(gGLModelView); | ||
1219 | glLoadMatrixd(gGLLastModelView); | 1376 | glLoadMatrixd(gGLLastModelView); |
1220 | 1377 | ||
1221 | LLVertexBuffer::unbind(); | 1378 | LLVertexBuffer::unbind(); |
@@ -1223,7 +1380,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl | |||
1223 | LLGLDisable test(GL_ALPHA_TEST); | 1380 | LLGLDisable test(GL_ALPHA_TEST); |
1224 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 1381 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
1225 | 1382 | ||
1226 | gGL.setColorMask(false, false); | 1383 | if (sUseOcclusion > 1) |
1384 | { | ||
1385 | gGL.setColorMask(false, false); | ||
1386 | } | ||
1387 | |||
1227 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | 1388 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); |
1228 | 1389 | ||
1229 | for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); | 1390 | for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); |
@@ -1281,13 +1442,17 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl | |||
1281 | sCull->pushDrawable(gSky.mVOGroundp->mDrawable); | 1442 | sCull->pushDrawable(gSky.mVOGroundp->mDrawable); |
1282 | } | 1443 | } |
1283 | 1444 | ||
1284 | gGL.setColorMask(true, false); | 1445 | |
1285 | glPopMatrix(); | 1446 | glPopMatrix(); |
1286 | 1447 | ||
1448 | if (sUseOcclusion > 1) | ||
1449 | { | ||
1450 | gGL.setColorMask(true, false); | ||
1451 | } | ||
1452 | |||
1287 | if (to_texture) | 1453 | if (to_texture) |
1288 | { | 1454 | { |
1289 | mScreen.flush(); | 1455 | mScreen.flush(); |
1290 | LLRenderTarget::unbindTarget(); | ||
1291 | } | 1456 | } |
1292 | else if (LLPipeline::sUseOcclusion > 1) | 1457 | else if (LLPipeline::sUseOcclusion > 1) |
1293 | { | 1458 | { |
@@ -1356,6 +1521,7 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) | |||
1356 | void LLPipeline::doOcclusion(LLCamera& camera) | 1521 | void LLPipeline::doOcclusion(LLCamera& camera) |
1357 | { | 1522 | { |
1358 | LLVertexBuffer::unbind(); | 1523 | LLVertexBuffer::unbind(); |
1524 | |||
1359 | if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) | 1525 | if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) |
1360 | { | 1526 | { |
1361 | gGL.setColorMask(true, false, false, false); | 1527 | gGL.setColorMask(true, false, false, false); |
@@ -1524,7 +1690,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) | |||
1524 | 1690 | ||
1525 | if (!drawablep) | 1691 | if (!drawablep) |
1526 | { | 1692 | { |
1527 | llerrs << "Sending null drawable to moved list!" << llendl; | 1693 | //llerrs << "Sending null drawable to moved list!" << llendl; |
1528 | return; | 1694 | return; |
1529 | } | 1695 | } |
1530 | 1696 | ||
@@ -1594,8 +1760,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) | |||
1594 | assertInitialized(); | 1760 | assertInitialized(); |
1595 | 1761 | ||
1596 | glClear(GL_DEPTH_BUFFER_BIT); | 1762 | glClear(GL_DEPTH_BUFFER_BIT); |
1597 | gDepthDirty = FALSE; | 1763 | gDepthDirty = TRUE; |
1598 | 1764 | ||
1599 | for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); | 1765 | for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); |
1600 | iter != mShiftList.end(); iter++) | 1766 | iter != mShiftList.end(); iter++) |
1601 | { | 1767 | { |
@@ -1771,6 +1937,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) | |||
1771 | stateSort(drawablep, camera); | 1937 | stateSort(drawablep, camera); |
1772 | } | 1938 | } |
1773 | } | 1939 | } |
1940 | |||
1774 | } | 1941 | } |
1775 | 1942 | ||
1776 | void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) | 1943 | void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) |
@@ -1778,7 +1945,8 @@ void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) | |||
1778 | LLMemType mt(LLMemType::MTYPE_PIPELINE); | 1945 | LLMemType mt(LLMemType::MTYPE_PIPELINE); |
1779 | if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) | 1946 | if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) |
1780 | { | 1947 | { |
1781 | bridge->updateDistance(camera); | 1948 | bool force_update = false; |
1949 | bridge->updateDistance(camera, force_update); | ||
1782 | } | 1950 | } |
1783 | } | 1951 | } |
1784 | 1952 | ||
@@ -1839,11 +2007,13 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | |||
1839 | { | 2007 | { |
1840 | if (!drawablep->isActive()) | 2008 | if (!drawablep->isActive()) |
1841 | { | 2009 | { |
1842 | drawablep->updateDistance(camera); | 2010 | bool force_update = false; |
2011 | drawablep->updateDistance(camera, force_update); | ||
1843 | } | 2012 | } |
1844 | else if (drawablep->isAvatar()) | 2013 | else if (drawablep->isAvatar()) |
1845 | { | 2014 | { |
1846 | drawablep->updateDistance(camera); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() | 2015 | bool force_update = false; |
2016 | drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() | ||
1847 | } | 2017 | } |
1848 | } | 2018 | } |
1849 | } | 2019 | } |
@@ -2044,6 +2214,22 @@ void LLPipeline::postSort(LLCamera& camera) | |||
2044 | } | 2214 | } |
2045 | LLSpatialGroup::sNoDelete = TRUE; | 2215 | LLSpatialGroup::sNoDelete = TRUE; |
2046 | 2216 | ||
2217 | |||
2218 | const S32 bin_count = 1024*8; | ||
2219 | |||
2220 | static LLCullResult::drawinfo_list_t alpha_bins[bin_count]; | ||
2221 | static U32 bin_size[bin_count]; | ||
2222 | |||
2223 | //clear one bin per frame to avoid memory bloat | ||
2224 | static S32 clear_idx = 0; | ||
2225 | clear_idx = (1+clear_idx)%bin_count; | ||
2226 | alpha_bins[clear_idx].clear(); | ||
2227 | |||
2228 | for (U32 j = 0; j < bin_count; j++) | ||
2229 | { | ||
2230 | bin_size[j] = 0; | ||
2231 | } | ||
2232 | |||
2047 | //build render map | 2233 | //build render map |
2048 | for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) | 2234 | for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) |
2049 | { | 2235 | { |
@@ -2063,7 +2249,7 @@ void LLPipeline::postSort(LLCamera& camera) | |||
2063 | sCull->pushDrawInfo(j->first, *k); | 2249 | sCull->pushDrawInfo(j->first, *k); |
2064 | } | 2250 | } |
2065 | } | 2251 | } |
2066 | 2252 | ||
2067 | LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); | 2253 | LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); |
2068 | 2254 | ||
2069 | if (alpha != group->mDrawMap.end()) | 2255 | if (alpha != group->mDrawMap.end()) |
@@ -2089,28 +2275,26 @@ void LLPipeline::postSort(LLCamera& camera) | |||
2089 | } | 2275 | } |
2090 | } | 2276 | } |
2091 | 2277 | ||
2278 | if (!sShadowRender) | ||
2092 | { | 2279 | { |
2093 | //sort by texture or bump map | 2280 | //sort by texture or bump map |
2094 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) | 2281 | for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) |
2095 | { | 2282 | { |
2096 | //if (!mRenderMap[i].empty()) | 2283 | if (i == LLRenderPass::PASS_BUMP) |
2097 | { | 2284 | { |
2098 | if (i == LLRenderPass::PASS_BUMP) | 2285 | std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump()); |
2099 | { | ||
2100 | std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump()); | ||
2101 | } | ||
2102 | else | ||
2103 | { | ||
2104 | std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix()); | ||
2105 | } | ||
2106 | } | 2286 | } |
2287 | else | ||
2288 | { | ||
2289 | std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix()); | ||
2290 | } | ||
2107 | } | 2291 | } |
2108 | 2292 | ||
2109 | std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); | 2293 | std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); |
2110 | } | 2294 | } |
2111 | 2295 | ||
2112 | // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus | 2296 | // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus |
2113 | if (gSavedSettings.getBOOL("BeaconsEnabled")) | 2297 | if (gSavedSettings.getBOOL("BeaconsEnabled") && !sShadowRender) |
2114 | { | 2298 | { |
2115 | if (sRenderScriptedTouchBeacons) | 2299 | if (sRenderScriptedTouchBeacons) |
2116 | { | 2300 | { |
@@ -2163,23 +2347,26 @@ void LLPipeline::postSort(LLCamera& camera) | |||
2163 | LLFloaterTelehub::addBeacons(); | 2347 | LLFloaterTelehub::addBeacons(); |
2164 | } | 2348 | } |
2165 | 2349 | ||
2166 | mSelectedFaces.clear(); | 2350 | if (!sShadowRender) |
2167 | |||
2168 | // Draw face highlights for selected faces. | ||
2169 | if (LLSelectMgr::getInstance()->getTEMode()) | ||
2170 | { | 2351 | { |
2171 | struct f : public LLSelectedTEFunctor | 2352 | mSelectedFaces.clear(); |
2353 | |||
2354 | // Draw face highlights for selected faces. | ||
2355 | if (LLSelectMgr::getInstance()->getTEMode()) | ||
2172 | { | 2356 | { |
2173 | virtual bool apply(LLViewerObject* object, S32 te) | 2357 | struct f : public LLSelectedTEFunctor |
2174 | { | 2358 | { |
2175 | if (object->mDrawable) | 2359 | virtual bool apply(LLViewerObject* object, S32 te) |
2176 | { | 2360 | { |
2177 | gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te)); | 2361 | if (object->mDrawable) |
2362 | { | ||
2363 | gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te)); | ||
2364 | } | ||
2365 | return true; | ||
2178 | } | 2366 | } |
2179 | return true; | 2367 | } func; |
2180 | } | 2368 | LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); |
2181 | } func; | 2369 | } |
2182 | LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func); | ||
2183 | } | 2370 | } |
2184 | 2371 | ||
2185 | LLSpatialGroup::sNoDelete = FALSE; | 2372 | LLSpatialGroup::sNoDelete = FALSE; |
@@ -2327,8 +2514,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2327 | stop_glerror(); | 2514 | stop_glerror(); |
2328 | gFrameStats.start(LLFrameStats::RENDER_SYNC); | 2515 | gFrameStats.start(LLFrameStats::RENDER_SYNC); |
2329 | 2516 | ||
2330 | glEnableClientState(GL_VERTEX_ARRAY); | ||
2331 | |||
2332 | LLVertexBuffer::unbind(); | 2517 | LLVertexBuffer::unbind(); |
2333 | 2518 | ||
2334 | // Do verification of GL state | 2519 | // Do verification of GL state |
@@ -2378,7 +2563,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2378 | } | 2563 | } |
2379 | 2564 | ||
2380 | gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep); | 2565 | gGL.getTexUnit(0)->bind(LLViewerImage::sDefaultImagep); |
2381 | LLViewerImage::sDefaultImagep->setClamp(FALSE, FALSE); | 2566 | LLViewerImage::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); |
2382 | 2567 | ||
2383 | ////////////////////////////////////////////// | 2568 | ////////////////////////////////////////////// |
2384 | // | 2569 | // |
@@ -2386,37 +2571,37 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2386 | // | 2571 | // |
2387 | // | 2572 | // |
2388 | stop_glerror(); | 2573 | stop_glerror(); |
2389 | BOOL occlude = sUseOcclusion > 1; | ||
2390 | 2574 | ||
2391 | U32 cur_type = 0; | ||
2392 | |||
2393 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); | 2575 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); |
2394 | 2576 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | |
2577 | { | ||
2578 | LLDrawPool *poolp = *iter; | ||
2579 | if (hasRenderType(poolp->getType())) | ||
2580 | { | ||
2581 | poolp->prerender(); | ||
2582 | } | ||
2583 | } | ||
2584 | |||
2395 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) | 2585 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) |
2396 | { | 2586 | { |
2397 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); | 2587 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); |
2398 | gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); | 2588 | gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); |
2399 | } | 2589 | } |
2400 | else if (gSavedSettings.getBOOL("RenderDeferred")) | ||
2401 | { | ||
2402 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred"); | ||
2403 | renderGeomDeferred(); | ||
2404 | } | ||
2405 | else | 2590 | else |
2406 | { | 2591 | { |
2407 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | 2592 | LLFastTimer t(LLFastTimer::FTM_POOLS); |
2593 | |||
2594 | // HACK: don't calculate local lights if we're rendering the HUD! | ||
2595 | // Removing this check will cause bad flickering when there are | ||
2596 | // HUD elements being rendered AND the user is in flycam mode -nyx | ||
2597 | if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) | ||
2408 | { | 2598 | { |
2409 | LLDrawPool *poolp = *iter; | 2599 | calcNearbyLights(camera); |
2410 | if (hasRenderType(poolp->getType())) | 2600 | setupHWLights(NULL); |
2411 | { | ||
2412 | poolp->prerender(); | ||
2413 | } | ||
2414 | } | 2601 | } |
2415 | 2602 | ||
2416 | 2603 | BOOL occlude = sUseOcclusion > 1; | |
2417 | LLFastTimer t(LLFastTimer::FTM_POOLS); | 2604 | U32 cur_type = 0; |
2418 | calcNearbyLights(camera); | ||
2419 | setupHWLights(NULL); | ||
2420 | 2605 | ||
2421 | pool_set_t::iterator iter1 = mPools.begin(); | 2606 | pool_set_t::iterator iter1 = mPools.begin(); |
2422 | while ( iter1 != mPools.end() ) | 2607 | while ( iter1 != mPools.end() ) |
@@ -2425,7 +2610,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2425 | 2610 | ||
2426 | cur_type = poolp->getType(); | 2611 | cur_type = poolp->getType(); |
2427 | 2612 | ||
2428 | if (occlude && cur_type > LLDrawPool::POOL_AVATAR) | 2613 | if (occlude && cur_type >= LLDrawPool::POOL_GRASS) |
2429 | { | 2614 | { |
2430 | occlude = FALSE; | 2615 | occlude = FALSE; |
2431 | gGLLastMatrix = NULL; | 2616 | gGLLastMatrix = NULL; |
@@ -2443,6 +2628,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2443 | 2628 | ||
2444 | for( S32 i = 0; i < poolp->getNumPasses(); i++ ) | 2629 | for( S32 i = 0; i < poolp->getNumPasses(); i++ ) |
2445 | { | 2630 | { |
2631 | LLVertexBuffer::unbind(); | ||
2446 | poolp->beginRenderPass(i); | 2632 | poolp->beginRenderPass(i); |
2447 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | 2633 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) |
2448 | { | 2634 | { |
@@ -2486,25 +2672,29 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2486 | iter1 = iter2; | 2672 | iter1 = iter2; |
2487 | stop_glerror(); | 2673 | stop_glerror(); |
2488 | } | 2674 | } |
2489 | } | ||
2490 | 2675 | ||
2491 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); | 2676 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); |
2492 | 2677 | ||
2493 | LLVertexBuffer::unbind(); | 2678 | LLVertexBuffer::unbind(); |
2679 | |||
2680 | gGLLastMatrix = NULL; | ||
2681 | glLoadMatrixd(gGLModelView); | ||
2682 | |||
2683 | if (occlude) | ||
2684 | { | ||
2685 | occlude = FALSE; | ||
2686 | gGLLastMatrix = NULL; | ||
2687 | glLoadMatrixd(gGLModelView); | ||
2688 | doOcclusion(camera); | ||
2689 | } | ||
2690 | } | ||
2691 | |||
2692 | LLVertexBuffer::unbind(); | ||
2494 | LLGLState::checkStates(); | 2693 | LLGLState::checkStates(); |
2495 | LLGLState::checkTextureChannels(); | 2694 | LLGLState::checkTextureChannels(); |
2496 | LLGLState::checkClientArrays(); | 2695 | LLGLState::checkClientArrays(); |
2497 | 2696 | ||
2498 | gGLLastMatrix = NULL; | 2697 | |
2499 | glLoadMatrixd(gGLModelView); | ||
2500 | |||
2501 | if (occlude) | ||
2502 | { | ||
2503 | occlude = FALSE; | ||
2504 | gGLLastMatrix = NULL; | ||
2505 | glLoadMatrixd(gGLModelView); | ||
2506 | doOcclusion(camera); | ||
2507 | } | ||
2508 | 2698 | ||
2509 | stop_glerror(); | 2699 | stop_glerror(); |
2510 | 2700 | ||
@@ -2529,7 +2719,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2529 | 2719 | ||
2530 | LLVertexBuffer::unbind(); | 2720 | LLVertexBuffer::unbind(); |
2531 | 2721 | ||
2532 | if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) | 2722 | if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) |
2533 | { | 2723 | { |
2534 | // Render debugging beacons. | 2724 | // Render debugging beacons. |
2535 | gObjectList.renderObjectBeacons(); | 2725 | gObjectList.renderObjectBeacons(); |
@@ -2556,13 +2746,284 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) | |||
2556 | LLGLState::checkClientArrays(); | 2746 | LLGLState::checkClientArrays(); |
2557 | } | 2747 | } |
2558 | 2748 | ||
2559 | void LLPipeline::renderGeomDeferred() | 2749 | void LLPipeline::renderGeomDeferred(LLCamera& camera) |
2560 | { | 2750 | { |
2561 | gDeferredDiffuseProgram.bind(); | 2751 | LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); |
2562 | gPipeline.renderObjects(LLRenderPass::PASS_SIMPLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL, TRUE); | 2752 | LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); |
2563 | gDeferredDiffuseProgram.unbind(); | 2753 | |
2754 | LLFastTimer t2(LLFastTimer::FTM_POOLS); | ||
2755 | |||
2756 | LLGLEnable cull(GL_CULL_FACE); | ||
2757 | |||
2758 | LLGLEnable stencil(GL_STENCIL_TEST); | ||
2759 | glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); | ||
2760 | stop_glerror(); | ||
2761 | glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); | ||
2762 | stop_glerror(); | ||
2763 | |||
2764 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
2765 | { | ||
2766 | LLDrawPool *poolp = *iter; | ||
2767 | if (hasRenderType(poolp->getType())) | ||
2768 | { | ||
2769 | poolp->prerender(); | ||
2770 | } | ||
2771 | } | ||
2772 | |||
2773 | LLGLEnable multisample(GL_MULTISAMPLE_ARB); | ||
2774 | |||
2775 | LLVertexBuffer::unbind(); | ||
2776 | |||
2777 | LLGLState::checkStates(); | ||
2778 | LLGLState::checkTextureChannels(); | ||
2779 | LLGLState::checkClientArrays(); | ||
2780 | |||
2781 | U32 cur_type = 0; | ||
2782 | |||
2783 | gGL.setColorMask(true, true); | ||
2784 | |||
2785 | pool_set_t::iterator iter1 = mPools.begin(); | ||
2786 | |||
2787 | while ( iter1 != mPools.end() ) | ||
2788 | { | ||
2789 | LLDrawPool *poolp = *iter1; | ||
2790 | |||
2791 | cur_type = poolp->getType(); | ||
2792 | |||
2793 | pool_set_t::iterator iter2 = iter1; | ||
2794 | if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0) | ||
2795 | { | ||
2796 | LLFastTimer t(LLFastTimer::FTM_POOLRENDER); | ||
2797 | |||
2798 | gGLLastMatrix = NULL; | ||
2799 | glLoadMatrixd(gGLModelView); | ||
2800 | |||
2801 | for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) | ||
2802 | { | ||
2803 | LLVertexBuffer::unbind(); | ||
2804 | poolp->beginDeferredPass(i); | ||
2805 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | ||
2806 | { | ||
2807 | LLDrawPool *p = *iter2; | ||
2808 | if (p->getType() != cur_type) | ||
2809 | { | ||
2810 | break; | ||
2811 | } | ||
2812 | |||
2813 | p->renderDeferred(i); | ||
2814 | } | ||
2815 | poolp->endDeferredPass(i); | ||
2816 | LLVertexBuffer::unbind(); | ||
2817 | |||
2818 | GLint depth; | ||
2819 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); | ||
2820 | if (depth > 3) | ||
2821 | { | ||
2822 | llerrs << "GL matrix stack corrupted!" << llendl; | ||
2823 | } | ||
2824 | LLGLState::checkStates(); | ||
2825 | LLGLState::checkTextureChannels(); | ||
2826 | LLGLState::checkClientArrays(); | ||
2827 | } | ||
2828 | } | ||
2829 | else | ||
2830 | { | ||
2831 | // Skip all pools of this type | ||
2832 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | ||
2833 | { | ||
2834 | LLDrawPool *p = *iter2; | ||
2835 | if (p->getType() != cur_type) | ||
2836 | { | ||
2837 | break; | ||
2838 | } | ||
2839 | } | ||
2840 | } | ||
2841 | iter1 = iter2; | ||
2842 | stop_glerror(); | ||
2843 | } | ||
2844 | |||
2845 | gGLLastMatrix = NULL; | ||
2846 | glLoadMatrixd(gGLModelView); | ||
2847 | |||
2848 | gGL.setColorMask(true, false); | ||
2849 | } | ||
2850 | |||
2851 | void LLPipeline::renderGeomPostDeferred(LLCamera& camera) | ||
2852 | { | ||
2853 | LLFastTimer t(LLFastTimer::FTM_POOLS); | ||
2854 | U32 cur_type = 0; | ||
2855 | |||
2856 | LLGLEnable cull(GL_CULL_FACE); | ||
2857 | |||
2858 | LLGLEnable multisample(GL_MULTISAMPLE_ARB); | ||
2859 | |||
2860 | calcNearbyLights(camera); | ||
2861 | setupHWLights(NULL); | ||
2862 | |||
2863 | gGL.setColorMask(true, false); | ||
2864 | |||
2865 | pool_set_t::iterator iter1 = mPools.begin(); | ||
2866 | BOOL occlude = LLPipeline::sUseOcclusion > 1; | ||
2867 | |||
2868 | while ( iter1 != mPools.end() ) | ||
2869 | { | ||
2870 | LLDrawPool *poolp = *iter1; | ||
2871 | |||
2872 | cur_type = poolp->getType(); | ||
2873 | |||
2874 | if (occlude && cur_type >= LLDrawPool::POOL_GRASS) | ||
2875 | { | ||
2876 | occlude = FALSE; | ||
2877 | gGLLastMatrix = NULL; | ||
2878 | glLoadMatrixd(gGLModelView); | ||
2879 | doOcclusion(camera); | ||
2880 | gGL.setColorMask(true, false); | ||
2881 | } | ||
2882 | |||
2883 | pool_set_t::iterator iter2 = iter1; | ||
2884 | if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0) | ||
2885 | { | ||
2886 | LLFastTimer t(LLFastTimer::FTM_POOLRENDER); | ||
2887 | |||
2888 | gGLLastMatrix = NULL; | ||
2889 | glLoadMatrixd(gGLModelView); | ||
2890 | |||
2891 | for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) | ||
2892 | { | ||
2893 | LLVertexBuffer::unbind(); | ||
2894 | poolp->beginPostDeferredPass(i); | ||
2895 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | ||
2896 | { | ||
2897 | LLDrawPool *p = *iter2; | ||
2898 | if (p->getType() != cur_type) | ||
2899 | { | ||
2900 | break; | ||
2901 | } | ||
2902 | |||
2903 | p->renderPostDeferred(i); | ||
2904 | } | ||
2905 | poolp->endPostDeferredPass(i); | ||
2906 | LLVertexBuffer::unbind(); | ||
2907 | |||
2908 | GLint depth; | ||
2909 | glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); | ||
2910 | if (depth > 3) | ||
2911 | { | ||
2912 | llerrs << "GL matrix stack corrupted!" << llendl; | ||
2913 | } | ||
2914 | LLGLState::checkStates(); | ||
2915 | LLGLState::checkTextureChannels(); | ||
2916 | LLGLState::checkClientArrays(); | ||
2917 | } | ||
2918 | } | ||
2919 | else | ||
2920 | { | ||
2921 | // Skip all pools of this type | ||
2922 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | ||
2923 | { | ||
2924 | LLDrawPool *p = *iter2; | ||
2925 | if (p->getType() != cur_type) | ||
2926 | { | ||
2927 | break; | ||
2928 | } | ||
2929 | } | ||
2930 | } | ||
2931 | iter1 = iter2; | ||
2932 | stop_glerror(); | ||
2933 | } | ||
2934 | |||
2935 | gGLLastMatrix = NULL; | ||
2936 | glLoadMatrixd(gGLModelView); | ||
2937 | |||
2938 | renderHighlights(); | ||
2939 | mHighlightFaces.clear(); | ||
2940 | |||
2941 | renderDebug(); | ||
2942 | |||
2943 | LLVertexBuffer::unbind(); | ||
2944 | |||
2945 | if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) | ||
2946 | { | ||
2947 | // Render debugging beacons. | ||
2948 | gObjectList.renderObjectBeacons(); | ||
2949 | LLHUDObject::renderAll(); | ||
2950 | gObjectList.resetObjectBeacons(); | ||
2951 | } | ||
2952 | |||
2953 | if (occlude) | ||
2954 | { | ||
2955 | occlude = FALSE; | ||
2956 | gGLLastMatrix = NULL; | ||
2957 | glLoadMatrixd(gGLModelView); | ||
2958 | doOcclusion(camera); | ||
2959 | } | ||
2960 | } | ||
2961 | |||
2962 | void LLPipeline::renderGeomShadow(LLCamera& camera) | ||
2963 | { | ||
2964 | U32 cur_type = 0; | ||
2965 | |||
2966 | LLGLEnable cull(GL_CULL_FACE); | ||
2967 | |||
2968 | LLVertexBuffer::unbind(); | ||
2969 | |||
2970 | pool_set_t::iterator iter1 = mPools.begin(); | ||
2971 | |||
2972 | while ( iter1 != mPools.end() ) | ||
2973 | { | ||
2974 | LLDrawPool *poolp = *iter1; | ||
2975 | |||
2976 | cur_type = poolp->getType(); | ||
2977 | |||
2978 | pool_set_t::iterator iter2 = iter1; | ||
2979 | if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) | ||
2980 | { | ||
2981 | gGLLastMatrix = NULL; | ||
2982 | glLoadMatrixd(gGLModelView); | ||
2983 | |||
2984 | for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) | ||
2985 | { | ||
2986 | LLVertexBuffer::unbind(); | ||
2987 | poolp->beginShadowPass(i); | ||
2988 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | ||
2989 | { | ||
2990 | LLDrawPool *p = *iter2; | ||
2991 | if (p->getType() != cur_type) | ||
2992 | { | ||
2993 | break; | ||
2994 | } | ||
2995 | |||
2996 | p->renderShadow(i); | ||
2997 | } | ||
2998 | poolp->endShadowPass(i); | ||
2999 | LLVertexBuffer::unbind(); | ||
3000 | |||
3001 | LLGLState::checkStates(); | ||
3002 | LLGLState::checkTextureChannels(); | ||
3003 | LLGLState::checkClientArrays(); | ||
3004 | } | ||
3005 | } | ||
3006 | else | ||
3007 | { | ||
3008 | // Skip all pools of this type | ||
3009 | for (iter2 = iter1; iter2 != mPools.end(); iter2++) | ||
3010 | { | ||
3011 | LLDrawPool *p = *iter2; | ||
3012 | if (p->getType() != cur_type) | ||
3013 | { | ||
3014 | break; | ||
3015 | } | ||
3016 | } | ||
3017 | } | ||
3018 | iter1 = iter2; | ||
3019 | stop_glerror(); | ||
3020 | } | ||
3021 | |||
3022 | gGLLastMatrix = NULL; | ||
3023 | glLoadMatrixd(gGLModelView); | ||
2564 | } | 3024 | } |
2565 | 3025 | ||
3026 | |||
2566 | void LLPipeline::addTrianglesDrawn(S32 count) | 3027 | void LLPipeline::addTrianglesDrawn(S32 count) |
2567 | { | 3028 | { |
2568 | assertInitialized(); | 3029 | assertInitialized(); |
@@ -2608,7 +3069,7 @@ void LLPipeline::renderDebug() | |||
2608 | } | 3069 | } |
2609 | } | 3070 | } |
2610 | 3071 | ||
2611 | for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) | 3072 | for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) |
2612 | { | 3073 | { |
2613 | LLSpatialBridge* bridge = *i; | 3074 | LLSpatialBridge* bridge = *i; |
2614 | if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) | 3075 | if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) |
@@ -2620,6 +3081,99 @@ void LLPipeline::renderDebug() | |||
2620 | } | 3081 | } |
2621 | } | 3082 | } |
2622 | 3083 | ||
3084 | if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) | ||
3085 | { | ||
3086 | gGL.color4f(1,1,1,1); | ||
3087 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
3088 | |||
3089 | F32 col[] = | ||
3090 | { | ||
3091 | 1,1,0, | ||
3092 | 0,1,1, | ||
3093 | 1,0,1, | ||
3094 | 1,1,1, | ||
3095 | 1,0,0, | ||
3096 | 0,1,0, | ||
3097 | 0,0,1, | ||
3098 | 0,0,0 | ||
3099 | }; | ||
3100 | |||
3101 | for (U32 i = 0; i < 8; i++) | ||
3102 | { | ||
3103 | gGL.color3fv(col+i*3); | ||
3104 | |||
3105 | gGL.begin(LLRender::LINES); | ||
3106 | |||
3107 | LLVector3* frust = mShadowCamera[i].mAgentFrustum; | ||
3108 | |||
3109 | gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); | ||
3110 | gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); | ||
3111 | gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); | ||
3112 | gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); | ||
3113 | |||
3114 | gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); | ||
3115 | gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); | ||
3116 | gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); | ||
3117 | gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); | ||
3118 | |||
3119 | gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); | ||
3120 | gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); | ||
3121 | gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); | ||
3122 | gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); | ||
3123 | |||
3124 | if (i < 4) | ||
3125 | { | ||
3126 | LLVector3* ext = mShadowExtents[i]; | ||
3127 | |||
3128 | LLVector3 box[] = | ||
3129 | { | ||
3130 | LLVector3(ext[0][0], ext[0][1], ext[0][2]), | ||
3131 | LLVector3(ext[1][0], ext[0][1], ext[0][2]), | ||
3132 | LLVector3(ext[1][0], ext[1][1], ext[0][2]), | ||
3133 | LLVector3(ext[0][0], ext[1][1], ext[0][2]), | ||
3134 | LLVector3(ext[0][0], ext[0][1], ext[1][2]), | ||
3135 | LLVector3(ext[1][0], ext[0][1], ext[1][2]), | ||
3136 | LLVector3(ext[1][0], ext[1][1], ext[1][2]), | ||
3137 | LLVector3(ext[0][0], ext[1][1], ext[1][2]), | ||
3138 | }; | ||
3139 | |||
3140 | gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV); | ||
3141 | gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV); | ||
3142 | gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV); | ||
3143 | gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV); | ||
3144 | |||
3145 | gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV); | ||
3146 | gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV); | ||
3147 | gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV); | ||
3148 | gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV); | ||
3149 | |||
3150 | gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV); | ||
3151 | gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV); | ||
3152 | gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV); | ||
3153 | gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV); | ||
3154 | } | ||
3155 | |||
3156 | gGL.end(); | ||
3157 | |||
3158 | for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); | ||
3159 | iter != LLWorld::getInstance()->getRegionList().end(); ++iter) | ||
3160 | { | ||
3161 | LLViewerRegion* region = *iter; | ||
3162 | for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) | ||
3163 | { | ||
3164 | LLSpatialPartition* part = region->getSpatialPartition(j); | ||
3165 | if (part) | ||
3166 | { | ||
3167 | if (hasRenderType(part->mDrawableType)) | ||
3168 | { | ||
3169 | part->renderIntersectingBBoxes(&mShadowCamera[i]); | ||
3170 | } | ||
3171 | } | ||
3172 | } | ||
3173 | } | ||
3174 | } | ||
3175 | } | ||
3176 | |||
2623 | if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) | 3177 | if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) |
2624 | { | 3178 | { |
2625 | // Debug composition layers | 3179 | // Debug composition layers |
@@ -2652,6 +3206,7 @@ void LLPipeline::renderDebug() | |||
2652 | gGL.end(); | 3206 | gGL.end(); |
2653 | } | 3207 | } |
2654 | } | 3208 | } |
3209 | |||
2655 | gGL.flush(); | 3210 | gGL.flush(); |
2656 | } | 3211 | } |
2657 | 3212 | ||
@@ -2734,7 +3289,7 @@ void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render | |||
2734 | gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); | 3289 | gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); |
2735 | 3290 | ||
2736 | U32 prim_mask = LLVertexBuffer::MAP_VERTEX | | 3291 | U32 prim_mask = LLVertexBuffer::MAP_VERTEX | |
2737 | LLVertexBuffer::MAP_TEXCOORD; | 3292 | LLVertexBuffer::MAP_TEXCOORD0; |
2738 | 3293 | ||
2739 | for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i) | 3294 | for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i) |
2740 | { | 3295 | { |
@@ -2890,6 +3445,30 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp ) | |||
2890 | } | 3445 | } |
2891 | break; | 3446 | break; |
2892 | 3447 | ||
3448 | case LLDrawPool::POOL_GRASS: | ||
3449 | if (mGrassPool) | ||
3450 | { | ||
3451 | llassert(0); | ||
3452 | llwarns << "Ignoring duplicate grass pool." << llendl; | ||
3453 | } | ||
3454 | else | ||
3455 | { | ||
3456 | mGrassPool = (LLRenderPass*) new_poolp; | ||
3457 | } | ||
3458 | break; | ||
3459 | |||
3460 | case LLDrawPool::POOL_FULLBRIGHT: | ||
3461 | if (mFullbrightPool) | ||
3462 | { | ||
3463 | llassert(0); | ||
3464 | llwarns << "Ignoring duplicate simple pool." << llendl; | ||
3465 | } | ||
3466 | else | ||
3467 | { | ||
3468 | mFullbrightPool = (LLRenderPass*) new_poolp; | ||
3469 | } | ||
3470 | break; | ||
3471 | |||
2893 | case LLDrawPool::POOL_INVISIBLE: | 3472 | case LLDrawPool::POOL_INVISIBLE: |
2894 | if (mInvisiblePool) | 3473 | if (mInvisiblePool) |
2895 | { | 3474 | { |
@@ -3023,6 +3602,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp ) | |||
3023 | mSimplePool = NULL; | 3602 | mSimplePool = NULL; |
3024 | break; | 3603 | break; |
3025 | 3604 | ||
3605 | case LLDrawPool::POOL_GRASS: | ||
3606 | llassert(mGrassPool == poolp); | ||
3607 | mGrassPool = NULL; | ||
3608 | break; | ||
3609 | |||
3610 | case LLDrawPool::POOL_FULLBRIGHT: | ||
3611 | llassert(mFullbrightPool == poolp); | ||
3612 | mFullbrightPool = NULL; | ||
3613 | break; | ||
3614 | |||
3026 | case LLDrawPool::POOL_INVISIBLE: | 3615 | case LLDrawPool::POOL_INVISIBLE: |
3027 | llassert(mInvisiblePool == poolp); | 3616 | llassert(mInvisiblePool == poolp); |
3028 | mInvisiblePool = NULL; | 3617 | mInvisiblePool = NULL; |
@@ -3116,7 +3705,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) | |||
3116 | 3705 | ||
3117 | if (for_edit) | 3706 | if (for_edit) |
3118 | { | 3707 | { |
3119 | LLColor4 diffuse(0.8f, 0.8f, 0.8f, 0.f); | 3708 | LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); |
3120 | LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light | 3709 | LLVector4 light_pos_cam(-8.f, 0.25f, 10.f, 0.f); // w==0 => directional light |
3121 | LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); | 3710 | LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); |
3122 | LLMatrix4 camera_rot(camera_mat.getMat3()); | 3711 | LLMatrix4 camera_rot(camera_mat.getMat3()); |
@@ -3287,6 +3876,10 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) | |||
3287 | { | 3876 | { |
3288 | continue; | 3877 | continue; |
3289 | } | 3878 | } |
3879 | if (!sRenderAttachedLights && light && light->isAttachment()) | ||
3880 | { | ||
3881 | continue; | ||
3882 | } | ||
3290 | new_nearby_lights.insert(Light(drawable, dist, 0.f)); | 3883 | new_nearby_lights.insert(Light(drawable, dist, 0.f)); |
3291 | if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) | 3884 | if (new_nearby_lights.size() > (U32)MAX_LOCAL_LIGHTS) |
3292 | { | 3885 | { |
@@ -4281,11 +4874,11 @@ void LLPipeline::resetVertexBuffers() | |||
4281 | void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) | 4874 | void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) |
4282 | { | 4875 | { |
4283 | assertInitialized(); | 4876 | assertInitialized(); |
4877 | glLoadMatrixd(gGLModelView); | ||
4284 | gGLLastMatrix = NULL; | 4878 | gGLLastMatrix = NULL; |
4285 | glLoadMatrixd(gGLLastModelView); | 4879 | mSimplePool->pushBatches(type, mask); |
4286 | mSimplePool->renderGroups(type, mask, texture); | 4880 | glLoadMatrixd(gGLModelView); |
4287 | gGLLastMatrix = NULL; | 4881 | gGLLastMatrix = NULL; |
4288 | glLoadMatrixd(gGLLastModelView); | ||
4289 | } | 4882 | } |
4290 | 4883 | ||
4291 | void LLPipeline::setUseVBO(BOOL use_vbo) | 4884 | void LLPipeline::setUseVBO(BOOL use_vbo) |
@@ -4333,191 +4926,6 @@ void apply_cube_face_rotation(U32 face) | |||
4333 | break; | 4926 | break; |
4334 | } | 4927 | } |
4335 | } | 4928 | } |
4336 | void LLPipeline::generateReflectionMap(LLCubeMap* cube_map, LLCamera& cube_cam) | ||
4337 | { | ||
4338 | LLGLState::checkStates(); | ||
4339 | LLGLState::checkTextureChannels(); | ||
4340 | LLGLState::checkClientArrays(); | ||
4341 | |||
4342 | assertInitialized(); | ||
4343 | |||
4344 | //render dynamic cube map | ||
4345 | U32 type_mask = gPipeline.getRenderTypeMask(); | ||
4346 | S32 use_occlusion = LLPipeline::sUseOcclusion; | ||
4347 | LLPipeline::sUseOcclusion = 0; | ||
4348 | LLPipeline::sSkipUpdate = TRUE; | ||
4349 | U32 res = REFLECTION_MAP_RES; | ||
4350 | |||
4351 | LLPipeline::sReflectionRender = TRUE; | ||
4352 | |||
4353 | gGL.getTexUnit(cube_map->getStage())->bind(cube_map); | ||
4354 | gGL.getTexUnit(0)->activate(); | ||
4355 | GLint width; | ||
4356 | glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width); | ||
4357 | if (width != res) | ||
4358 | { | ||
4359 | cube_map->setReflection(); | ||
4360 | |||
4361 | for (U32 i = 0; i < 6; i++) | ||
4362 | { | ||
4363 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
4364 | } | ||
4365 | } | ||
4366 | gGL.getTexUnit(cube_map->getStage())->unbind(LLTexUnit::TT_CUBE_MAP); | ||
4367 | gGL.getTexUnit(cube_map->getStage())->disable(); | ||
4368 | gGL.getTexUnit(0)->activate(); | ||
4369 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | ||
4370 | |||
4371 | BOOL toggle_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); | ||
4372 | if (toggle_ui) | ||
4373 | { | ||
4374 | gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); | ||
4375 | } | ||
4376 | |||
4377 | U32 cube_mask = (1 << LLPipeline::RENDER_TYPE_SIMPLE) | | ||
4378 | (1 << LLPipeline::RENDER_TYPE_WATER) | | ||
4379 | //(1 << LLPipeline::RENDER_TYPE_BUMP) | | ||
4380 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | | ||
4381 | (1 << LLPipeline::RENDER_TYPE_TREE) | | ||
4382 | //(1 << LLPipeline::RENDER_TYPE_PARTICLES) | | ||
4383 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | ||
4384 | //(1 << LLPipeline::RENDER_TYPE_STARS) | | ||
4385 | //(1 << LLPipeline::RENDER_TYPE_AVATAR) | | ||
4386 | (1 << LLPipeline::RENDER_TYPE_GLOW) | | ||
4387 | (1 << LLPipeline::RENDER_TYPE_GRASS) | | ||
4388 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | | ||
4389 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | | ||
4390 | (1 << LLPipeline::RENDER_TYPE_SKY) | | ||
4391 | (1 << LLPipeline::RENDER_TYPE_WL_SKY) | | ||
4392 | (1 << LLPipeline::RENDER_TYPE_GROUND); | ||
4393 | |||
4394 | LLDrawPoolWater::sSkipScreenCopy = TRUE; | ||
4395 | LLPipeline::sSkipUpdate = TRUE; | ||
4396 | cube_mask = cube_mask & type_mask; | ||
4397 | gPipeline.setRenderTypeMask(cube_mask); | ||
4398 | |||
4399 | glMatrixMode(GL_PROJECTION); | ||
4400 | glPushMatrix(); | ||
4401 | glMatrixMode(GL_MODELVIEW); | ||
4402 | glPushMatrix(); | ||
4403 | |||
4404 | glViewport(0,0,res,res); | ||
4405 | |||
4406 | glClearColor(0,0,0,0); | ||
4407 | |||
4408 | LLVector3 origin = cube_cam.getOrigin(); | ||
4409 | |||
4410 | gPipeline.calcNearbyLights(cube_cam); | ||
4411 | |||
4412 | stop_glerror(); | ||
4413 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
4414 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); | ||
4415 | glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, | ||
4416 | GL_RENDERBUFFER_EXT, mCubeDepth); | ||
4417 | stop_glerror(); | ||
4418 | |||
4419 | for (S32 i = 0; i < 6; i++) | ||
4420 | { | ||
4421 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mCubeFrameBuffer); | ||
4422 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | ||
4423 | gl_cube_face[i], cube_map->getGLName(), 0); | ||
4424 | validate_framebuffer_object(); | ||
4425 | glMatrixMode(GL_PROJECTION); | ||
4426 | glLoadIdentity(); | ||
4427 | gluPerspective(90.f, 1.f, 0.1f, 1024.f); | ||
4428 | glMatrixMode(GL_MODELVIEW); | ||
4429 | glLoadIdentity(); | ||
4430 | |||
4431 | apply_cube_face_rotation(i); | ||
4432 | |||
4433 | glTranslatef(-origin.mV[0], -origin.mV[1], -origin.mV[2]); | ||
4434 | cube_cam.setOrigin(origin); | ||
4435 | LLViewerCamera::updateFrustumPlanes(cube_cam); | ||
4436 | cube_cam.setOrigin(LLViewerCamera::getInstance()->getOrigin()); | ||
4437 | static LLCullResult result; | ||
4438 | gPipeline.updateCull(cube_cam, result); | ||
4439 | gPipeline.stateSort(cube_cam, result); | ||
4440 | |||
4441 | glClearColor(0,0,0,0); | ||
4442 | gGL.setColorMask(true, true); | ||
4443 | glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); | ||
4444 | gGL.setColorMask(true, false); | ||
4445 | stop_glerror(); | ||
4446 | gPipeline.renderGeom(cube_cam); | ||
4447 | } | ||
4448 | |||
4449 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
4450 | |||
4451 | cube_cam.setOrigin(origin); | ||
4452 | gShinyOrigin.setVec(cube_cam.getOrigin(), cube_cam.getFar()*2.f); | ||
4453 | glMatrixMode(GL_PROJECTION); | ||
4454 | glPopMatrix(); | ||
4455 | glMatrixMode(GL_MODELVIEW); | ||
4456 | glPopMatrix(); | ||
4457 | |||
4458 | gViewerWindow->setupViewport(); | ||
4459 | |||
4460 | gPipeline.setRenderTypeMask(type_mask); | ||
4461 | LLPipeline::sUseOcclusion = use_occlusion; | ||
4462 | LLPipeline::sSkipUpdate = FALSE; | ||
4463 | |||
4464 | if (toggle_ui) | ||
4465 | { | ||
4466 | gPipeline.toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); | ||
4467 | } | ||
4468 | LLDrawPoolWater::sSkipScreenCopy = FALSE; | ||
4469 | LLPipeline::sSkipUpdate = FALSE; | ||
4470 | LLPipeline::sReflectionRender = FALSE; | ||
4471 | |||
4472 | LLGLState::checkStates(); | ||
4473 | LLGLState::checkTextureChannels(); | ||
4474 | LLGLState::checkClientArrays(); | ||
4475 | } | ||
4476 | |||
4477 | //send cube map vertices and texture coordinates | ||
4478 | void render_cube_map() | ||
4479 | { | ||
4480 | U16 idx[36]; | ||
4481 | |||
4482 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front | ||
4483 | idx[3] = 3; idx[4] = 2; idx[5] = 0; | ||
4484 | |||
4485 | idx[6] = 4; idx[7] = 5; idx[8] = 1; //top | ||
4486 | idx[9] = 0; idx[10] = 1; idx[11] = 5; | ||
4487 | |||
4488 | idx[12] = 5; idx[13] = 4; idx[14] = 6; //back | ||
4489 | idx[15] = 7; idx[16] = 6; idx[17] = 4; | ||
4490 | |||
4491 | idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom | ||
4492 | idx[21] = 2; idx[22] = 3; idx[23] = 7; | ||
4493 | |||
4494 | idx[24] = 0; idx[25] = 5; idx[26] = 3; //left | ||
4495 | idx[27] = 6; idx[28] = 3; idx[29] = 5; | ||
4496 | |||
4497 | idx[30] = 4; idx[31] = 1; idx[32] = 7; //right | ||
4498 | idx[33] = 2; idx[34] = 7; idx[35] = 1; | ||
4499 | |||
4500 | LLVector3 vert[8]; | ||
4501 | LLVector3 r = LLVector3(1,1,1); | ||
4502 | |||
4503 | vert[0] = r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front | ||
4504 | vert[1] = r.scaledVec(LLVector3(1,1,1)); // 1 - right top front | ||
4505 | vert[2] = r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front | ||
4506 | vert[3] = r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front | ||
4507 | |||
4508 | vert[4] = r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back | ||
4509 | vert[5] = r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back | ||
4510 | vert[6] = r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back | ||
4511 | vert[7] = r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back | ||
4512 | |||
4513 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4514 | glTexCoordPointer(3, GL_FLOAT, 0, vert); | ||
4515 | glVertexPointer(3, GL_FLOAT, 0, vert); | ||
4516 | |||
4517 | glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (GLushort*) idx); | ||
4518 | |||
4519 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4520 | } | ||
4521 | 4929 | ||
4522 | void validate_framebuffer_object() | 4930 | void validate_framebuffer_object() |
4523 | { | 4931 | { |
@@ -4546,132 +4954,12 @@ void validate_framebuffer_object() | |||
4546 | } | 4954 | } |
4547 | } | 4955 | } |
4548 | 4956 | ||
4549 | void LLPipeline::blurReflectionMap(LLCubeMap* cube_in, LLCubeMap* cube_out) | ||
4550 | { | ||
4551 | LLGLState::checkStates(); | ||
4552 | LLGLState::checkTextureChannels(); | ||
4553 | LLGLState::checkClientArrays(); | ||
4554 | |||
4555 | assertInitialized(); | ||
4556 | |||
4557 | U32 res = (U32) gSavedSettings.getS32("RenderReflectionRes"); | ||
4558 | enableLightsFullbright(LLColor4::white); | ||
4559 | LLGLDepthTest depth(GL_FALSE); | ||
4560 | gGL.setColorMask(true, true); | ||
4561 | glMatrixMode(GL_PROJECTION); | ||
4562 | glPushMatrix(); | ||
4563 | glLoadIdentity(); | ||
4564 | gluPerspective(90.f+45.f/res, 1.f, 0.1f, 1024.f); | ||
4565 | glMatrixMode(GL_MODELVIEW); | ||
4566 | glPushMatrix(); | ||
4567 | |||
4568 | cube_out->enableTexture(0); | ||
4569 | gGL.getTexUnit(cube_out->getStage())->bind(cube_out); | ||
4570 | gGL.getTexUnit(0)->activate(); | ||
4571 | GLint width; | ||
4572 | glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL_TEXTURE_WIDTH, &width); | ||
4573 | if (width != res) | ||
4574 | { | ||
4575 | cube_out->setReflection(); | ||
4576 | |||
4577 | for (U32 i = 0; i < 6; i++) | ||
4578 | { | ||
4579 | glTexImage2D(gl_cube_face[i], 0, GL_RGBA, res, res, 0, GL_RGBA, GL_FLOAT, NULL); | ||
4580 | } | ||
4581 | } | ||
4582 | gGL.getTexUnit(cube_out->getStage())->unbind(LLTexUnit::TT_CUBE_MAP); | ||
4583 | gGL.getTexUnit(0)->activate(); | ||
4584 | glViewport(0, 0, res, res); | ||
4585 | LLGLEnable blend(GL_BLEND); | ||
4586 | |||
4587 | S32 kernel = 2; | ||
4588 | F32 step = 90.f/res; | ||
4589 | F32 alpha = 1.f / ((kernel*2)+1); | ||
4590 | |||
4591 | gGL.color4f(alpha,alpha,alpha,alpha*1.25f); | ||
4592 | |||
4593 | LLVector3 axis[] = | ||
4594 | { | ||
4595 | LLVector3(1,0,0), | ||
4596 | LLVector3(0,1,0), | ||
4597 | LLVector3(0,0,1) | ||
4598 | }; | ||
4599 | |||
4600 | stop_glerror(); | ||
4601 | glViewport(0,0,res, res); | ||
4602 | gGL.setSceneBlendType(LLRender::BT_ADD); | ||
4603 | cube_in->enableTexture(0); | ||
4604 | //3-axis blur | ||
4605 | for (U32 j = 0; j < 3; j++) | ||
4606 | { | ||
4607 | stop_glerror(); | ||
4608 | |||
4609 | if (j == 0) | ||
4610 | { | ||
4611 | gGL.getTexUnit(cube_in->getStage())->bind(cube_in); | ||
4612 | } | ||
4613 | else | ||
4614 | { | ||
4615 | gGL.getTexUnit(cube_in->getStage())->bindManual(LLTexUnit::TT_CUBE_MAP, mBlurCubeTexture[j-1]); | ||
4616 | } | ||
4617 | gGL.getTexUnit(0)->activate(); | ||
4618 | |||
4619 | stop_glerror(); | ||
4620 | |||
4621 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
4622 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mBlurCubeBuffer[j]); | ||
4623 | stop_glerror(); | ||
4624 | |||
4625 | for (U32 i = 0; i < 6; i++) | ||
4626 | { | ||
4627 | stop_glerror(); | ||
4628 | glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, | ||
4629 | GL_COLOR_ATTACHMENT0_EXT, | ||
4630 | gl_cube_face[i], | ||
4631 | j < 2 ? mBlurCubeTexture[j] : cube_out->getGLName(), 0); | ||
4632 | validate_framebuffer_object(); | ||
4633 | gGL.setColorMask(true, true); | ||
4634 | glClear(GL_COLOR_BUFFER_BIT); | ||
4635 | glLoadIdentity(); | ||
4636 | apply_cube_face_rotation(i); | ||
4637 | for (S32 x = -kernel; x <= kernel; ++x) | ||
4638 | { | ||
4639 | glPushMatrix(); | ||
4640 | glRotatef(x*step, axis[j].mV[0], axis[j].mV[1], axis[j].mV[2]); | ||
4641 | render_cube_map(); | ||
4642 | glPopMatrix(); | ||
4643 | } | ||
4644 | stop_glerror(); | ||
4645 | } | ||
4646 | } | ||
4647 | |||
4648 | stop_glerror(); | ||
4649 | |||
4650 | gGL.getTexUnit(cube_in->getStage())->unbind(LLTexUnit::TT_CUBE_MAP); | ||
4651 | |||
4652 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | ||
4653 | gGL.setColorMask(true, false); | ||
4654 | glMatrixMode(GL_PROJECTION); | ||
4655 | glPopMatrix(); | ||
4656 | glMatrixMode(GL_MODELVIEW); | ||
4657 | glPopMatrix(); | ||
4658 | |||
4659 | gGL.getTexUnit(cube_in->getStage())->disable(); | ||
4660 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | ||
4661 | gViewerWindow->setupViewport(); | ||
4662 | gGL.setSceneBlendType(LLRender::BT_ALPHA); | ||
4663 | |||
4664 | LLGLState::checkStates(); | ||
4665 | LLGLState::checkTextureChannels(); | ||
4666 | LLGLState::checkClientArrays(); | ||
4667 | } | ||
4668 | |||
4669 | void LLPipeline::bindScreenToTexture() | 4957 | void LLPipeline::bindScreenToTexture() |
4670 | { | 4958 | { |
4671 | 4959 | ||
4672 | } | 4960 | } |
4673 | 4961 | ||
4674 | void LLPipeline::renderBloom(BOOL for_snapshot) | 4962 | void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) |
4675 | { | 4963 | { |
4676 | if (!(gPipeline.canUseVertexShaders() && | 4964 | if (!(gPipeline.canUseVertexShaders() && |
4677 | sRenderGlow)) | 4965 | sRenderGlow)) |
@@ -4693,8 +4981,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4693 | U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); | 4981 | U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); |
4694 | 4982 | ||
4695 | LLVector2 tc1(0,0); | 4983 | LLVector2 tc1(0,0); |
4696 | LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth(), | 4984 | LLVector2 tc2((F32) gViewerWindow->getWindowDisplayWidth()*2, |
4697 | (F32) gViewerWindow->getWindowDisplayHeight()); | 4985 | (F32) gViewerWindow->getWindowDisplayHeight()*2); |
4698 | 4986 | ||
4699 | if (res_mod > 1) | 4987 | if (res_mod > 1) |
4700 | { | 4988 | { |
@@ -4731,9 +5019,22 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4731 | //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); | 5019 | //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); |
4732 | //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | 5020 | //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
4733 | //LLGLDisable blend(GL_BLEND); | 5021 | //LLGLDisable blend(GL_BLEND); |
5022 | |||
5023 | // If the snapshot is constructed from tiles, calculate which | ||
5024 | // tile we're in. | ||
5025 | const S32 num_horizontal_tiles = llceil(zoom_factor); | ||
5026 | const LLVector2 tile(subfield % num_horizontal_tiles, | ||
5027 | (S32)(subfield / num_horizontal_tiles)); | ||
5028 | llassert(zoom_factor > 0.0); // Non-zero, non-negative. | ||
5029 | const F32 tile_size = 1.0/zoom_factor; | ||
5030 | |||
5031 | tc1 = tile*tile_size; // Top left texture coordinates | ||
5032 | tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates | ||
5033 | |||
4734 | LLGLEnable blend(GL_BLEND); | 5034 | LLGLEnable blend(GL_BLEND); |
4735 | gGL.setSceneBlendType(LLRender::BT_ADD); | 5035 | gGL.setSceneBlendType(LLRender::BT_ADD); |
4736 | tc2.setVec(1,1); | 5036 | |
5037 | |||
4737 | gGL.begin(LLRender::TRIANGLE_STRIP); | 5038 | gGL.begin(LLRender::TRIANGLE_STRIP); |
4738 | gGL.color4f(1,1,1,1); | 5039 | gGL.color4f(1,1,1,1); |
4739 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | 5040 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); |
@@ -4747,6 +5048,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4747 | 5048 | ||
4748 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | 5049 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); |
4749 | gGL.vertex2f(1,1); | 5050 | gGL.vertex2f(1,1); |
5051 | |||
4750 | gGL.end(); | 5052 | gGL.end(); |
4751 | 5053 | ||
4752 | gGL.flush(); | 5054 | gGL.flush(); |
@@ -4770,7 +5072,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4770 | } | 5072 | } |
4771 | 5073 | ||
4772 | gGlowExtractProgram.bind(); | 5074 | gGlowExtractProgram.bind(); |
4773 | F32 minLum = llclamp(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f, 1.0f); | 5075 | F32 minLum = llmax(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f); |
4774 | F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); | 5076 | F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); |
4775 | F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); | 5077 | F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); |
4776 | LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); | 5078 | LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); |
@@ -4797,13 +5099,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4797 | gGL.vertex2f(-1,-1); | 5099 | gGL.vertex2f(-1,-1); |
4798 | 5100 | ||
4799 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | 5101 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); |
4800 | gGL.vertex2f(-1,1); | 5102 | gGL.vertex2f(-1,3); |
4801 | 5103 | ||
4802 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | 5104 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); |
4803 | gGL.vertex2f(1,-1); | 5105 | gGL.vertex2f(3,-1); |
4804 | 5106 | ||
4805 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4806 | gGL.vertex2f(1,1); | ||
4807 | gGL.end(); | 5107 | gGL.end(); |
4808 | 5108 | ||
4809 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | 5109 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); |
@@ -4812,7 +5112,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4812 | } | 5112 | } |
4813 | 5113 | ||
4814 | tc1.setVec(0,0); | 5114 | tc1.setVec(0,0); |
4815 | tc2.setVec(1,1); | 5115 | tc2.setVec(2,2); |
4816 | 5116 | ||
4817 | 5117 | ||
4818 | 5118 | ||
@@ -4866,13 +5166,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4866 | gGL.vertex2f(-1,-1); | 5166 | gGL.vertex2f(-1,-1); |
4867 | 5167 | ||
4868 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | 5168 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); |
4869 | gGL.vertex2f(-1,1); | 5169 | gGL.vertex2f(-1,3); |
4870 | 5170 | ||
4871 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | 5171 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); |
4872 | gGL.vertex2f(1,-1); | 5172 | gGL.vertex2f(3,-1); |
4873 | 5173 | ||
4874 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4875 | gGL.vertex2f(1,1); | ||
4876 | gGL.end(); | 5174 | gGL.end(); |
4877 | 5175 | ||
4878 | mGlow[i%2].flush(); | 5176 | mGlow[i%2].flush(); |
@@ -4888,81 +5186,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4888 | 5186 | ||
4889 | gViewerWindow->setupViewport(); | 5187 | gViewerWindow->setupViewport(); |
4890 | 5188 | ||
4891 | /*mGlow[1].bindTexture(); | ||
4892 | { | ||
4893 | LLGLEnable stencil(GL_STENCIL_TEST); | ||
4894 | glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); | ||
4895 | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | ||
4896 | LLGLDisable blend(GL_BLEND); | ||
4897 | |||
4898 | gGL.begin(LLVertexBuffer::TRIANGLE_STRIP); | ||
4899 | gGL.color4f(1,1,1,1); | ||
4900 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4901 | gGL.vertex2f(-1,-1); | ||
4902 | |||
4903 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | ||
4904 | gGL.vertex2f(-1,1); | ||
4905 | |||
4906 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4907 | gGL.vertex2f(1,-1); | ||
4908 | |||
4909 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4910 | gGL.vertex2f(1,1); | ||
4911 | gGL.end(); | ||
4912 | |||
4913 | gGL.flush(); | ||
4914 | } | ||
4915 | |||
4916 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_GLOW)) | ||
4917 | { | ||
4918 | tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), | ||
4919 | (F32) gViewerWindow->getWindowDisplayHeight()); | ||
4920 | |||
4921 | if (res_mod > 1) | ||
4922 | { | ||
4923 | tc2 /= (F32) res_mod; | ||
4924 | } | ||
4925 | |||
4926 | LLGLEnable blend(GL_BLEND); | ||
4927 | gGL.blendFunc(GL_ONE, GL_ONE); | ||
4928 | |||
4929 | gGL.getTexUnit(0)->disable(); | ||
4930 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); | ||
4931 | mScreen.bindTexture(); | ||
4932 | |||
4933 | gGL.begin(LLVertexBuffer::TRIANGLE_STRIP); | ||
4934 | gGL.color4f(1,1,1,1); | ||
4935 | gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); | ||
4936 | gGL.vertex2f(-1,-1); | ||
4937 | |||
4938 | gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); | ||
4939 | gGL.vertex2f(-1,1); | ||
4940 | |||
4941 | gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); | ||
4942 | gGL.vertex2f(1,-1); | ||
4943 | |||
4944 | gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); | ||
4945 | gGL.vertex2f(1,1); | ||
4946 | gGL.end(); | ||
4947 | |||
4948 | gGL.flush(); | ||
4949 | |||
4950 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | ||
4951 | |||
4952 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
4953 | }*/ | ||
4954 | gGL.flush(); | 5189 | gGL.flush(); |
4955 | 5190 | ||
4956 | { | 5191 | { |
4957 | LLVertexBuffer::unbind(); | 5192 | LLVertexBuffer::unbind(); |
4958 | 5193 | ||
4959 | F32 uv0[] = | 5194 | |
4960 | { | ||
4961 | tc1.mV[0], tc1.mV[1], | ||
4962 | tc1.mV[0], tc2.mV[1], | ||
4963 | tc2.mV[0], tc1.mV[1], | ||
4964 | tc2.mV[0], tc2.mV[1] | ||
4965 | }; | ||
4966 | 5195 | ||
4967 | tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), | 5196 | tc2.setVec((F32) gViewerWindow->getWindowDisplayWidth(), |
4968 | (F32) gViewerWindow->getWindowDisplayHeight()); | 5197 | (F32) gViewerWindow->getWindowDisplayHeight()); |
@@ -4972,55 +5201,56 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
4972 | tc2 /= (F32) res_mod; | 5201 | tc2 /= (F32) res_mod; |
4973 | } | 5202 | } |
4974 | 5203 | ||
4975 | F32 uv1[] = | 5204 | U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; |
4976 | { | 5205 | LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); |
4977 | tc1.mV[0], tc1.mV[1], | 5206 | buff->allocateBuffer(3,0,TRUE); |
4978 | tc1.mV[0], tc2.mV[1], | ||
4979 | tc2.mV[0], tc1.mV[1], | ||
4980 | tc2.mV[0], tc2.mV[1] | ||
4981 | }; | ||
4982 | 5207 | ||
4983 | F32 v[] = | 5208 | LLStrider<LLVector3> v; |
4984 | { | 5209 | LLStrider<LLVector2> uv1; |
4985 | -1,-1, | 5210 | LLStrider<LLVector2> uv2; |
4986 | -1,1, | 5211 | |
4987 | 1,-1, | 5212 | buff->getVertexStrider(v); |
4988 | 1,1 | 5213 | buff->getTexCoord0Strider(uv1); |
4989 | }; | 5214 | buff->getTexCoord1Strider(uv2); |
5215 | |||
5216 | uv1[0] = LLVector2(0, 0); | ||
5217 | uv1[1] = LLVector2(0, 2); | ||
5218 | uv1[2] = LLVector2(2, 0); | ||
4990 | 5219 | ||
5220 | uv2[0] = LLVector2(0, 0); | ||
5221 | uv2[1] = LLVector2(0, tc2.mV[1]*2.f); | ||
5222 | uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); | ||
5223 | |||
5224 | v[0] = LLVector3(-1,-1,0); | ||
5225 | v[1] = LLVector3(-1,3,0); | ||
5226 | v[2] = LLVector3(3,-1,0); | ||
5227 | |||
5228 | buff->setBuffer(0); | ||
5229 | |||
4991 | LLGLDisable blend(GL_BLEND); | 5230 | LLGLDisable blend(GL_BLEND); |
4992 | 5231 | ||
4993 | //tex unit 0 | 5232 | //tex unit 0 |
4994 | gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); | 5233 | gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); |
4995 | 5234 | ||
4996 | gGL.getTexUnit(0)->bind(&mGlow[1]); | 5235 | gGL.getTexUnit(0)->bind(&mGlow[1]); |
4997 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
4998 | glTexCoordPointer(2, GL_FLOAT, 0, uv0); | ||
4999 | gGL.getTexUnit(1)->activate(); | 5236 | gGL.getTexUnit(1)->activate(); |
5000 | gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE); | 5237 | gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE); |
5001 | 5238 | ||
5002 | //tex unit 1 | 5239 | //tex unit 1 |
5003 | gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); | 5240 | gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); |
5004 | 5241 | ||
5005 | glClientActiveTextureARB(GL_TEXTURE1_ARB); | ||
5006 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
5007 | glTexCoordPointer(2, GL_FLOAT, 0, uv1); | ||
5008 | |||
5009 | glVertexPointer(2, GL_FLOAT, 0, v); | ||
5010 | |||
5011 | gGL.getTexUnit(1)->bind(&mScreen); | 5242 | gGL.getTexUnit(1)->bind(&mScreen); |
5012 | gGL.getTexUnit(1)->activate(); | 5243 | gGL.getTexUnit(1)->activate(); |
5013 | 5244 | ||
5014 | LLGLEnable multisample(GL_MULTISAMPLE_ARB); | 5245 | LLGLEnable multisample(GL_MULTISAMPLE_ARB); |
5015 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 5246 | |
5247 | buff->setBuffer(mask); | ||
5248 | buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); | ||
5016 | 5249 | ||
5017 | gGL.getTexUnit(1)->disable(); | 5250 | gGL.getTexUnit(1)->disable(); |
5018 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
5019 | gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); | 5251 | gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); |
5020 | 5252 | ||
5021 | glClientActiveTextureARB(GL_TEXTURE0_ARB); | ||
5022 | gGL.getTexUnit(0)->activate(); | 5253 | gGL.getTexUnit(0)->activate(); |
5023 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
5024 | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); | 5254 | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); |
5025 | } | 5255 | } |
5026 | 5256 | ||
@@ -5037,6 +5267,515 @@ void LLPipeline::renderBloom(BOOL for_snapshot) | |||
5037 | 5267 | ||
5038 | } | 5268 | } |
5039 | 5269 | ||
5270 | void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) | ||
5271 | { | ||
5272 | shader.bind(); | ||
5273 | S32 channel = 0; | ||
5274 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); | ||
5275 | if (channel > -1) | ||
5276 | { | ||
5277 | mDeferredScreen.bindTexture(0,channel); | ||
5278 | //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||
5279 | //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
5280 | } | ||
5281 | |||
5282 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); | ||
5283 | if (channel > -1) | ||
5284 | { | ||
5285 | mDeferredScreen.bindTexture(1, channel); | ||
5286 | } | ||
5287 | |||
5288 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); | ||
5289 | if (channel > -1) | ||
5290 | { | ||
5291 | mDeferredScreen.bindTexture(2, channel); | ||
5292 | } | ||
5293 | |||
5294 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); | ||
5295 | if (channel > -1) | ||
5296 | { | ||
5297 | mDeferredScreen.bindTexture(3, channel); | ||
5298 | } | ||
5299 | |||
5300 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); | ||
5301 | if (channel > -1) | ||
5302 | { | ||
5303 | gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE); | ||
5304 | } | ||
5305 | |||
5306 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); | ||
5307 | if (channel > -1) | ||
5308 | { | ||
5309 | gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); | ||
5310 | } | ||
5311 | |||
5312 | stop_glerror(); | ||
5313 | |||
5314 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); | ||
5315 | if (channel > -1) | ||
5316 | { | ||
5317 | mDeferredLight[light_index].bindTexture(0, channel); | ||
5318 | } | ||
5319 | |||
5320 | stop_glerror(); | ||
5321 | |||
5322 | for (U32 i = 0; i < 4; i++) | ||
5323 | { | ||
5324 | channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); | ||
5325 | stop_glerror(); | ||
5326 | if (channel > -1) | ||
5327 | { | ||
5328 | stop_glerror(); | ||
5329 | gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE); | ||
5330 | gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); | ||
5331 | stop_glerror(); | ||
5332 | |||
5333 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); | ||
5334 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); | ||
5335 | stop_glerror(); | ||
5336 | } | ||
5337 | } | ||
5338 | |||
5339 | stop_glerror(); | ||
5340 | |||
5341 | F32 mat[64]; | ||
5342 | for (U32 i = 0; i < 16; i++) | ||
5343 | { | ||
5344 | mat[i] = mSunShadowMatrix[0].m[i]; | ||
5345 | mat[i+16] = mSunShadowMatrix[1].m[i]; | ||
5346 | mat[i+32] = mSunShadowMatrix[2].m[i]; | ||
5347 | mat[i+48] = mSunShadowMatrix[3].m[i]; | ||
5348 | } | ||
5349 | |||
5350 | shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat); | ||
5351 | shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat); | ||
5352 | |||
5353 | stop_glerror(); | ||
5354 | |||
5355 | channel = shader.enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); | ||
5356 | if (channel > -1) | ||
5357 | { | ||
5358 | LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; | ||
5359 | if (cube_map) | ||
5360 | { | ||
5361 | cube_map->enable(channel); | ||
5362 | cube_map->bind(); | ||
5363 | F64* m = gGLModelView; | ||
5364 | |||
5365 | |||
5366 | F32 mat[] = { m[0], m[1], m[2], | ||
5367 | m[4], m[5], m[6], | ||
5368 | m[8], m[9], m[10] }; | ||
5369 | |||
5370 | shader.uniform3fv("env_mat[0]", 3, mat); | ||
5371 | shader.uniform3fv("env_mat", 3, mat); | ||
5372 | } | ||
5373 | } | ||
5374 | |||
5375 | shader.uniform4fv("shadow_clip", 1, mSunClipPlanes.mV); | ||
5376 | shader.uniform1f("sun_wash", gSavedSettings.getF32("RenderDeferredSunWash")); | ||
5377 | shader.uniform1f("shadow_noise", gSavedSettings.getF32("RenderShadowNoise")); | ||
5378 | shader.uniform1f("blur_size", gSavedSettings.getF32("RenderShadowBlurSize")); | ||
5379 | |||
5380 | shader.uniform1f("ssao_radius", gSavedSettings.getF32("RenderSSAOScale")); | ||
5381 | shader.uniform1f("ssao_max_radius", gSavedSettings.getU32("RenderSSAOMaxScale")); | ||
5382 | |||
5383 | F32 ssao_factor = gSavedSettings.getF32("RenderSSAOFactor"); | ||
5384 | shader.uniform1f("ssao_factor", ssao_factor); | ||
5385 | shader.uniform1f("ssao_factor_inv", 1.0/ssao_factor); | ||
5386 | |||
5387 | LLVector3 ssao_effect = gSavedSettings.getVector3("RenderSSAOEffect"); | ||
5388 | F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0; | ||
5389 | F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0; | ||
5390 | // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by | ||
5391 | // value factor, and scales remainder by saturation factor | ||
5392 | F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag, | ||
5393 | matrix_nondiag, matrix_diag, matrix_nondiag, | ||
5394 | matrix_nondiag, matrix_nondiag, matrix_diag}; | ||
5395 | shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat); | ||
5396 | |||
5397 | shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); | ||
5398 | shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); | ||
5399 | shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften")); | ||
5400 | } | ||
5401 | |||
5402 | void LLPipeline::renderDeferredLighting() | ||
5403 | { | ||
5404 | if (!sCull) | ||
5405 | { | ||
5406 | return; | ||
5407 | } | ||
5408 | |||
5409 | LLGLEnable multisample(GL_MULTISAMPLE_ARB); | ||
5410 | |||
5411 | if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) | ||
5412 | { | ||
5413 | gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); | ||
5414 | } | ||
5415 | |||
5416 | //ati doesn't seem to love actually using the stencil buffer on FBO's | ||
5417 | LLGLEnable stencil(GL_STENCIL_TEST); | ||
5418 | glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); | ||
5419 | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | ||
5420 | |||
5421 | gGL.setColorMask(true, true); | ||
5422 | |||
5423 | mDeferredLight[0].bindTarget(); | ||
5424 | |||
5425 | //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), | ||
5426 | // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); | ||
5427 | |||
5428 | //draw a cube around every light | ||
5429 | LLVertexBuffer::unbind(); | ||
5430 | |||
5431 | glBlendFunc(GL_ONE, GL_ONE); | ||
5432 | LLGLEnable cull(GL_CULL_FACE); | ||
5433 | LLGLEnable blend(GL_BLEND); | ||
5434 | |||
5435 | glh::matrix4f mat = glh_copy_matrix(gGLModelView); | ||
5436 | |||
5437 | F32 vert[] = | ||
5438 | { | ||
5439 | -1,1, | ||
5440 | -1,-3, | ||
5441 | 3,1, | ||
5442 | }; | ||
5443 | |||
5444 | bindDeferredShader(gDeferredSunProgram); | ||
5445 | |||
5446 | glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); | ||
5447 | |||
5448 | const U32 slice = 32; | ||
5449 | F32 offset[slice*3]; | ||
5450 | for (U32 i = 0; i < 4; i++) | ||
5451 | { | ||
5452 | for (U32 j = 0; j < 8; j++) | ||
5453 | { | ||
5454 | glh::vec3f v; | ||
5455 | v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); | ||
5456 | v.normalize(); | ||
5457 | inv_trans.mult_matrix_vec(v); | ||
5458 | v.normalize(); | ||
5459 | offset[(i*8+j)*3+0] = v.v[0]; | ||
5460 | offset[(i*8+j)*3+1] = v.v[2]; | ||
5461 | offset[(i*8+j)*3+2] = v.v[1]; | ||
5462 | } | ||
5463 | } | ||
5464 | |||
5465 | gDeferredSunProgram.uniform3fv("offset", slice, offset); | ||
5466 | gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); | ||
5467 | |||
5468 | setupHWLights(NULL); //to set mSunDir; | ||
5469 | |||
5470 | glPushMatrix(); | ||
5471 | glLoadIdentity(); | ||
5472 | glMatrixMode(GL_PROJECTION); | ||
5473 | glPushMatrix(); | ||
5474 | glLoadIdentity(); | ||
5475 | |||
5476 | LLVector4 dir(mSunDir, 0.f); | ||
5477 | |||
5478 | glh::vec4f tc(dir.mV); | ||
5479 | mat.mult_matrix_vec(tc); | ||
5480 | glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); | ||
5481 | glColor3f(1,1,1); | ||
5482 | |||
5483 | glVertexPointer(2, GL_FLOAT, 0, vert); | ||
5484 | { | ||
5485 | LLGLDisable blend(GL_BLEND); | ||
5486 | LLGLDepthTest depth(GL_FALSE); | ||
5487 | stop_glerror(); | ||
5488 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); | ||
5489 | stop_glerror(); | ||
5490 | } | ||
5491 | |||
5492 | unbindDeferredShader(gDeferredSunProgram); | ||
5493 | |||
5494 | mDeferredLight[0].flush(); | ||
5495 | |||
5496 | //blur lightmap | ||
5497 | mDeferredLight[1].bindTarget(); | ||
5498 | |||
5499 | //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), | ||
5500 | // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); | ||
5501 | |||
5502 | bindDeferredShader(gDeferredBlurLightProgram); | ||
5503 | |||
5504 | LLVector3 gauss[32]; // xweight, yweight, offset | ||
5505 | |||
5506 | LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); | ||
5507 | U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; | ||
5508 | F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); | ||
5509 | |||
5510 | // sample symmetrically with the middle sample falling exactly on 0.0 | ||
5511 | F32 x = -(kern_length/2.0f) + 0.5f; | ||
5512 | |||
5513 | for (U32 i = 0; i < kern_length; i++) | ||
5514 | { | ||
5515 | gauss[i].mV[0] = llgaussian(x, go.mV[0]); | ||
5516 | gauss[i].mV[1] = llgaussian(x, go.mV[1]); | ||
5517 | gauss[i].mV[2] = x; | ||
5518 | x += 1.f; | ||
5519 | } | ||
5520 | /* swap the x=0 position to the start of gauss[] so we can | ||
5521 | treat it specially as an optimization. */ | ||
5522 | LLVector3 swap; | ||
5523 | swap = gauss[kern_length/2]; | ||
5524 | gauss[kern_length/2] = gauss[0]; | ||
5525 | gauss[0] = swap; | ||
5526 | llassert(gauss[0].mV[2] == 0.0f); | ||
5527 | |||
5528 | gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); | ||
5529 | gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); | ||
5530 | gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); | ||
5531 | gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); | ||
5532 | gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); | ||
5533 | |||
5534 | { | ||
5535 | LLGLDisable blend(GL_BLEND); | ||
5536 | LLGLDepthTest depth(GL_FALSE); | ||
5537 | stop_glerror(); | ||
5538 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); | ||
5539 | stop_glerror(); | ||
5540 | } | ||
5541 | |||
5542 | mDeferredLight[1].flush(); | ||
5543 | unbindDeferredShader(gDeferredBlurLightProgram); | ||
5544 | |||
5545 | bindDeferredShader(gDeferredBlurLightProgram, 1); | ||
5546 | mDeferredLight[0].bindTarget(); | ||
5547 | |||
5548 | gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); | ||
5549 | gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); | ||
5550 | gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); | ||
5551 | gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); | ||
5552 | gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); | ||
5553 | |||
5554 | { | ||
5555 | LLGLDisable blend(GL_BLEND); | ||
5556 | LLGLDepthTest depth(GL_FALSE); | ||
5557 | stop_glerror(); | ||
5558 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||
5559 | stop_glerror(); | ||
5560 | } | ||
5561 | mDeferredLight[0].flush(); | ||
5562 | unbindDeferredShader(gDeferredBlurLightProgram); | ||
5563 | |||
5564 | stop_glerror(); | ||
5565 | glPopMatrix(); | ||
5566 | stop_glerror(); | ||
5567 | glMatrixMode(GL_MODELVIEW); | ||
5568 | stop_glerror(); | ||
5569 | glPopMatrix(); | ||
5570 | stop_glerror(); | ||
5571 | |||
5572 | //copy depth and stencil from deferred screen | ||
5573 | //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), | ||
5574 | // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); | ||
5575 | |||
5576 | mScreen.bindTarget(); | ||
5577 | mScreen.clear(GL_COLOR_BUFFER_BIT); | ||
5578 | |||
5579 | bindDeferredShader(gDeferredSoftenProgram); | ||
5580 | { | ||
5581 | LLGLDepthTest depth(GL_FALSE); | ||
5582 | LLGLDisable blend(GL_BLEND); | ||
5583 | LLGLDisable test(GL_ALPHA_TEST); | ||
5584 | |||
5585 | //full screen blit | ||
5586 | glPushMatrix(); | ||
5587 | glLoadIdentity(); | ||
5588 | glMatrixMode(GL_PROJECTION); | ||
5589 | glPushMatrix(); | ||
5590 | glLoadIdentity(); | ||
5591 | |||
5592 | glVertexPointer(2, GL_FLOAT, 0, vert); | ||
5593 | |||
5594 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); | ||
5595 | |||
5596 | glPopMatrix(); | ||
5597 | glMatrixMode(GL_MODELVIEW); | ||
5598 | glPopMatrix(); | ||
5599 | } | ||
5600 | |||
5601 | unbindDeferredShader(gDeferredSoftenProgram); | ||
5602 | |||
5603 | bindDeferredShader(gDeferredLightProgram); | ||
5604 | |||
5605 | std::list<LLVector4> fullscreen_lights; | ||
5606 | std::list<LLVector4> light_colors; | ||
5607 | |||
5608 | F32 v[24]; | ||
5609 | glVertexPointer(3, GL_FLOAT, 0, v); | ||
5610 | { | ||
5611 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | ||
5612 | for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) | ||
5613 | { | ||
5614 | LLDrawable* drawablep = *iter; | ||
5615 | |||
5616 | LLVOVolume* volume = drawablep->getVOVolume(); | ||
5617 | if (!volume) | ||
5618 | { | ||
5619 | continue; | ||
5620 | } | ||
5621 | |||
5622 | LLVector3 center = drawablep->getPositionAgent(); | ||
5623 | F32* c = center.mV; | ||
5624 | F32 s = volume->getLightRadius()*1.5f; | ||
5625 | |||
5626 | if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) | ||
5627 | { | ||
5628 | continue; | ||
5629 | } | ||
5630 | |||
5631 | sVisibleLightCount++; | ||
5632 | glh::vec3f tc(c); | ||
5633 | mat.mult_matrix_vec(tc); | ||
5634 | |||
5635 | LLColor3 col = volume->getLightColor(); | ||
5636 | col *= volume->getLightIntensity(); | ||
5637 | |||
5638 | //vertex positions are encoded so the 3 bits of their vertex index | ||
5639 | //correspond to their axis facing, with bit position 3,2,1 matching | ||
5640 | //axis facing x,y,z, bit set meaning positive facing, bit clear | ||
5641 | //meaning negative facing | ||
5642 | v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 | ||
5643 | v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 | ||
5644 | v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 | ||
5645 | v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 | ||
5646 | |||
5647 | v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 | ||
5648 | v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 | ||
5649 | v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 | ||
5650 | v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 | ||
5651 | |||
5652 | if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || | ||
5653 | LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || | ||
5654 | LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || | ||
5655 | LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || | ||
5656 | LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || | ||
5657 | LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) | ||
5658 | { //draw box if camera is outside box | ||
5659 | glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); | ||
5660 | glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); | ||
5661 | glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, | ||
5662 | GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); | ||
5663 | } | ||
5664 | else | ||
5665 | { | ||
5666 | fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); | ||
5667 | light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); | ||
5668 | } | ||
5669 | } | ||
5670 | } | ||
5671 | |||
5672 | unbindDeferredShader(gDeferredLightProgram); | ||
5673 | |||
5674 | if (!fullscreen_lights.empty()) | ||
5675 | { | ||
5676 | bindDeferredShader(gDeferredMultiLightProgram); | ||
5677 | LLGLDepthTest depth(GL_FALSE); | ||
5678 | |||
5679 | //full screen blit | ||
5680 | glPushMatrix(); | ||
5681 | glLoadIdentity(); | ||
5682 | glMatrixMode(GL_PROJECTION); | ||
5683 | glPushMatrix(); | ||
5684 | glLoadIdentity(); | ||
5685 | |||
5686 | U32 count = 0; | ||
5687 | |||
5688 | LLVector4 light[16]; | ||
5689 | LLVector4 col[16]; | ||
5690 | |||
5691 | glVertexPointer(2, GL_FLOAT, 0, vert); | ||
5692 | |||
5693 | while (!fullscreen_lights.empty()) | ||
5694 | { | ||
5695 | light[count] = fullscreen_lights.front(); | ||
5696 | fullscreen_lights.pop_front(); | ||
5697 | col[count] = light_colors.front(); | ||
5698 | light_colors.pop_front(); | ||
5699 | |||
5700 | count++; | ||
5701 | if (count == 16 || fullscreen_lights.empty()) | ||
5702 | { | ||
5703 | gDeferredMultiLightProgram.uniform1i("light_count", count); | ||
5704 | gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); | ||
5705 | gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); | ||
5706 | gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); | ||
5707 | gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); | ||
5708 | count = 0; | ||
5709 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); | ||
5710 | } | ||
5711 | } | ||
5712 | |||
5713 | |||
5714 | glPopMatrix(); | ||
5715 | glMatrixMode(GL_MODELVIEW); | ||
5716 | glPopMatrix(); | ||
5717 | |||
5718 | unbindDeferredShader(gDeferredMultiLightProgram); | ||
5719 | } | ||
5720 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
5721 | |||
5722 | { //render non-deferred geometry | ||
5723 | LLGLDisable blend(GL_BLEND); | ||
5724 | LLGLDisable stencil(GL_STENCIL_TEST); | ||
5725 | |||
5726 | U32 render_mask = mRenderTypeMask; | ||
5727 | mRenderTypeMask = mRenderTypeMask & | ||
5728 | ((1 << LLPipeline::RENDER_TYPE_SKY) | | ||
5729 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | ||
5730 | (1 << LLPipeline::RENDER_TYPE_WL_SKY) | | ||
5731 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | | ||
5732 | (1 << LLPipeline::RENDER_TYPE_AVATAR) | | ||
5733 | (1 << LLPipeline::RENDER_TYPE_WATER) | | ||
5734 | (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | | ||
5735 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | | ||
5736 | (1 << LLPipeline::RENDER_TYPE_GLOW) | | ||
5737 | (1 << LLPipeline::RENDER_TYPE_BUMP)); | ||
5738 | |||
5739 | renderGeomPostDeferred(*LLViewerCamera::getInstance()); | ||
5740 | mRenderTypeMask = render_mask; | ||
5741 | } | ||
5742 | |||
5743 | mScreen.flush(); | ||
5744 | |||
5745 | } | ||
5746 | |||
5747 | void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) | ||
5748 | { | ||
5749 | stop_glerror(); | ||
5750 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); | ||
5751 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); | ||
5752 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); | ||
5753 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); | ||
5754 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); | ||
5755 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); | ||
5756 | for (U32 i = 0; i < 4; i++) | ||
5757 | { | ||
5758 | if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) | ||
5759 | { | ||
5760 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); | ||
5761 | } | ||
5762 | } | ||
5763 | shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); | ||
5764 | |||
5765 | S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); | ||
5766 | if (channel > -1) | ||
5767 | { | ||
5768 | LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; | ||
5769 | if (cube_map) | ||
5770 | { | ||
5771 | cube_map->disable(); | ||
5772 | } | ||
5773 | } | ||
5774 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
5775 | gGL.getTexUnit(0)->activate(); | ||
5776 | shader.unbind(); | ||
5777 | } | ||
5778 | |||
5040 | inline float sgn(float a) | 5779 | inline float sgn(float a) |
5041 | { | 5780 | { |
5042 | if (a > 0.0F) return (1.0F); | 5781 | if (a > 0.0F) return (1.0F); |
@@ -5048,6 +5787,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5048 | { | 5787 | { |
5049 | if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) | 5788 | if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) |
5050 | { | 5789 | { |
5790 | LLVOAvatar* agent = gAgent.getAvatarObject(); | ||
5791 | if (gAgent.getCameraAnimating() || gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK) | ||
5792 | { | ||
5793 | agent = NULL; | ||
5794 | } | ||
5795 | |||
5796 | if (agent) | ||
5797 | { | ||
5798 | agent->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); | ||
5799 | } | ||
5051 | LLVertexBuffer::unbind(); | 5800 | LLVertexBuffer::unbind(); |
5052 | 5801 | ||
5053 | LLGLState::checkStates(); | 5802 | LLGLState::checkStates(); |
@@ -5059,6 +5808,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5059 | LLPipeline::sReflectionRender = TRUE; | 5808 | LLPipeline::sReflectionRender = TRUE; |
5060 | S32 occlusion = LLPipeline::sUseOcclusion; | 5809 | S32 occlusion = LLPipeline::sUseOcclusion; |
5061 | LLPipeline::sUseOcclusion = llmin(occlusion, 1); | 5810 | LLPipeline::sUseOcclusion = llmin(occlusion, 1); |
5811 | |||
5062 | U32 type_mask = gPipeline.mRenderTypeMask; | 5812 | U32 type_mask = gPipeline.mRenderTypeMask; |
5063 | 5813 | ||
5064 | glh::matrix4f projection = glh_get_current_projection(); | 5814 | glh::matrix4f projection = glh_get_current_projection(); |
@@ -5126,15 +5876,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5126 | //initial sky pass (no user clip plane) | 5876 | //initial sky pass (no user clip plane) |
5127 | { //mask out everything but the sky | 5877 | { //mask out everything but the sky |
5128 | U32 tmp = mRenderTypeMask; | 5878 | U32 tmp = mRenderTypeMask; |
5129 | mRenderTypeMask &= ((1 << LLPipeline::RENDER_TYPE_SKY) | | 5879 | mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | |
5130 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | ||
5131 | (1 << LLPipeline::RENDER_TYPE_WL_SKY)); | 5880 | (1 << LLPipeline::RENDER_TYPE_WL_SKY)); |
5132 | |||
5133 | static LLCullResult result; | 5881 | static LLCullResult result; |
5134 | updateCull(camera, result); | 5882 | updateCull(camera, result); |
5135 | stateSort(camera, result); | 5883 | stateSort(camera, result); |
5884 | mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | | ||
5885 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | ||
5886 | (1 << LLPipeline::RENDER_TYPE_WL_SKY)); | ||
5136 | renderGeom(camera, TRUE); | 5887 | renderGeom(camera, TRUE); |
5137 | |||
5138 | mRenderTypeMask = tmp; | 5888 | mRenderTypeMask = tmp; |
5139 | } | 5889 | } |
5140 | 5890 | ||
@@ -5226,6 +5976,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5226 | last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; | 5976 | last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; |
5227 | 5977 | ||
5228 | LLRenderTarget::unbindTarget(); | 5978 | LLRenderTarget::unbindTarget(); |
5979 | |||
5229 | LLPipeline::sReflectionRender = FALSE; | 5980 | LLPipeline::sReflectionRender = FALSE; |
5230 | 5981 | ||
5231 | if (!LLRenderTarget::sUseFBO) | 5982 | if (!LLRenderTarget::sUseFBO) |
@@ -5244,7 +5995,422 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5244 | LLGLState::checkStates(); | 5995 | LLGLState::checkStates(); |
5245 | LLGLState::checkTextureChannels(); | 5996 | LLGLState::checkTextureChannels(); |
5246 | LLGLState::checkClientArrays(); | 5997 | LLGLState::checkClientArrays(); |
5998 | |||
5999 | if (agent) | ||
6000 | { | ||
6001 | agent->updateAttachmentVisibility(gAgent.getCameraMode()); | ||
6002 | } | ||
6003 | } | ||
6004 | } | ||
6005 | |||
6006 | glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) | ||
6007 | { | ||
6008 | glh::matrix4f ret; | ||
6009 | |||
6010 | LLVector3 dirN; | ||
6011 | LLVector3 upN; | ||
6012 | LLVector3 lftN; | ||
6013 | |||
6014 | lftN = dir % up; | ||
6015 | lftN.normVec(); | ||
6016 | |||
6017 | upN = lftN % dir; | ||
6018 | upN.normVec(); | ||
6019 | |||
6020 | dirN = dir; | ||
6021 | dirN.normVec(); | ||
6022 | |||
6023 | |||
6024 | ret.m[ 0] = lftN[0]; | ||
6025 | ret.m[ 1] = upN[0]; | ||
6026 | ret.m[ 2] = -dirN[0]; | ||
6027 | ret.m[ 3] = 0.f; | ||
6028 | |||
6029 | ret.m[ 4] = lftN[1]; | ||
6030 | ret.m[ 5] = upN[1]; | ||
6031 | ret.m[ 6] = -dirN[1]; | ||
6032 | ret.m[ 7] = 0.f; | ||
6033 | |||
6034 | ret.m[ 8] = lftN[2]; | ||
6035 | ret.m[ 9] = upN[2]; | ||
6036 | ret.m[10] = -dirN[2]; | ||
6037 | ret.m[11] = 0.f; | ||
6038 | |||
6039 | ret.m[12] = -(lftN*pos); | ||
6040 | ret.m[13] = -(upN*pos); | ||
6041 | ret.m[14] = dirN*pos; | ||
6042 | ret.m[15] = 1.f; | ||
6043 | |||
6044 | return ret; | ||
6045 | } | ||
6046 | |||
6047 | glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) | ||
6048 | { | ||
6049 | glh::matrix4f ret; | ||
6050 | ret.m[ 0] = 2/(max[0]-min[0]); | ||
6051 | ret.m[ 4] = 0; | ||
6052 | ret.m[ 8] = 0; | ||
6053 | ret.m[12] = -(max[0]+min[0])/(max[0]-min[0]); | ||
6054 | |||
6055 | ret.m[ 1] = 0; | ||
6056 | ret.m[ 5] = 2/(max[1]-min[1]); | ||
6057 | ret.m[ 9] = 0; | ||
6058 | ret.m[13] = -(max[1]+min[1])/(max[1]-min[1]); | ||
6059 | |||
6060 | ret.m[ 2] = 0; | ||
6061 | ret.m[ 6] = 0; | ||
6062 | ret.m[10] = 2/(max[2]-min[2]); | ||
6063 | ret.m[14] = -(max[2]+min[2])/(max[2]-min[2]); | ||
6064 | |||
6065 | ret.m[ 3] = 0; | ||
6066 | ret.m[ 7] = 0; | ||
6067 | ret.m[11] = 0; | ||
6068 | ret.m[15] = 1; | ||
6069 | |||
6070 | return ret; | ||
6071 | } | ||
6072 | |||
6073 | void LLPipeline::generateSunShadow(LLCamera& camera) | ||
6074 | { | ||
6075 | |||
6076 | if (!sRenderDeferred) | ||
6077 | { | ||
6078 | return; | ||
6079 | } | ||
6080 | |||
6081 | //temporary hack to disable shadows but keep local lights | ||
6082 | static BOOL clear = TRUE; | ||
6083 | BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); | ||
6084 | if (!gen_shadow) | ||
6085 | { | ||
6086 | if (clear) | ||
6087 | { | ||
6088 | clear = FALSE; | ||
6089 | for (U32 i = 0; i < 4; i++) | ||
6090 | { | ||
6091 | mSunShadow[i].bindTarget(); | ||
6092 | mSunShadow[i].clear(); | ||
6093 | mSunShadow[i].flush(); | ||
6094 | } | ||
6095 | } | ||
6096 | return; | ||
6097 | } | ||
6098 | clear = TRUE; | ||
6099 | |||
6100 | gGL.setColorMask(false, false); | ||
6101 | |||
6102 | //get sun view matrix | ||
6103 | |||
6104 | F32 range = 128.f; | ||
6105 | |||
6106 | //store current projection/modelview matrix | ||
6107 | glh::matrix4f saved_proj = glh_get_current_projection(); | ||
6108 | glh::matrix4f saved_view = glh_get_current_modelview(); | ||
6109 | glh::matrix4f inv_view = saved_view.inverse(); | ||
6110 | |||
6111 | glh::matrix4f view[4]; | ||
6112 | glh::matrix4f proj[4]; | ||
6113 | LLVector3 up; | ||
6114 | |||
6115 | //clip contains parallel split distances for 3 splits | ||
6116 | LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes"); | ||
6117 | |||
6118 | //far clip on last split is minimum of camera view distance and 128 | ||
6119 | mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); | ||
6120 | |||
6121 | const LLPickInfo& pick_info = gViewerWindow->getLastPick(); | ||
6122 | |||
6123 | if (!pick_info.mPosGlobal.isExactlyZero()) | ||
6124 | { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object | ||
6125 | F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec(); | ||
6126 | mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]); | ||
5247 | } | 6127 | } |
6128 | |||
6129 | // convenience array of 4 near clip plane distances | ||
6130 | F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; | ||
6131 | |||
6132 | //currently used for amount to extrude frusta corners for constructing shadow frusta | ||
6133 | LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); | ||
6134 | F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; | ||
6135 | |||
6136 | for (S32 j = 0; j < 4; j++) | ||
6137 | { | ||
6138 | //restore render matrices | ||
6139 | glh_set_current_modelview(saved_view); | ||
6140 | glh_set_current_projection(saved_proj); | ||
6141 | |||
6142 | //get center of far clip plane (for point of interest later) | ||
6143 | LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range; | ||
6144 | |||
6145 | LLVector3 eye = camera.getOrigin(); | ||
6146 | |||
6147 | //camera used for shadow cull/render | ||
6148 | LLCamera shadow_cam; | ||
6149 | |||
6150 | // perspective shadow map | ||
6151 | glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space) | ||
6152 | glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space) | ||
6153 | |||
6154 | LLVector3 lightDir = -mSunDir; | ||
6155 | glh::vec3f light_dir(lightDir.mV); | ||
6156 | |||
6157 | //create light space camera matrix | ||
6158 | LLVector3 at; | ||
6159 | F32 dl = camera.getLeftAxis() * lightDir; | ||
6160 | F32 du = camera.getUpAxis() * lightDir; | ||
6161 | |||
6162 | //choose an at axis such that up will be most aligned with lightDir | ||
6163 | if (dl*dl < du*du) | ||
6164 | { | ||
6165 | at = lightDir%camera.getLeftAxis(); | ||
6166 | } | ||
6167 | else | ||
6168 | { | ||
6169 | at = lightDir%camera.getUpAxis(); | ||
6170 | } | ||
6171 | |||
6172 | if (at * camera.getAtAxis() < 0) | ||
6173 | { | ||
6174 | at = -at; | ||
6175 | } | ||
6176 | |||
6177 | LLVector3 left = lightDir%at; | ||
6178 | up = left%lightDir; | ||
6179 | up.normVec(); | ||
6180 | |||
6181 | //create world space camera frustum for this split | ||
6182 | shadow_cam = camera; | ||
6183 | shadow_cam.setFar(16.f); | ||
6184 | |||
6185 | LLViewerCamera::updateFrustumPlanes(shadow_cam); | ||
6186 | |||
6187 | LLVector3* frust = shadow_cam.mAgentFrustum; | ||
6188 | |||
6189 | LLVector3 pn = shadow_cam.getAtAxis(); | ||
6190 | |||
6191 | LLVector3 frust_center; | ||
6192 | |||
6193 | LLVector3 min, max; | ||
6194 | |||
6195 | //construct 8 corners of split frustum section | ||
6196 | for (U32 i = 0; i < 4; i++) | ||
6197 | { | ||
6198 | LLVector3 delta = frust[i+4]-eye; | ||
6199 | delta.normVec(); | ||
6200 | F32 dp = delta*pn; | ||
6201 | frust[i] = eye + (delta*dist[j])/dp; | ||
6202 | frust[i+4] = eye + (delta*dist[j+1])/dp; | ||
6203 | frust_center += frust[i] + frust[i+4]; | ||
6204 | } | ||
6205 | |||
6206 | //get frustum center | ||
6207 | frust_center /= 8.f; | ||
6208 | |||
6209 | shadow_cam.calcAgentFrustumPlanes(frust); | ||
6210 | |||
6211 | |||
6212 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) | ||
6213 | { | ||
6214 | mShadowCamera[j] = shadow_cam; | ||
6215 | } | ||
6216 | |||
6217 | if (gPipeline.getVisibleExtents(shadow_cam, min, max)) | ||
6218 | { | ||
6219 | //no possible shadow receivers | ||
6220 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) | ||
6221 | { | ||
6222 | mShadowExtents[j][0] = LLVector3(); | ||
6223 | mShadowExtents[j][1] = LLVector3(); | ||
6224 | mShadowCamera[j+4] = shadow_cam; | ||
6225 | } | ||
6226 | |||
6227 | continue; | ||
6228 | } | ||
6229 | |||
6230 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) | ||
6231 | { | ||
6232 | mShadowExtents[j][0] = min; | ||
6233 | mShadowExtents[j][1] = max; | ||
6234 | } | ||
6235 | |||
6236 | view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up); | ||
6237 | F32 shadow_dist = nearDist[j]; | ||
6238 | |||
6239 | for (U32 i = 0; i < 8; i++) | ||
6240 | { | ||
6241 | //points in worldspace (wp) and light camera space (p) | ||
6242 | //that must be included in shadow generation | ||
6243 | wp[i] = glh::vec3f(frust[i].mV); | ||
6244 | wp[i+8] = wp[i] - light_dir*shadow_dist; | ||
6245 | view[j].mult_matrix_vec(wp[i], p[i]); | ||
6246 | view[j].mult_matrix_vec(wp[i+8], p[i+8]); | ||
6247 | } | ||
6248 | |||
6249 | min = LLVector3(p[0].v); | ||
6250 | max = LLVector3(p[0].v); | ||
6251 | |||
6252 | LLVector3 fmin = min; | ||
6253 | LLVector3 fmax = max; | ||
6254 | |||
6255 | for (U32 i = 1; i < 16; i++) | ||
6256 | { //find camera space AABB of frustum in light camera space | ||
6257 | update_min_max(min, max, LLVector3(p[i].v)); | ||
6258 | if (i < 8) | ||
6259 | { | ||
6260 | update_min_max(fmin, fmax, LLVector3(p[i].v)); | ||
6261 | } | ||
6262 | } | ||
6263 | |||
6264 | //generate perspective matrix that contains frustum | ||
6265 | //proj[j] = matrix_perspective(min, max); | ||
6266 | proj[j] = gl_ortho(min.mV[0], max.mV[0], | ||
6267 | min.mV[1], max.mV[1], | ||
6268 | -max.mV[2], -min.mV[2]); | ||
6269 | |||
6270 | shadow_cam.setFar(128.f); | ||
6271 | shadow_cam.setOriginAndLookAt(eye, up, center); | ||
6272 | |||
6273 | glh_set_current_modelview(view[j]); | ||
6274 | glh_set_current_projection(proj[j]); | ||
6275 | |||
6276 | LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); | ||
6277 | |||
6278 | proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0], | ||
6279 | fmin.mV[1], fmax.mV[1], | ||
6280 | -fmax.mV[2], -fmin.mV[2]); | ||
6281 | |||
6282 | //translate and scale to from [-1, 1] to [0, 1] | ||
6283 | glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, | ||
6284 | 0.f, 0.5f, 0.f, 0.5f, | ||
6285 | 0.f, 0.f, 0.5f, 0.5f, | ||
6286 | 0.f, 0.f, 0.f, 1.f); | ||
6287 | |||
6288 | glh_set_current_modelview(view[j]); | ||
6289 | glh_set_current_projection(proj[j]); | ||
6290 | |||
6291 | mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; | ||
6292 | |||
6293 | U32 type_mask = mRenderTypeMask; | ||
6294 | mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | | ||
6295 | (1<<LLPipeline::RENDER_TYPE_ALPHA) | | ||
6296 | (1<<LLPipeline::RENDER_TYPE_GRASS) | | ||
6297 | (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | | ||
6298 | (1<<LLPipeline::RENDER_TYPE_BUMP) | | ||
6299 | (1<<LLPipeline::RENDER_TYPE_VOLUME) | | ||
6300 | (1<<LLPipeline::RENDER_TYPE_AVATAR) | | ||
6301 | (1<<LLPipeline::RENDER_TYPE_TREE) | | ||
6302 | (1<<LLPipeline::RENDER_TYPE_TERRAIN) | | ||
6303 | 0); | ||
6304 | |||
6305 | //clip out geometry on the same side of water as the camera | ||
6306 | static LLCullResult result; | ||
6307 | S32 occlude = LLPipeline::sUseOcclusion; | ||
6308 | LLPipeline::sUseOcclusion = 1; | ||
6309 | LLPipeline::sShadowRender = TRUE; | ||
6310 | //hack to prevent LOD updates from using sun camera origin | ||
6311 | shadow_cam.setOrigin(camera.getOrigin()); | ||
6312 | updateCull(shadow_cam, result); | ||
6313 | stateSort(shadow_cam, result); | ||
6314 | |||
6315 | if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) | ||
6316 | { | ||
6317 | LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); | ||
6318 | mShadowCamera[j+4] = shadow_cam; | ||
6319 | } | ||
6320 | |||
6321 | LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); | ||
6322 | |||
6323 | stop_glerror(); | ||
6324 | |||
6325 | mSunShadow[j].bindTarget(); | ||
6326 | mSunShadow[j].getViewport(gGLViewport); | ||
6327 | |||
6328 | { | ||
6329 | LLGLDepthTest depth(GL_TRUE); | ||
6330 | mSunShadow[j].clear(); | ||
6331 | } | ||
6332 | |||
6333 | U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; | ||
6334 | LLGLEnable cull(GL_CULL_FACE); | ||
6335 | |||
6336 | //generate sun shadow map | ||
6337 | glMatrixMode(GL_PROJECTION); | ||
6338 | glPushMatrix(); | ||
6339 | glLoadMatrixf(proj[j].m); | ||
6340 | glMatrixMode(GL_MODELVIEW); | ||
6341 | glPushMatrix(); | ||
6342 | glLoadMatrixf(view[j].m); | ||
6343 | |||
6344 | stop_glerror(); | ||
6345 | gGLLastMatrix = NULL; | ||
6346 | |||
6347 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
6348 | |||
6349 | glColor4f(1,1,1,1); | ||
6350 | |||
6351 | glCullFace(GL_FRONT); | ||
6352 | |||
6353 | stop_glerror(); | ||
6354 | |||
6355 | gGL.setColorMask(false, false); | ||
6356 | |||
6357 | gDeferredShadowProgram.bind(); | ||
6358 | { | ||
6359 | LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); | ||
6360 | LLGLDisable test(GL_ALPHA_TEST); | ||
6361 | gGL.getTexUnit(0)->disable(); | ||
6362 | for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) | ||
6363 | { | ||
6364 | renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); | ||
6365 | } | ||
6366 | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | ||
6367 | } | ||
6368 | |||
6369 | { | ||
6370 | LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); | ||
6371 | LLGLEnable test(GL_ALPHA_TEST); | ||
6372 | gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); | ||
6373 | renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); | ||
6374 | glColor4f(1,1,1,1); | ||
6375 | renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); | ||
6376 | gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); | ||
6377 | } | ||
6378 | |||
6379 | gDeferredShadowProgram.unbind(); | ||
6380 | |||
6381 | renderGeomShadow(shadow_cam); | ||
6382 | |||
6383 | gGL.setColorMask(true, true); | ||
6384 | |||
6385 | glCullFace(GL_BACK); | ||
6386 | LLPipeline::sUseOcclusion = occlude; | ||
6387 | LLPipeline::sShadowRender = FALSE; | ||
6388 | mRenderTypeMask = type_mask; | ||
6389 | |||
6390 | glMatrixMode(GL_PROJECTION); | ||
6391 | glPopMatrix(); | ||
6392 | glMatrixMode(GL_MODELVIEW); | ||
6393 | glPopMatrix(); | ||
6394 | gGLLastMatrix = NULL; | ||
6395 | |||
6396 | mSunShadow[j].flush(); | ||
6397 | } | ||
6398 | |||
6399 | if (!gSavedSettings.getBOOL("CameraOffset")) | ||
6400 | { | ||
6401 | glh_set_current_modelview(saved_view); | ||
6402 | glh_set_current_projection(saved_proj); | ||
6403 | } | ||
6404 | else | ||
6405 | { | ||
6406 | glh_set_current_modelview(view[1]); | ||
6407 | glh_set_current_projection(proj[1]); | ||
6408 | glLoadMatrixf(view[1].m); | ||
6409 | glMatrixMode(GL_PROJECTION); | ||
6410 | glLoadMatrixf(proj[1].m); | ||
6411 | glMatrixMode(GL_MODELVIEW); | ||
6412 | } | ||
6413 | gGL.setColorMask(true, false); | ||
5248 | } | 6414 | } |
5249 | 6415 | ||
5250 | void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) | 6416 | void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) |
@@ -5264,6 +6430,10 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu | |||
5264 | 6430 | ||
5265 | void LLPipeline::generateImpostor(LLVOAvatar* avatar) | 6431 | void LLPipeline::generateImpostor(LLVOAvatar* avatar) |
5266 | { | 6432 | { |
6433 | LLGLState::checkStates(); | ||
6434 | LLGLState::checkTextureChannels(); | ||
6435 | LLGLState::checkClientArrays(); | ||
6436 | |||
5267 | static LLCullResult result; | 6437 | static LLCullResult result; |
5268 | result.clear(); | 6438 | result.clear(); |
5269 | grabReferences(result); | 6439 | grabReferences(result); |
@@ -5289,6 +6459,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5289 | (1<<LLPipeline::RENDER_TYPE_BUMP) | | 6459 | (1<<LLPipeline::RENDER_TYPE_BUMP) | |
5290 | (1<<LLPipeline::RENDER_TYPE_GRASS) | | 6460 | (1<<LLPipeline::RENDER_TYPE_GRASS) | |
5291 | (1<<LLPipeline::RENDER_TYPE_SIMPLE) | | 6461 | (1<<LLPipeline::RENDER_TYPE_SIMPLE) | |
6462 | (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | | ||
5292 | (1<<LLPipeline::RENDER_TYPE_ALPHA) | | 6463 | (1<<LLPipeline::RENDER_TYPE_ALPHA) | |
5293 | (1<<LLPipeline::RENDER_TYPE_INVISIBLE); | 6464 | (1<<LLPipeline::RENDER_TYPE_INVISIBLE); |
5294 | } | 6465 | } |
@@ -5299,7 +6470,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5299 | 6470 | ||
5300 | S32 occlusion = sUseOcclusion; | 6471 | S32 occlusion = sUseOcclusion; |
5301 | sUseOcclusion = 0; | 6472 | sUseOcclusion = 0; |
5302 | sReflectionRender = TRUE; | 6473 | sReflectionRender = sRenderDeferred ? FALSE : TRUE; |
5303 | sImpostorRender = TRUE; | 6474 | sImpostorRender = TRUE; |
5304 | 6475 | ||
5305 | markVisible(avatar->mDrawable, *LLViewerCamera::getInstance()); | 6476 | markVisible(avatar->mDrawable, *LLViewerCamera::getInstance()); |
@@ -5376,10 +6547,17 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5376 | if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || | 6547 | if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || |
5377 | resY != avatar->mImpostor.getHeight()) | 6548 | resY != avatar->mImpostor.getHeight()) |
5378 | { | 6549 | { |
5379 | avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE); | 6550 | if (LLPipeline::sRenderDeferred) |
6551 | { | ||
6552 | avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE); | ||
6553 | addDeferredAttachments(avatar->mImpostor); | ||
6554 | } | ||
6555 | else | ||
6556 | { | ||
6557 | avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,TRUE); | ||
6558 | } | ||
5380 | gGL.getTexUnit(0)->bind(&avatar->mImpostor); | 6559 | gGL.getTexUnit(0)->bind(&avatar->mImpostor); |
5381 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 6560 | gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); |
5382 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||
5383 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | 6561 | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); |
5384 | } | 6562 | } |
5385 | 6563 | ||
@@ -5387,8 +6565,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5387 | LLGLEnable scissor(GL_SCISSOR_TEST); | 6565 | LLGLEnable scissor(GL_SCISSOR_TEST); |
5388 | glScissor(0, 0, resX, resY); | 6566 | glScissor(0, 0, resX, resY); |
5389 | avatar->mImpostor.bindTarget(); | 6567 | avatar->mImpostor.bindTarget(); |
5390 | avatar->mImpostor.getViewport(gGLViewport); | 6568 | avatar->mImpostor.clear(); |
5391 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
5392 | } | 6569 | } |
5393 | 6570 | ||
5394 | LLGLEnable stencil(GL_STENCIL_TEST); | 6571 | LLGLEnable stencil(GL_STENCIL_TEST); |
@@ -5396,11 +6573,20 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5396 | glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); | 6573 | glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); |
5397 | glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); | 6574 | glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); |
5398 | 6575 | ||
5399 | renderGeom(camera); | 6576 | if (LLPipeline::sRenderDeferred) |
6577 | { | ||
6578 | stop_glerror(); | ||
6579 | renderGeomDeferred(camera); | ||
6580 | } | ||
6581 | else | ||
6582 | { | ||
6583 | renderGeom(camera); | ||
6584 | } | ||
5400 | 6585 | ||
5401 | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | 6586 | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); |
5402 | glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); | 6587 | glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); |
5403 | 6588 | ||
6589 | if (!sRenderDeferred || muted) | ||
5404 | { | 6590 | { |
5405 | LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; | 6591 | LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; |
5406 | LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; | 6592 | LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; |
@@ -5431,7 +6617,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5431 | gGL.end(); | 6617 | gGL.end(); |
5432 | gGL.flush(); | 6618 | gGL.flush(); |
5433 | 6619 | ||
5434 | |||
5435 | gGL.setSceneBlendType(LLRender::BT_ALPHA); | 6620 | gGL.setSceneBlendType(LLRender::BT_ALPHA); |
5436 | } | 6621 | } |
5437 | 6622 | ||
@@ -5453,6 +6638,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) | |||
5453 | 6638 | ||
5454 | avatar->mNeedsImpostorUpdate = FALSE; | 6639 | avatar->mNeedsImpostorUpdate = FALSE; |
5455 | avatar->cacheImpostorValues(); | 6640 | avatar->cacheImpostorValues(); |
6641 | |||
6642 | LLVertexBuffer::unbind(); | ||
6643 | LLGLState::checkStates(); | ||
6644 | LLGLState::checkTextureChannels(); | ||
6645 | LLGLState::checkClientArrays(); | ||
5456 | } | 6646 | } |
5457 | 6647 | ||
5458 | BOOL LLPipeline::hasRenderBatches(const U32 type) const | 6648 | BOOL LLPipeline::hasRenderBatches(const U32 type) const |