Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ad8d824bd | |||
| 53ee2123c1 | |||
| fe3ace7d35 | |||
| 4d4dff2373 | |||
| f388911468 | |||
| 9704ad80f1 | |||
| 026d9a425e | |||
| 85bff28758 | |||
| 213060d473 | |||
| ca400ccf59 | |||
| 9dc6d17d7b | |||
| 15d3af3c66 | |||
| d9d1c4dfaf | |||
| 1c2974cf6a | |||
| c353335968 | |||
| 2ee76a413f | |||
| 7b074fc155 | |||
| 28220f62ad | |||
| cc7e4359ec | |||
| 72a292aeb6 | |||
| ca8f63cf7d | |||
| 4f518a0701 | |||
| b81253af67 | |||
| fd3d4e92af | |||
| 7418a196a9 |
@@ -1,19 +0,0 @@
|
||||
**/.git
|
||||
**/.gitlab
|
||||
**/.cache
|
||||
|
||||
buildAllJars
|
||||
|
||||
**/_Misc Files
|
||||
*.bat
|
||||
*.md
|
||||
*.sh
|
||||
*.txt
|
||||
|
||||
coreSubProjects/*.md
|
||||
coreSubProjects/*.txt
|
||||
|
||||
**/.gitignore
|
||||
**/.gitattributes
|
||||
**/.gitlab-cy.yml
|
||||
**/.gitmodules
|
||||
-700
@@ -1,700 +0,0 @@
|
||||
# DH Main
|
||||
root = true
|
||||
|
||||
# Note: please keep this and the core .editorconfig in sync
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = false
|
||||
max_line_length = 1000
|
||||
tab_width = 4
|
||||
trim_trailing_whitespace = false
|
||||
ij_continuation_indent_size = 4
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = true
|
||||
ij_smart_tabs = false
|
||||
ij_visual_guides = none
|
||||
ij_wrap_on_typing = false
|
||||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
ij_smart_tabs = true
|
||||
ij_java_align_consecutive_assignments = false
|
||||
ij_java_align_consecutive_variable_declarations = false
|
||||
ij_java_align_group_field_declarations = false
|
||||
ij_java_align_multiline_annotation_parameters = false
|
||||
ij_java_align_multiline_array_initializer_expression = false
|
||||
ij_java_align_multiline_assignment = false
|
||||
ij_java_align_multiline_binary_operation = false
|
||||
ij_java_align_multiline_chained_methods = false
|
||||
ij_java_align_multiline_deconstruction_list_components = false
|
||||
ij_java_align_multiline_extends_list = false
|
||||
ij_java_align_multiline_for = false
|
||||
ij_java_align_multiline_method_parentheses = false
|
||||
ij_java_align_multiline_parameters = false
|
||||
ij_java_align_multiline_parameters_in_calls = false
|
||||
ij_java_align_multiline_parenthesized_expression = false
|
||||
ij_java_align_multiline_records = false
|
||||
ij_java_align_multiline_resources = false
|
||||
ij_java_align_multiline_ternary_operation = false
|
||||
ij_java_align_multiline_text_blocks = false
|
||||
ij_java_align_multiline_throws_list = false
|
||||
ij_java_align_subsequent_simple_methods = false
|
||||
ij_java_align_throws_keyword = false
|
||||
ij_java_align_types_in_multi_catch = false
|
||||
ij_java_annotation_parameter_wrap = off
|
||||
ij_java_array_initializer_new_line_after_left_brace = false
|
||||
ij_java_array_initializer_right_brace_on_new_line = false
|
||||
ij_java_array_initializer_wrap = normal
|
||||
ij_java_assert_statement_colon_on_next_line = false
|
||||
ij_java_assert_statement_wrap = off
|
||||
ij_java_assignment_wrap = off
|
||||
ij_java_binary_operation_sign_on_next_line = false
|
||||
ij_java_binary_operation_wrap = off
|
||||
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||
ij_java_blank_lines_after_class_header = 0
|
||||
ij_java_blank_lines_after_imports = 1
|
||||
ij_java_blank_lines_after_package = 1
|
||||
ij_java_blank_lines_around_class = 1
|
||||
ij_java_blank_lines_around_field = 0
|
||||
ij_java_blank_lines_around_field_in_interface = 0
|
||||
ij_java_blank_lines_around_initializer = 0
|
||||
ij_java_blank_lines_around_method = 0
|
||||
ij_java_blank_lines_around_method_in_interface = 0
|
||||
ij_java_blank_lines_before_class_end = 1
|
||||
ij_java_blank_lines_before_imports = 1
|
||||
ij_java_blank_lines_before_method_body = 0
|
||||
ij_java_blank_lines_before_package = 1
|
||||
ij_java_block_brace_style = next_line
|
||||
ij_java_block_comment_add_space = false
|
||||
ij_java_block_comment_at_first_column = true
|
||||
ij_java_builder_methods = none
|
||||
ij_java_call_parameters_new_line_after_left_paren = false
|
||||
ij_java_call_parameters_right_paren_on_new_line = false
|
||||
ij_java_call_parameters_wrap = normal
|
||||
ij_java_case_statement_on_separate_line = true
|
||||
ij_java_catch_on_new_line = true
|
||||
ij_java_class_annotation_wrap = off
|
||||
ij_java_class_brace_style = next_line
|
||||
ij_java_class_count_to_use_import_on_demand = 5
|
||||
ij_java_class_names_in_javadoc = 1
|
||||
ij_java_deconstruction_list_wrap = normal
|
||||
ij_java_do_not_indent_top_level_class_members = false
|
||||
ij_java_do_not_wrap_after_single_annotation = false
|
||||
ij_java_do_not_wrap_after_single_annotation_in_parameter = false
|
||||
ij_java_do_while_brace_force = never
|
||||
ij_java_doc_add_blank_line_after_description = true
|
||||
ij_java_doc_add_blank_line_after_param_comments = false
|
||||
ij_java_doc_add_blank_line_after_return = false
|
||||
ij_java_doc_add_p_tag_on_empty_lines = false
|
||||
ij_java_doc_align_exception_comments = false
|
||||
ij_java_doc_align_param_comments = false
|
||||
ij_java_doc_do_not_wrap_if_one_line = true
|
||||
ij_java_doc_enable_formatting = true
|
||||
ij_java_doc_enable_leading_asterisks = true
|
||||
ij_java_doc_indent_on_continuation = false
|
||||
ij_java_doc_keep_empty_lines = true
|
||||
ij_java_doc_keep_empty_parameter_tag = true
|
||||
ij_java_doc_keep_empty_return_tag = false
|
||||
ij_java_doc_keep_empty_throws_tag = true
|
||||
ij_java_doc_keep_invalid_tags = true
|
||||
ij_java_doc_param_description_on_new_line = false
|
||||
ij_java_doc_preserve_line_breaks = false
|
||||
ij_java_doc_use_throws_not_exception_tag = true
|
||||
ij_java_else_on_new_line = true
|
||||
ij_java_enum_constants_wrap = off
|
||||
ij_java_extends_keyword_wrap = normal
|
||||
ij_java_extends_list_wrap = normal
|
||||
ij_java_field_annotation_wrap = off
|
||||
ij_java_finally_on_new_line = true
|
||||
ij_java_for_brace_force = always
|
||||
ij_java_for_statement_new_line_after_left_paren = false
|
||||
ij_java_for_statement_right_paren_on_new_line = false
|
||||
ij_java_for_statement_wrap = off
|
||||
ij_java_generate_final_locals = false
|
||||
ij_java_generate_final_parameters = false
|
||||
ij_java_if_brace_force = never
|
||||
ij_java_imports_layout = *,|,javax.**,java.**,|,$*
|
||||
ij_java_indent_case_from_switch = true
|
||||
ij_java_insert_inner_class_imports = false
|
||||
ij_java_insert_override_annotation = true
|
||||
ij_java_keep_blank_lines_before_right_brace = 10
|
||||
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||
ij_java_keep_blank_lines_in_code = 10
|
||||
ij_java_keep_blank_lines_in_declarations = 10
|
||||
ij_java_keep_builder_methods_indents = false
|
||||
ij_java_keep_control_statement_in_one_line = true
|
||||
ij_java_keep_first_column_comment = true
|
||||
ij_java_keep_indents_on_empty_lines = true
|
||||
ij_java_keep_line_breaks = true
|
||||
ij_java_keep_multiple_expressions_in_one_line = true
|
||||
ij_java_keep_simple_blocks_in_one_line = false
|
||||
ij_java_keep_simple_classes_in_one_line = true
|
||||
ij_java_keep_simple_lambdas_in_one_line = true
|
||||
ij_java_keep_simple_methods_in_one_line = true
|
||||
ij_java_label_indent_absolute = false
|
||||
ij_java_label_indent_size = 0
|
||||
ij_java_lambda_brace_style = end_of_line
|
||||
ij_java_layout_static_imports_separately = true
|
||||
ij_java_line_comment_add_space = false
|
||||
ij_java_line_comment_add_space_on_reformat = false
|
||||
ij_java_line_comment_at_first_column = false
|
||||
ij_java_method_annotation_wrap = off
|
||||
ij_java_method_brace_style = next_line
|
||||
ij_java_method_call_chain_wrap = normal
|
||||
ij_java_method_parameters_new_line_after_left_paren = true
|
||||
ij_java_method_parameters_right_paren_on_new_line = false
|
||||
ij_java_method_parameters_wrap = normal
|
||||
ij_java_modifier_list_wrap = false
|
||||
ij_java_multi_catch_types_wrap = normal
|
||||
ij_java_names_count_to_use_import_on_demand = 3
|
||||
ij_java_new_line_after_lparen_in_annotation = false
|
||||
ij_java_new_line_after_lparen_in_deconstruction_pattern = true
|
||||
ij_java_new_line_after_lparen_in_record_header = false
|
||||
ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
|
||||
ij_java_parameter_annotation_wrap = off
|
||||
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_java_place_assignment_sign_on_next_line = false
|
||||
ij_java_prefer_longer_names = true
|
||||
ij_java_prefer_parameters_wrap = false
|
||||
ij_java_record_components_wrap = normal
|
||||
ij_java_repeat_synchronized = true
|
||||
ij_java_replace_instanceof_and_cast = false
|
||||
ij_java_replace_null_check = false
|
||||
ij_java_replace_sum_lambda_with_method_ref = false
|
||||
ij_java_resource_list_new_line_after_left_paren = false
|
||||
ij_java_resource_list_right_paren_on_new_line = false
|
||||
ij_java_resource_list_wrap = on_every_item
|
||||
ij_java_rparen_on_new_line_in_annotation = false
|
||||
ij_java_rparen_on_new_line_in_deconstruction_pattern = true
|
||||
ij_java_rparen_on_new_line_in_record_header = false
|
||||
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||
ij_java_space_after_colon = true
|
||||
ij_java_space_after_comma = true
|
||||
ij_java_space_after_comma_in_type_arguments = true
|
||||
ij_java_space_after_for_semicolon = true
|
||||
ij_java_space_after_quest = true
|
||||
ij_java_space_after_type_cast = true
|
||||
ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||
ij_java_space_before_annotation_parameter_list = false
|
||||
ij_java_space_before_array_initializer_left_brace = false
|
||||
ij_java_space_before_catch_keyword = true
|
||||
ij_java_space_before_catch_left_brace = true
|
||||
ij_java_space_before_catch_parentheses = true
|
||||
ij_java_space_before_class_left_brace = true
|
||||
ij_java_space_before_colon = true
|
||||
ij_java_space_before_colon_in_foreach = true
|
||||
ij_java_space_before_comma = false
|
||||
ij_java_space_before_deconstruction_list = false
|
||||
ij_java_space_before_do_left_brace = true
|
||||
ij_java_space_before_else_keyword = true
|
||||
ij_java_space_before_else_left_brace = true
|
||||
ij_java_space_before_finally_keyword = true
|
||||
ij_java_space_before_finally_left_brace = true
|
||||
ij_java_space_before_for_left_brace = true
|
||||
ij_java_space_before_for_parentheses = true
|
||||
ij_java_space_before_for_semicolon = false
|
||||
ij_java_space_before_if_left_brace = true
|
||||
ij_java_space_before_if_parentheses = true
|
||||
ij_java_space_before_method_call_parentheses = false
|
||||
ij_java_space_before_method_left_brace = true
|
||||
ij_java_space_before_method_parentheses = false
|
||||
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||
ij_java_space_before_quest = true
|
||||
ij_java_space_before_switch_left_brace = true
|
||||
ij_java_space_before_switch_parentheses = true
|
||||
ij_java_space_before_synchronized_left_brace = false
|
||||
ij_java_space_before_synchronized_parentheses = true
|
||||
ij_java_space_before_try_left_brace = true
|
||||
ij_java_space_before_try_parentheses = true
|
||||
ij_java_space_before_type_parameter_list = false
|
||||
ij_java_space_before_while_keyword = true
|
||||
ij_java_space_before_while_left_brace = true
|
||||
ij_java_space_before_while_parentheses = true
|
||||
ij_java_space_inside_one_line_enum_braces = false
|
||||
ij_java_space_within_empty_array_initializer_braces = true
|
||||
ij_java_space_within_empty_method_call_parentheses = false
|
||||
ij_java_space_within_empty_method_parentheses = false
|
||||
ij_java_spaces_around_additive_operators = true
|
||||
ij_java_spaces_around_annotation_eq = true
|
||||
ij_java_spaces_around_assignment_operators = true
|
||||
ij_java_spaces_around_bitwise_operators = true
|
||||
ij_java_spaces_around_equality_operators = true
|
||||
ij_java_spaces_around_lambda_arrow = true
|
||||
ij_java_spaces_around_logical_operators = true
|
||||
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||
ij_java_spaces_around_multiplicative_operators = true
|
||||
ij_java_spaces_around_relational_operators = true
|
||||
ij_java_spaces_around_shift_operators = true
|
||||
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||
ij_java_spaces_around_unary_operator = false
|
||||
ij_java_spaces_within_angle_brackets = false
|
||||
ij_java_spaces_within_annotation_parentheses = false
|
||||
ij_java_spaces_within_array_initializer_braces = false
|
||||
ij_java_spaces_within_braces = true
|
||||
ij_java_spaces_within_brackets = false
|
||||
ij_java_spaces_within_cast_parentheses = false
|
||||
ij_java_spaces_within_catch_parentheses = false
|
||||
ij_java_spaces_within_deconstruction_list = false
|
||||
ij_java_spaces_within_for_parentheses = false
|
||||
ij_java_spaces_within_if_parentheses = false
|
||||
ij_java_spaces_within_method_call_parentheses = false
|
||||
ij_java_spaces_within_method_parentheses = false
|
||||
ij_java_spaces_within_parentheses = false
|
||||
ij_java_spaces_within_record_header = false
|
||||
ij_java_spaces_within_switch_parentheses = false
|
||||
ij_java_spaces_within_synchronized_parentheses = false
|
||||
ij_java_spaces_within_try_parentheses = false
|
||||
ij_java_spaces_within_while_parentheses = false
|
||||
ij_java_special_else_if_treatment = true
|
||||
ij_java_subclass_name_suffix = Impl
|
||||
ij_java_ternary_operation_signs_on_next_line = false
|
||||
ij_java_ternary_operation_wrap = on_every_item
|
||||
ij_java_test_name_suffix = Test
|
||||
ij_java_throws_keyword_wrap = normal
|
||||
ij_java_throws_list_wrap = normal
|
||||
ij_java_use_external_annotations = false
|
||||
ij_java_use_fq_class_names = false
|
||||
ij_java_use_relative_indents = false
|
||||
ij_java_use_single_class_imports = true
|
||||
ij_java_variable_annotation_wrap = off
|
||||
ij_java_visibility = public
|
||||
ij_java_while_brace_force = always
|
||||
ij_java_while_on_new_line = true
|
||||
ij_java_wrap_comments = false
|
||||
ij_java_wrap_first_method_in_call_chain = false
|
||||
ij_java_wrap_long_lines = false
|
||||
|
||||
[*.nbtt]
|
||||
indent_style = tab
|
||||
max_line_length = 150
|
||||
ij_continuation_indent_size = 4
|
||||
ij_nbtt_keep_indents_on_empty_lines = false
|
||||
ij_nbtt_space_after_colon = true
|
||||
ij_nbtt_space_after_comma = true
|
||||
ij_nbtt_space_before_colon = true
|
||||
ij_nbtt_space_before_comma = false
|
||||
ij_nbtt_spaces_within_brackets = false
|
||||
ij_nbtt_spaces_within_parentheses = false
|
||||
|
||||
[*.properties]
|
||||
ij_properties_align_group_field_declarations = false
|
||||
ij_properties_keep_blank_lines = false
|
||||
ij_properties_key_value_delimiter = equals
|
||||
ij_properties_spaces_around_key_value_delimiter = false
|
||||
|
||||
[.editorconfig]
|
||||
ij_editorconfig_align_group_field_declarations = false
|
||||
ij_editorconfig_space_after_colon = false
|
||||
ij_editorconfig_space_after_comma = true
|
||||
ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.jspx,*.pom,*.rng,*.tagx,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
|
||||
ij_xml_align_attributes = true
|
||||
ij_xml_align_text = false
|
||||
ij_xml_attribute_wrap = normal
|
||||
ij_xml_block_comment_add_space = false
|
||||
ij_xml_block_comment_at_first_column = true
|
||||
ij_xml_keep_blank_lines = 2
|
||||
ij_xml_keep_indents_on_empty_lines = false
|
||||
ij_xml_keep_line_breaks = true
|
||||
ij_xml_keep_line_breaks_in_text = true
|
||||
ij_xml_keep_whitespaces = false
|
||||
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||
ij_xml_keep_whitespaces_inside_cdata = false
|
||||
ij_xml_line_comment_at_first_column = true
|
||||
ij_xml_space_after_tag_name = false
|
||||
ij_xml_space_around_equals_in_attribute = false
|
||||
ij_xml_space_inside_empty_tag = false
|
||||
ij_xml_text_wrap = normal
|
||||
ij_xml_use_custom_settings = false
|
||||
|
||||
[{*.bash,*.sh,*.zsh}]
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
ij_shell_binary_ops_start_line = false
|
||||
ij_shell_keep_column_alignment_padding = false
|
||||
ij_shell_minify_program = false
|
||||
ij_shell_redirect_followed_by_space = false
|
||||
ij_shell_switch_cases_indented = false
|
||||
ij_shell_use_unix_line_separator = true
|
||||
|
||||
[{*.comp,*.frag,*.fsh,*.geom,*.glsl,*.gsh,*.tesc,*.tese,*.vert,*.vsh}]
|
||||
ij_glsl_space_after_colon = true
|
||||
ij_glsl_space_after_comma = true
|
||||
ij_glsl_space_after_for_semicolon = true
|
||||
ij_glsl_space_after_quest = true
|
||||
ij_glsl_space_before_colon = false
|
||||
ij_glsl_space_before_comma = false
|
||||
ij_glsl_space_before_for_semicolon = false
|
||||
ij_glsl_space_before_quest = true
|
||||
ij_glsl_spaces_around_additive_operators = true
|
||||
ij_glsl_spaces_around_assignment_operators = true
|
||||
ij_glsl_spaces_around_bitwise_operators = true
|
||||
ij_glsl_spaces_around_equality_operators = true
|
||||
ij_glsl_spaces_around_logical_operators = true
|
||||
ij_glsl_spaces_around_multiplicative_operators = true
|
||||
ij_glsl_spaces_around_relational_operators = true
|
||||
ij_glsl_spaces_around_shift_operators = true
|
||||
ij_glsl_spaces_within_brackets = false
|
||||
ij_glsl_spaces_within_parentheses = false
|
||||
|
||||
[{*.gant,*.groovy,*.gy}]
|
||||
ij_groovy_align_group_field_declarations = false
|
||||
ij_groovy_align_multiline_array_initializer_expression = false
|
||||
ij_groovy_align_multiline_assignment = false
|
||||
ij_groovy_align_multiline_binary_operation = false
|
||||
ij_groovy_align_multiline_chained_methods = false
|
||||
ij_groovy_align_multiline_extends_list = false
|
||||
ij_groovy_align_multiline_for = true
|
||||
ij_groovy_align_multiline_list_or_map = true
|
||||
ij_groovy_align_multiline_method_parentheses = false
|
||||
ij_groovy_align_multiline_parameters = true
|
||||
ij_groovy_align_multiline_parameters_in_calls = false
|
||||
ij_groovy_align_multiline_resources = true
|
||||
ij_groovy_align_multiline_ternary_operation = false
|
||||
ij_groovy_align_multiline_throws_list = false
|
||||
ij_groovy_align_named_args_in_map = true
|
||||
ij_groovy_align_throws_keyword = false
|
||||
ij_groovy_array_initializer_new_line_after_left_brace = false
|
||||
ij_groovy_array_initializer_right_brace_on_new_line = false
|
||||
ij_groovy_array_initializer_wrap = off
|
||||
ij_groovy_assert_statement_wrap = off
|
||||
ij_groovy_assignment_wrap = off
|
||||
ij_groovy_binary_operation_wrap = off
|
||||
ij_groovy_blank_lines_after_class_header = 0
|
||||
ij_groovy_blank_lines_after_imports = 1
|
||||
ij_groovy_blank_lines_after_package = 1
|
||||
ij_groovy_blank_lines_around_class = 1
|
||||
ij_groovy_blank_lines_around_field = 0
|
||||
ij_groovy_blank_lines_around_field_in_interface = 0
|
||||
ij_groovy_blank_lines_around_method = 1
|
||||
ij_groovy_blank_lines_around_method_in_interface = 1
|
||||
ij_groovy_blank_lines_before_imports = 1
|
||||
ij_groovy_blank_lines_before_method_body = 0
|
||||
ij_groovy_blank_lines_before_package = 0
|
||||
ij_groovy_block_brace_style = end_of_line
|
||||
ij_groovy_block_comment_add_space = false
|
||||
ij_groovy_block_comment_at_first_column = true
|
||||
ij_groovy_call_parameters_new_line_after_left_paren = false
|
||||
ij_groovy_call_parameters_right_paren_on_new_line = false
|
||||
ij_groovy_call_parameters_wrap = off
|
||||
ij_groovy_catch_on_new_line = false
|
||||
ij_groovy_class_annotation_wrap = split_into_lines
|
||||
ij_groovy_class_brace_style = end_of_line
|
||||
ij_groovy_class_count_to_use_import_on_demand = 5
|
||||
ij_groovy_do_while_brace_force = never
|
||||
ij_groovy_else_on_new_line = false
|
||||
ij_groovy_enable_groovydoc_formatting = true
|
||||
ij_groovy_enum_constants_wrap = off
|
||||
ij_groovy_extends_keyword_wrap = off
|
||||
ij_groovy_extends_list_wrap = off
|
||||
ij_groovy_field_annotation_wrap = split_into_lines
|
||||
ij_groovy_finally_on_new_line = false
|
||||
ij_groovy_for_brace_force = never
|
||||
ij_groovy_for_statement_new_line_after_left_paren = false
|
||||
ij_groovy_for_statement_right_paren_on_new_line = false
|
||||
ij_groovy_for_statement_wrap = off
|
||||
ij_groovy_ginq_general_clause_wrap_policy = 2
|
||||
ij_groovy_ginq_having_wrap_policy = 1
|
||||
ij_groovy_ginq_indent_having_clause = true
|
||||
ij_groovy_ginq_indent_on_clause = true
|
||||
ij_groovy_ginq_on_wrap_policy = 1
|
||||
ij_groovy_ginq_space_after_keyword = true
|
||||
ij_groovy_if_brace_force = never
|
||||
ij_groovy_import_annotation_wrap = 2
|
||||
ij_groovy_imports_layout = *,|,javax.**,java.**,|,$*
|
||||
ij_groovy_indent_case_from_switch = true
|
||||
ij_groovy_indent_label_blocks = true
|
||||
ij_groovy_insert_inner_class_imports = false
|
||||
ij_groovy_keep_blank_lines_before_right_brace = 2
|
||||
ij_groovy_keep_blank_lines_in_code = 2
|
||||
ij_groovy_keep_blank_lines_in_declarations = 2
|
||||
ij_groovy_keep_control_statement_in_one_line = true
|
||||
ij_groovy_keep_first_column_comment = true
|
||||
ij_groovy_keep_indents_on_empty_lines = false
|
||||
ij_groovy_keep_line_breaks = true
|
||||
ij_groovy_keep_multiple_expressions_in_one_line = false
|
||||
ij_groovy_keep_simple_blocks_in_one_line = false
|
||||
ij_groovy_keep_simple_classes_in_one_line = true
|
||||
ij_groovy_keep_simple_lambdas_in_one_line = true
|
||||
ij_groovy_keep_simple_methods_in_one_line = true
|
||||
ij_groovy_label_indent_absolute = false
|
||||
ij_groovy_label_indent_size = 0
|
||||
ij_groovy_lambda_brace_style = end_of_line
|
||||
ij_groovy_layout_static_imports_separately = true
|
||||
ij_groovy_line_comment_add_space = false
|
||||
ij_groovy_line_comment_add_space_on_reformat = false
|
||||
ij_groovy_line_comment_at_first_column = true
|
||||
ij_groovy_method_annotation_wrap = split_into_lines
|
||||
ij_groovy_method_brace_style = end_of_line
|
||||
ij_groovy_method_call_chain_wrap = off
|
||||
ij_groovy_method_parameters_new_line_after_left_paren = false
|
||||
ij_groovy_method_parameters_right_paren_on_new_line = false
|
||||
ij_groovy_method_parameters_wrap = off
|
||||
ij_groovy_modifier_list_wrap = false
|
||||
ij_groovy_names_count_to_use_import_on_demand = 3
|
||||
ij_groovy_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
|
||||
ij_groovy_parameter_annotation_wrap = off
|
||||
ij_groovy_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_groovy_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_groovy_prefer_parameters_wrap = false
|
||||
ij_groovy_resource_list_new_line_after_left_paren = false
|
||||
ij_groovy_resource_list_right_paren_on_new_line = false
|
||||
ij_groovy_resource_list_wrap = off
|
||||
ij_groovy_space_after_assert_separator = true
|
||||
ij_groovy_space_after_colon = true
|
||||
ij_groovy_space_after_comma = true
|
||||
ij_groovy_space_after_comma_in_type_arguments = true
|
||||
ij_groovy_space_after_for_semicolon = true
|
||||
ij_groovy_space_after_quest = true
|
||||
ij_groovy_space_after_type_cast = true
|
||||
ij_groovy_space_before_annotation_parameter_list = false
|
||||
ij_groovy_space_before_array_initializer_left_brace = false
|
||||
ij_groovy_space_before_assert_separator = false
|
||||
ij_groovy_space_before_catch_keyword = true
|
||||
ij_groovy_space_before_catch_left_brace = true
|
||||
ij_groovy_space_before_catch_parentheses = true
|
||||
ij_groovy_space_before_class_left_brace = true
|
||||
ij_groovy_space_before_closure_left_brace = true
|
||||
ij_groovy_space_before_colon = true
|
||||
ij_groovy_space_before_comma = false
|
||||
ij_groovy_space_before_do_left_brace = true
|
||||
ij_groovy_space_before_else_keyword = true
|
||||
ij_groovy_space_before_else_left_brace = true
|
||||
ij_groovy_space_before_finally_keyword = true
|
||||
ij_groovy_space_before_finally_left_brace = true
|
||||
ij_groovy_space_before_for_left_brace = true
|
||||
ij_groovy_space_before_for_parentheses = true
|
||||
ij_groovy_space_before_for_semicolon = false
|
||||
ij_groovy_space_before_if_left_brace = true
|
||||
ij_groovy_space_before_if_parentheses = true
|
||||
ij_groovy_space_before_method_call_parentheses = false
|
||||
ij_groovy_space_before_method_left_brace = true
|
||||
ij_groovy_space_before_method_parentheses = false
|
||||
ij_groovy_space_before_quest = true
|
||||
ij_groovy_space_before_record_parentheses = false
|
||||
ij_groovy_space_before_switch_left_brace = true
|
||||
ij_groovy_space_before_switch_parentheses = true
|
||||
ij_groovy_space_before_synchronized_left_brace = true
|
||||
ij_groovy_space_before_synchronized_parentheses = true
|
||||
ij_groovy_space_before_try_left_brace = true
|
||||
ij_groovy_space_before_try_parentheses = true
|
||||
ij_groovy_space_before_while_keyword = true
|
||||
ij_groovy_space_before_while_left_brace = true
|
||||
ij_groovy_space_before_while_parentheses = true
|
||||
ij_groovy_space_in_named_argument = true
|
||||
ij_groovy_space_in_named_argument_before_colon = false
|
||||
ij_groovy_space_within_empty_array_initializer_braces = false
|
||||
ij_groovy_space_within_empty_method_call_parentheses = false
|
||||
ij_groovy_spaces_around_additive_operators = true
|
||||
ij_groovy_spaces_around_assignment_operators = true
|
||||
ij_groovy_spaces_around_bitwise_operators = true
|
||||
ij_groovy_spaces_around_equality_operators = true
|
||||
ij_groovy_spaces_around_lambda_arrow = true
|
||||
ij_groovy_spaces_around_logical_operators = true
|
||||
ij_groovy_spaces_around_multiplicative_operators = true
|
||||
ij_groovy_spaces_around_regex_operators = true
|
||||
ij_groovy_spaces_around_relational_operators = true
|
||||
ij_groovy_spaces_around_shift_operators = true
|
||||
ij_groovy_spaces_within_annotation_parentheses = false
|
||||
ij_groovy_spaces_within_array_initializer_braces = false
|
||||
ij_groovy_spaces_within_braces = true
|
||||
ij_groovy_spaces_within_brackets = false
|
||||
ij_groovy_spaces_within_cast_parentheses = false
|
||||
ij_groovy_spaces_within_catch_parentheses = false
|
||||
ij_groovy_spaces_within_for_parentheses = false
|
||||
ij_groovy_spaces_within_gstring_injection_braces = false
|
||||
ij_groovy_spaces_within_if_parentheses = false
|
||||
ij_groovy_spaces_within_list_or_map = false
|
||||
ij_groovy_spaces_within_method_call_parentheses = false
|
||||
ij_groovy_spaces_within_method_parentheses = false
|
||||
ij_groovy_spaces_within_parentheses = false
|
||||
ij_groovy_spaces_within_switch_parentheses = false
|
||||
ij_groovy_spaces_within_synchronized_parentheses = false
|
||||
ij_groovy_spaces_within_try_parentheses = false
|
||||
ij_groovy_spaces_within_tuple_expression = false
|
||||
ij_groovy_spaces_within_while_parentheses = false
|
||||
ij_groovy_special_else_if_treatment = true
|
||||
ij_groovy_ternary_operation_wrap = off
|
||||
ij_groovy_throws_keyword_wrap = off
|
||||
ij_groovy_throws_list_wrap = off
|
||||
ij_groovy_use_flying_geese_braces = false
|
||||
ij_groovy_use_fq_class_names = false
|
||||
ij_groovy_use_fq_class_names_in_javadoc = true
|
||||
ij_groovy_use_relative_indents = false
|
||||
ij_groovy_use_single_class_imports = true
|
||||
ij_groovy_variable_annotation_wrap = off
|
||||
ij_groovy_while_brace_force = never
|
||||
ij_groovy_while_on_new_line = false
|
||||
ij_groovy_wrap_chain_calls_after_dot = false
|
||||
ij_groovy_wrap_long_lines = false
|
||||
|
||||
[{*.har,*.json,*.png.mcmeta,mcmod.info,pack.mcmeta}]
|
||||
indent_size = 4
|
||||
ij_json_array_wrapping = split_into_lines
|
||||
ij_json_keep_blank_lines_in_code = 0
|
||||
ij_json_keep_indents_on_empty_lines = false
|
||||
ij_json_keep_line_breaks = true
|
||||
ij_json_keep_trailing_comma = false
|
||||
ij_json_object_wrapping = split_into_lines
|
||||
ij_json_property_alignment = do_not_align
|
||||
ij_json_space_after_colon = true
|
||||
ij_json_space_after_comma = true
|
||||
ij_json_space_before_colon = false
|
||||
ij_json_space_before_comma = false
|
||||
ij_json_spaces_within_braces = false
|
||||
ij_json_spaces_within_brackets = false
|
||||
ij_json_wrap_long_lines = false
|
||||
|
||||
[{*.htm,*.html,*.sht,*.shtm,*.shtml}]
|
||||
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
|
||||
ij_html_align_attributes = true
|
||||
ij_html_align_text = false
|
||||
ij_html_attribute_wrap = normal
|
||||
ij_html_block_comment_add_space = false
|
||||
ij_html_block_comment_at_first_column = true
|
||||
ij_html_do_not_align_children_of_min_lines = 0
|
||||
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
|
||||
ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
|
||||
ij_html_enforce_quotes = false
|
||||
ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
|
||||
ij_html_keep_blank_lines = 2
|
||||
ij_html_keep_indents_on_empty_lines = false
|
||||
ij_html_keep_line_breaks = true
|
||||
ij_html_keep_line_breaks_in_text = true
|
||||
ij_html_keep_whitespaces = false
|
||||
ij_html_keep_whitespaces_inside = span,pre,textarea
|
||||
ij_html_line_comment_at_first_column = true
|
||||
ij_html_new_line_after_last_attribute = never
|
||||
ij_html_new_line_before_first_attribute = never
|
||||
ij_html_quote_style = double
|
||||
ij_html_remove_new_line_before_tags = br
|
||||
ij_html_space_after_tag_name = false
|
||||
ij_html_space_around_equality_in_attribute = false
|
||||
ij_html_space_inside_empty_tag = false
|
||||
ij_html_text_wrap = normal
|
||||
|
||||
[{*.kt,*.kts}]
|
||||
ij_kotlin_align_in_columns_case_branch = false
|
||||
ij_kotlin_align_multiline_binary_operation = false
|
||||
ij_kotlin_align_multiline_extends_list = false
|
||||
ij_kotlin_align_multiline_method_parentheses = false
|
||||
ij_kotlin_align_multiline_parameters = true
|
||||
ij_kotlin_align_multiline_parameters_in_calls = false
|
||||
ij_kotlin_allow_trailing_comma = false
|
||||
ij_kotlin_allow_trailing_comma_on_call_site = false
|
||||
ij_kotlin_assignment_wrap = off
|
||||
ij_kotlin_blank_lines_after_class_header = 0
|
||||
ij_kotlin_blank_lines_around_block_when_branches = 0
|
||||
ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
|
||||
ij_kotlin_block_comment_add_space = false
|
||||
ij_kotlin_block_comment_at_first_column = true
|
||||
ij_kotlin_call_parameters_new_line_after_left_paren = false
|
||||
ij_kotlin_call_parameters_right_paren_on_new_line = false
|
||||
ij_kotlin_call_parameters_wrap = off
|
||||
ij_kotlin_catch_on_new_line = false
|
||||
ij_kotlin_class_annotation_wrap = split_into_lines
|
||||
ij_kotlin_continuation_indent_for_chained_calls = true
|
||||
ij_kotlin_continuation_indent_for_expression_bodies = true
|
||||
ij_kotlin_continuation_indent_in_argument_lists = true
|
||||
ij_kotlin_continuation_indent_in_elvis = true
|
||||
ij_kotlin_continuation_indent_in_if_conditions = true
|
||||
ij_kotlin_continuation_indent_in_parameter_lists = true
|
||||
ij_kotlin_continuation_indent_in_supertype_lists = true
|
||||
ij_kotlin_else_on_new_line = false
|
||||
ij_kotlin_enum_constants_wrap = off
|
||||
ij_kotlin_extends_list_wrap = off
|
||||
ij_kotlin_field_annotation_wrap = split_into_lines
|
||||
ij_kotlin_finally_on_new_line = false
|
||||
ij_kotlin_if_rparen_on_new_line = false
|
||||
ij_kotlin_import_nested_classes = false
|
||||
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
|
||||
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
|
||||
ij_kotlin_keep_blank_lines_before_right_brace = 2
|
||||
ij_kotlin_keep_blank_lines_in_code = 2
|
||||
ij_kotlin_keep_blank_lines_in_declarations = 2
|
||||
ij_kotlin_keep_first_column_comment = true
|
||||
ij_kotlin_keep_indents_on_empty_lines = false
|
||||
ij_kotlin_keep_line_breaks = true
|
||||
ij_kotlin_lbrace_on_next_line = false
|
||||
ij_kotlin_line_break_after_multiline_when_entry = true
|
||||
ij_kotlin_line_comment_add_space = false
|
||||
ij_kotlin_line_comment_add_space_on_reformat = false
|
||||
ij_kotlin_line_comment_at_first_column = true
|
||||
ij_kotlin_method_annotation_wrap = split_into_lines
|
||||
ij_kotlin_method_call_chain_wrap = off
|
||||
ij_kotlin_method_parameters_new_line_after_left_paren = false
|
||||
ij_kotlin_method_parameters_right_paren_on_new_line = false
|
||||
ij_kotlin_method_parameters_wrap = off
|
||||
ij_kotlin_name_count_to_use_star_import = 5
|
||||
ij_kotlin_name_count_to_use_star_import_for_members = 3
|
||||
ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.**
|
||||
ij_kotlin_parameter_annotation_wrap = off
|
||||
ij_kotlin_space_after_comma = true
|
||||
ij_kotlin_space_after_extend_colon = true
|
||||
ij_kotlin_space_after_type_colon = true
|
||||
ij_kotlin_space_before_catch_parentheses = true
|
||||
ij_kotlin_space_before_comma = false
|
||||
ij_kotlin_space_before_extend_colon = true
|
||||
ij_kotlin_space_before_for_parentheses = true
|
||||
ij_kotlin_space_before_if_parentheses = true
|
||||
ij_kotlin_space_before_lambda_arrow = true
|
||||
ij_kotlin_space_before_type_colon = false
|
||||
ij_kotlin_space_before_when_parentheses = true
|
||||
ij_kotlin_space_before_while_parentheses = true
|
||||
ij_kotlin_spaces_around_additive_operators = true
|
||||
ij_kotlin_spaces_around_assignment_operators = true
|
||||
ij_kotlin_spaces_around_equality_operators = true
|
||||
ij_kotlin_spaces_around_function_type_arrow = true
|
||||
ij_kotlin_spaces_around_logical_operators = true
|
||||
ij_kotlin_spaces_around_multiplicative_operators = true
|
||||
ij_kotlin_spaces_around_range = false
|
||||
ij_kotlin_spaces_around_relational_operators = true
|
||||
ij_kotlin_spaces_around_unary_operator = false
|
||||
ij_kotlin_spaces_around_when_arrow = true
|
||||
ij_kotlin_variable_annotation_wrap = off
|
||||
ij_kotlin_while_on_new_line = false
|
||||
ij_kotlin_wrap_elvis_expressions = 1
|
||||
ij_kotlin_wrap_expression_body_functions = 0
|
||||
ij_kotlin_wrap_first_method_in_call_chain = false
|
||||
|
||||
[{*.markdown,*.md}]
|
||||
ij_markdown_force_one_space_after_blockquote_symbol = true
|
||||
ij_markdown_force_one_space_after_header_symbol = true
|
||||
ij_markdown_force_one_space_after_list_bullet = true
|
||||
ij_markdown_force_one_space_between_words = true
|
||||
ij_markdown_format_tables = true
|
||||
ij_markdown_insert_quote_arrows_on_wrap = true
|
||||
ij_markdown_keep_indents_on_empty_lines = false
|
||||
ij_markdown_keep_line_breaks_inside_text_blocks = true
|
||||
ij_markdown_max_lines_around_block_elements = 1
|
||||
ij_markdown_max_lines_around_header = 1
|
||||
ij_markdown_max_lines_between_paragraphs = 1
|
||||
ij_markdown_min_lines_around_block_elements = 1
|
||||
ij_markdown_min_lines_around_header = 1
|
||||
ij_markdown_min_lines_between_paragraphs = 1
|
||||
ij_markdown_wrap_text_if_long = true
|
||||
ij_markdown_wrap_text_inside_blockquotes = true
|
||||
|
||||
[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}]
|
||||
ij_toml_keep_indents_on_empty_lines = false
|
||||
|
||||
[{*.yaml,*.yml}]
|
||||
indent_size = 4
|
||||
ij_yaml_align_values_properties = do_not_align
|
||||
ij_yaml_autoinsert_sequence_marker = true
|
||||
ij_yaml_block_mapping_on_new_line = false
|
||||
ij_yaml_indent_sequence_value = true
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
ij_yaml_sequence_on_new_line = false
|
||||
ij_yaml_space_before_colon = false
|
||||
ij_yaml_spaces_within_braces = true
|
||||
ij_yaml_spaces_within_brackets = true
|
||||
@@ -0,0 +1 @@
|
||||
<factorypath />
|
||||
@@ -1,5 +0,0 @@
|
||||
# Disable autocrlf on generated files, they always generate with LF
|
||||
# Add any extra files or paths here to make git stop saying they
|
||||
# are changed when only line endings change.
|
||||
src/generated/**/.cache/cache text eol=lf
|
||||
src/generated/**/*.json text eol=lf
|
||||
+21
-40
@@ -1,46 +1,27 @@
|
||||
build/
|
||||
*.ipr
|
||||
run/
|
||||
*.iws
|
||||
out/
|
||||
*.iml
|
||||
.gradle/
|
||||
.gradle-cache/
|
||||
output/
|
||||
bin/
|
||||
libs/
|
||||
.architectury-transformer/
|
||||
|
||||
# eclipse
|
||||
bin
|
||||
*.launch
|
||||
.settings
|
||||
.metadata
|
||||
.classpath
|
||||
.project
|
||||
.idea/
|
||||
classes/
|
||||
.metadata
|
||||
.vscode
|
||||
.settings
|
||||
*.launch
|
||||
hs_err_pid*
|
||||
|
||||
**/src/generated/
|
||||
Merged/
|
||||
# Folder created by the buildAll scripts
|
||||
buildAllJars/
|
||||
# idea
|
||||
out
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
relocate_natives/.venv/
|
||||
relocate_natives/__pycache__/
|
||||
relocate_natives/apple-codesign/
|
||||
# gradle
|
||||
build
|
||||
.gradle
|
||||
|
||||
# file from notepad++
|
||||
*.bak
|
||||
# other
|
||||
eclipse
|
||||
|
||||
# file genearated via MC version switching using preprocessor
|
||||
build.properties
|
||||
|
||||
# Sqlite databases
|
||||
*.sqlite
|
||||
*.sqlite-journal
|
||||
*.sqlite-shm
|
||||
*.sqlite-wal
|
||||
|
||||
# Don't add access transformers to git as they're dynamically generated
|
||||
accesstransformer.cfg
|
||||
# minecraft run folder,
|
||||
# ignore everything but the mods folder
|
||||
run/*
|
||||
!run/mods
|
||||
/Users/
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
# use Eclipse's JDK
|
||||
# The ci should always use a unix(-like) OS to work
|
||||
image: eclipse-temurin:25
|
||||
|
||||
# all stages need to be defined here
|
||||
stages:
|
||||
- build
|
||||
- api
|
||||
- pages
|
||||
|
||||
variables:
|
||||
# Pull core when building
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
|
||||
|
||||
# These can be extended so code is a bit less duplicated
|
||||
.build_java:
|
||||
#image: eclipse-temurin:17
|
||||
cache:
|
||||
key: "gradleCache_$CI_JOB_NAME_SLUG"
|
||||
policy: pull-push
|
||||
paths:
|
||||
- .gradle
|
||||
- cache/
|
||||
allow_failure: true
|
||||
retry:
|
||||
max: 2
|
||||
when:
|
||||
- runner_system_failure
|
||||
- stuck_or_timeout_failure
|
||||
|
||||
|
||||
build:
|
||||
stage: build
|
||||
parallel:
|
||||
matrix:
|
||||
- MC_VER: [
|
||||
"1.26.1",
|
||||
"1.21.11", "1.21.10", "1.21.9", "1.21.8", "1.21.6", "1.21.5", "1.21.4", "1.21.3", "1.21.1",
|
||||
"1.20.6", "1.20.4", "1.20.2", "1.20.1",
|
||||
"1.19.4", "1.19.2",
|
||||
"1.18.2",
|
||||
"1.17.1",
|
||||
"1.16.5"
|
||||
]
|
||||
script:
|
||||
# this both runs the unit tests and assembles the code
|
||||
- ./gradlew clean -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||
- ./gradlew build -PmcVer="${MC_VER}" -PinfoGitCommit="${CI_COMMIT_SHA}" -PinfoGitBranch="${CI_COMMIT_BRANCH}" -PinfoBuildSource="GitLab CI (${CI_PIPELINE_ID})" --gradle-user-home cache/;
|
||||
- cp ./fabric/build/libs/* ./forge/build/libs/* ./neoforge/build/libs/* ./build/forgix/* . || true
|
||||
artifacts:
|
||||
name: "NightlyBuild_${MC_VER}-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||
paths:
|
||||
- ./*.jar
|
||||
exclude:
|
||||
- ./*-all.jar
|
||||
- ./*-dev.jar
|
||||
- ./*-sources.jar
|
||||
expire_in: 14 days
|
||||
when: always
|
||||
extends: .build_java
|
||||
|
||||
|
||||
api:
|
||||
stage: api
|
||||
needs: []
|
||||
script:
|
||||
# this should only run for the API
|
||||
- ./gradlew api:clean --gradle-user-home cache/;
|
||||
# this also runs unit tests
|
||||
- ./gradlew api:build --gradle-user-home cache/;
|
||||
- ./gradlew api:addSourcesToCompiledJar --gradle-user-home cache/;
|
||||
- cp ./coreSubProjects/api/build/libs/merged/* .
|
||||
artifacts:
|
||||
name: "NightlyBuild_Api-${CI_COMMIT_SHORT_SHA}-${CI_COMMIT_TIMESTAMP}"
|
||||
paths:
|
||||
- ./*.jar
|
||||
exclude:
|
||||
- ./*-all.jar
|
||||
- ./*-dev.jar
|
||||
- ./*-sources.jar
|
||||
expire_in: 1 day
|
||||
when: always
|
||||
extends: .build_java
|
||||
|
||||
|
||||
# generate and publish API javadocs
|
||||
pages:
|
||||
stage: pages
|
||||
needs: []
|
||||
script:
|
||||
# this should only run for the API
|
||||
- ./gradlew api:clean --gradle-user-home cache/;
|
||||
# this also runs unit tests
|
||||
- ./gradlew api:build --gradle-user-home cache/;
|
||||
- ./gradlew api:javadoc --gradle-user-home cache/;
|
||||
- mkdir public
|
||||
- cp -r $CI_PROJECT_DIR/coreSubProjects/api/build/docs/javadoc/. public
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
allow_failure: false
|
||||
extends: .build_java
|
||||
@@ -1,37 +0,0 @@
|
||||
## Check off each item in this list before submitting:
|
||||
|
||||
<!--
|
||||
To mark a section as complete either put an "x" in between the square brackets, example: "[x]"
|
||||
Or click the checkbox once the issue has been created.
|
||||
-->
|
||||
|
||||
1. [ ] Check the FAQ to see if your issue has already been reported and has a solution:
|
||||
[Problems-and-solutions](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
||||
|
||||
2. [ ] Make sure you are not using any mods on the incompatible list:
|
||||
[Mod support FAQ](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/4-mod-support/Mod-Support)
|
||||
|
||||
3. [ ] Check the existing issues to verify that your bug hasn't already been submitted:
|
||||
[Issues](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues)
|
||||
|
||||
4. [ ] Upload Minecraft's crash report and/or log. \
|
||||
Minecraft crash reports are located in: `.minecraft/crash-reports` \
|
||||
Minecraft logs are located in: `.minecraft/logs`
|
||||
|
||||
5. [ ] Upload your Distant Horizons Config. \
|
||||
The config is found in: `.minecraft/configs/DistantHorizons.toml`
|
||||
|
||||
6. [ ] Fill out the information below:
|
||||
|
||||
* **minecraft version**:
|
||||
|
||||
* **Distant Horizons version**:
|
||||
|
||||
* **Mod loader**:
|
||||
|
||||
* **Installed mods (list the smallest number of mods that you can use to re-create the bug)**:
|
||||
|
||||
* **Describe the bug**:
|
||||
|
||||
* **Steps to reproduce the bug**:
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
## Check off each item in this list before submitting:
|
||||
|
||||
<!--
|
||||
To mark a section as complete either put an "x" in between the square brackets, example: "[x]"
|
||||
Or click the checkbox once the issue has been created.
|
||||
-->
|
||||
|
||||
1. [ ] Check the FAQ to see if your issue has already been reported and has a solution:
|
||||
[Problems-and-solutions](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions)
|
||||
|
||||
2. [ ] Make sure you are not using any mods on the incompatible list:
|
||||
[Mod support FAQ](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/4-mod-support/Mod-Support)
|
||||
|
||||
3. [ ] Check the existing issues to verify that your bug hasn't already been submitted:
|
||||
[Issues](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues)
|
||||
|
||||
4. [ ] Upload Minecraft's crash report and/or log. \
|
||||
Minecraft crash reports are located in: `.minecraft/crash-reports` \
|
||||
Minecraft logs are located in: `.minecraft/logs`
|
||||
|
||||
5. [ ] Upload your Distant Horizons Config. \
|
||||
The config is found in: `.minecraft/configs/DistantHorizons.toml`
|
||||
|
||||
6. [ ] Fill out the information below:
|
||||
|
||||
* **minecraft version**:
|
||||
|
||||
* **Distant Horizons version**:
|
||||
|
||||
* **Mod loader**:
|
||||
|
||||
* **Installed mods (list the smallest number of mods that you can use to re-create the bug)**:
|
||||
|
||||
* **Describe the bug**:
|
||||
|
||||
* **Steps to reproduce the bug**:
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
- [ ] Check the existing [feature requests](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues?sort=updated_desc&state=opened&label_name%5B%5D=Feature) to verify that your feature hasn't already been suggested.
|
||||
|
||||
1. **Describe the feature**:
|
||||
|
||||
2. **Describe why this feature should be added**:
|
||||
@@ -1,3 +0,0 @@
|
||||
1. Check the existing [improvement requests](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues?sort=updated_desc&state=all&label_name%5B%5D=Improvement) to verify that your improvement hasn't already been suggested.
|
||||
|
||||
2. **Describe the improvement**:
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "coreSubProjects"]
|
||||
path = coreSubProjects
|
||||
url = https://gitlab.com/jeseibel/distant-horizons-core.git
|
||||
@@ -1,16 +0,0 @@
|
||||
# See mailmap docs: https://git-scm.com/docs/gitmailmap
|
||||
# Test with git shortlog --summary --email
|
||||
# Keep sorted for easier editing and smaller diffs
|
||||
|
||||
Ada Aster <an.ada.poirier@gmail.com>
|
||||
CodeF53 <fseusb@gmail.com> <37855219+CodeF53@users.noreply.github.com>
|
||||
coolGi <me@coolgi.dev> <sasanaps@hotmail.com>
|
||||
James Seibel <jeseibel@gondtc.com> <jseibel@vertsys.com>
|
||||
Morippi <leoleo97@libero.it> <leoloe97@libero.it>
|
||||
Morippi <leoleo97@libero.it> <Morippi>
|
||||
Ran <43445785+Ran-Mewo@users.noreply.github.com> <10044908-_Ran@users.noreply.gitlab.com>
|
||||
Ran <43445785+Ran-Mewo@users.noreply.github.com> <43445785+Ran-Mewo@users.noreply.github.com>
|
||||
Ran <43445785+Ran-Mewo@users.noreply.github.com> <43445785+RanCraftPlayz@users.noreply.github.com>
|
||||
TomTheFurry <tomlee92502@yahoo.com>
|
||||
TomTheFurry <tomlee92502@yahoo.com> <46843632+TomTheFurry@users.noreply.github.com>
|
||||
Yeshi <yeshi@newengine.org>
|
||||
@@ -1,7 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Fabric Client & Server" type="CompoundRunConfigurationType">
|
||||
<toRun name="Fabric Client (:fabric)" type="Application" />
|
||||
<toRun name="Fabric Server (:fabric)" type="Application" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,7 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Forge Client & Server" type="CompoundRunConfigurationType">
|
||||
<toRun name="Forge Client (gradle)" type="GradleRunConfiguration" />
|
||||
<toRun name="Forge Server (gradle)" type="GradleRunConfiguration" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Forge Client (gradle)" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="forge:runClient" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Forge Server (gradle)" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="forge:runServer" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,7 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Neoforge Client & Server" type="CompoundRunConfigurationType">
|
||||
<toRun name="Neoforge Client (gradle)" type="GradleRunConfiguration" />
|
||||
<toRun name="Neoforge Server (gradle)" type="GradleRunConfiguration" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Neoforge Client (gradle)" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="neoforge:runClient" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Neoforge Server (gradle)" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="neoforge:runServer" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [build]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="build" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [clean]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="clean" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [core:build]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="core:build" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [fabric:runClient]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="fabric:runClient" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [forge:runClient]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="forge:runClient" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [mergeJars]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="mergeJars" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [neoforge:runClient]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="neoforge:runClient" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="distant-horizons [test]" type="GradleRunConfiguration" factoryName="Gradle" nameIsGenerated="true">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="test" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
Minecraft Forge: Credits/Thank You
|
||||
|
||||
Forge is a set of tools and modifications to the Minecraft base game code to assist
|
||||
mod developers in creating new and exciting content. It has been in development for
|
||||
several years now, but I would like to take this time thank a few people who have
|
||||
helped it along it's way.
|
||||
|
||||
First, the people who originally created the Forge projects way back in Minecraft
|
||||
alpha. Eloraam of RedPower, and SpaceToad of Buildcraft, without their acceptiance
|
||||
of me taking over the project, who knows what Minecraft modding would be today.
|
||||
|
||||
Secondly, someone who has worked with me, and developed some of the core features
|
||||
that allow modding to he as functional, and as simple as it is, cpw. For developing
|
||||
FML, which stabelized the client and server modding ecosystem. As well as the base
|
||||
loading system that allows us to modify Minecraft's code as elegently as possible.
|
||||
|
||||
Mezz, who has stepped up as the issue and pull request manager. Helping to keep me
|
||||
sane as well as guiding the community into creating better additions to Forge.
|
||||
|
||||
Searge, Bspks, Fesh0r, ProfMobious, and all the rest over on the MCP team {of which
|
||||
I am a part}. For creating some of the core tools needed to make Minecraft modding
|
||||
both possible, and as stable as can be.
|
||||
On that note, here is some specific information of the MCP data we use:
|
||||
* Minecraft Coder Pack (MCP) *
|
||||
Forge Mod Loader and Minecraft Forge have permission to distribute and automatically
|
||||
download components of MCP and distribute MCP data files. This permission is not
|
||||
transitive and others wishing to redistribute the Minecraft Forge source independently
|
||||
should seek permission of MCP or remove the MCP data files and request their users
|
||||
to download MCP separately.
|
||||
|
||||
And lastly, the countless community members who have spent time submitting bug reports,
|
||||
pull requests, and just helping out the community in general. Thank you.
|
||||
|
||||
--LexManos
|
||||
|
||||
=========================================================================
|
||||
|
||||
This is Forge Mod Loader.
|
||||
|
||||
You can find the source code at all times at https://github.com/MinecraftForge/MinecraftForge/tree/1.12.x/src/main/java/net/minecraftforge/fml
|
||||
|
||||
This minecraft mod is a clean open source implementation of a mod loader for minecraft servers
|
||||
and minecraft clients.
|
||||
|
||||
The code is authored by cpw.
|
||||
|
||||
It began by partially implementing an API defined by the client side ModLoader, authored by Risugami.
|
||||
http://www.minecraftforum.net/topic/75440-
|
||||
This support has been dropped as of Minecraft release 1.7, as Risugami no longer maintains ModLoader.
|
||||
|
||||
It also contains suggestions and hints and generous helpings of code from LexManos, author of MinecraftForge.
|
||||
http://www.minecraftforge.net/
|
||||
|
||||
Additionally, it contains an implementation of topological sort based on that
|
||||
published at http://keithschwarz.com/interesting/code/?dir=topological-sort
|
||||
|
||||
It also contains code from the Maven project for performing versioned dependency
|
||||
resolution. http://maven.apache.org/
|
||||
|
||||
It also contains a partial repackaging of the javaxdelta library from http://sourceforge.net/projects/javaxdelta/
|
||||
with credit to it's authors.
|
||||
|
||||
Forge Mod Loader downloads components from the Minecraft Coder Pack
|
||||
(http://mcp.ocean-labs.de/index.php/Main_Page) with kind permission from the MCP team.
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
FROM eclipse-temurin:25-jdk
|
||||
|
||||
WORKDIR /home/build/
|
||||
COPY ./gradlew .
|
||||
RUN chmod +x ./gradlew
|
||||
CMD echo "\r========== [CLEAN: $MC_VER] ==========" && \
|
||||
./gradlew clean -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \
|
||||
echo "\r========== [BUILD: $MC_VER] ==========" && \
|
||||
./gradlew build -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \
|
||||
echo "\r========== [MERGE: $MC_VER] ==========" && \
|
||||
./gradlew mergeJars -PmcVer="$MC_VER" --gradle-user-home .gradle-cache/ && \
|
||||
echo "\r========== [DONE: $MC_VER] =========="
|
||||
@@ -1 +0,0 @@
|
||||
Distant Horizons logos © 2024 by Pankakes are licensed under CC BY-SA 4.0
|
||||
@@ -0,0 +1,10 @@
|
||||
IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
SoundSystem CodecIBXM Class License:
|
||||
|
||||
You are free to use this class for any purpose, commercial or otherwise.
|
||||
You may modify this class or source code, and distribute it any way you
|
||||
like, provided the following conditions are met:
|
||||
|
||||
1) You may not falsely claim to be the author of this class or any
|
||||
unmodified portion of it.
|
||||
2) You may not copyright this class or a modified version of it and then
|
||||
sue me for copyright infringement.
|
||||
3) If you modify the source code, you must clearly document the changes
|
||||
made before redistributing the modified source code, so other users know
|
||||
it is not the original code.
|
||||
4) You are not required to give me credit for this class in any derived
|
||||
work, but if you do, you must also mention my website:
|
||||
http://www.paulscode.com
|
||||
5) I the author will not be responsible for any damages (physical,
|
||||
financial, or otherwise) caused by the use if this class or any
|
||||
portion of it.
|
||||
6) I the author do not guarantee, warrant, or make any representations,
|
||||
either expressed or implied, regarding the use of this class or any
|
||||
portion of it.
|
||||
|
||||
Author: Paul Lamb
|
||||
http://www.paulscode.com
|
||||
|
||||
|
||||
This software is based on or using the IBXM library available from
|
||||
http://www.geocities.com/sunet2000/
|
||||
|
||||
|
||||
IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,165 +0,0 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
+497
-592
File diff suppressed because it is too large
Load Diff
@@ -1,210 +0,0 @@
|
||||
# <img src="https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/_Misc%20Files/logo%20files/new/SVG/Distant-Horizons.svg" height="128px">
|
||||
_See farther without turning your game into a slide show._
|
||||
|
||||
<br>
|
||||
|
||||
# What is Distant Horizons?
|
||||
|
||||
Distant Horizons is a mod which implements a [Level of Detail](https://en.wikipedia.org/wiki/Level_of_detail_(computer_graphics)) system to Minecraft.\
|
||||
This allows for far greater render distances without harming performance by gradually lowering the quality of distant terrain.
|
||||
|
||||
Below is a video demonstrating the system:
|
||||
|
||||
<a href="https://youtu.be/SxQdbtjGEsc" target="_blank"></a>
|
||||
|
||||
<br>
|
||||
|
||||
## Minecraft and Library Versions
|
||||
|
||||
### This branch supports the following versions of Minecraft:
|
||||
|
||||
#### 1.20.4, 1.20.3 (Default)
|
||||
Fabric: 0.15.1\
|
||||
Fabric API: 0.91.2+1.20.4\
|
||||
Forge: 49.0.30\
|
||||
NeoForge: 118-beta\
|
||||
Parchment: 1.20.2:2023.12.10\
|
||||
Modmenu: 9.0.0-pre.1
|
||||
|
||||
#### 1.20.2
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.90.4+1.20.2\
|
||||
Forge: 48.0.13\
|
||||
Parchment: 1.20.1:2023.09.03\
|
||||
Modmenu: 8.0.0
|
||||
|
||||
#### 1.20.1, 1.20
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.90.4+1.20.1\
|
||||
Forge: 47.2.1\
|
||||
Parchment: 1.20.1:2023.09.03\
|
||||
Modmenu: 7.2.2
|
||||
|
||||
#### 1.19.4
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.87.1+1.19.4\
|
||||
Forge: 45.2.4\
|
||||
Parchment: 1.19.4:2023.06.26\
|
||||
Modmenu: 6.3.1
|
||||
|
||||
#### 1.19.2
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.76.1+1.19.2\
|
||||
Forge: 43.3.2\
|
||||
Parchment: 1.19.2:2022.11.27\
|
||||
Modmenu: 4.2.0-beta.2
|
||||
|
||||
#### 1.18.2
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.76.0+1.18.2\
|
||||
Forge: 40.2.10\
|
||||
Parchment: 1.18.2:2022.11.06\
|
||||
Modmenu: 3.2.5
|
||||
|
||||
#### 1.17.1, 1.17
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.46.1+1.17\
|
||||
Forge: 37.1.1\
|
||||
Parchment: 1.17.1:2021.12.12\
|
||||
Modmenu: 2.0.14
|
||||
|
||||
#### 1.16.5, 1.16.4
|
||||
Fabric: 0.14.24\
|
||||
Fabric API: 0.42.0+1.16\
|
||||
Forge: 36.2.39\
|
||||
Parchment: 1.16.5:2022.03.06\
|
||||
Modmenu: 1.16.22
|
||||
|
||||
### Versions no longer supported
|
||||
- 1.18.1, 1.18
|
||||
- 1.19.1, 1.19
|
||||
- 1.19.3
|
||||
|
||||
<br>
|
||||
|
||||
### Plugin and Library versions
|
||||
|
||||
Gradle: 8.5\
|
||||
Fabric loom: 1.4-SNAPSHOT\
|
||||
Architectury loom (Forge gradle replacement): 1.4-SNAPSHOT\
|
||||
Sponge vanilla gradle: 0.2.1-SNAPSHOT\
|
||||
Java Preprocessor plugin: Manifold Preprocessor
|
||||
|
||||
<br>
|
||||
|
||||
## Source Code Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* A Java Development Kit (JDK) for Java 17 (recommended) or newer. <br>
|
||||
Visit https://www.oracle.com/java/technologies/downloads/ for installers.
|
||||
* Git or someway to clone git projects. <br>
|
||||
Visit https://git-scm.com/ for installers.
|
||||
* (Not required) Any Java IDE with plugins that support Manifold, for example IntelliJ IDEA.
|
||||
|
||||
**If using IntelliJ:**
|
||||
1. Install the Manifold plugin
|
||||
2. Open IDEA and import the build.gradle
|
||||
3. Refresh the Gradle project in IDEA if required
|
||||
|
||||
**If using Eclipse: (Note that Eclipse doesn't support Manifold's preprocessor!)**
|
||||
1. Run the command: `./gradlew geneclipseruns`
|
||||
2. Run the command: `./gradlew eclipse`
|
||||
3. Make sure eclipse has the JDK 17 installed. (This is needed so that eclipse can run minecraft)
|
||||
4. Import the project into eclipse
|
||||
|
||||
<br>
|
||||
|
||||
## Switching Versions
|
||||
|
||||
To switch between different Minecraft versions, change `mcVer=1.?` in the `gradle.properties` file.
|
||||
|
||||
If running in an IDE, to ensure the IDE noticed the version change, run any gradle command to refresh gradle.\
|
||||
In IntelliJ, you will also need to do a gradle sync if it didn't happen automatically.
|
||||
|
||||
<br>
|
||||
|
||||
## Compiling
|
||||
|
||||
Prerequisites:
|
||||
- JDK 17 or newer
|
||||
|
||||
From the File Explorer:
|
||||
1. Download and extract the project zip
|
||||
2. Download the core from https://gitlab.com/distant-horizons-team/distant-horizons-core and extract into a folder called `coreSubProjects`
|
||||
3. Open a terminal emulator in the project folder (On Windows you can type `cmd` in the title bar)
|
||||
4. Run the commands: `./gradlew assemble` (You may need to use a `.\` on Windows)
|
||||
5. Merge the jars with `./gradlew mergeJars`
|
||||
6. The compiled jar file will be in the folder `Merged`
|
||||
|
||||
From the command line:
|
||||
1. `git clone --recurse-submodules https://gitlab.com/distant-horizons-team/distant-horizons.git`
|
||||
2. `cd distant-horizons`
|
||||
3. `./gradlew assemble`
|
||||
4. `./gradlew mergeJars`
|
||||
5. The compiled jar file will be in the folder `Merged`
|
||||
|
||||
Run tests with: `./gradlew test`
|
||||
|
||||
>Note: You can add the argument `-PmcVer=?` to tell gradle to build a selected MC version instead of having to modify the `gradle.properties` file.\
|
||||
> For example: `./gradlew assemble -PmcVer=1.18.2`
|
||||
|
||||
<br>
|
||||
|
||||
## Compiling with Docker
|
||||
|
||||
`./compile <version>`
|
||||
|
||||
You can also locally compile the DH jars without a Java environment by using Docker. Where `<version>` is the version of Minecraft to compile for (ie `1.20.1`), or the keyword `all`. See [Versions](#minecraft-and-library-versions) for a list of all supported values.
|
||||
|
||||
<br>
|
||||
|
||||
## Other commands
|
||||
|
||||
`./gradlew --refresh-dependencies` to refresh local dependencies.
|
||||
|
||||
`./gradlew clean` to delete any compiled code.
|
||||
|
||||
<br>
|
||||
|
||||
## Note to self
|
||||
|
||||
The Minecraft source code is NOT added to your workspace in an editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
|
||||
|
||||
Source code uses Mojang mappings & [Parchment](https://parchmentmc.org/) mappings.
|
||||
|
||||
To generate the source code run `./gradlew genSources` <br>
|
||||
If your IDE fails to auto-detect the source jars when browsing Minecraft classes; manually select the JAR file ending with -sources.jar when prompted by your IDE. <br>
|
||||
(In IntelliJ it's at the top where it says "choose sources" when browsing a Minecraft class)
|
||||
|
||||
<br>
|
||||
|
||||
## Other Useful commands
|
||||
|
||||
Run the standalone jar: `./gradlew run` <br>
|
||||
Build the standalone jar: `./gradlew core:build` <br>
|
||||
Only build Fabric: `./gradlew fabric:assemble` or `./gradlew fabric:build` <br>
|
||||
Only build Forge: `./gradlew forge:assemble` or `./gradlew forge:build` <br>
|
||||
Run the Fabric client (for debugging): `./gradlew fabric:runClient` <br>
|
||||
Run the Forge client (for debugging): `./gradlew forge:runClient` <br>
|
||||
|
||||
To build all versions: `./buildAll` (all builds will end up in the `Merged` folder)
|
||||
|
||||
<br>
|
||||
|
||||
## Open Source Acknowledgements
|
||||
|
||||
Forgix (To merge multiple mod versions into one jar) [_Formerly_ [_DHJarMerger_](https://github.com/Ran-helo/DHJarMerger)]\
|
||||
https://github.com/PacifistMC/Forgix
|
||||
|
||||
LZ4 for Java (data compression)\
|
||||
https://github.com/lz4/lz4-java
|
||||
|
||||
NightConfig for JSON & TOML (config handling)\
|
||||
https://github.com/TheElectronWill/night-config
|
||||
|
||||
SVG Salamander for SVG support (not being used atm)\
|
||||
https://github.com/blackears/svgSalamander
|
||||
|
||||
sqlite-jdbc\
|
||||
https://github.com/xerial/sqlite-jdbc
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
This program is an attempt to implement a Level Of Detail system for Minecraft.
|
||||
With the purpose of increasing the maximum view distance in game without harming performance.
|
||||
|
||||
Forge version: 1.12.2-14.23.5.2854
|
||||
|
||||
Notes:
|
||||
This version will run in eclipse perfectly fine, but will crash retail Minecraft.
|
||||
(However this appears to be because of an incompatible update to the core mod.)
|
||||
This version also doesn't work with Optifine at all.
|
||||
(Attempting to run with Optifine in either eclipse or retail Minecraft
|
||||
will either prevent the game from launching at all or crash during loading.)
|
||||
|
||||
|
||||
Used in conjunction with:
|
||||
https://gitlab.com/jeseibel/minecraft-lod-core-mod
|
||||
|
||||
|
||||
========================
|
||||
source code installation
|
||||
========================
|
||||
|
||||
See the Forge Documentation online for more detailed instructions:
|
||||
http://mcforge.readthedocs.io/en/latest/gettingstarted/
|
||||
|
||||
Step 1: open a command line in the project folder
|
||||
|
||||
Step 2: run the command: "./gradlew genEclipseRuns"
|
||||
|
||||
Step 3: run the command: "./gradlew eclipse"
|
||||
|
||||
Step 4: Import project
|
||||
|
||||
Step 5: Create a system variable called "JAVA_MC_HOME" with the location of the JDK 1.8.0_251 (This is needed for gradle to work correctly)
|
||||
And make sure it is used in the gradle.bat file.
|
||||
|
||||
Step 6: Import the lodcore and lodcore_source jar files into the referenced libraries.
|
||||
|
||||
Step 7: Make sure the eclipse has the JDK 1.8.0_251 installed. (This is needed so that eclipse can run minecraft)
|
||||
|
||||
|
||||
Other commands:
|
||||
"gradlew --refresh-dependencies" to refresh local dependencies.
|
||||
"gradlew clean" to reset everything (this does not affect your code) and then start the process again.
|
||||
|
||||
|
||||
|
||||
Tip:
|
||||
The Minecraft source code is NOT added to your workspace in a editable way. Minecraft is treated like a normal Library. Sources are there for documentation and research purposes only.
|
||||
|
||||
Current location of mcp-srg.srg:
|
||||
"C:/Users/James Seibel/.gradle/caches/minecraft/de/oceanlabs/mcp/mcp_snapshot/20171003/1.12.2/srgs/"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
these are tools needed for looking at obfuscated minecraft code.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
these are tools needed for deobfuscating and looking at the code of optifine.
|
||||
@@ -0,0 +1,3 @@
|
||||
java -jar ./simpledeobf-0.6.jar --input ./OptiFine_1.12.2_HD_U_F5.jar --output ./OptiFine_1.12.2_HD_U_F5_dev.jar --mapFile C:/Users/James_Seibel/.gradle/caches/minecraft/de/oceanlabs/mcp/mcp_snapshot/20171003/1.12.2/srgs/notch-mcp.srg --ref C:/Users/James_Seibel/.gradle/caches/minecraft/net/minecraft/minecraft/1.12.2/minecraft-1.12.2.jar
|
||||
|
||||
pause
|
||||
Binary file not shown.
+84
-5
@@ -1,8 +1,87 @@
|
||||
plugins {
|
||||
id 'root'
|
||||
id 'io.github.pacifistmc.forgix' version '2.+'
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url = 'https://files.minecraftforge.net/maven' }
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:3.+'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
version = "1.0"
|
||||
group = "com.backsun.lod" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "lod"
|
||||
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
|
||||
|
||||
minecraft {
|
||||
// The mappings can be changed at any time, and must be in the following format.
|
||||
// snapshot_YYYYMMDD Snapshot are built nightly.
|
||||
// stable_# Stables are built at the discretion of the MCP team.
|
||||
// Use non-default mappings at your own risk. they may not always work.
|
||||
// Simply re-run your setup task after changing the mappings to update your workspace.
|
||||
//mappings channel: 'snapshot', version: '20171003-1.12'
|
||||
mappings channel: 'snapshot', version: '20171003-1.12'
|
||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
|
||||
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
|
||||
// Default run configurations.
|
||||
// These can be tweaked, removed, or duplicated as needed.
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
|
||||
|
||||
// Recommended logging level for the console
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
}
|
||||
|
||||
server {
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
|
||||
|
||||
// Recommended logging level for the console
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forgix {
|
||||
autoRun = true
|
||||
dependencies {
|
||||
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
|
||||
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
|
||||
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
|
||||
minecraft 'net.minecraftforge:forge:1.12.2-14.23.5.2854'
|
||||
|
||||
compile fileTree(dir: 'libs', include: '*.jar')
|
||||
|
||||
// You may put jars on which you depend on in ./libs or you may define them like so..
|
||||
//compile "some.group:artifact:version:classifier"
|
||||
//compile "some.group:artifact:version"
|
||||
|
||||
// Real examples
|
||||
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
|
||||
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
|
||||
|
||||
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
|
||||
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||
|
||||
// These dependencies get remapped to your current MCP mappings
|
||||
// deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
|
||||
|
||||
// For more info...
|
||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "==================== Note: All build jars will be in the folder called 'buildAllJars' ===================="
|
||||
mkdir -p buildAllJars
|
||||
rm -rf buildAllJars/*
|
||||
|
||||
# Loop trough everything in the version properties folder
|
||||
for d in versionProperties/*; do
|
||||
# Get the name of the version that is going to be compiled
|
||||
version=$(echo "$d" | sed "s/versionProperties\///" | sed "s/.properties//")
|
||||
|
||||
# Clean out the folders, build it, and merge it
|
||||
# (We could use "./" to run gradlew, but as it is a shell script im going to be running it with the "sh" command)
|
||||
echo "==================== Cleaning workspace to build $version ===================="
|
||||
sh gradlew clean -PmcVer=$version
|
||||
if [ $? != 0 ]; then continue; fi
|
||||
|
||||
echo "====================Building $version ===================="
|
||||
sh gradlew build -PmcVer=$version
|
||||
if [ $? != 0 ]; then continue; fi
|
||||
|
||||
echo "==================== Merging $version ===================="
|
||||
sh gradlew mergeJars -PmcVer=$version
|
||||
if [ $? != 0 ]; then continue; fi
|
||||
|
||||
echo "==================== Moving jar ===================="
|
||||
mv build/merged/*.jar buildAllJars/
|
||||
done
|
||||
@@ -1,29 +0,0 @@
|
||||
@echo off & setlocal enabledelayedexpansion
|
||||
@rem Note for devs: If this script doesnt work, please look at the unix buildAll script
|
||||
@rem This script was originally created on linux, so there may be some problems with this translation
|
||||
|
||||
|
||||
echo ==================== Note: All build jars will be in the folder called 'buildAllJars' ====================
|
||||
mkdir buildAllJars
|
||||
del buildAllJars/*
|
||||
|
||||
@rem Loop trough everything in the version properties folder
|
||||
for %%f in (versionProperties\*) do (
|
||||
@rem Get the name of the version that is going to be compiled
|
||||
set version=%%~nf
|
||||
|
||||
@rem Clean out the folders, build it, and merge it
|
||||
echo ==================== Cleaning workspace to build !version! ====================
|
||||
call .\gradlew.bat clean
|
||||
|
||||
echo ==================== Building !version! ====================
|
||||
call .\gradlew.bat build -PmcVer="!version!"
|
||||
|
||||
echo ==================== Merging !version! ====================
|
||||
call .\gradlew.bat mergeJars -PmcVer="!version!"
|
||||
|
||||
echo ==================== Moving jar ====================
|
||||
move build\merged\*.jar buildAllJars\
|
||||
)
|
||||
|
||||
endlocal
|
||||
@@ -1,24 +0,0 @@
|
||||
plugins {
|
||||
id 'groovy-gradle-plugin'
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
maven { url = 'https://maven.wagyourtail.xyz/releases' } // Jvmdowngrader & unimined libs
|
||||
maven { url = 'https://maven.outlands.top/releases' } // Hosts the kappa fork of unimined
|
||||
maven { url = 'https://maven.wagyourtail.xyz/snapshots' } // The manifold gradle plugin we use
|
||||
maven { url = 'https://maven.architectury.dev/' } // Minecraft mod libs
|
||||
maven { url = 'https://maven.fabricmc.net/' } // Fabric
|
||||
maven { url = 'https://maven.neoforged.net/releases/' } // NeoForge
|
||||
maven { url = 'https://maven.minecraftforge.net/' } // Forge
|
||||
maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } // Hosts minecraft libs
|
||||
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' } // Hosts a few dependencies we use
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.gradleup.shadow:shadow-gradle-plugin:9.0.0'
|
||||
implementation 'xyz.wagyourtail.unimined:xyz.wagyourtail.unimined.gradle.plugin:1.4.17-kappa'
|
||||
implementation 'xyz.wagyourtail:manifold-gradle:1.0.0-SNAPSHOT'
|
||||
implementation 'xyz.wagyourtail.jvmdowngrader:xyz.wagyourtail.jvmdowngrader.gradle.plugin:1.3.4'
|
||||
}
|
||||
@@ -1,467 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.ResourceTransformer
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
||||
import org.apache.tools.zip.ZipEntry
|
||||
import org.apache.tools.zip.ZipOutputStream
|
||||
|
||||
import javax.annotation.Nonnull
|
||||
import java.util.function.Function
|
||||
import java.util.function.Predicate
|
||||
|
||||
// Convention plugin for all MC-facing subprojects (common + loaders).
|
||||
// Common uses this directly; loaders use it via unimined-fabric/forge/neoforge.
|
||||
// IMPORTANT: unimined MUST be applied before shadow/jvmdowngrader
|
||||
// so its afterEvaluate runs first and can modify configs.
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'maven-publish'
|
||||
id 'xyz.wagyourtail.unimined'
|
||||
id 'com.gradleup.shadow'
|
||||
id 'xyz.wagyourtail.manifold'
|
||||
id 'xyz.wagyourtail.jvmdowngrader'
|
||||
}
|
||||
|
||||
def isNotCommonProject = project.name != "common"
|
||||
|
||||
|
||||
// ==================== Version Properties ====================
|
||||
|
||||
project.gradle.ext.getProperties().each { prop ->
|
||||
rootProject.ext.set(prop.key, prop.value)
|
||||
}
|
||||
|
||||
manifold {
|
||||
version = rootProject.manifold_version
|
||||
}
|
||||
|
||||
|
||||
// ==================== Repositories ====================
|
||||
|
||||
repositories {
|
||||
maven { url "https://libraries.minecraft.net/" }
|
||||
mavenCentral()
|
||||
maven { url "https://repo.enonic.com/public/" }
|
||||
maven { url "https://maven.parchmentmc.org" }
|
||||
maven { url "https://maven.architectury.dev" }
|
||||
maven { url "https://jitpack.io" }
|
||||
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven {
|
||||
name = "Modrinth"
|
||||
url = "https://api.modrinth.com/maven"
|
||||
content { includeGroup "maven.modrinth" }
|
||||
}
|
||||
maven {
|
||||
url "https://www.cursemaven.com"
|
||||
content { includeGroup "curse.maven" }
|
||||
}
|
||||
maven { url "https://repo.spongepowered.org/maven/" }
|
||||
maven { url "https://maven.terraformersmc.com/" }
|
||||
maven { url "https://maven.neoforged.net/releases/" }
|
||||
flatDir {
|
||||
dirs "${rootDir}/mods/fabric"
|
||||
content { includeGroup "fabric-mod" }
|
||||
}
|
||||
flatDir {
|
||||
dirs "${rootDir}/mods/quilt"
|
||||
content { includeGroup "quilt-mod" }
|
||||
}
|
||||
flatDir {
|
||||
dirs "${rootDir}/mods/forge"
|
||||
content { includeGroup "forge-mod" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== Java Config ====================
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.release = rootProject.java_version as Integer
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.toVersion(gradle.ext.java_version as Integer)
|
||||
targetCompatibility = JavaVersion.toVersion(gradle.ext.java_version as Integer)
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
|
||||
// ==================== Loader-Only Config ====================
|
||||
|
||||
if (isNotCommonProject) {
|
||||
base { archivesName = rootProject.mod_name }
|
||||
rootProject.ext.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version
|
||||
version = project.name + "-" + rootProject.versionStr
|
||||
group = rootProject.maven_group
|
||||
|
||||
javadoc.title = rootProject.mod_name + "-" + project.name
|
||||
|
||||
tasks.withType(GenerateModuleMetadata).configureEach {
|
||||
enabled = false
|
||||
}
|
||||
tasks.withType(Test).configureEach {
|
||||
enabled = false
|
||||
}
|
||||
compileTestJava.enabled = false
|
||||
tasks.withType(Sign).configureEach {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
jar {
|
||||
from "LICENSE.txt"
|
||||
manifest {
|
||||
attributes(
|
||||
'Implementation-Title': rootProject.mod_name,
|
||||
'Implementation-Version': rootProject.mod_version,
|
||||
'Multi-Release': true,
|
||||
'Main-Class': 'com.seibel.distanthorizons.core.jar.JarMain',
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== Unimined Minecraft Config ====================
|
||||
|
||||
unimined.minecraft(sourceSets.main, true) {
|
||||
version gradle.ext.minecraft_version
|
||||
|
||||
if (gradle.ext.minecraft_version.startsWith("1.")) { // 26.1+ doesn't use obfuscation
|
||||
mappings {
|
||||
mojmap()
|
||||
devNamespace "mojmap"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNotCommonProject) {
|
||||
// Mixin remapping and common project wiring
|
||||
unimined.minecraft(sourceSets.main, true) {
|
||||
mods.modImplementation {
|
||||
mixinRemap {
|
||||
reset()
|
||||
enableBaseMixin()
|
||||
enableMixinExtra()
|
||||
}
|
||||
// Some Fabric API modules ship AW in 'named' namespace instead of 'intermediary'
|
||||
catchAWNamespaceAssertion()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":common"))
|
||||
}
|
||||
|
||||
processResources {
|
||||
from project(":common").sourceSets.main.resources
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
source(project(":common").sourceSets.main.allSource)
|
||||
}
|
||||
} else {
|
||||
// Common: fabric for compilation + access widener, no jar remapping or runs
|
||||
unimined.minecraft {
|
||||
fabric {
|
||||
loader gradle.ext.fabric_loader_version
|
||||
accessWidener project.file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
}
|
||||
defaultRemapJar = false
|
||||
runs.off = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== Configurations ====================
|
||||
|
||||
evaluationDependsOn(":core")
|
||||
|
||||
configurations {
|
||||
shadowMe
|
||||
coreProjects
|
||||
shadowMe.extendsFrom(coreProjects)
|
||||
implementation.extendsFrom(shadowMe)
|
||||
|
||||
common
|
||||
implementation.extendsFrom(common)
|
||||
}
|
||||
|
||||
|
||||
// ==================== Dependencies ====================
|
||||
|
||||
// Copy core's compileOnly deps so MC-provided deps are visible without redeclaring them.
|
||||
project(":core").configurations.compileOnly.allDependencies.each { dep ->
|
||||
if (!(dep instanceof ProjectDependency))
|
||||
dependencies.add("compileOnly", dep)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Manifold preprocessor & strings
|
||||
annotationProcessor(manifold.module("preprocessor"))
|
||||
|
||||
// NightConfig: implementation in core (bundled) but Unimined strips it from compile classpath
|
||||
compileOnly("com.electronwill.night-config:toml:${rootProject.nightconfig_version}")
|
||||
|
||||
// Core & API projects — bundled into shadow jar
|
||||
coreProjects(project(":core"))
|
||||
coreProjects(project(":api"))
|
||||
|
||||
// JOML: shadow for old MC versions that don't bundle it (core has it compileOnly already)
|
||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||
shadowMe("org.joml:joml:${rootProject.joml_version}")
|
||||
|
||||
// Common project dependency
|
||||
if (isNotCommonProject)
|
||||
common(project(":common")) { transitive false }
|
||||
}
|
||||
|
||||
|
||||
// ==================== NativeTransformer ====================
|
||||
|
||||
class NativeTransformer implements ResourceTransformer {
|
||||
private Predicate<String> fileMatcher
|
||||
private Function<String, String> filePathMapper
|
||||
|
||||
private final HashMap<String, String> replacements = new HashMap()
|
||||
private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
|
||||
private nativeRelocator
|
||||
|
||||
public File rootDir
|
||||
|
||||
void matchFiles(Predicate<String> matcher) {
|
||||
fileMatcher = matcher
|
||||
}
|
||||
|
||||
void mapPaths(Function<String, String> mapper) {
|
||||
filePathMapper = mapper
|
||||
}
|
||||
|
||||
void relocateNative(String target, String replacement) {
|
||||
if (replacement.length() > target.length()) {
|
||||
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
|
||||
}
|
||||
replacements.put(target, replacement)
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean canTransformResource(@Nonnull FileTreeElement element) {
|
||||
return fileMatcher != null && fileMatcher.test(element.relativePath.pathString)
|
||||
}
|
||||
|
||||
@Override
|
||||
void transform(@Nonnull TransformerContext context) {
|
||||
byte[] content = context.inputStream.readAllBytes()
|
||||
|
||||
if (nativeRelocator == null) {
|
||||
nativeRelocator = new NativeRelocator(rootDir.toPath().resolve("relocate_natives"))
|
||||
}
|
||||
|
||||
try {
|
||||
String path = filePathMapper != null
|
||||
? filePathMapper.apply(context.path)
|
||||
: context.path
|
||||
content = nativeRelocator.processBinary(path, content, replacements)
|
||||
rewrittenFiles.put(path, content)
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new GradleException("Failed to relocate", e)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasTransformedResource() { return !rewrittenFiles.isEmpty() }
|
||||
|
||||
@Override
|
||||
void modifyOutputStream(@Nonnull ZipOutputStream os, boolean preserveFileTimestamps) {
|
||||
for (Map.Entry<String, byte[]> rewrittenFile : rewrittenFiles.entrySet()) {
|
||||
os.putNextEntry(new ZipEntry(rewrittenFile.key))
|
||||
os.write(rewrittenFile.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== Shadow JAR (loaders only) ====================
|
||||
|
||||
if (isNotCommonProject) {
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadowMe]
|
||||
relocate "com.seibel.distanthorizons.common", "loaderCommon.${project.name}.com.seibel.distanthorizons.common"
|
||||
def librariesLocation = "DistantHorizons.libraries"
|
||||
|
||||
// LZ4
|
||||
relocate "net.jpountz", "${librariesLocation}.jpountz"
|
||||
|
||||
// SLF4J
|
||||
relocate "org.slf4j", "${librariesLocation}.slf4j"
|
||||
|
||||
// SQLite
|
||||
relocate "org.sqlite", "dh_sqlite", { exclude "org/sqlite/native/**" }
|
||||
relocate "jdbc:sqlite", "jdbc:dh_sqlite"
|
||||
|
||||
transform(NativeTransformer) {
|
||||
rootDir = project.rootDir
|
||||
matchFiles { it.startsWith("org/sqlite") }
|
||||
mapPaths { it.replace("org/sqlite", "dh_sqlite") }
|
||||
relocateNative "org/sqlite", "dh_sqlite"
|
||||
relocateNative "org_sqlite", "dh_1sqlite"
|
||||
}
|
||||
|
||||
// ZStd
|
||||
relocate "com.github.luben", "dhcomgithubluben"
|
||||
relocate "libzstd-jni", "libzstd-jni_dh"
|
||||
relocate "zstd-jni", "zstd-jni_dh"
|
||||
|
||||
transform(NativeTransformer) {
|
||||
rootDir = project.rootDir
|
||||
matchFiles { it.contains("libzstd-jni") && !it.contains("aix/ppc64") }
|
||||
mapPaths { it.replace("libzstd-jni", "libzstd-jni_dh") }
|
||||
relocateNative "com/github/luben", "dhcomgithubluben"
|
||||
relocateNative "com_github_luben", "dhcomgithubluben"
|
||||
}
|
||||
|
||||
// JOML (conditional)
|
||||
if (project.hasProperty("embed_joml") && embed_joml == "true")
|
||||
relocate "org.joml", "${librariesLocation}.joml"
|
||||
|
||||
// NightConfig
|
||||
relocate "com.electronwill.nightconfig", "${librariesLocation}.electronwill.nightconfig"
|
||||
|
||||
mergeServiceFiles()
|
||||
}
|
||||
afterEvaluate {
|
||||
tasks.named("remapJar").configure {
|
||||
dependsOn(shadowJar)
|
||||
inputFile.set(shadowJar.archiveFile)
|
||||
}
|
||||
|
||||
// Make run tasks use the shadow jar so relocated deps work in dev.
|
||||
// Filter out jars bundled in the shadow jar, but keep jars that the loader also
|
||||
// needs (e.g. NightConfig — DH relocates it, but NeoForge needs the original).
|
||||
def shadowedPaths = configurations.shadowMe.resolve().collect { it.path }.toSet()
|
||||
def loaderPaths = configurations.minecraftLibraries.resolve().collect { it.path }.toSet()
|
||||
tasks.withType(JavaExec).configureEach { runTask ->
|
||||
dependsOn(shadowJar)
|
||||
classpath = files(shadowJar.archiveFile) + classpath.filter { file ->
|
||||
!file.path.contains(project.buildDir.path) &&
|
||||
!file.path.contains("core${File.separator}build") &&
|
||||
!file.path.contains("api${File.separator}build") &&
|
||||
!file.path.contains("common${File.separator}build") &&
|
||||
!(shadowedPaths.contains(file.path) && !loaderPaths.contains(file.path))
|
||||
}
|
||||
|
||||
// Shared run directory so all loaders use the same worlds
|
||||
def isClient = runTask.name.toLowerCase().contains("client")
|
||||
runTask.workingDir = rootProject.file("run/${isClient ? 'client' : 'server'}")
|
||||
|
||||
// JVM args
|
||||
runTask.jvmArgs(
|
||||
"-Dio.netty.leakDetection.level=advanced",
|
||||
//"-XX:+UseZGC",
|
||||
//"-XX:+ZGenerational",
|
||||
)
|
||||
if (isClient) {
|
||||
runTask.jvmArgs(
|
||||
"-Dminecraft.api.auth.host=https://nope.invalid",
|
||||
"-Dminecraft.api.account.host=https://nope.invalid",
|
||||
"-Dminecraft.api.session.host=https://nope.invalid",
|
||||
"-Dminecraft.api.services.host=https://nope.invalid",
|
||||
)
|
||||
runTask.args("--username", "Dev", "--renderDebugLabels", "--tracy")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== Process Resources (loaders only) ====================
|
||||
|
||||
if (isNotCommonProject) {
|
||||
processResources {
|
||||
def resourceTargets = [
|
||||
"build_info.json",
|
||||
"fabric.mod.json",
|
||||
"quilt.mod.json",
|
||||
"META-INF/mods.toml",
|
||||
"META-INF/neoforge.mods.toml",
|
||||
]
|
||||
|
||||
def compatible_forgemc_versions = "${rootProject.compatible_minecraft_versions}".replaceAll("\"", "").replaceAll("]", ",)")
|
||||
|
||||
// Quilt contributors
|
||||
def quilt_contributors = []
|
||||
def mod_author_list = rootProject.mod_authors.replaceAll("\"", "").replace("[", "").replace("]", "").split(",")
|
||||
for (dev in mod_author_list) {
|
||||
quilt_contributors.push("\"${dev.strip()}\": \"Developer\"")
|
||||
}
|
||||
quilt_contributors.reverse()
|
||||
|
||||
try {
|
||||
if (rootProject.infoGitCommit == "null")
|
||||
rootProject.ext.infoGitCommit = 'git rev-parse --verify HEAD'.execute().text.trim()
|
||||
if (rootProject.infoGitBranch == "null")
|
||||
rootProject.ext.infoGitBranch = 'git symbolic-ref --short HEAD'.execute().text.trim()
|
||||
} catch (Exception e) {
|
||||
rootProject.ext.infoGitCommit = "Git not found"
|
||||
rootProject.ext.infoGitBranch = "Git not found"
|
||||
}
|
||||
|
||||
def replaceProperties = [
|
||||
version : rootProject.mod_version,
|
||||
mod_name : rootProject.mod_readable_name,
|
||||
group : rootProject.maven_group,
|
||||
authors : rootProject.mod_authors,
|
||||
description : rootProject.mod_description,
|
||||
homepage : rootProject.mod_homepage,
|
||||
source : rootProject.mod_source,
|
||||
issues : rootProject.mod_issues,
|
||||
discord : rootProject.mod_discord,
|
||||
minecraft_version : rootProject.minecraft_version,
|
||||
compatible_minecraft_versions: rootProject.compatible_minecraft_versions,
|
||||
compatible_forgemc_versions : compatible_forgemc_versions,
|
||||
java_version : rootProject.java_version,
|
||||
quilt_contributors : "{" + quilt_contributors.join(", ") + "}",
|
||||
info_git_commit : rootProject.infoGitBranch,
|
||||
info_git_branch : rootProject.infoGitCommit,
|
||||
info_build_source : rootProject.infoBuildSource,
|
||||
fabric_incompatibility_list : rootProject.fabric_incompatibility_list,
|
||||
fabric_recommend_list : rootProject.fabric_recommend_list,
|
||||
neoforge_version_range : rootProject.neoforge_version_range,
|
||||
]
|
||||
|
||||
inputs.properties replaceProperties
|
||||
replaceProperties.put "project", project
|
||||
filesMatching(resourceTargets) {
|
||||
expand replaceProperties
|
||||
}
|
||||
|
||||
// Remove unused access wideners
|
||||
exclude { file ->
|
||||
if (file.name.contains(".distanthorizons.accesswidener") && file.name != "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener") {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ==================== Resource Copy Tasks ====================
|
||||
|
||||
task copyCommonLoaderResources(type: Copy) {
|
||||
from project(":common").file("src/main/resources/${rootProject.accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
into(file(project.file("build/resources/main")))
|
||||
rename "${rootProject.accessWidenerVersion}.distanthorizons.accesswidener", "distanthorizons.accesswidener"
|
||||
}
|
||||
|
||||
task copyCoreResources(type: Copy) {
|
||||
from fileTree(project(":core").file("src/main/resources"))
|
||||
into project.file("build/resources/main")
|
||||
}
|
||||
|
||||
|
||||
// ==================== JVMDowngrader ====================
|
||||
|
||||
jvmdg.downgradeTo = JavaVersion.toVersion(rootProject.java_version)
|
||||
downgradeJar.archiveClassifier.set(null)
|
||||
shadeDowngradedApi.archiveClassifier.set(null)
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
// Transfer version properties from settings.gradle to project
|
||||
project.gradle.ext.getProperties().each { prop ->
|
||||
rootProject.ext.set(prop.key, prop.value)
|
||||
}
|
||||
|
||||
// Version string for archives
|
||||
rootProject.ext.versionStr = rootProject.mod_version + "-" + rootProject.minecraft_version
|
||||
rootProject.allprojects {
|
||||
version = (it == rootProject ? "" : it.name + "-") + rootProject.versionStr
|
||||
group = rootProject.maven_group
|
||||
|
||||
// Custom javadoc tags for all subprojects
|
||||
plugins.withType(JavaPlugin) {
|
||||
javadoc {
|
||||
options.tags(
|
||||
'todo:X"',
|
||||
'apiNote:a:API Note:',
|
||||
'implSpec:a:Implementation Requirements:',
|
||||
'implNote:a:Implementation Note:'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create build.properties with preprocessor definitions
|
||||
def writePreprocessorDefinitions() {
|
||||
StringBuilder sb = new StringBuilder()
|
||||
sb.append("# DON'T TOUCH THIS FILE, This is handled by the build script\n")
|
||||
|
||||
gradle.ext.mcVers.eachWithIndex { ver, idx ->
|
||||
sb.append("MC_${ver.replace('.', '_')}=${idx}\n")
|
||||
if (gradle.ext.mcIndex == idx)
|
||||
sb.append("MC_VER=${idx}\n")
|
||||
}
|
||||
|
||||
if (rootProject.mod_version.toLowerCase().contains("dev")) {
|
||||
sb.append("DEV_BUILD=\n")
|
||||
}
|
||||
|
||||
new File(rootDir, "build.properties").text = sb.toString()
|
||||
}
|
||||
writePreprocessorDefinitions()
|
||||
|
||||
// Wire JVMDowngrader to process remapped jars
|
||||
gradle.projectsEvaluated {
|
||||
rootProject.subprojects.each {
|
||||
if (it.tasks.findByName('remapJar') == null) return
|
||||
it.tasks.downgradeJar.inputFile = it.tasks.remapJar.archiveFile
|
||||
it.tasks.jar.finalizedBy(it.tasks.remapJar)
|
||||
it.tasks.remapJar.finalizedBy(it.tasks.shadeDowngradedApi)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
plugins {
|
||||
id 'dh-loader'
|
||||
}
|
||||
|
||||
unimined.minecraft {
|
||||
fabric {
|
||||
loader gradle.ext.fabric_loader_version
|
||||
accessWidener project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
}
|
||||
}
|
||||
|
||||
runClient.javaLauncher = null
|
||||
runServer.javaLauncher = null
|
||||
@@ -1,17 +0,0 @@
|
||||
plugins {
|
||||
id 'dh-loader'
|
||||
}
|
||||
|
||||
def awFile = project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
|
||||
unimined.minecraft {
|
||||
forge {
|
||||
loader gradle.ext.forge_version
|
||||
useToolchains = false
|
||||
mixinConfig("DistantHorizons.forge.mixins.json")
|
||||
accessTransformer aw2at(awFile)
|
||||
}
|
||||
}
|
||||
|
||||
runClient.javaLauncher = null
|
||||
runServer.javaLauncher = null
|
||||
@@ -1,16 +0,0 @@
|
||||
plugins {
|
||||
id 'dh-loader'
|
||||
}
|
||||
|
||||
def awFile = project(":common").file("src/main/resources/${gradle.ext.accessWidenerVersion}.distanthorizons.accesswidener")
|
||||
|
||||
unimined.minecraft {
|
||||
neoForged {
|
||||
loader gradle.ext.neoforge_version
|
||||
useToolchains = false
|
||||
accessTransformer aw2at(awFile)
|
||||
}
|
||||
}
|
||||
|
||||
runClient.javaLauncher = null
|
||||
runServer.javaLauncher = null
|
||||
@@ -1,239 +0,0 @@
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AWToAT {
|
||||
private static final Map<String, String> ACCESS_POINT_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
ACCESS_POINT_MAP.put("accessible", "public");
|
||||
ACCESS_POINT_MAP.put("extendable", "public-f");
|
||||
ACCESS_POINT_MAP.put("mutable", "public-f");
|
||||
}
|
||||
|
||||
public String minecraftVersion;
|
||||
|
||||
public File remap(File file, String minecraftVersion) {
|
||||
this.minecraftVersion = minecraftVersion.replace("_", ".");
|
||||
File atFile = createATFile(file);
|
||||
processFile(file, atFile);
|
||||
return atFile;
|
||||
}
|
||||
|
||||
private File createATFile(File file) {
|
||||
File metaInf = new File(file.getParentFile(), "META-INF");
|
||||
if (!metaInf.exists() && !metaInf.mkdir()) throw new RuntimeException("Error creating META-INF folder");
|
||||
File atFile = new File(metaInf, "accesstransformer.cfg");
|
||||
try {
|
||||
atFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error creating new file", e);
|
||||
}
|
||||
return atFile;
|
||||
}
|
||||
|
||||
private void processFile(File file, File atFile) {
|
||||
/* Validates if we need to recreate the Access Transformer file if it's out of date */
|
||||
// Get the hash of the file
|
||||
String fileHash = getFileHash(file);
|
||||
try (Scanner atScanner = new Scanner(atFile)) {
|
||||
// Check if the AT file is up-to-date by comparing the hash of the file with the hash stored in the AT file
|
||||
boolean hashFound = false;
|
||||
while (atScanner.hasNextLine()) {
|
||||
String line = atScanner.nextLine();
|
||||
if (hashCheck(line, fileHash)) {
|
||||
hashFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the AT file is up-to-date, print a message and return
|
||||
if (hashFound) {
|
||||
System.out.println("Access Transformer file is already up to date.");
|
||||
return;
|
||||
}
|
||||
} catch (FileNotFoundException ignored) {
|
||||
// If the AT file does not exist, continue
|
||||
}
|
||||
|
||||
/* Creates the Access Transformer file */
|
||||
// Opens a scanner for reading the Access Widener file and a writer for writing to the Access Transformer file
|
||||
try (Scanner scanner = new Scanner(file); FileWriter writer = new FileWriter(atFile)) {
|
||||
// Create an ExecutorService with a fixed thread pool size equal to the number of available processors
|
||||
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
// List to hold Future objects representing results of computation
|
||||
List<Future<String>> futures = new ArrayList<>();
|
||||
|
||||
// Write the hash of the file to the AT file
|
||||
writer.write("#DH_MAPPING_HASH:" + fileHash + "\n");
|
||||
|
||||
// Read each line from the file
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
// Skip lines starting with "accessWidener", "#" or blank lines
|
||||
if (line.startsWith("accessWidener") || line.startsWith("#") || line.isBlank()) continue;
|
||||
|
||||
// Submit the line to the executor service for processing
|
||||
// The processing is done by the processLine method
|
||||
futures.add(executor.submit(() -> processLine(line.split(" "))));
|
||||
}
|
||||
|
||||
// Write the results to the output file
|
||||
// The results are obtained by calling the get method on each Future
|
||||
for (Future<String> future : futures) {
|
||||
writer.write(future.get());
|
||||
}
|
||||
|
||||
// Shutdown the executor service to free up resources
|
||||
executor.shutdown();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error reading or writing to file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String processLine(String[] fields) {
|
||||
// fields[0] = access point like "accessible", "extendable", "mutable"
|
||||
// fields[1] = type like "field", "method", "class"
|
||||
// fields[2] = class name
|
||||
// fields[3] = field/method name
|
||||
// fields[4] = field/method descriptor
|
||||
|
||||
try {
|
||||
// Store the original field/method name
|
||||
String originalName = "";
|
||||
|
||||
// If there is a class name, replace the slashes with dots in the package name
|
||||
if (fields.length > 2) fields[2] = fields[2].replace("/", ".");
|
||||
|
||||
// If there is a field/method name, store the original name and remap it to SRG
|
||||
if (fields.length > 3) {
|
||||
originalName = fields[3];
|
||||
fields[3] = remapToSRG(fields[2], fields[3]);
|
||||
}
|
||||
|
||||
StringBuilder line = new StringBuilder(ACCESS_POINT_MAP.getOrDefault(fields[0], "public")).append(" ");
|
||||
switch (fields[1]) {
|
||||
case "field":
|
||||
line.append(fields[2]).append(" ").append(fields[3]).append(" #").append(originalName);
|
||||
// It'll be like: access-point class-name field-name-SRG # field-name-Mojmap
|
||||
// Eg: public net.minecraft.client.Minecraft f_90981_ # instance
|
||||
break;
|
||||
case "method":
|
||||
line.append(fields[2]).append(" ").append(fields[3]).append(fields[4]).append(" #").append(originalName);
|
||||
// It'll be like: access-point class-name method-name-SRG method-descriptor # method-name-Mojmap
|
||||
// Eg: public net.minecraft.client.Minecraft m_172797_()Lnet/minecraft/client/Minecraft; # getInstance
|
||||
break;
|
||||
default:
|
||||
line.append(fields[2]);
|
||||
// It'll be like: access-point class-name
|
||||
// Eg: public net.minecraft.client.Minecraft
|
||||
break;
|
||||
}
|
||||
line.append("\n");
|
||||
return line.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error processing line", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hashCheck(String line, String fileHash) {
|
||||
if (line.startsWith("#DH_MAPPING_HASH:")) {
|
||||
String hash = line.substring(17);
|
||||
return hash.equals(fileHash);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getFileHash(File file) {
|
||||
try {
|
||||
MessageDigest shaDigest = MessageDigest.getInstance("SHA-256");
|
||||
try (InputStream fis = new FileInputStream(file)) {
|
||||
byte[] byteArray = new byte[1024];
|
||||
int bytesCount;
|
||||
|
||||
// Read file data and update in message digest
|
||||
while ((bytesCount = fis.read(byteArray)) != -1) {
|
||||
shaDigest.update(byteArray, 0, bytesCount);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] bytes = shaDigest.digest();
|
||||
|
||||
// Convert byte array into signum representation
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte aByte : bytes) {
|
||||
sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
|
||||
// Return complete hash
|
||||
return sb.toString();
|
||||
} catch (NoSuchAlgorithmException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// WARNING: BELOW LIES HIGHLY CURSED CODE AND MIGHT EVEN BE ILLEGAL
|
||||
|
||||
|
||||
|
||||
|
||||
// Flag to track if there was an error in the GET request
|
||||
boolean error = false;
|
||||
|
||||
/**
|
||||
* This method returns a field or method name from Mojang mappings as SRG mappings.
|
||||
* It makes a GET request to the Linkie API to fetch the SRG name.
|
||||
*
|
||||
* @param clazz The class name
|
||||
* @param name The field or method name
|
||||
* @return The SRG name
|
||||
* @throws Exception If there is an error in the GET request or the SRG name is not found in the response
|
||||
*/
|
||||
private String remapToSRG(String clazz, String name) throws Exception {
|
||||
// Encode the class and field/method name to be used in the URL
|
||||
String query = URLEncoder.encode(clazz + "." + name, StandardCharsets.UTF_8);
|
||||
// Construct the URL for the GET request
|
||||
String urlString = "https://linkieapi.shedaniel.me/api/search?namespace=mojang&query=" + query + "&version=" + this.minecraftVersion + "&limit=1&allowClasses=false&allowFields=true&allowMethods=true&translate=mojang_srg";
|
||||
URL url = new URI(urlString).toURL();
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
int responseCode = conn.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuilder content = new StringBuilder();
|
||||
// Read the response line by line
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
content.append(inputLine);
|
||||
}
|
||||
in.close();
|
||||
conn.disconnect();
|
||||
// Regex to find the SRG name in the response
|
||||
Pattern pattern = Pattern.compile("\"l\"\\s*:\\s*\\{[^}]*\"i\"\\s*:\\s*\"([^\"]*)\"");
|
||||
Matcher matcher = pattern.matcher(content.toString());
|
||||
if (matcher.find()) return matcher.group(1);
|
||||
else throw new Exception("Couldn't find the SRG mapping for name: " + name + "\nCould not find 'i' in 'l' object in the response"); // `i` is the SRG name which is stored in the `l` JSON object
|
||||
} else {
|
||||
if (error) {
|
||||
// If there was an error in the GET request, and we already tried again, throw an exception
|
||||
throw new Exception("The GET request failed");
|
||||
}
|
||||
// If there was an error in the GET request, wait 2.5 seconds and try again as we probably got rate limited
|
||||
error = true;
|
||||
Thread.sleep(2500);
|
||||
return remapToSRG(clazz, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
class NativeRelocator
|
||||
{
|
||||
private final Path rootDirectory;
|
||||
private final Path cacheRoot;
|
||||
|
||||
/**
|
||||
* Initializes the NativeRelocator by preparing the environment if necessary.
|
||||
* Executes the appropriate preparation script based on the OS.
|
||||
*/
|
||||
NativeRelocator(Path rootDirectory)
|
||||
{
|
||||
this.rootDirectory = rootDirectory;
|
||||
this.cacheRoot = this.rootDirectory.resolve("cache");
|
||||
}
|
||||
|
||||
private void prepare() throws Exception
|
||||
{
|
||||
if (this.rootDirectory.resolve(".venv").toFile().exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
processBuilder.directory(this.rootDirectory.toFile());
|
||||
|
||||
String os = System.getProperty("os.name").toLowerCase();
|
||||
if (os.contains("win"))
|
||||
{
|
||||
processBuilder.command("powershell", "-ExecutionPolicy", "Bypass", "./prepare.ps1");
|
||||
}
|
||||
else if (os.contains("nix")
|
||||
|| os.contains("nux")
|
||||
|| os.contains("mac")
|
||||
|| os.contains("freebsd"))
|
||||
{
|
||||
processBuilder.command("./prepare.sh");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("Unsupported operating system: " + os);
|
||||
}
|
||||
|
||||
Process process = processBuilder.start();
|
||||
CompletableFuture<Void> outputFuture = readOutputStreams(process);
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
outputFuture.get();
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
throw new Exception("Prepare failed: " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and prints the output and error streams of a process asynchronously.
|
||||
*
|
||||
* @param process The process whose streams should be read.
|
||||
* @return A CompletableFuture that completes once all output has been processed.
|
||||
*/
|
||||
private static CompletableFuture<Void> readOutputStreams(Process process)
|
||||
{
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try
|
||||
{
|
||||
while (process.isAlive() || process.getInputStream().available() > 0 || process.getErrorStream().available() > 0)
|
||||
{
|
||||
if (process.getInputStream().available() > 0)
|
||||
{
|
||||
byte[] data = new byte[process.getInputStream().available()];
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
process.getInputStream().read(data);
|
||||
System.out.write(data);
|
||||
}
|
||||
if (process.getErrorStream().available() > 0)
|
||||
{
|
||||
byte[] data = new byte[process.getErrorStream().available()];
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
process.getErrorStream().read(data);
|
||||
System.err.write(data);
|
||||
}
|
||||
|
||||
//noinspection BusyWait
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
catch (Throwable ignored)
|
||||
{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces occurrences of a target string in a byte array, ensuring null termination.
|
||||
*
|
||||
* @param byteArray The byte array where replacements should occur.
|
||||
* @param target The string to replace.
|
||||
* @param replacement The replacement string (must not be longer than the target).
|
||||
* @throws IllegalArgumentException if the replacement is longer than the target.
|
||||
*/
|
||||
private void replaceInNullTerminatedStrings(byte[] byteArray, String target, String replacement)
|
||||
{
|
||||
if (target.length() < replacement.length())
|
||||
{
|
||||
throw new IllegalArgumentException("Replacement must be the same length or shorter than the target.");
|
||||
}
|
||||
|
||||
byte[] targetBytes = target.getBytes(StandardCharsets.US_ASCII);
|
||||
byte[] replacementBytes = replacement.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
byte nullByte = 0;
|
||||
|
||||
for (int endPos = 0; endPos < byteArray.length - targetBytes.length - 1; endPos++)
|
||||
{
|
||||
int startPos = endPos;
|
||||
int targetPos = 0;
|
||||
while (targetPos < targetBytes.length && byteArray[endPos] == targetBytes[targetPos])
|
||||
{
|
||||
targetPos++;
|
||||
endPos++;
|
||||
}
|
||||
|
||||
if (targetPos == targetBytes.length)
|
||||
{
|
||||
System.arraycopy(replacementBytes, 0, byteArray, startPos, replacementBytes.length);
|
||||
|
||||
startPos = startPos + replacementBytes.length;
|
||||
while (byteArray[endPos] != nullByte)
|
||||
{
|
||||
byteArray[startPos] = byteArray[endPos];
|
||||
endPos++;
|
||||
startPos++;
|
||||
}
|
||||
byteArray[startPos] = nullByte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an external script to fix a modified binary and returns the processed content.
|
||||
*
|
||||
* @param outputFilePath Path to store the processed binary.
|
||||
* @param content The original binary content.
|
||||
* @return The modified binary content.
|
||||
* @throws Exception if the process execution fails.
|
||||
*/
|
||||
public byte[] fixModifiedBinary(Path outputFilePath, byte[] content) throws Exception
|
||||
{
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
processBuilder.directory(this.rootDirectory.toFile());
|
||||
|
||||
processBuilder.command(
|
||||
this.rootDirectory.resolve(".venv/Scripts").toFile().exists()
|
||||
? this.rootDirectory.resolve(".venv/Scripts/python.exe").toString()
|
||||
: this.rootDirectory.resolve(".venv/bin/python").toString(),
|
||||
"./fix_modified_binary.py",
|
||||
outputFilePath.toString()
|
||||
);
|
||||
|
||||
Process process = processBuilder.start();
|
||||
CompletableFuture<Void> outputFuture = readOutputStreams(process);
|
||||
|
||||
process.getOutputStream().write(content);
|
||||
process.getOutputStream().close();
|
||||
|
||||
int exitCode = process.waitFor();
|
||||
outputFuture.get();
|
||||
|
||||
if (exitCode != 0)
|
||||
{
|
||||
throw new Exception("Process failed: " + exitCode);
|
||||
}
|
||||
|
||||
return Files.readAllBytes(outputFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a binary file, applying string replacements and fixing modifications.
|
||||
*
|
||||
* @param outputPath The output file path relative to the cache directory.
|
||||
* @param content The binary content to process.
|
||||
* @param replacements A map of string replacements to apply.
|
||||
* @return The modified binary content.
|
||||
* @throws Exception if processing fails.
|
||||
*/
|
||||
public byte[] processBinary(String outputPath, byte[] content, Map<String, String> replacements) throws Exception
|
||||
{
|
||||
Path outputFilePath = this.cacheRoot.resolve(outputPath);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
outputFilePath.getParent().toFile().mkdirs();
|
||||
|
||||
if (outputFilePath.toFile().exists())
|
||||
{
|
||||
return Files.readAllBytes(outputFilePath);
|
||||
}
|
||||
|
||||
System.out.println("Relocating to " + outputPath + "...");
|
||||
this.prepare();
|
||||
|
||||
for (Map.Entry<String, String> replacement : replacements.entrySet())
|
||||
{
|
||||
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
|
||||
}
|
||||
|
||||
return this.fixModifiedBinary(outputFilePath, content);
|
||||
}
|
||||
|
||||
}
|
||||
+467
@@ -0,0 +1,467 @@
|
||||
=========
|
||||
Build: 1.12.2-14.23.5.2846 - Tue Sep 03 21:22:46 GMT 2019
|
||||
ichttt:
|
||||
Fix CME when removing ticket managers (#5861)
|
||||
|
||||
=========
|
||||
Build: 1.12.2-14.23.5.2844 - Thu Aug 29 02:33:00 GMT 2019
|
||||
Barteks2x:
|
||||
Fix client sometimes generating biomes, causing incorrect biome
|
||||
generation on integrated server (#5720)
|
||||
|
||||
bs2609:
|
||||
Add checks for tile entities in now-unloaded chunks (#5724)
|
||||
|
||||
=========
|
||||
Build: 1.12.2-14.23.5.2843 - Thu Aug 29 02:23:04 GMT 2019
|
||||
bs2609:
|
||||
Fix invalid placeholder entity attributes (MC-150405) (#5718)
|
||||
|
||||
=========
|
||||
Build: 1.12.2-14.23.5.2842 - Thu Aug 29 02:08:57 GMT 2019
|
||||
bs2609:
|
||||
Allow conditional loading of advancements (#5255)
|
||||
|
||||
=========
|
||||
Build: 1.12.2-14.23.5.2841 - Thu Aug 29 01:58:50 GMT 2019
|
||||
bs2609:
|
||||
Improve performance of persistent chunk checks (#5706)
|
||||
|
||||
jensen.derik:
|
||||
Fix lightning not triggering EntityJoinWorldEvent (#5290)
|
||||
|
||||
=========
|
||||
Build: 1.12.2-14.23.5.2840 - Thu Aug 29 01:19:55 GMT 2019
|
||||
lex:
|
||||
Fix copy paste derp
|
||||
|
||||
|
||||
Build 2838:
|
||||
bs2609: Fix vanilla handling of options file (MC-117449, MC-151173) (#5725)
|
||||
|
||||
Build 2837:
|
||||
clienthax: Update EnumHelper to be compatible with Eclipse's OpenJ9 JVM. (#5712)
|
||||
|
||||
Build 2836:
|
||||
tterrag:
|
||||
Revert "Invalidate tile entities that are queued for removal (#5512)"
|
||||
This reverts commit 75788f63eea6c33ccef7e5cbcab27ad9ad2c2a04.
|
||||
This solution is invalid as TEs are free to modify the world
|
||||
tileEntities list, usually indirectly via chunkloading, from inside
|
||||
invalidate().
|
||||
This happens in vanilla, in TileEntityChest#invalidate, where it calls
|
||||
checkForAdjacentChests(), which has the potential to load neighboring
|
||||
chunks and cause a CME.
|
||||
A more sophisticated solution is needed.
|
||||
|
||||
Build 2835:
|
||||
bs2609: Fix some vertex format changes not being handled correctly (#5368)
|
||||
|
||||
Build 2834:
|
||||
bs2609:
|
||||
Transform vertex normals as well as positions when generating quads
|
||||
(#5242)
|
||||
|
||||
Build 2833:
|
||||
rseifert.phone: Fix for SidedInvWrapper isItemValid using wrong slot (#5642)
|
||||
|
||||
Build 2832:
|
||||
bs2609: Invalidate tile entities that are queued for removal (#5512)
|
||||
|
||||
Build 2831:
|
||||
lclc98: Added Wool to OreDictionary (#5414)
|
||||
|
||||
Build 2830:
|
||||
CreativeMD: Fixed boat not taking care of block-liquid hooks (#5086)
|
||||
|
||||
Build 2829:
|
||||
bs2609: Add Forge dimension-changing hooks to spectator handling code (#5212)
|
||||
|
||||
Build 2828:
|
||||
ichttt:
|
||||
Minor performace improvement when building chunks and rendering blocks
|
||||
(#5286)
|
||||
|
||||
Build 2827:
|
||||
bs2609: Catch json parsing errors from constants/factories files (#5258)
|
||||
|
||||
Build 2826:
|
||||
bs2609: Allow custom DataSerializers to be registered safely (#5245)
|
||||
|
||||
Build 2825:
|
||||
cpw:
|
||||
Try and make 1.13 mods more obviously wrong in 1.12..
|
||||
Signed-off-by: cpw <cpw+github@weeksfamily.ca>
|
||||
|
||||
Build 2824:
|
||||
tterrag: Fix #5651 Re-add canPlaceBlockOnSide check in World#mayPlace
|
||||
|
||||
Build 2823:
|
||||
Pokechu022:
|
||||
Fail fast when null is used with setTag instead of crashing in
|
||||
writeEntry (#5257)
|
||||
|
||||
Build 2822:
|
||||
tterrag: Fix block placement not checking for player collision
|
||||
|
||||
Build 2821:
|
||||
wynprice999: Added more Constants (#5323)
|
||||
|
||||
Build 2820:
|
||||
python0429: [1.12.2] Add a few events pertaining to villages (#5302)
|
||||
|
||||
Build 2819:
|
||||
Tyler Hancock: [1.12] Fix special spawn event not firing in many cases. (#5389)
|
||||
|
||||
Build 2818:
|
||||
bs2609: Only prompt for missing registries on local worlds (#5348)
|
||||
|
||||
Build 2817:
|
||||
ckrier.3000: Add EntityPlaceEvent (#5057)
|
||||
|
||||
Build 2816:
|
||||
bs2609: Generalise EnumRarity to an interface (#5182)
|
||||
|
||||
Build 2815:
|
||||
bs2609: Apply access-level changes to inner class attributes (#5468)
|
||||
|
||||
Build 2814:
|
||||
bs2609: Fix small logic error in ItemTextureQuadConverter (#5463)
|
||||
|
||||
Build 2813:
|
||||
bs2609: Better support for custom bows (#5209)
|
||||
|
||||
Build 2812:
|
||||
CovertJaguar: Remove FluidStack amount from hashcode calculation (#5272)
|
||||
molecularphylo:
|
||||
Fixed incorrect string representation of string list config property
|
||||
default values in their comments.
|
||||
bs2609:
|
||||
Improve tracking of used dimension IDs (#5249)
|
||||
Closes #5378 Large dimension IDs bloat level.data
|
||||
|
||||
Build 2811:
|
||||
bs2609:
|
||||
Fix up torch placement logic to handle more vanilla special-casing
|
||||
(#5426)
|
||||
|
||||
Build 2810:
|
||||
LexManos: Written size does not include int bytes.
|
||||
|
||||
Build 2809:
|
||||
LexManos:
|
||||
Extend Region files to support >1MB per chunk. If the 'sector count' is
|
||||
255, ask the compressed data header for the proper length.
|
||||
|
||||
Build 2808:
|
||||
tterrag1098: Add default impl to IConfigElement#getValidValuesDisplay
|
||||
|
||||
Build 2807:
|
||||
tterrag: Simplify custom item rendering by removing GL emissivity hacks
|
||||
|
||||
Build 2806:
|
||||
tterrag: Support diffuse lighting flag in item rendering
|
||||
|
||||
Build 2805:
|
||||
bs2609:
|
||||
Add a hook to allow continuously using items through stack changes
|
||||
(#4834)
|
||||
* Add a hook to allow continuously using items through stack changes
|
||||
|
||||
* Update licences
|
||||
|
||||
Build 2804:
|
||||
oOMitchOo:
|
||||
Added an additional constructor to every implementation of IFluidBlock.
|
||||
It is now possible to create a fluid block with a Fluid, Material and
|
||||
MapColor, so that the Material's MapColor isn't used for the blocks
|
||||
MapColor. (#5293)
|
||||
|
||||
Build 2803:
|
||||
bs2609: Add redirects to PotionEffect to respect registry replacement (#5213)
|
||||
|
||||
Build 2802:
|
||||
alexiy.ov:
|
||||
Add an annotation for @Config elements which will automatically create a
|
||||
slider control (#5026)
|
||||
|
||||
Build 2801:
|
||||
bs2609: Fix small logic error in emissive item rendering code (#5320)
|
||||
|
||||
Build 2800:
|
||||
molecularphylo:
|
||||
Allow config GUI cycling button elements generated from enums to display
|
||||
toString return values, rather than actual values. (#5125)
|
||||
|
||||
Build 2799:
|
||||
bs2609: Fix incorrect indexing in mipmap generation code (#5201)
|
||||
|
||||
Build 2798:
|
||||
bs2609:
|
||||
Ensure slave maps are cleaned up when handling registry overrides
|
||||
(#5250)
|
||||
|
||||
Build 2797:
|
||||
d_scalzi: Fix issue with --modListFile. (#5316)
|
||||
|
||||
Build 2796:
|
||||
LexManos:
|
||||
Fix potential issues with the Minecraft FakePlayer lingering around
|
||||
after world unloads.
|
||||
|
||||
Build 2795:
|
||||
tterrag: Fix potion remove event not always firing, add expiry event
|
||||
|
||||
Build 2794:
|
||||
tterrag: Clean up CraftingHelper constants loading API
|
||||
|
||||
Build 2793:
|
||||
tterrag: Fix crash from CraftingHelper due to FileSystem being closed early
|
||||
|
||||
Build 2792:
|
||||
tterrag:
|
||||
added PotionHooks, closes #3867, #4375 (#4614)
|
||||
* solved merge confilct
|
||||
|
||||
* improved var names & removed tabs
|
||||
|
||||
* Added spaces around !=
|
||||
|
||||
* fixed typo
|
||||
|
||||
Build 2791:
|
||||
tterrag:
|
||||
Add a hook for farmland watering (#4891)
|
||||
* Add a FarmlandWaterCheckEvent to allow mods to override when Farmland
|
||||
is watered or not
|
||||
|
||||
* revert 1.12.2 json
|
||||
|
||||
* Move the farmland patch to a ticket based instead of a event based
|
||||
system
|
||||
|
||||
* Minor changes
|
||||
|
||||
* Faster isValid checks, faster validation/invalidation if the state did
|
||||
not change, expand test mod to include a test for the validation system
|
||||
|
||||
* remove isValid boolean flag, we can express it with the tick counter
|
||||
|
||||
* Fix test mod resource warnings
|
||||
|
||||
* Remove tick timeout, add a javadoc note to invalidate on chunk unload,
|
||||
cleaned up test mod
|
||||
|
||||
* Allow mods to provide custom handling to determine if a pos is valid
|
||||
or not
|
||||
|
||||
* Make SimpleTicket more simple, make register public so custom tickets
|
||||
can be registered
|
||||
|
||||
* Fixes for review
|
||||
|
||||
* Add missing license headers
|
||||
|
||||
* Use a weak hash set
|
||||
|
||||
* Split up the map into smaller chunk based maps
|
||||
|
||||
* Add missing license headers
|
||||
|
||||
* Make MultiTicketManager more universal for custom implementations,
|
||||
cleanup imports
|
||||
|
||||
Build 2790:
|
||||
tterrag:
|
||||
Add methods to allow loading json constants outside of _constants
|
||||
(#4975)
|
||||
* add interface methods for loading json constants from an arbitary file
|
||||
|
||||
|
||||
* use try-with-resources
|
||||
|
||||
* don't make modders create jsoncontext, clean up resource use
|
||||
|
||||
* very minor cleanup
|
||||
|
||||
Build 2789:
|
||||
tterrag:
|
||||
Compute ASMDataTable submaps parallel, speeds up contructing mods
|
||||
(#5246)
|
||||
* Compute submaps parallel, speeds up contructing mods by a lot
|
||||
|
||||
* Use stream API better
|
||||
|
||||
Build 2788:
|
||||
mezz: Add logging for data manager key registration errors (#5129)
|
||||
|
||||
Build 2787:
|
||||
mezz: Improve support for custom block path types (#5203)
|
||||
|
||||
Build 2786:
|
||||
mezz: Fix missing comments in configs created with annotations (#5189)
|
||||
|
||||
Build 2785:
|
||||
mezz: Allow items to control the rate of repair from mending (#5102)
|
||||
|
||||
Build 2784:
|
||||
mezz: Improve exception handling from server starting events (#5226)
|
||||
|
||||
Build 2783:
|
||||
mezz: Improve context provided by potion icon rendering hooks (#5111)
|
||||
|
||||
Build 2782:
|
||||
mezz: Fix an ObjectHolderRef internal error message (#5214)
|
||||
|
||||
Build 2781:
|
||||
mezz: Implement rendering for item models with emissive quads (#5047)
|
||||
|
||||
Build 2780:
|
||||
mezz: Clean up logged mod states (#5227)
|
||||
mezz: Fix minor issue in getFilledPercentage for Fluid rendering (#5206)
|
||||
|
||||
Build 2779:
|
||||
mezz: Improve reflection helper methods (#4853)
|
||||
mezz: Fix inaccurate main thread name shown in client log (#5078)
|
||||
|
||||
Build 2778:
|
||||
mezz: Fix Baked Item models with transformations (#5241)
|
||||
|
||||
Build 2777:
|
||||
mezz:
|
||||
Re-add some missing villager profession patches (#5200)
|
||||
* Fix zombie villagers only spawning with vanilla professions
|
||||
* Fix spawning modded villagers that do not have their own building
|
||||
mezz: Fix missing string parameters in some log messages (#5210)
|
||||
mezz: Stop firing LivingSetAttackTargetEvent for setRevengeTarget (#5217)
|
||||
mezz: Prevent RecipeBook from crashing on empty modded ingredients (#5234)
|
||||
|
||||
Build 2776:
|
||||
mezz: Fix the bed position given to the SleepingTimeCheck event (#5107)
|
||||
|
||||
Build 2775:
|
||||
LexManos: Fix some null returns from defaulted registries (#5235)
|
||||
|
||||
Build 2774:
|
||||
LexManos:
|
||||
Only remove synthetic lambda methods referenced in body of SideOnly
|
||||
methods (#5127)
|
||||
|
||||
Build 2773:
|
||||
LexManos:
|
||||
A different approach to my changes in
|
||||
https://github.com/MinecraftForge/MinecraftForge/commit/8ace535995522bec0557d4217e0d98b3dc76cf1e
|
||||
to fix #5207
|
||||
LexManos: Fix patches from #5160 setting rotation as well as position (#5233)
|
||||
LexManos: Use HTTPS for files website.
|
||||
|
||||
Build 2772:
|
||||
tterrag: Make Forge-provided default transforms accessible to custom models
|
||||
tterrag:
|
||||
Make Forge blockstate variants correctly inherit AO setting from vanilla
|
||||
models (#5190)
|
||||
* Make Forge blockstate variants correctly inherit AO setting
|
||||
|
||||
* Move variant format checks into variant, check for added properties
|
||||
|
||||
* Small code cleanup
|
||||
tterrag: fixed visual bug with guislider
|
||||
tterrag:
|
||||
Allow IModel to express itself as a vanilla parent (#5195)
|
||||
* Fix errors caused by fancy missing model being non-vanilla parent
|
||||
|
||||
* Switch instanceof checks to a default IModel method
|
||||
|
||||
* Small code tweaks
|
||||
|
||||
Build 2771:
|
||||
tterrag: Add CreativeTabs#getLabelColor
|
||||
|
||||
Build 2770:
|
||||
tterrag:
|
||||
Allow providing a BufferedImage for banner render generation (#5041)
|
||||
* Adds an Event to allow providing a BufferedImage for the banner render
|
||||
generation (cached)
|
||||
textures, since banners don't use an atlas.
|
||||
implementation.
|
||||
|
||||
* Missed some copyright; might as well absolut text match, I guess
|
||||
|
||||
* Remove unneeded patch change
|
||||
|
||||
* Fix event variable access convention
|
||||
|
||||
* Formatting fix
|
||||
|
||||
* Improve event handling registration
|
||||
|
||||
* Import cleanup
|
||||
|
||||
* Replace event approach with Supplier approach
|
||||
|
||||
* Better name for test mod (now that it's no longer an event); adds
|
||||
ENABLE flag
|
||||
|
||||
* Moves MC code into
|
||||
net.minecraftforge.client.MinecraftForgeClient.getImageLayer to simplify
|
||||
patch
|
||||
|
||||
* Generalize naming
|
||||
|
||||
Build 2769:
|
||||
mezz: Fix Mesa biome entry tags in the BiomeDictionary (#5177)
|
||||
|
||||
Build 2768:
|
||||
LexManos: Bump version number for RB.
|
||||
|
||||
Build 2767:
|
||||
LexManos:
|
||||
Change biome spawn list entries to use factory method where possible
|
||||
(#5075)
|
||||
LexManos: Prevent some texture loading errors from crashing the game (#5121)
|
||||
LexManos: Patch PotionHelper to use registry delegates (#5142)
|
||||
LexManos: Add a notification event for handling game rule changes (#5152)
|
||||
|
||||
Build 2766:
|
||||
LexManos:
|
||||
Change universal bucket support to use fluid names instead of instances
|
||||
(#5031)
|
||||
|
||||
Build 2765:
|
||||
LexManos: Fix NPE on clientside entities constructed with null world (#5170)
|
||||
|
||||
Build 2764:
|
||||
tterrag: Fix patches from #5160 running on the client and causing stutter
|
||||
|
||||
Build 2763:
|
||||
LexManos:
|
||||
Class transformer optimizations (#5159)
|
||||
* Filter packages for deobf transformation
|
||||
* Only serialize transformed class with TerminalTransformer if bytecode
|
||||
changed
|
||||
|
||||
Build 2762:
|
||||
github: Update github stale so issues can be Assigned
|
||||
|
||||
Build 2761:
|
||||
LexManos:
|
||||
Fix MC-136995 - Chunk loading and unloading issue with entities placed
|
||||
in exact positions. (#5160)
|
||||
Scatter gun patches to improve entity tracking and position tracking.
|
||||
Provided by Aikar through the Paper project, this commit of patches
|
||||
combines the following patches:
|
||||
|
||||
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0306-Mark-chunk-dirty-anytime-entities-change-to-guarante.patch
|
||||
|
||||
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0315-Always-process-chunk-registration-after-moving.patch
|
||||
|
||||
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0335-Ensure-chunks-are-always-loaded-on-hard-position-set.patch
|
||||
|
||||
https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0378-Sync-Player-Position-to-Vehicles.patch
|
||||
|
||||
Build 2760:
|
||||
LexManos: Fix --mods and --modListFile arguments not making it past LaunchWrapper.
|
||||
|
||||
Build 2759:
|
||||
LexManos: Remove BlamingTransformer (#5115)
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the team lead James Seibel through Discord at `@backsun`. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
plugins {
|
||||
id 'dh-loader'
|
||||
}
|
||||
@@ -1,414 +0,0 @@
|
||||
package com.seibel.distanthorizons.common;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiAfterDhInitEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeDhInitEvent;
|
||||
import com.seibel.distanthorizons.common.commands.CommandInitializer;
|
||||
import com.seibel.distanthorizons.common.wrappers.DependencySetup;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.DhDebugScreenEntry;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftServerWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ClientApi;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||
import com.seibel.distanthorizons.core.config.eventHandlers.presets.ThreadPresetConfigEventHandler;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
|
||||
import com.seibel.distanthorizons.core.jar.ModJarInfo;
|
||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.StubDebugWireframeRenderer;
|
||||
import com.seibel.distanthorizons.core.util.NativeDialogUtil;
|
||||
import com.seibel.distanthorizons.core.util.ThreadUtil;
|
||||
import com.seibel.distanthorizons.core.util.threading.DhThreadFactory;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Base for all mod loader initializers
|
||||
* and handles most setup.
|
||||
*/
|
||||
public abstract class AbstractModInitializer
|
||||
{
|
||||
protected static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private CommandInitializer commandInitializer;
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// abstract methods //
|
||||
//==================//
|
||||
//region
|
||||
|
||||
protected abstract void createInitialSharedBindings();
|
||||
protected abstract void createInitialClientBindings();
|
||||
protected abstract IEventProxy createClientProxy();
|
||||
protected abstract IEventProxy createServerProxy(boolean isDedicated);
|
||||
protected abstract void initializeModCompat();
|
||||
|
||||
protected abstract void subscribeRegisterCommandsEvent(Consumer<CommandDispatcher<CommandSourceStack>> eventHandler);
|
||||
|
||||
protected abstract void subscribeClientStartedEvent(Runnable eventHandler);
|
||||
protected abstract void subscribeServerStartingEvent(Consumer<MinecraftServer> eventHandler);
|
||||
protected abstract void runDelayedSetup();
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// initialize events //
|
||||
//===================//
|
||||
//region
|
||||
|
||||
public void onInitializeClient()
|
||||
{
|
||||
DependencySetup.createClientBindings();
|
||||
this.createInitialClientBindings();
|
||||
|
||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " client, firing DhApiBeforeDhInitEvent...");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
|
||||
this.startup();
|
||||
this.logBuildInfo();
|
||||
|
||||
this.createClientProxy().registerEvents();
|
||||
this.createServerProxy(false).registerEvents();
|
||||
|
||||
this.initializeModCompat();
|
||||
|
||||
// Client uses config for auto-updater, so it's initialized here instead of post-init stage
|
||||
this.initConfig();
|
||||
logModIncompatibilityWarnings(); // needs to be called after config loading
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " client Initialized.");
|
||||
|
||||
#if MC_VER < MC_1_21_9
|
||||
// debug screen rendering handled via a mixin
|
||||
#else
|
||||
DhDebugScreenEntry.register();
|
||||
#endif
|
||||
|
||||
this.subscribeClientStartedEvent(this::postInit);
|
||||
this.subscribeClientStartedEvent(this::postClientInit);
|
||||
}
|
||||
|
||||
public void onInitializeServer()
|
||||
{
|
||||
DependencySetup.createServerBindings();
|
||||
|
||||
LOGGER.info("Initializing " + ModInfo.READABLE_NAME + " server, firing DhApiBeforeDhInitEvent event...");
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeDhInitEvent.class, null);
|
||||
|
||||
this.startup();
|
||||
this.logBuildInfo();
|
||||
|
||||
// This prevents returning uninitialized Config values,
|
||||
// resulting from a circular reference mid-initialization in a static class
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
ThreadPresetConfigEventHandler.INSTANCE.toString();
|
||||
|
||||
this.createServerProxy(true).registerEvents();
|
||||
|
||||
this.initializeModCompat();
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized, adding event subscribers...");
|
||||
this.commandInitializer = new CommandInitializer();
|
||||
this.subscribeRegisterCommandsEvent(dispatcher -> { this.commandInitializer.initCommands(dispatcher); });
|
||||
|
||||
this.subscribeServerStartingEvent(server ->
|
||||
{
|
||||
MinecraftServerWrapper.INSTANCE.dedicatedServer = (DedicatedServer)server;
|
||||
|
||||
this.initConfig();
|
||||
this.postInit();
|
||||
this.postServerInit();
|
||||
this.commandInitializer.onServerReady();
|
||||
|
||||
this.checkForUpdates();
|
||||
|
||||
LOGGER.info(ModInfo.READABLE_NAME + " server Initialized at " + server.getServerDirectory());
|
||||
});
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========================//
|
||||
// inner initializer methods //
|
||||
//===========================//
|
||||
//region
|
||||
|
||||
private void startup()
|
||||
{
|
||||
DependencySetup.createSharedBindings();
|
||||
SharedApi.init();
|
||||
this.createInitialSharedBindings();
|
||||
}
|
||||
|
||||
private void logBuildInfo()
|
||||
{
|
||||
LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
|
||||
|
||||
// if the build is stable the branch/commit/etc shouldn't be needed
|
||||
if (ModInfo.IS_DEV_BUILD)
|
||||
{
|
||||
LOGGER.info("DH Branch: " + ModJarInfo.Git_Branch);
|
||||
LOGGER.info("DH Commit: " + ModJarInfo.Git_Commit);
|
||||
LOGGER.info("DH Jar Build Source: " + ModJarInfo.Build_Source);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends IModAccessor> void tryCreateModCompatAccessor(String modId, Class<? super T> accessorClass, Supplier<T> accessorConstructor)
|
||||
{
|
||||
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||
if (modChecker.isModLoaded(modId))
|
||||
{
|
||||
//noinspection unchecked
|
||||
ModAccessorInjector.INSTANCE.bind((Class<? extends IModAccessor>) accessorClass, accessorConstructor.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.debug("Skipping mod compatibility accessor for: ["+modId+"]");
|
||||
}
|
||||
}
|
||||
|
||||
private void initConfig()
|
||||
{
|
||||
ConfigHandler.tryRunFirstTimeSetup();
|
||||
Config.completeDelayedSetup();
|
||||
DhLogger.runDelayedConfigSetup();
|
||||
}
|
||||
|
||||
private void checkForUpdates()
|
||||
{
|
||||
if (Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get())
|
||||
{
|
||||
if (Config.Client.Advanced.AutoUpdater.enableSilentUpdates.get())
|
||||
{
|
||||
LOGGER.info("Silent updates are not allowed for dedicated servers; force disabling.");
|
||||
Config.Client.Advanced.AutoUpdater.enableSilentUpdates.set(false);
|
||||
}
|
||||
|
||||
SelfUpdater.onStart();
|
||||
}
|
||||
}
|
||||
|
||||
private void postInit()
|
||||
{
|
||||
LOGGER.info("Running Delayed setup...");
|
||||
this.runDelayedSetup();
|
||||
|
||||
if (ConfigHandler.INSTANCE == null)
|
||||
{
|
||||
throw new IllegalStateException("Config was not initialized. Make sure to call LodCommonMain.initConfig() before calling this method.");
|
||||
}
|
||||
|
||||
LOGGER.info("Delayed setup complete, firing DhApiAfterDhInitEvent event...");
|
||||
|
||||
// should be fired after all delayed setup so singletons and config can be accessed
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterDhInitEvent.class, null);
|
||||
}
|
||||
|
||||
private void postClientInit()
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
|
||||
// This method may be called from either the render thread,
|
||||
// or some other random setup thread depending on the mod loader.
|
||||
// In order to avoid confusion/inconsistent problems, we're always going
|
||||
// to run setup on our own thread.
|
||||
Thread dhSetupThread = new Thread(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
DependencySetup.setRenderingApiBindings();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
future.complete(null);
|
||||
}
|
||||
});
|
||||
dhSetupThread.setName(ThreadUtil.THREAD_NAME_PREFIX + "PostClientInit Thread");
|
||||
dhSetupThread.start();
|
||||
|
||||
future.join();
|
||||
}
|
||||
private void postServerInit() { SingletonInjector.INSTANCE.bind(AbstractDebugWireframeRenderer.class, new StubDebugWireframeRenderer()); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==================================//
|
||||
// mod partial compatibility checks //
|
||||
//==================================//
|
||||
//region
|
||||
|
||||
/**
|
||||
* Some mods will work with a few tweaks
|
||||
* or will partially work but have some known issues we can't solve.
|
||||
* This method will log (and display to chat if enabled)
|
||||
* these warnings and potential fixes.
|
||||
*/
|
||||
private static void logModIncompatibilityWarnings()
|
||||
{
|
||||
boolean showChatWarnings = Config.Common.Logging.Warning.showModCompatibilityWarningsOnStartup.get();
|
||||
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
|
||||
|
||||
String startingString = "Partially Incompatible Distant Horizons mod detected: ";
|
||||
|
||||
|
||||
|
||||
// Alex's caves
|
||||
//region
|
||||
if (modChecker.isModLoaded("alexscaves"))
|
||||
{
|
||||
// There've been a few reports about this mod breaking DH at a few different points in time
|
||||
// the fixes for said breakage changes depending on the version so unfortunately
|
||||
// all we can do is log a warning so the user can handle it.
|
||||
|
||||
if (showChatWarnings)
|
||||
{
|
||||
String message =
|
||||
MinecraftTextFormat.ORANGE + "Distant Horizons: Alex's Cave detected." + MinecraftTextFormat.CLEAR_FORMATTING +
|
||||
"You may have to change Alex's config for DH to render. ";
|
||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||
}
|
||||
|
||||
LOGGER.warn(startingString + "[Alex's Caves] may require some config changes in order to render Distant Horizons correctly.");
|
||||
}
|
||||
//endregion
|
||||
|
||||
// William Wythers' Overhauled Overworld (WWOO)
|
||||
//region
|
||||
if (modChecker.isModLoaded("wwoo"))
|
||||
{
|
||||
// WWOO has a bug with it's world gen that can't be fixed by DH or WWOO
|
||||
// (at least that is what James learned after talking with WWOO)
|
||||
// WWOO will cause grid lines to appear in the world when DH generates the chunks
|
||||
// this might be due to how WWOO uses features for everything when generating
|
||||
// and said features don't always get to the edge of said chunks.
|
||||
|
||||
String wwooWarning = "LODs generated by DH may have grid lines between sections. Disabling either WWOO or DH's distant generator will fix the problem.";
|
||||
|
||||
if (showChatWarnings)
|
||||
{
|
||||
String message =
|
||||
MinecraftTextFormat.ORANGE + "Distant Horizons: WWOO detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||
wwooWarning;
|
||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||
}
|
||||
|
||||
LOGGER.warn(startingString + "[WWOO] "+ wwooWarning);
|
||||
}
|
||||
//endregion
|
||||
|
||||
// Chunky //
|
||||
//region
|
||||
|
||||
boolean chunkyPresent = false;
|
||||
try
|
||||
{
|
||||
Class.forName("org.popcraft.chunky.api.ChunkyAPI");
|
||||
chunkyPresent = true;
|
||||
}
|
||||
catch (ClassNotFoundException ignore) { }
|
||||
|
||||
if (chunkyPresent)
|
||||
{
|
||||
// Chunky can generate chunks faster than DH can process them,
|
||||
// causing holes in the LODs.
|
||||
// Generally it's better and faster to use DH's world generator.
|
||||
|
||||
String chunkyWarning = "Chunky can cause DH LODs to have holes " +
|
||||
"since Chunky can generate chunks faster than DH can process them. \n" +
|
||||
"Using DH's distant generator instead of chunky or increasing DH's CPU thread count can resolve the issue.";
|
||||
|
||||
if (showChatWarnings)
|
||||
{
|
||||
String message =
|
||||
MinecraftTextFormat.ORANGE + "Distant Horizons: Chunky detected." + MinecraftTextFormat.CLEAR_FORMATTING + "\n" +
|
||||
chunkyWarning;
|
||||
ClientApi.INSTANCE.showChatMessageNextFrame(message);
|
||||
}
|
||||
|
||||
LOGGER.warn(startingString + "[Chunky] "+ chunkyWarning);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
// iris //
|
||||
//region
|
||||
|
||||
IIrisAccessor iris = ModAccessorInjector.INSTANCE.get(IIrisAccessor.class);
|
||||
if (iris != null)
|
||||
{
|
||||
// get the currently selected rendering API
|
||||
EDhApiRenderApi renderApi = Config.Client.Advanced.Graphics.Experimental.renderingApi.get();
|
||||
if (renderApi == EDhApiRenderApi.AUTO)
|
||||
{
|
||||
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
renderApi = versionConstants.getDefaultRenderingApi();
|
||||
}
|
||||
|
||||
// Iris only supports nataive OpenGL
|
||||
if (renderApi != EDhApiRenderApi.OPEN_GL)
|
||||
{
|
||||
String irisUnsupportedMessage = "Iris doesn't support DH when using the ["+EDhApiRenderApi.BLAZE_3D+"] rendering API, this will need to be fixed on Iris' end. As a temporary fix please change the rendering API to ["+EDhApiRenderApi.OPEN_GL+"] in DH's config file.";
|
||||
LOGGER.fatal(irisUnsupportedMessage);
|
||||
NativeDialogUtil.showDialog(ModInfo.READABLE_NAME, irisUnsupportedMessage, "ok", "error");
|
||||
|
||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
String errorMessage = "loading Distant Horizons. "+irisUnsupportedMessage;
|
||||
String exceptionError = "Distant Horizons conditional mod config Exception";
|
||||
mc.crashMinecraft(errorMessage, new Exception(exceptionError));
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
//region
|
||||
|
||||
public interface IEventProxy
|
||||
{
|
||||
void registerEvents();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-138
@@ -1,138 +0,0 @@
|
||||
package com.seibel.distanthorizons.common;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.network.event.internal.IncompatibleMessageInternalEvent;
|
||||
import com.seibel.distanthorizons.core.network.event.internal.ProtocolErrorInternalEvent;
|
||||
import com.seibel.distanthorizons.core.network.messages.MessageRegistry;
|
||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||
import com.seibel.distanthorizons.core.network.messages.base.CloseReasonMessage;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
#else
|
||||
import net.minecraft.resources.Identifier;
|
||||
#endif
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractPluginPacketSender implements IPluginPacketSender
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder()
|
||||
.fileLevelConfig(Config.Common.Logging.logNetworkEventToFile)
|
||||
.build();
|
||||
|
||||
#if MC_VER <= MC_1_20_6
|
||||
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = new ResourceLocation(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||
#elif MC_VER <= MC_1_21_10
|
||||
public static final ResourceLocation WRAPPER_PACKET_RESOURCE = ResourceLocation.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||
#else
|
||||
public static final Identifier WRAPPER_PACKET_RESOURCE = Identifier.fromNamespaceAndPath(ModInfo.RESOURCE_NAMESPACE, ModInfo.WRAPPER_PACKET_PATH);
|
||||
#endif
|
||||
|
||||
// "Forge byte" is an unused packet ID. We have our own system which works with all mod loaders,
|
||||
// so we're just accounting for it by reading the protocol version as a byte instead of a short in Forge, to keep cross-loader compatibility
|
||||
private final boolean forgeByteInProtocolVersion;
|
||||
|
||||
|
||||
public AbstractPluginPacketSender() { this(false); }
|
||||
public AbstractPluginPacketSender(boolean forgeByteInProtocolVersion)
|
||||
{
|
||||
this.forgeByteInProtocolVersion = forgeByteInProtocolVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void sendToClient(IServerPlayerWrapper serverPlayer, AbstractNetworkMessage message)
|
||||
{
|
||||
this.sendToClient((ServerPlayer) serverPlayer.getWrappedMcObject(), message);
|
||||
}
|
||||
public abstract void sendToClient(ServerPlayer serverPlayer, AbstractNetworkMessage message);
|
||||
|
||||
@Override
|
||||
public abstract void sendToServer(AbstractNetworkMessage message);
|
||||
|
||||
public AbstractNetworkMessage decodeMessage(FriendlyByteBuf in)
|
||||
{
|
||||
AbstractNetworkMessage message = null;
|
||||
|
||||
try
|
||||
{
|
||||
in.markReaderIndex();
|
||||
|
||||
int protocolVersion = this.forgeByteInProtocolVersion ? in.readByte() : in.readShort();
|
||||
if (protocolVersion != ModInfo.PROTOCOL_VERSION)
|
||||
{
|
||||
return new IncompatibleMessageInternalEvent(protocolVersion);
|
||||
}
|
||||
|
||||
message = MessageRegistry.INSTANCE.createMessage(in.readUnsignedShort());
|
||||
message.decode(in);
|
||||
|
||||
if (in.isReadable())
|
||||
{
|
||||
throw new IOException("Buffer has not been fully read");
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
in.resetReaderIndex();
|
||||
|
||||
LOGGER.error("Failed to decode message", e);
|
||||
LOGGER.error("Buffer: ["+in+"]");
|
||||
LOGGER.error("Buffer contents: ["+ByteBufUtil.hexDump(in)+"]");
|
||||
|
||||
return new ProtocolErrorInternalEvent(e, message, true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Prevent connection crashing if not entire buffer has been read
|
||||
in.readerIndex(in.writerIndex());
|
||||
}
|
||||
}
|
||||
|
||||
public void encodeMessage(FriendlyByteBuf out, AbstractNetworkMessage message)
|
||||
{
|
||||
// This is intentionally unhandled, because errors related to this are unlikely to appear in wild
|
||||
Objects.requireNonNull(message);
|
||||
|
||||
if (this.forgeByteInProtocolVersion)
|
||||
{
|
||||
out.writeByte(ModInfo.PROTOCOL_VERSION);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.writeShort(ModInfo.PROTOCOL_VERSION);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
out.markWriterIndex();
|
||||
out.writeShort(MessageRegistry.INSTANCE.getMessageId(message));
|
||||
message.encode(out);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Failed to encode message", e);
|
||||
LOGGER.error("Message: ["+message+"]");
|
||||
|
||||
message.getSession().tryHandleMessage(new ProtocolErrorInternalEvent(e, message, false));
|
||||
|
||||
// Encode close reason message instead
|
||||
out.resetWriterIndex();
|
||||
message = new CloseReasonMessage("Internal error on other side");
|
||||
out.writeShort(MessageRegistry.INSTANCE.getMessageId(message));
|
||||
message.encode(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.seibel.distanthorizons.common;
|
||||
|
||||
#if MC_VER >= MC_1_20_6
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record CommonPacketPayload(@Nullable AbstractNetworkMessage message) implements CustomPacketPayload
|
||||
{
|
||||
public static final Type<CommonPacketPayload> TYPE = new Type<>(AbstractPluginPacketSender.WRAPPER_PACKET_RESOURCE);
|
||||
private static final AbstractPluginPacketSender PACKET_SENDER = (AbstractPluginPacketSender) SingletonInjector.INSTANCE.get(IPluginPacketSender.class);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() { return TYPE; }
|
||||
|
||||
|
||||
public static class Codec implements StreamCodec<FriendlyByteBuf, CommonPacketPayload>
|
||||
{
|
||||
@NotNull
|
||||
@Override
|
||||
public CommonPacketPayload decode(@NotNull FriendlyByteBuf in)
|
||||
{ return new CommonPacketPayload(PACKET_SENDER.decodeMessage(in)); }
|
||||
|
||||
@Override
|
||||
public void encode(@NotNull FriendlyByteBuf out, CommonPacketPayload payload)
|
||||
{ PACKET_SENDER.encodeMessage(out, payload.message()); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,102 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commands;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.ServerPlayerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
#if MC_VER >= MC_1_19_2
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import java.util.Objects;
|
||||
#else // < 1.19.2
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Abstract class providing common functionality for DH's commands.
|
||||
*/
|
||||
public abstract class AbstractCommand
|
||||
{
|
||||
public abstract LiteralArgumentBuilder<CommandSourceStack> buildCommand();
|
||||
|
||||
|
||||
/**
|
||||
* Sends a success response to the player with the given text.
|
||||
*
|
||||
* @param commandContext The command context to send the response to.
|
||||
* @param text The text to display in the success message.
|
||||
* @return 1, indicating that the command was successful.
|
||||
*/
|
||||
protected int sendSuccessResponse(CommandContext<CommandSourceStack> commandContext, String text, boolean notifyAdmins)
|
||||
{
|
||||
#if MC_VER >= MC_1_20_1
|
||||
commandContext.getSource().sendSuccess(() -> Component.literal(text), notifyAdmins);
|
||||
#elif MC_VER >= MC_1_19_2
|
||||
commandContext.getSource().sendSuccess(Component.literal(text), notifyAdmins);
|
||||
#else
|
||||
commandContext.getSource().sendSuccess(new TranslatableComponent(text), notifyAdmins);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a failure response to the player with the given text.
|
||||
*
|
||||
* @param commandContext The command context to send the response to.
|
||||
* @param text The text to display in the failure message.
|
||||
* @return 1, indicating that the command was successful.
|
||||
*/
|
||||
protected int sendFailureResponse(CommandContext<CommandSourceStack> commandContext, String text)
|
||||
{
|
||||
#if MC_VER >= MC_1_20_1
|
||||
commandContext.getSource().sendFailure(Component.literal(text));
|
||||
#elif MC_VER >= MC_1_19_2
|
||||
commandContext.getSource().sendFailure(Component.literal(text));
|
||||
#else
|
||||
commandContext.getSource().sendFailure(new TranslatableComponent(text));
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server player from a command context.
|
||||
*
|
||||
* @param commandContext The command context to get the server player from.
|
||||
* @return The server player wrapper for the player who sent the command.
|
||||
*/
|
||||
protected IServerPlayerWrapper getSourcePlayer(CommandContext<CommandSourceStack> commandContext) #if MC_VER < MC_1_19_2 throws CommandSyntaxException #endif
|
||||
{
|
||||
#if MC_VER >= MC_1_19_2
|
||||
return ServerPlayerWrapper.getWrapper(Objects.requireNonNull(commandContext.getSource().getPlayer()));
|
||||
#else
|
||||
return ServerPlayerWrapper.getWrapper(commandContext.getSource().getPlayerOrException());
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the source of a command is a player.
|
||||
*
|
||||
* @param source The source of the command to check.
|
||||
* @return True if the source is a player, false otherwise.
|
||||
*/
|
||||
protected boolean isPlayerSource(CommandSourceStack source)
|
||||
{
|
||||
#if MC_VER >= MC_1_19_2
|
||||
return source.isPlayer();
|
||||
#else
|
||||
try
|
||||
{
|
||||
source.getPlayerOrException();
|
||||
return true;
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commands;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.seibel.distanthorizons.core.network.messages.MessageRegistry.DEBUG_CODEC_CRASH_MESSAGE;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
#else
|
||||
import net.minecraft.server.permissions.PermissionCheck;
|
||||
import net.minecraft.server.permissions.Permissions;
|
||||
#endif
|
||||
|
||||
public class CommandInitializer
|
||||
{
|
||||
private boolean serverReady = false;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
private static final int REQUIRED_PERMISSION_LEVEL = 4;
|
||||
#else
|
||||
private static final PermissionCheck COMMAND_PERMISSION_CHECK = new PermissionCheck.Require(Permissions.COMMANDS_OWNER);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* A received command dispatcher, which is held until the server is ready to initialize the commands.
|
||||
*/
|
||||
@Nullable
|
||||
private CommandDispatcher<CommandSourceStack> commandDispatcher;
|
||||
|
||||
/**
|
||||
* Notify the command initializer that the game is ready to accept commands.
|
||||
* If {@link CommandInitializer#initCommands(CommandDispatcher)} has been fired before it was ready, it will also initialize the commands.
|
||||
*/
|
||||
public void onServerReady()
|
||||
{
|
||||
this.serverReady = true;
|
||||
if (this.commandDispatcher != null)
|
||||
{
|
||||
this.initCommands(this.commandDispatcher);
|
||||
this.commandDispatcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all available commands.
|
||||
* If the game is not ready yet, it stores the dispatcher to initialize the commands later.
|
||||
*
|
||||
* @param commandDispatcher The command dispatcher to register commands to.
|
||||
*/
|
||||
public void initCommands(CommandDispatcher<CommandSourceStack> commandDispatcher)
|
||||
{
|
||||
if (!this.serverReady)
|
||||
{
|
||||
this.commandDispatcher = commandDispatcher;
|
||||
return;
|
||||
}
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("dh")
|
||||
.requires((source) ->
|
||||
{
|
||||
#if MC_VER <= MC_1_21_10
|
||||
return source.hasPermission(REQUIRED_PERMISSION_LEVEL);
|
||||
#else
|
||||
return COMMAND_PERMISSION_CHECK.check(source.permissions());
|
||||
#endif
|
||||
});
|
||||
|
||||
builder.then(new ConfigCommand().buildCommand());
|
||||
builder.then(new DebugCommand().buildCommand());
|
||||
builder.then(new PregenCommand().buildCommand());
|
||||
|
||||
if (DEBUG_CODEC_CRASH_MESSAGE)
|
||||
{
|
||||
builder.then(new CrashCommand().buildCommand());
|
||||
}
|
||||
|
||||
commandDispatcher.register(builder);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commands;
|
||||
|
||||
import com.mojang.brigadier.arguments.*;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.seibel.distanthorizons.core.config.ConfigHandler;
|
||||
import com.seibel.distanthorizons.core.config.types.AbstractConfigBase;
|
||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToIntBiFunction;
|
||||
|
||||
import static com.mojang.brigadier.arguments.DoubleArgumentType.doubleArg;
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
/**
|
||||
* Command for managing config.
|
||||
*/
|
||||
public class ConfigCommand extends AbstractCommand
|
||||
{
|
||||
private static final List<CommandArgumentData<?>> commandArguments = Arrays.asList(
|
||||
new CommandArgumentData<>(Integer.class, configEntry -> integer(configEntry.getMin(), configEntry.getMax()), IntegerArgumentType::getInteger),
|
||||
new CommandArgumentData<>(Double.class, configEntry -> doubleArg(configEntry.getMin(), configEntry.getMax()), DoubleArgumentType::getDouble),
|
||||
new CommandArgumentData<>(Boolean.class, BoolArgumentType::bool, BoolArgumentType::getBool),
|
||||
new CommandArgumentData<>(String.class, StringArgumentType::string, StringArgumentType::getString)
|
||||
);
|
||||
|
||||
/**
|
||||
* Builds a command tree.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||
{
|
||||
LiteralArgumentBuilder<CommandSourceStack> builder = literal("config");
|
||||
HashSet<String> addedCommands = new HashSet<>();
|
||||
|
||||
for (AbstractConfigBase<?> type : ConfigHandler.INSTANCE.configBaseList)
|
||||
{
|
||||
// Skip non-config entries
|
||||
if (!(type instanceof ConfigEntry))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//noinspection PatternVariableCanBeUsed
|
||||
ConfigEntry configEntry = (ConfigEntry) type;
|
||||
if (configEntry.getChatCommandName() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addedCommands.add(configEntry.getChatCommandName()))
|
||||
{
|
||||
throw new IllegalStateException("Duplicate command name: " + configEntry.getChatCommandName());
|
||||
}
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> subcommand = literal(configEntry.getChatCommandName())
|
||||
.executes(commandContext -> this.sendSuccessResponse(commandContext,
|
||||
"\n" +
|
||||
"Description of §l" + configEntry.getChatCommandName() + "§r:\n" +
|
||||
"§o" + configEntry.getComment().trim() + "§r\n" +
|
||||
"§7Config file name: §f" + configEntry.name + "§7, category: §f" + configEntry.category + "\n" +
|
||||
"\n" +
|
||||
"Current value of " + configEntry.getChatCommandName() + " is §n" + configEntry.get() + "§r",
|
||||
false
|
||||
));
|
||||
|
||||
ToIntBiFunction<CommandContext<CommandSourceStack>, Object> updateConfigValue = (commandContext, value) -> {
|
||||
configEntry.set(value);
|
||||
return this.sendSuccessResponse(commandContext, "Changed the value of [" + configEntry.getChatCommandName() + "] to [" + value + "]", true);
|
||||
};
|
||||
|
||||
// Enum type needs a special case since enums aren't represented by existing argument type
|
||||
// and need literals for each individual value
|
||||
if (Enum.class.isAssignableFrom(configEntry.getType()))
|
||||
{
|
||||
for (Object choice : configEntry.getType().getEnumConstants())
|
||||
{
|
||||
subcommand.then(
|
||||
literal(choice.toString())
|
||||
.executes(c -> updateConfigValue.applyAsInt(c, choice))
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean setterAdded = false;
|
||||
for (CommandArgumentData<?> commandArgumentData : commandArguments)
|
||||
{
|
||||
if (!commandArgumentData.argumentClass.isAssignableFrom(configEntry.getType()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
subcommand.then(argument("value", commandArgumentData.getArgumentType(configEntry))
|
||||
.executes(c -> updateConfigValue.applyAsInt(c, commandArgumentData.getValue(c, "value"))));
|
||||
|
||||
setterAdded = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!setterAdded)
|
||||
{
|
||||
throw new RuntimeException("Config type of " + type.getName() + " is not supported: " + configEntry.getType().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
builder.then(subcommand);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class CommandArgumentData<T>
|
||||
{
|
||||
public final Class<T> argumentClass;
|
||||
public final Function<ConfigEntry<T>, ArgumentType<T>> argumentTypeFunction;
|
||||
private final BiFunction<CommandContext<CommandSourceStack>, String, T> valueGetter;
|
||||
|
||||
public CommandArgumentData(Class<T> argumentClass, Supplier<ArgumentType<T>> argumentTypeSupplier, BiFunction<CommandContext<CommandSourceStack>, String, T> valueGetter)
|
||||
{
|
||||
this(argumentClass, configEntry -> argumentTypeSupplier.get(), valueGetter);
|
||||
}
|
||||
public CommandArgumentData(Class<T> argumentClass, Function<ConfigEntry<T>, ArgumentType<T>> argumentTypeFunction, BiFunction<CommandContext<CommandSourceStack>, String, T> valueGetter)
|
||||
{
|
||||
this.argumentClass = argumentClass;
|
||||
this.argumentTypeFunction = argumentTypeFunction;
|
||||
this.valueGetter = valueGetter;
|
||||
}
|
||||
|
||||
public ArgumentType<T> getArgumentType(ConfigEntry<T> configEntry)
|
||||
{
|
||||
return this.argumentTypeFunction.apply(configEntry);
|
||||
}
|
||||
|
||||
public T getValue(CommandContext<CommandSourceStack> commandContext, String argumentName)
|
||||
{
|
||||
return this.valueGetter.apply(commandContext, argumentName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commands;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.multiplayer.server.ServerPlayerState;
|
||||
import com.seibel.distanthorizons.core.network.messages.base.CodecCrashMessage;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
public class CrashCommand extends AbstractCommand
|
||||
{
|
||||
@Override
|
||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||
{
|
||||
return literal("crash")
|
||||
.requires(this::isPlayerSource)
|
||||
.then(literal("encode")
|
||||
.executes(c -> {
|
||||
assert SharedApi.tryGetDhServerWorld() != null;
|
||||
|
||||
ServerPlayerState serverPlayerState = SharedApi.tryGetDhServerWorld().getServerPlayerStateManager()
|
||||
.getConnectedPlayer(this.getSourcePlayer(c));
|
||||
if (serverPlayerState != null)
|
||||
{
|
||||
serverPlayerState.networkSession.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.ENCODE));
|
||||
}
|
||||
return 1;
|
||||
}))
|
||||
.then(literal("decode")
|
||||
.executes(c -> {
|
||||
assert SharedApi.tryGetDhServerWorld() != null;
|
||||
|
||||
ServerPlayerState serverPlayerState = SharedApi.tryGetDhServerWorld().getServerPlayerStateManager()
|
||||
.getConnectedPlayer(this.getSourcePlayer(c));
|
||||
if (serverPlayerState != null)
|
||||
{
|
||||
serverPlayerState.networkSession.sendMessage(new CodecCrashMessage(CodecCrashMessage.ECrashPhase.DECODE));
|
||||
}
|
||||
return 1;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commands;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
public class DebugCommand extends AbstractCommand
|
||||
{
|
||||
@Override
|
||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||
{
|
||||
return literal("debug")
|
||||
.executes(c -> {
|
||||
List<String> lines = new ArrayList<>();
|
||||
F3Screen.addStringToDisplay(lines);
|
||||
return this.sendSuccessResponse(c, String.join("\n", lines), false);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commands;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.generation.PregenManager;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.world.DhServerWorld;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.DimensionArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
|
||||
import net.minecraft.server.level.ColumnPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
|
||||
public class PregenCommand extends AbstractCommand
|
||||
{
|
||||
private PregenManager getPregenManager()
|
||||
{
|
||||
DhServerWorld world = (DhServerWorld) Objects.requireNonNull(SharedApi.getAbstractDhWorld());
|
||||
return world.getPregenManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LiteralArgumentBuilder<CommandSourceStack> buildCommand()
|
||||
{
|
||||
LiteralArgumentBuilder<CommandSourceStack> statusCommand = literal("status")
|
||||
.executes(this::pregenStatus);
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> startCommand = literal("start")
|
||||
.then(argument("dimension", DimensionArgument.dimension())
|
||||
.then(argument("origin", ColumnPosArgument.columnPos())
|
||||
.then(argument("chunkRadius", integer(32))
|
||||
.executes(this::pregenStart))));
|
||||
|
||||
LiteralArgumentBuilder<CommandSourceStack> stopCommand = literal("stop")
|
||||
.executes(this::pregenStop);
|
||||
|
||||
return literal("pregen")
|
||||
.then(statusCommand)
|
||||
.then(startCommand)
|
||||
.then(stopCommand);
|
||||
}
|
||||
|
||||
|
||||
private int pregenStatus(CommandContext<CommandSourceStack> c)
|
||||
{
|
||||
String statusString = this.getPregenManager().getStatusString();
|
||||
//noinspection ReplaceNullCheck
|
||||
if (statusString != null)
|
||||
{
|
||||
return this.sendSuccessResponse(c, statusString, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.sendSuccessResponse(c, "Pregen is not running", false);
|
||||
}
|
||||
}
|
||||
|
||||
private int pregenStart(CommandContext<CommandSourceStack> c) throws CommandSyntaxException
|
||||
{
|
||||
this.sendSuccessResponse(c, "Starting pregen. Progress will be in the server console.", true);
|
||||
|
||||
ServerLevel level = DimensionArgument.getDimension(c, "dimension");
|
||||
ColumnPos origin = ColumnPosArgument.getColumnPos(c, "origin");
|
||||
int chunkRadius = getInteger(c, "chunkRadius");
|
||||
|
||||
CompletableFuture<Void> future = this.getPregenManager().startPregen(
|
||||
ServerLevelWrapper.getWrapper(level),
|
||||
new DhBlockPos2D(#if MC_VER >= MC_1_19_2 origin.x(), origin.z() #else origin.x, origin.z #endif),
|
||||
chunkRadius
|
||||
);
|
||||
|
||||
future.whenComplete((result, throwable) -> {
|
||||
if (throwable instanceof CancellationException)
|
||||
{
|
||||
this.sendSuccessResponse(c, "Pregen is cancelled", true);
|
||||
return;
|
||||
}
|
||||
else if (throwable != null)
|
||||
{
|
||||
this.sendFailureResponse(c, "Pregen failed: " + throwable.getMessage() + "\n Check the logs for more details.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendSuccessResponse(c, "Pregen is complete", true);
|
||||
});
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private int pregenStop(CommandContext<CommandSourceStack> c)
|
||||
{
|
||||
CompletableFuture<Void> runningPregen = this.getPregenManager().getRunningPregen();
|
||||
if (runningPregen == null)
|
||||
{
|
||||
return this.sendFailureResponse(c, "Pregen is not running");
|
||||
}
|
||||
|
||||
runningPregen.cancel(true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commonMixins;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
|
||||
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
|
||||
import com.seibel.distanthorizons.core.jar.installer.ModrinthGetter;
|
||||
import com.seibel.distanthorizons.core.jar.updater.SelfUpdater;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screens.TitleScreen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DhUpdateScreenBase
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final Minecraft MC = Minecraft.getInstance();
|
||||
|
||||
|
||||
|
||||
public static void tryShowUpdateScreenAndRunAutoUpdateStartup(Runnable runnable)
|
||||
{
|
||||
// always needs to be called, otherwise auto update setup won't be completed
|
||||
boolean newUpdateAvailable = SelfUpdater.onStart();
|
||||
if (!newUpdateAvailable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.Client.Advanced.AutoUpdater.enableAutoUpdater.get())
|
||||
{
|
||||
LOGGER.info("Auto update disabled, ignoring new version...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
runnable = () ->
|
||||
{
|
||||
String versionId;
|
||||
EDhApiUpdateBranch updateBranch = EDhApiUpdateBranch.convertAutoToStableOrNightly(Config.Client.Advanced.AutoUpdater.updateBranch.get());
|
||||
if (updateBranch == EDhApiUpdateBranch.STABLE)
|
||||
{
|
||||
versionId = ModrinthGetter.getLatestIDForVersion(SingletonInjector.INSTANCE.get(IVersionConstants.class).getMinecraftVersion());
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList<com.electronwill.nightconfig.core.Config> pipelines = GitlabGetter.INSTANCE.projectPipelines;
|
||||
if (pipelines != null
|
||||
&& pipelines.size() > 0)
|
||||
{
|
||||
versionId = pipelines.get(0).get("sha");
|
||||
}
|
||||
else
|
||||
{
|
||||
versionId = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (versionId == null)
|
||||
{
|
||||
LOGGER.info("Unable to find new DH update for the ["+updateBranch+"] branch. Assuming DH is up to date...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
MC.setScreen(new UpdateModScreen(
|
||||
new TitleScreen(false),
|
||||
versionId
|
||||
));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// info instead of error since this can be ignored and probably just means
|
||||
// there isn't a new DH version available
|
||||
LOGGER.info("Unable to show DH update screen, reason: ["+e.getMessage()+"].");
|
||||
}
|
||||
};
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.commonMixins;
|
||||
|
||||
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
|
||||
import com.seibel.distanthorizons.core.api.internal.ServerApi;
|
||||
import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.pos.DhChunkPos;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
public class MixinChunkMapCommon
|
||||
{
|
||||
|
||||
public static void onChunkSave(ServerLevel level, ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
|
||||
{
|
||||
IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level);
|
||||
|
||||
int chunkPosX;
|
||||
int chunkPosZ;
|
||||
#if MC_VER <= MC_1_21_11
|
||||
chunkPosX = chunk.getPos().x;
|
||||
chunkPosZ = chunk.getPos().z;
|
||||
#else
|
||||
chunkPosX = chunk.getPos().x();
|
||||
chunkPosZ = chunk.getPos().z();
|
||||
#endif
|
||||
|
||||
// is this position already being updated?
|
||||
if (SharedApi.isChunkAtChunkPosAlreadyUpdating(levelWrapper, chunkPosX, chunkPosZ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// is this chunk being saved to disk?
|
||||
boolean savingChunkToDisk = ci.getReturnValue();
|
||||
// true means a chunk was saved to disk
|
||||
if (!savingChunkToDisk)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// corrupt/incomplete chunk validation //
|
||||
|
||||
// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
|
||||
// this logic should prevent that from happening
|
||||
#if MC_VER <= MC_1_17_1
|
||||
if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect() || chunk instanceof ProtoChunk)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// biome validation //
|
||||
|
||||
// some chunks may be missing their biomes, which cause issues when attempting to save them
|
||||
#if MC_VER <= MC_1_17_1
|
||||
if (chunk.getBiomes() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#else
|
||||
try
|
||||
{
|
||||
// this will throw an exception if the biomes aren't set up
|
||||
chunk.getNoiseBiome(0,0,0);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// submit the update event
|
||||
ServerApi.INSTANCE.serverChunkSaveEvent(
|
||||
new ChunkWrapper(chunk, levelWrapper),
|
||||
levelWrapper
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
-331
@@ -1,331 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDebugWireframeRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Handles rendering the wireframe particles
|
||||
* that are used for seeing what the system's doing.
|
||||
*/
|
||||
public class BlazeDebugWireframeRenderer extends AbstractDebugWireframeRenderer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
public static BlazeDebugWireframeRenderer INSTANCE = new BlazeDebugWireframeRenderer();
|
||||
|
||||
|
||||
|
||||
/** A box from 0,0,0 to 1,1,1 */
|
||||
private static final float[] BOX_VERTICES = {
|
||||
//region
|
||||
// Pos x y z
|
||||
0, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 1, 1,
|
||||
//endregion
|
||||
};
|
||||
|
||||
private static final int[] BOX_OUTLINE_INDICES = {
|
||||
//region
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
7, 4,
|
||||
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7,
|
||||
//endregion
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// rendering setup
|
||||
private boolean init = false;
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
|
||||
private GpuBuffer boxVertexBuffer;
|
||||
private GpuBuffer boxIndexBuffer;
|
||||
|
||||
private GpuBuffer uniformBuffer;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public BlazeDebugWireframeRenderer() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
this.createPipelines();
|
||||
this.createBuffers();
|
||||
|
||||
}
|
||||
private void createPipelines()
|
||||
{
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(true);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.WIREFRAME);
|
||||
pipelineBuilder.withName("debug_wireframe_renderer");
|
||||
|
||||
pipelineBuilder.withVertexShader("debug/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("debug/blaze/frag");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("uniformBlock");
|
||||
|
||||
|
||||
VertexFormat vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
|
||||
.build();
|
||||
pipelineBuilder.withVertexFormat(vertexFormat);
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.LINES);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
}
|
||||
private void createBuffers()
|
||||
{
|
||||
GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
|
||||
// box vertices
|
||||
ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES);
|
||||
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
boxVerticesBuffer.rewind();
|
||||
MemoryUtil.memFree(boxVerticesBuffer);
|
||||
|
||||
// upload vertex data
|
||||
{
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX;
|
||||
int size = BOX_VERTICES.length * Float.BYTES;
|
||||
this.boxVertexBuffer = GPU_DEVICE.createBuffer(() -> "distantHorizons:McDebugWireframeBox", usage, size);
|
||||
|
||||
{
|
||||
int length = BOX_VERTICES.length * Float.BYTES;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.boxVertexBuffer, /*offset*/ 0, length);
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
byteBuffer.rewind();
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, byteBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// box vertex indexes
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer.asIntBuffer().put(BOX_OUTLINE_INDICES);
|
||||
buffer.rewind();
|
||||
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX
|
||||
| GpuBuffer.USAGE_INDEX
|
||||
| GpuBuffer.USAGE_UNIFORM;
|
||||
this.boxIndexBuffer = GPU_DEVICE.createBuffer(() -> "DH Debug Index Buffer", usage, buffer.capacity());
|
||||
|
||||
int offset = 0;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.boxIndexBuffer, offset, buffer.capacity());
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void renderBox(Box box)
|
||||
{
|
||||
this.init();
|
||||
|
||||
//if (BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty()
|
||||
// || BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty())
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// shouldn't happen, but just in case
|
||||
if (box == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// delayed getters since this class may be initialized before
|
||||
// the GPU device has been set
|
||||
GpuDevice gpuDevice = RenderSystem.getDevice();
|
||||
CommandEncoder commandEncoder = gpuDevice.createCommandEncoder();
|
||||
|
||||
|
||||
|
||||
// uniforms
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putMat4f() // uTransform
|
||||
.putVec4() // uColor
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
||||
Vec3f camPosFloatThisFrame = new Vec3f((float) camPos.x, (float) camPos.y, (float) camPos.z);
|
||||
|
||||
Mat4f boxTransform = Mat4f.createTranslateMatrix(
|
||||
box.minPos.x - camPosFloatThisFrame.x,
|
||||
box.minPos.y - camPosFloatThisFrame.y,
|
||||
box.minPos.z - camPosFloatThisFrame.z);
|
||||
boxTransform.multiply(Mat4f.createScaleMatrix(
|
||||
box.maxPos.x - box.minPos.x,
|
||||
box.maxPos.y - box.minPos.y,
|
||||
box.maxPos.z - box.minPos.z));
|
||||
|
||||
Mat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy();
|
||||
transformMatrix.multiply(boxTransform);
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putMat4f(transformMatrix.createJomlMatrix()) // uTransform
|
||||
.putVec4(
|
||||
box.color.getRed() / 255.0f,
|
||||
box.color.getGreen() / 255.0f,
|
||||
box.color.getBlue() / 255.0f,
|
||||
box.color.getAlpha() / 255.0f) // uColor
|
||||
.get()
|
||||
;
|
||||
|
||||
this.uniformBuffer = BlazeUniformUtil.createBuffer("uniformBlock", uniformBufferSize, this.uniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.uniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
commandEncoder.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// render //
|
||||
|
||||
//try (RenderPass renderPass = commandEncoder.createRenderPass(
|
||||
// this::getRenderPassName,
|
||||
// BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
|
||||
// /*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
// BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
|
||||
// /*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
//{
|
||||
// // Bind instance data //
|
||||
// renderPass.setUniform("uniformBlock", this.uniformBuffer);
|
||||
//
|
||||
// renderPass.setPipeline(this.pipeline);
|
||||
// renderPass.setIndexBuffer(this.boxIndexBuffer, VertexFormat.IndexType.INT);
|
||||
//
|
||||
// renderPass.setVertexBuffer(0, this.boxVertexBuffer);
|
||||
//
|
||||
// renderPass.drawIndexed(
|
||||
// /*indexStart*/ 0,
|
||||
// /*firstIndex*/0,
|
||||
// /*indexCount*/BOX_OUTLINE_INDICES.length,
|
||||
// /*instanceCount*/1);
|
||||
//}
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:McDebugRenderer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-624
@@ -1,624 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhGenericObjectRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericObjectRenderEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderCleanupEvent;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeGenericRenderSetupEvent;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Handles rendering generic groups of {@link DhApiRenderableBox}.
|
||||
*
|
||||
* @see IDhApiCustomRenderRegister
|
||||
* @see DhApiRenderableBox
|
||||
*/
|
||||
public class BlazeDhGenericObjectRenderer implements IDhGenericRenderer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded();
|
||||
|
||||
/**
|
||||
* Can be used to troubleshoot the renderer.
|
||||
* If enabled several debug objects will render around (0,150,0).
|
||||
*/
|
||||
public static final boolean RENDER_DEBUG_OBJECTS = false;
|
||||
|
||||
private final ConcurrentHashMap<Long, RenderableBoxGroup> boxGroupById = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
// rendering setup
|
||||
private boolean init = false;
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
|
||||
private GpuBuffer vertUniformBuffer;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public BlazeDhGenericObjectRenderer() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
this.createPipelines();
|
||||
|
||||
if (RENDER_DEBUG_OBJECTS)
|
||||
{
|
||||
this.addGenericDebugObjects();
|
||||
}
|
||||
}
|
||||
private void createPipelines()
|
||||
{
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(true);
|
||||
pipelineBuilder.withDepthWrite(true);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
|
||||
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT); // TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("generic_objects");
|
||||
|
||||
pipelineBuilder.withVertexShader("generic/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("generic/blaze/frag");
|
||||
|
||||
pipelineBuilder.withSampler("uLightMap");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("vertUniformBlock");
|
||||
|
||||
VertexFormat vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", BlazeDhVertexFormatUtil.FLOAT_XYZ_POS)
|
||||
.add("aColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
|
||||
.add("aMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
|
||||
|
||||
.add("paddingOne", BlazeDhVertexFormatUtil.BYTE_PAD)
|
||||
.add("paddingTwo", BlazeDhVertexFormatUtil.BYTE_PAD)
|
||||
.add("paddingThree", BlazeDhVertexFormatUtil.BYTE_PAD)
|
||||
.build();
|
||||
pipelineBuilder.withVertexFormat(vertexFormat);
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLES);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
}
|
||||
private void addGenericDebugObjects()
|
||||
{
|
||||
GenericRenderObjectFactory factory = GenericRenderObjectFactory.INSTANCE;
|
||||
|
||||
|
||||
// single giant box
|
||||
IDhApiRenderableBoxGroup singleGiantBoxGroup = factory.createForSingleBox(
|
||||
ModInfo.NAME + ":CyanChunkBox",
|
||||
new DhApiRenderableBox(
|
||||
new DhApiVec3d(0,0,0), new DhApiVec3d(16,190,16),
|
||||
new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 125),
|
||||
EDhApiBlockMaterial.WATER)
|
||||
);
|
||||
singleGiantBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
singleGiantBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.add(singleGiantBoxGroup);
|
||||
|
||||
|
||||
// single slender box
|
||||
IDhApiRenderableBoxGroup singleTallBoxGroup = factory.createForSingleBox(
|
||||
ModInfo.NAME + ":GreenBeacon",
|
||||
new DhApiRenderableBox(
|
||||
new DhApiVec3d(16,0,31), new DhApiVec3d(17,2000,32),
|
||||
new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 125),
|
||||
EDhApiBlockMaterial.ILLUMINATED)
|
||||
);
|
||||
singleTallBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
singleTallBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.add(singleTallBoxGroup);
|
||||
|
||||
|
||||
// absolute box group
|
||||
ArrayList<DhApiRenderableBox> absBoxList = new ArrayList<>();
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
absBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(i,150+i,24), new DhApiVec3d(1+i,151+i,25),
|
||||
new Color(Color.ORANGE.getRed(), Color.ORANGE.getGreen(), Color.ORANGE.getBlue()),
|
||||
EDhApiBlockMaterial.LAVA
|
||||
)
|
||||
);
|
||||
}
|
||||
IDhApiRenderableBoxGroup absolutePosBoxGroup = factory.createAbsolutePositionedGroup(ModInfo.NAME + ":OrangeStairs", absBoxList);
|
||||
this.add(absolutePosBoxGroup);
|
||||
|
||||
|
||||
// relative box group
|
||||
ArrayList<DhApiRenderableBox> relBoxList = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i+=2)
|
||||
{
|
||||
relBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(0,i,0), new DhApiVec3d(1,1+i,1),
|
||||
new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue()),
|
||||
EDhApiBlockMaterial.METAL
|
||||
)
|
||||
);
|
||||
}
|
||||
IDhApiRenderableBoxGroup relativePosBoxGroup = factory.createRelativePositionedGroup(
|
||||
ModInfo.NAME + ":MovingMagentaGroup",
|
||||
new DhApiVec3d(24, 140, 24),
|
||||
relBoxList);
|
||||
relativePosBoxGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
DhApiVec3d pos = relativePosBoxGroup.getOriginBlockPos();
|
||||
pos.x += event.partialTicks / 2;
|
||||
pos.x %= 32;
|
||||
relativePosBoxGroup.setOriginBlockPos(pos);
|
||||
});
|
||||
this.add(relativePosBoxGroup);
|
||||
|
||||
|
||||
// massive relative box group
|
||||
ArrayList<DhApiRenderableBox> massRelBoxList = new ArrayList<>();
|
||||
for (int x = 0; x < 50*2; x+=2)
|
||||
{
|
||||
for (int z = 0; z < 50*2; z+=2)
|
||||
{
|
||||
massRelBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(-x, 0, -z), new DhApiVec3d(1-x, 1, 1-z),
|
||||
new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue()),
|
||||
EDhApiBlockMaterial.TERRACOTTA
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
IDhApiRenderableBoxGroup massRelativePosBoxGroup = factory.createRelativePositionedGroup(
|
||||
ModInfo.NAME + ":MassRedGroup",
|
||||
new DhApiVec3d(-25, 140, 0),
|
||||
massRelBoxList);
|
||||
massRelativePosBoxGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
DhApiVec3d blockPos = massRelativePosBoxGroup.getOriginBlockPos();
|
||||
blockPos.y += event.partialTicks / 4;
|
||||
if (blockPos.y > 150f)
|
||||
{
|
||||
blockPos.y = 140f;
|
||||
|
||||
Color newColor = (massRelativePosBoxGroup.get(0).color == Color.RED) ? Color.RED.darker() : Color.RED;
|
||||
massRelativePosBoxGroup.forEach((box) -> { box.color = newColor; });
|
||||
massRelativePosBoxGroup.triggerBoxChange();
|
||||
}
|
||||
|
||||
massRelativePosBoxGroup.setOriginBlockPos(blockPos);
|
||||
});
|
||||
this.add(massRelativePosBoxGroup);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// registration //
|
||||
//==============//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void add(IDhApiRenderableBoxGroup iBoxGroup) throws IllegalArgumentException
|
||||
{
|
||||
if (!(iBoxGroup instanceof RenderableBoxGroup))
|
||||
{
|
||||
throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"].");
|
||||
}
|
||||
RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup;
|
||||
if (boxGroup.size() != 0)
|
||||
{
|
||||
// trigger a box change to make sure the initial data is uploaded
|
||||
boxGroup.triggerBoxChange();
|
||||
}
|
||||
|
||||
long id = boxGroup.getId();
|
||||
if (this.boxGroupById.containsKey(id))
|
||||
{
|
||||
throw new IllegalArgumentException("A box group with the ID [" + id + "] is already present.");
|
||||
}
|
||||
|
||||
this.boxGroupById.put(id, boxGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup remove(long id) { return this.boxGroupById.remove(id); }
|
||||
|
||||
public void clear() { this.boxGroupById.clear(); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
/**
|
||||
* @param renderingWithSsao
|
||||
* if true that means this render call is happening before the SSAO pass
|
||||
* and any objects rendered in this pass will have SSAO applied to them.
|
||||
*/
|
||||
@Override
|
||||
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
|
||||
{
|
||||
//==============//
|
||||
// render setup //
|
||||
//==============//
|
||||
//#region
|
||||
|
||||
profiler.push("setup");
|
||||
|
||||
this.init();
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
||||
|
||||
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
||||
|
||||
//#endregion
|
||||
|
||||
if (BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty()
|
||||
|| BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//#region
|
||||
|
||||
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
||||
for (RenderableBoxGroup boxGroup : boxList)
|
||||
{
|
||||
// validation //
|
||||
|
||||
// shouldn't happen, but just in case
|
||||
if (boxGroup == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip boxes that shouldn't render this pass
|
||||
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
profiler.popPush("render prep");
|
||||
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
||||
|
||||
// ignore inactive groups
|
||||
if (!boxGroup.active)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// allow API users to cancel this object's rendering
|
||||
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
||||
if (cancelRendering)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// update instanced data if needed
|
||||
{
|
||||
boxGroup.tryUpdateInstancedDataAsync();
|
||||
|
||||
// skip groups that haven't been uploaded yet
|
||||
if (boxGroup.vertexBufferContainer.getState() != IDhGenericObjectVertexBufferContainer.EState.RENDER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
||||
if (shading == null)
|
||||
{
|
||||
shading = DEFAULT_SHADING;
|
||||
}
|
||||
|
||||
// uniforms
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putIVec3() // uOffsetChunk
|
||||
.putVec3() // uOffsetSubChunk
|
||||
.putIVec3() // uCameraPosChunk
|
||||
.putVec3() // uCameraPosSubChunk
|
||||
|
||||
.putVec3() // aTranslateChunk
|
||||
.putVec3() // aTranslateSubChunk
|
||||
|
||||
.putMat4f() // uProjectionMvm
|
||||
.putInt() // uSkyLight
|
||||
.putInt() // uBlockLight
|
||||
|
||||
.putFloat() // uNorthShading
|
||||
.putFloat() // uSouthShading
|
||||
.putFloat() // uEastShading
|
||||
.putFloat() // uWestShading
|
||||
.putFloat() // uTopShading
|
||||
.putFloat() // uBottomShading
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
Mat4f projectionMvmMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||
projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putIVec3(
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
) // uOffsetChunk
|
||||
.putVec3(
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
) // uOffsetSubChunk
|
||||
.putIVec3(
|
||||
LodUtil.getChunkPosFromDouble(camPos.x),
|
||||
LodUtil.getChunkPosFromDouble(camPos.y),
|
||||
LodUtil.getChunkPosFromDouble(camPos.z)
|
||||
) // uCameraPosChunk
|
||||
.putVec3(
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.x),
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.y),
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.z)
|
||||
) // uCameraPosSubChunk
|
||||
|
||||
.putMat4f(projectionMvmMatrix.createJomlMatrix()) // uProjectionMvm
|
||||
.putInt(boxGroup.getSkyLight()) // uSkyLight
|
||||
.putInt(boxGroup.getBlockLight()) // uBlockLight
|
||||
|
||||
.putFloat(shading.north)
|
||||
.putFloat(shading.south)
|
||||
.putFloat(shading.east)
|
||||
.putFloat(shading.west)
|
||||
.putFloat(shading.top)
|
||||
.putFloat(shading.bottom)
|
||||
|
||||
.get()
|
||||
;
|
||||
|
||||
this.vertUniformBuffer = BlazeUniformUtil.createBuffer("vertUniformBlock", uniformBufferSize, this.vertUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// render //
|
||||
|
||||
profiler.popPush("rendering");
|
||||
profiler.push(boxGroup.getResourceLocationNamespace());
|
||||
profiler.push(boxGroup.getResourceLocationPath());
|
||||
|
||||
this.renderBoxGroupInstanced(renderEventParam, boxGroup, profiler);
|
||||
|
||||
profiler.pop(); // resource path
|
||||
profiler.pop(); // resource namespace
|
||||
|
||||
boxGroup.postRender(renderEventParam);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// clean up //
|
||||
//==========//
|
||||
//region
|
||||
|
||||
profiler.popPush("cleanup");
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
||||
|
||||
profiler.pop();
|
||||
|
||||
//endregion
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:McGenericObjectRenderer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=====================//
|
||||
// instanced rendering //
|
||||
//=====================//
|
||||
//region
|
||||
|
||||
private void renderBoxGroupInstanced(
|
||||
RenderParams renderEventParam,
|
||||
RenderableBoxGroup boxGroup,
|
||||
IProfilerWrapper profiler)
|
||||
{
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
|
||||
// update instance data //
|
||||
|
||||
profiler.push("vertex setup");
|
||||
|
||||
BlazeGenericObjectVertexContainer container = (BlazeGenericObjectVertexContainer) boxGroup.vertexBufferContainer;
|
||||
|
||||
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
||||
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
|
||||
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
|
||||
|
||||
|
||||
|
||||
// Bind instance data //
|
||||
profiler.popPush("binding");
|
||||
|
||||
|
||||
renderPass.setUniform("vertUniformBlock", this.vertUniformBuffer);
|
||||
|
||||
// set pipeline
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
renderPass.setIndexBuffer(container.indexGpuBuffer, VertexFormat.IndexType.INT);
|
||||
|
||||
renderPass.setVertexBuffer(0, container.vboGpuBuffer);
|
||||
|
||||
// Draw instanced
|
||||
profiler.popPush("render");
|
||||
if (container.uploadedBoxCount > 0)
|
||||
{
|
||||
renderPass.drawIndexed(
|
||||
/*indexStart*/ 0,
|
||||
/*firstIndex*/0,
|
||||
/*indexCount*/container.uploadedBoxCount * 36, // 36 = 6 faces * 6 verticies per face
|
||||
/*instanceCount*/1);
|
||||
|
||||
}
|
||||
}
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// F3 menu //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public String getVboRenderDebugMenuString()
|
||||
{
|
||||
// get counts
|
||||
int totalGroupCount = this.boxGroupById.size();
|
||||
int totalBoxCount = 0;
|
||||
|
||||
int activeGroupCount = 0;
|
||||
int activeBoxCount = 0;
|
||||
|
||||
for (long key : this.boxGroupById.keySet())
|
||||
{
|
||||
RenderableBoxGroup renderGroup = this.boxGroupById.get(key);
|
||||
if (renderGroup.active)
|
||||
{
|
||||
activeGroupCount++;
|
||||
activeBoxCount += renderGroup.size();
|
||||
}
|
||||
totalBoxCount += renderGroup.size();
|
||||
}
|
||||
|
||||
|
||||
return "Generic Obj #: " + F3Screen.NUMBER_FORMAT.format(activeGroupCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalGroupCount) + ", " +
|
||||
"Cube #: " + F3Screen.NUMBER_FORMAT.format(activeBoxCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalBoxCount);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhMetaRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.textures.GpuTexture;
|
||||
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class BlazeDhMetaRenderer implements IDhMetaRenderer
|
||||
{
|
||||
public static final BlazeDhMetaRenderer INSTANCE = new BlazeDhMetaRenderer();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
|
||||
private BlazeDhApplyRenderer applyRenderer;
|
||||
|
||||
public final BlazeTextureWrapper dhDepthTextureWrapper = BlazeTextureWrapper.createDepth("DhDepthTexture");
|
||||
public final BlazeTextureWrapper dhColorTextureWrapper = BlazeTextureWrapper.createColor("DhColorTexture");
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhMetaRenderer()
|
||||
{
|
||||
this.applyRenderer = new BlazeDhApplyRenderer(
|
||||
"dh_apply_to_mc",
|
||||
null,
|
||||
"apply/blaze/vert", "apply/blaze/frag"
|
||||
);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// pre/post render //
|
||||
//=================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void runRenderPassSetup(RenderParams renderParams)
|
||||
{
|
||||
// textures
|
||||
this.dhDepthTextureWrapper.tryCreateOrResize();
|
||||
this.dhColorTextureWrapper.tryCreateOrResize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runRenderPassCleanup(RenderParams renderParams) {}
|
||||
|
||||
@Override
|
||||
public void applyToMcTexture(RenderParams renderParams)
|
||||
{
|
||||
GpuTexture mcColorTexture = Minecraft.getInstance().getMainRenderTarget().getColorTexture();
|
||||
this.applyRenderer.render(this.dhColorTextureWrapper.texture, this.dhDepthTextureWrapper.texture, mcColorTexture);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// clear textures //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void clearDhDepthAndColorTextures(RenderParams renderParams)
|
||||
{
|
||||
this.dhDepthTextureWrapper.clearDepth(1.0f);
|
||||
|
||||
Color color = MC_RENDER.getSkyColor();
|
||||
this.dhColorTextureWrapper.clearColor(ColorUtil.toColorInt(color));
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhRenderApiDefinition {}
|
||||
|
||||
#else
|
||||
|
||||
import com.seibel.distanthorizons.common.render.blaze.objects.BlazeGenericObjectVertexContainer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhFarFadeRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhFogRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeDhSsaoRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.postProcessing.BlazeVanillaFadeRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.test.BlazeDhTestTriangleRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper;
|
||||
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*;
|
||||
|
||||
public class BlazeDhRenderApiDefinition extends AbstractDhRenderApiDefinition
|
||||
{
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public String getApiName() { return "Blaze3D"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// singletons //
|
||||
//============//
|
||||
//region
|
||||
|
||||
@Override public IDhMetaRenderer getMetaRenderer() { return BlazeDhMetaRenderer.INSTANCE; }
|
||||
@Override public IDhTerrainRenderer getTerrainRenderer() { return BlazeDhTerrainRenderer.INSTANCE; }
|
||||
@Override public IDhSsaoRenderer getSsaoRenderer() { return BlazeDhSsaoRenderer.INSTANCE; }
|
||||
@Override public IDhFogRenderer getFogRenderer() { return BlazeDhFogRenderer.INSTANCE; }
|
||||
@Override public IDhFarFadeRenderer getFarFadeRenderer() { return BlazeDhFarFadeRenderer.INSTANCE; }
|
||||
@Override public AbstractDebugWireframeRenderer getDebugWireframeRenderer() { return BlazeDebugWireframeRenderer.INSTANCE; }
|
||||
|
||||
@Override public IDhVanillaFadeRenderer getVanillaFadeRenderer() { return BlazeVanillaFadeRenderer.INSTANCE; }
|
||||
@Override public IDhTestTriangleRenderer getTestTriangleRenderer() { return BlazeDhTestTriangleRenderer.INSTANCE; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// factories //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
@Override public IDhGenericRenderer createGenericRenderer() { return new BlazeDhGenericObjectRenderer(); }
|
||||
|
||||
@Override public IVertexBufferWrapper createVboWrapper(String name) { return new BlazeVertexBufferWrapper(name); }
|
||||
@Override public ILodContainerUniformBufferWrapper createLodContainerUniformWrapper() { return new BlazeLodUniformBufferWrapper(); }
|
||||
@Override public IDhGenericObjectVertexBufferContainer createGenericVboContainer() { return new BlazeGenericObjectVertexContainer(); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-367
@@ -1,367 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhTerrainRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiBeforeBufferRenderEvent;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.uniform.BlazeLodUniformBufferWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.buffer.BlazeVertexBufferWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/** Renders rendering DH's LOD terrain. */
|
||||
public class BlazeDhTerrainRenderer implements IDhTerrainRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeDhTerrainRenderer INSTANCE = new BlazeDhTerrainRenderer();
|
||||
|
||||
|
||||
private RenderPipeline opaquePipeline;
|
||||
private RenderPipeline transparentPipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
private GpuBuffer vertSharedUniformBuffer;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhTerrainRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(true);
|
||||
pipelineBuilder.withDepthWrite(true);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.LESS);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("terrain");
|
||||
|
||||
pipelineBuilder.withSampler("uLightMap");
|
||||
|
||||
pipelineBuilder.withVertexShader("lod/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("lod/blaze/frag");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("vertUniqueUniformBlock");
|
||||
pipelineBuilder.withUniformBuffer("vertSharedUniformBlock");
|
||||
pipelineBuilder.withUniformBuffer("fragUniformBlock");
|
||||
|
||||
VertexFormat vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", BlazeDhVertexFormatUtil.SHORT_XYZ_POS)
|
||||
.add("meta", BlazeDhVertexFormatUtil.META)
|
||||
.add("vColor", BlazeDhVertexFormatUtil.RGBA_UBYTE_COLOR)
|
||||
.add("irisMaterial", BlazeDhVertexFormatUtil.IRIS_MATERIAL)
|
||||
.add("irisNormal", BlazeDhVertexFormatUtil.IRIS_NORMAL)
|
||||
.add("paddingTwo", BlazeDhVertexFormatUtil.BYTE_PAD)
|
||||
.add("paddingThree", BlazeDhVertexFormatUtil.BYTE_PAD) // padding is to make sure the format is a multiple of 4
|
||||
.build();
|
||||
pipelineBuilder.withVertexFormat(vertexFormat);
|
||||
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLES);
|
||||
}
|
||||
|
||||
// opaque
|
||||
{
|
||||
pipelineBuilder.withoutBlend();
|
||||
this.opaquePipeline = pipelineBuilder.build();
|
||||
}
|
||||
|
||||
// transparent
|
||||
{
|
||||
// TRANSLUCENT = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
pipelineBuilder.withBlend(BlendFunction.TRANSLUCENT);
|
||||
this.transparentPipeline = pipelineBuilder.build();
|
||||
}
|
||||
|
||||
this.init = true;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
RenderParams renderEventParam,
|
||||
boolean opaquePass,
|
||||
SortedArraySet<LodBufferContainer> bufferContainers,
|
||||
IProfilerWrapper profiler)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
|
||||
profiler.push("vert unique uniforms");
|
||||
{
|
||||
// create data //
|
||||
|
||||
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
|
||||
{
|
||||
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
|
||||
bufferContainer.uniformContainer.tryUpload();
|
||||
}
|
||||
}
|
||||
|
||||
profiler.popPush("vert share uniforms");
|
||||
{
|
||||
Mat4f combinedMatrix = new Mat4f(renderEventParam.dhProjectionMatrix);
|
||||
combinedMatrix.multiply(renderEventParam.dhModelViewMatrix);
|
||||
|
||||
float earthCurveRatio = Config.Client.Advanced.Graphics.Experimental.earthCurveRatio.get();
|
||||
if (earthCurveRatio < -1.0f || earthCurveRatio > 1.0f)
|
||||
{
|
||||
earthCurveRatio = /*6371KM*/ 6371000.0f / earthCurveRatio;
|
||||
}
|
||||
else
|
||||
{
|
||||
// disable curvature if the config value is between -1 and 1
|
||||
earthCurveRatio = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putInt() // uIsWhiteWorld
|
||||
|
||||
.putFloat() // uWorldYOffset
|
||||
.putFloat() // uMircoOffset
|
||||
.putFloat() // uEarthRadius
|
||||
|
||||
.putVec3() // uCameraPos
|
||||
.putMat4f() // uCombinedMatrix
|
||||
.get();
|
||||
|
||||
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
Std140Builder.intoBuffer(buffer)
|
||||
.putInt(0) // uIsWhiteWorld
|
||||
|
||||
.putFloat((float) renderEventParam.worldYOffset) // uWorldYOffset
|
||||
.putFloat(0.01f) // uMircoOffset // 0.01 block offset
|
||||
.putFloat(earthCurveRatio) // uEarthRadius
|
||||
|
||||
.putVec3(
|
||||
(float)renderEventParam.exactCameraPosition.x,
|
||||
(float)renderEventParam.exactCameraPosition.y,
|
||||
(float)renderEventParam.exactCameraPosition.z) // uCameraPos
|
||||
.putMat4f(combinedMatrix.createJomlMatrix()) // uCombinedMatrix
|
||||
.get();
|
||||
|
||||
this.vertSharedUniformBuffer = BlazeUniformUtil.createBuffer("vertSharedUniformBlock", uniformBufferSize, this.vertSharedUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertSharedUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
|
||||
MemoryUtil.memFree(buffer);
|
||||
}
|
||||
|
||||
profiler.popPush("set frag uniforms");
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putFloat() // uClipDistance
|
||||
.putFloat() // uNoiseIntensity
|
||||
.putInt() // uNoiseSteps
|
||||
.putInt() // uNoiseDropoff
|
||||
.putInt() // uDitherDhRendering
|
||||
.putInt() // uNoiseEnabled
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks();
|
||||
if (!Config.Client.Advanced.Debugging.lodOnlyMode.get())
|
||||
{
|
||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||
dhNearClipDistance += 16f;
|
||||
}
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = MemoryUtil.memAlloc(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putFloat(dhNearClipDistance) // uClipDistance
|
||||
.putFloat(Config.Client.Advanced.Graphics.NoiseTexture.noiseIntensity.get()) // uNoiseIntensity
|
||||
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseSteps.get()) // uNoiseSteps
|
||||
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.noiseDropoff.get()) // uNoiseDropoff
|
||||
.putInt(Config.Client.Advanced.Graphics.Quality.ditherDhFade.get() ? 1 : 0) // uDitherDhRendering
|
||||
.putInt(Config.Client.Advanced.Graphics.NoiseTexture.enableNoiseTexture.get() ? 1 : 0) // uNoiseEnabled
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
MemoryUtil.memFree(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// render pass setup
|
||||
{
|
||||
profiler.popPush("setup");
|
||||
|
||||
// create a render pass
|
||||
try(RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty())
|
||||
)
|
||||
{
|
||||
LightMapWrapper lightMapWrapper = (LightMapWrapper) renderEventParam.lightmap;
|
||||
BlazeTextureViewWrapper lightmapTextureViewWrapper = lightMapWrapper.getTextureViewWrapper();
|
||||
renderPass.bindTexture("uLightMap", lightmapTextureViewWrapper.textureView, lightmapTextureViewWrapper.textureSampler);
|
||||
|
||||
// set pipeline
|
||||
renderPass.setPipeline(opaquePass ? this.opaquePipeline : this.transparentPipeline);
|
||||
|
||||
// shared uniforms
|
||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||
renderPass.setUniform("vertSharedUniformBlock", this.vertSharedUniformBuffer);
|
||||
|
||||
|
||||
|
||||
for (int lodIndex = 0; lodIndex < bufferContainers.size(); lodIndex++)
|
||||
{
|
||||
profiler.popPush("binding");
|
||||
|
||||
LodBufferContainer bufferContainer = bufferContainers.get(lodIndex);
|
||||
BlazeLodUniformBufferWrapper uniformWrapper = (BlazeLodUniformBufferWrapper)bufferContainer.uniformContainer;
|
||||
|
||||
boolean columnBuilderDebugEnabled = Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugEnable.get();
|
||||
if (columnBuilderDebugEnabled)
|
||||
{
|
||||
if (DhSectionPos.getDetailLevel(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugDetailLevel.get()
|
||||
&& DhSectionPos.getX(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugXPos.get()
|
||||
&& DhSectionPos.getZ(bufferContainer.pos) == Config.Client.Advanced.Debugging.ColumnBuilderDebugging.columnBuilderDebugZPos.get())
|
||||
{
|
||||
int breakpoint = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
renderPass.setUniform("vertUniqueUniformBlock", uniformWrapper.gpuBuffer);
|
||||
|
||||
|
||||
|
||||
profiler.popPush("rendering");
|
||||
|
||||
// render each buffer
|
||||
IVertexBufferWrapper[] bufferWrapperList = opaquePass ? bufferContainer.vboOpaqueWrappers : bufferContainer.vboTransparentWrappers;
|
||||
for (int i = 0; i < bufferWrapperList.length; i++)
|
||||
{
|
||||
BlazeVertexBufferWrapper bufferWrapper = (BlazeVertexBufferWrapper) bufferWrapperList[i];
|
||||
if (!bufferWrapper.uploaded
|
||||
|| bufferWrapper.vertexCount == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// fire render event
|
||||
{
|
||||
Vec3d camPos = renderEventParam.exactCameraPosition;
|
||||
Vec3f modelPos = new Vec3f(
|
||||
(float) (bufferContainer.minCornerBlockPos.getX() - camPos.x),
|
||||
(float) (bufferContainer.minCornerBlockPos.getY() - camPos.y),
|
||||
(float) (bufferContainer.minCornerBlockPos.getZ() - camPos.z));
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeBufferRenderEvent.class, new DhApiBeforeBufferRenderEvent.EventParam(renderEventParam, modelPos));
|
||||
}
|
||||
|
||||
renderPass.setIndexBuffer(bufferWrapper.getIndexGpuBuffer(), VertexFormat.IndexType.INT);
|
||||
renderPass.setVertexBuffer(0, bufferWrapper.vertexGpuBuffer); // vertex buffer can only be "0" lol
|
||||
|
||||
if (!bufferWrapper.vertexGpuBuffer.isClosed())
|
||||
{
|
||||
renderPass.drawIndexed(
|
||||
/*indexStart*/ 0,
|
||||
/*firstIndex*/0,
|
||||
/*indexCount*/bufferWrapper.indexCount,
|
||||
/*instanceCount*/1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
}
|
||||
private String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
|
||||
private String getRenderPassName() { return "distantHorizons:McLodRenderer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-270
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.apply;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhApplyRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Copies the given color texture
|
||||
* where the depth (or another attribute) is valid.
|
||||
* Often used to apply post processing effects or
|
||||
* the DH texture to MC's color texture. <br><br>
|
||||
*
|
||||
* @see BlazeDhCopyRenderer
|
||||
*/
|
||||
public class BlazeDhApplyRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
|
||||
protected GpuBuffer vboGpuBuffer;
|
||||
|
||||
protected final String name;
|
||||
protected final String identifierName;
|
||||
public String getIdentifierName() { return this.identifierName; }
|
||||
|
||||
@Nullable
|
||||
private final BlendFunction blendFunction;
|
||||
private final String vertexShaderPath;
|
||||
private final String fragmentShaderPath;
|
||||
|
||||
private final BlazeTextureViewWrapper sourceColorTextureViewWrapper = new BlazeTextureViewWrapper();
|
||||
private final BlazeTextureViewWrapper sourceDepthTextureViewWrapper = new BlazeTextureViewWrapper();
|
||||
|
||||
private final BlazeTextureViewWrapper destinationColorTextureViewWrapper = new BlazeTextureViewWrapper();
|
||||
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
|
||||
private final BlazeTextureWrapper dummyDepthTextureWrapper = BlazeTextureWrapper.createDepth("apply_dummy_depth");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Can be set for special application shaders that need
|
||||
* extra information. <br><br>
|
||||
*
|
||||
* will be an empty array if unneeded
|
||||
*/
|
||||
private final String[] uniformNames;
|
||||
/** will be an empty array if unneeded */
|
||||
private final GpuBuffer[] uniformBuffers;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
public BlazeDhApplyRenderer(
|
||||
String name,
|
||||
@Nullable BlendFunction blendFunction,
|
||||
String vertexShaderPath, String fragmentShaderPath
|
||||
)
|
||||
{
|
||||
this(
|
||||
name,
|
||||
blendFunction,
|
||||
vertexShaderPath, fragmentShaderPath,
|
||||
new String[0] // no extra uniforms
|
||||
);
|
||||
}
|
||||
public BlazeDhApplyRenderer(
|
||||
String name,
|
||||
@Nullable BlendFunction blendFunction,
|
||||
String vertexShaderPath, String fragmentShaderPath,
|
||||
String[] uniformNames
|
||||
)
|
||||
{
|
||||
this.name = name;
|
||||
this.identifierName = "distanthorizons:"+this.name;
|
||||
this.blendFunction = blendFunction;
|
||||
|
||||
this.vertexShaderPath = vertexShaderPath;
|
||||
this.fragmentShaderPath = fragmentShaderPath;
|
||||
|
||||
this.uniformNames = uniformNames;
|
||||
this.uniformBuffers = new GpuBuffer[this.uniformNames.length];
|
||||
}
|
||||
|
||||
private void tryInit(
|
||||
GpuTexture sourceColorTexture,
|
||||
GpuTexture sourceDepthTexture,
|
||||
GpuTexture destinationColorTexture)
|
||||
{
|
||||
// one-time setup
|
||||
if (this.pipeline == null)
|
||||
{
|
||||
this.createPipeline();
|
||||
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData(this.name);
|
||||
}
|
||||
|
||||
this.sourceColorTextureViewWrapper.tryWrap(sourceColorTexture);
|
||||
this.sourceDepthTextureViewWrapper.tryWrap(sourceDepthTexture);
|
||||
|
||||
this.destinationColorTextureViewWrapper.tryWrap(destinationColorTexture);
|
||||
|
||||
}
|
||||
private void createPipeline()
|
||||
{
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
|
||||
if (this.blendFunction != null)
|
||||
{
|
||||
pipelineBuilder.withBlend(this.blendFunction);
|
||||
}
|
||||
else
|
||||
{
|
||||
pipelineBuilder.withoutBlend();
|
||||
}
|
||||
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName(this.name);
|
||||
|
||||
pipelineBuilder.withVertexShader(this.vertexShaderPath);
|
||||
pipelineBuilder.withFragmentShader(this.fragmentShaderPath);
|
||||
|
||||
for (int i = 0; i < this.uniformNames.length; i++)
|
||||
{
|
||||
String uniformName = this.uniformNames[i];
|
||||
pipelineBuilder.withUniformBuffer(uniformName);
|
||||
}
|
||||
|
||||
pipelineBuilder.withSampler("uSourceColorTexture");
|
||||
pipelineBuilder.withSampler("uSourceDepthTexture");
|
||||
|
||||
VertexFormat vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
|
||||
.build();
|
||||
pipelineBuilder.withVertexFormat(vertexFormat);
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
public void setUniform(String uniformName, GpuBuffer uniformBuffer)
|
||||
{
|
||||
// the uniform array should be short enough (less than 10 items)
|
||||
// where a sequential search should be plenty fast
|
||||
for (int i = 0; i < this.uniformNames.length; i++)
|
||||
{
|
||||
String nameAtIndex = this.uniformNames[i];
|
||||
if (nameAtIndex.equals(uniformName))
|
||||
{
|
||||
this.uniformBuffers[i] = uniformBuffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void render(
|
||||
GpuTexture sourceColorTexture,
|
||||
GpuTexture sourceDepthTexture,
|
||||
GpuTexture destinationColorTexture)
|
||||
{
|
||||
this.tryInit(sourceColorTexture, sourceDepthTexture, destinationColorTexture);
|
||||
|
||||
this.dummyDepthTextureWrapper.tryCreateOrResize();
|
||||
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getIdentifierName,
|
||||
this.destinationColorTextureViewWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.dummyDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
renderPass.bindTexture("uSourceColorTexture", this.sourceColorTextureViewWrapper.textureView, this.sourceColorTextureViewWrapper.textureSampler);
|
||||
renderPass.bindTexture("uSourceDepthTexture", this.sourceDepthTextureViewWrapper.textureView, this.sourceDepthTextureViewWrapper.textureSampler);
|
||||
|
||||
for (int i = 0; i < this.uniformNames.length; i++)
|
||||
{
|
||||
String uniformName = this.uniformNames[i];
|
||||
GpuBuffer uniformBuffer = this.uniformBuffers[i];
|
||||
if (uniformBuffer == null)
|
||||
{
|
||||
throw new IllegalStateException("Missing uniform ["+uniformName+"], please set the uniform before rendering.");
|
||||
}
|
||||
|
||||
renderPass.setUniform(uniformName, uniformBuffer);
|
||||
}
|
||||
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer);
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
|
||||
}
|
||||
|
||||
|
||||
// clear the uniforms after rendering
|
||||
// so we can check if they're missing during next frame's rendering
|
||||
if (ModInfo.IS_DEV_BUILD)
|
||||
{
|
||||
Arrays.fill(this.uniformBuffers, null);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.apply;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhCopyRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Blindly copies one texture into another.
|
||||
*
|
||||
* @see BlazeDhApplyRenderer
|
||||
*/
|
||||
public class BlazeDhCopyRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeDhCopyRenderer INSTANCE = new BlazeDhCopyRenderer();
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
private BlazeTextureWrapper dummyDepthTextureWrapper;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhCopyRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
this.dummyDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_copy_depth_texture");
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("copy");
|
||||
|
||||
pipelineBuilder.withVertexShader("copy/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("copy/blaze/frag");
|
||||
|
||||
pipelineBuilder.withSampler("uCopyTexture");
|
||||
|
||||
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
|
||||
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McCopyRenderer");
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
public void render(
|
||||
BlazeTextureWrapper sourceColorTextureWrapper,
|
||||
BlazeTextureViewWrapper destinationColorTextureWrapper)
|
||||
{
|
||||
this.render(
|
||||
sourceColorTextureWrapper.textureView, sourceColorTextureWrapper.textureSampler,
|
||||
destinationColorTextureWrapper.textureView);
|
||||
}
|
||||
public void render(
|
||||
BlazeTextureWrapper sourceColorTextureWrapper,
|
||||
BlazeTextureWrapper destinationColorTextureWrapper)
|
||||
{
|
||||
this.render(
|
||||
sourceColorTextureWrapper.textureView, sourceColorTextureWrapper.textureSampler,
|
||||
destinationColorTextureWrapper.textureView);
|
||||
}
|
||||
|
||||
private void render(
|
||||
GpuTextureView sourceTextureView,
|
||||
GpuSampler sourceTextureSampler,
|
||||
GpuTextureView destinationTextureView)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
this.dummyDepthTextureWrapper.tryCreateOrResize();
|
||||
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
destinationTextureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.dummyDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
renderPass.bindTexture("uCopyTexture", sourceTextureView, sourceTextureSampler);
|
||||
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol
|
||||
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
|
||||
}
|
||||
}
|
||||
|
||||
private String getRenderPassName() { return "distantHorizons:McCopyRenderer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-299
@@ -1,299 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.objects;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeGenericObjectVertexContainer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.enums.GLEnums;
|
||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* For use by {@link RenderableBoxGroup}
|
||||
*
|
||||
* @see RenderableBoxGroup
|
||||
*/
|
||||
public class BlazeGenericObjectVertexContainer implements IDhGenericObjectVertexBufferContainer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
private static final int[] BOX_INDICES = {
|
||||
//region
|
||||
// min X, vertical face
|
||||
2, 1, 0,
|
||||
0, 3, 2,
|
||||
// max X, vertical face
|
||||
6, 5, 4,
|
||||
4, 7, 6,
|
||||
|
||||
// min Z, vertical face
|
||||
10, 9, 8,
|
||||
8, 11, 10,
|
||||
// max Z, vertical face
|
||||
14, 13, 12,
|
||||
12, 15, 14,
|
||||
|
||||
// min Y, horizontal face
|
||||
18, 17, 16,
|
||||
16, 19, 18,
|
||||
// max Y, horizontal face
|
||||
20, 21, 22,
|
||||
22, 23, 20,
|
||||
//endregion
|
||||
};
|
||||
|
||||
|
||||
|
||||
public GpuBuffer vboGpuBuffer;
|
||||
public GpuBuffer indexGpuBuffer;
|
||||
|
||||
private ByteBuffer vertexBuffer = ByteBuffer.allocateDirect(0);
|
||||
private ByteBuffer indexBuffer = ByteBuffer.allocateDirect(0);
|
||||
|
||||
public int uploadedBoxCount = 0;
|
||||
|
||||
private EState state = EState.NEW;
|
||||
@Override
|
||||
public IDhGenericObjectVertexBufferContainer.EState getState() { return this.state; }
|
||||
@Override
|
||||
public void setState(IDhGenericObjectVertexBufferContainer.EState state) { this.state = state; }
|
||||
|
||||
|
||||
|
||||
//===========================//
|
||||
// render building/uploading //
|
||||
//===========================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void updateVertexData(List<DhApiRenderableBox> uploadBoxList)
|
||||
{
|
||||
int boxCount = uploadBoxList.size();
|
||||
|
||||
// recreate the data arrays if their size is different
|
||||
if (this.uploadedBoxCount != boxCount)
|
||||
{
|
||||
this.uploadedBoxCount = boxCount;
|
||||
|
||||
int vertexBufferSize = this.vertexBufferSize();
|
||||
this.vertexBuffer = ByteBuffer.allocateDirect(vertexBufferSize);
|
||||
this.vertexBuffer.order(ByteOrder.nativeOrder());
|
||||
|
||||
int indexBufferSize = this.indexBufferSize();
|
||||
this.indexBuffer = ByteBuffer.allocateDirect(indexBufferSize);
|
||||
this.indexBuffer.order(ByteOrder.nativeOrder());
|
||||
}
|
||||
this.vertexBuffer.position(0);
|
||||
this.indexBuffer.position(0);
|
||||
|
||||
|
||||
|
||||
for (int boxIndex = 0; boxIndex < boxCount; boxIndex++)
|
||||
{
|
||||
// index
|
||||
int indexOffset = (boxIndex * 24 /*24 is the number of vertices in a box*/);
|
||||
for (int i = 0; i < BOX_INDICES.length; i++)
|
||||
{
|
||||
this.indexBuffer.putInt(BOX_INDICES[i] + indexOffset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// vertex
|
||||
DhApiRenderableBox box = uploadBoxList.get(boxIndex);
|
||||
|
||||
final double[] boxVertices =
|
||||
{
|
||||
//region
|
||||
// Pos x y z
|
||||
|
||||
// min X, vertical face
|
||||
box.minPos.x, box.minPos.y, box.minPos.z,
|
||||
box.maxPos.x, box.minPos.y, box.minPos.z,
|
||||
box.maxPos.x, box.maxPos.y, box.minPos.z,
|
||||
box.minPos.x, box.maxPos.y, box.minPos.z,
|
||||
// max X, vertical face
|
||||
box.minPos.x, box.maxPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.maxPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.minPos.y, box.maxPos.z,
|
||||
box.minPos.x, box.minPos.y, box.maxPos.z,
|
||||
|
||||
// min Z, vertical face
|
||||
box.minPos.x, box.minPos.y, box.maxPos.z,
|
||||
box.minPos.x, box.minPos.y, box.minPos.z,
|
||||
box.minPos.x, box.maxPos.y, box.minPos.z,
|
||||
box.minPos.x, box.maxPos.y, box.maxPos.z,
|
||||
// max Z, vertical face
|
||||
box.maxPos.x, box.minPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.maxPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.maxPos.y, box.minPos.z,
|
||||
box.maxPos.x, box.minPos.y, box.minPos.z,
|
||||
|
||||
// min Y, horizontal face
|
||||
box.minPos.x, box.minPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.minPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.minPos.y, box.minPos.z,
|
||||
box.minPos.x, box.minPos.y, box.minPos.z,
|
||||
// max Y, horizontal face
|
||||
box.minPos.x, box.maxPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.maxPos.y, box.maxPos.z,
|
||||
box.maxPos.x, box.maxPos.y, box.minPos.z,
|
||||
box.minPos.x, box.maxPos.y, box.minPos.z,
|
||||
//endregion
|
||||
};
|
||||
|
||||
for (int vertexIndex = 0; vertexIndex < boxVertices.length; vertexIndex+=3)
|
||||
{
|
||||
this.vertexBuffer.putFloat((float)boxVertices[vertexIndex]); // x
|
||||
this.vertexBuffer.putFloat((float)boxVertices[vertexIndex+1]); // y
|
||||
this.vertexBuffer.putFloat((float)boxVertices[vertexIndex+2]); // z
|
||||
|
||||
int color = ColorUtil.toColorInt(box.color);
|
||||
byte r = (byte) ColorUtil.getRed(color);
|
||||
byte g = (byte) ColorUtil.getGreen(color);
|
||||
byte b = (byte) ColorUtil.getBlue(color);
|
||||
byte a = (byte) ColorUtil.getAlpha(color);
|
||||
this.vertexBuffer.put(r);
|
||||
this.vertexBuffer.put(g);
|
||||
this.vertexBuffer.put(b);
|
||||
this.vertexBuffer.put(a);
|
||||
|
||||
this.vertexBuffer.put(box.material);
|
||||
|
||||
// padding so the vertex format's byte count is a multiple of 4
|
||||
this.vertexBuffer.put((byte)0);
|
||||
this.vertexBuffer.put((byte)0);
|
||||
this.vertexBuffer.put((byte)0);
|
||||
}
|
||||
}
|
||||
this.vertexBuffer.flip();
|
||||
this.indexBuffer.flip();
|
||||
}
|
||||
|
||||
private int vertexBufferSize()
|
||||
{
|
||||
// minimum of 1 box to prevent trying to create a buffer of size 0
|
||||
int boxCount = Math.max(this.uploadedBoxCount, 1);
|
||||
|
||||
int faceCount = boxCount * 6; // 6 faces on a cube
|
||||
int vertexCount = faceCount * 6; // 6 vertices per cube
|
||||
|
||||
int byteSize = vertexCount * 3 * Float.BYTES; // x,y,z
|
||||
byteSize += vertexCount * 4; // r,g,b,a
|
||||
byteSize += 1; // material
|
||||
return byteSize;
|
||||
}
|
||||
private int indexBufferSize()
|
||||
{
|
||||
// minimum of 1 box to prevent trying to create a buffer of size 0
|
||||
int boxCount = Math.max(this.uploadedBoxCount, 1);
|
||||
|
||||
int quadCount = boxCount * 6 * 6; // 6 faces with 6 vertices each
|
||||
int byteSize = quadCount * GLEnums.getTypeSize(GL32.GL_UNSIGNED_INT);
|
||||
return byteSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadDataToGpu()
|
||||
{
|
||||
// vertex
|
||||
{
|
||||
int totalVertexByteSize = this.vertexBufferSize();
|
||||
if (this.vboGpuBuffer == null
|
||||
// recreating if the size changes is always necessary (even if we only need a smaller amount)
|
||||
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|
||||
|| this.vboGpuBuffer.size() != totalVertexByteSize)
|
||||
{
|
||||
if (this.vboGpuBuffer != null)
|
||||
{
|
||||
this.vboGpuBuffer.close();
|
||||
}
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX;
|
||||
this.vboGpuBuffer = GPU_DEVICE.createBuffer(this::getVertexBufferName, usage, totalVertexByteSize);
|
||||
}
|
||||
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vboGpuBuffer, /*offset*/0, totalVertexByteSize);
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, this.vertexBuffer);
|
||||
}
|
||||
|
||||
// index
|
||||
{
|
||||
int totalVertexByteSize = this.indexBufferSize();
|
||||
if (this.indexGpuBuffer == null
|
||||
// recreating if the size changes is always necessary (even if we only need a smaller amount)
|
||||
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|
||||
|| this.indexGpuBuffer.size() != totalVertexByteSize)
|
||||
{
|
||||
if (this.indexGpuBuffer != null)
|
||||
{
|
||||
this.indexGpuBuffer.close();
|
||||
}
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_INDEX;
|
||||
this.indexGpuBuffer = GPU_DEVICE.createBuffer(this::getIndexBufferName, usage, totalVertexByteSize);
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.indexGpuBuffer, offset, totalVertexByteSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, this.indexBuffer);
|
||||
}
|
||||
}
|
||||
private String getVertexBufferName() { return "distantHorizons:GenericVertexBuffer"; }
|
||||
private String getIndexBufferName() { return "distantHorizons:GenericIndexBuffer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("BlazeGenericObjectVertexContainer close", () ->
|
||||
{
|
||||
if (this.vboGpuBuffer != null)
|
||||
{
|
||||
this.vboGpuBuffer.close();
|
||||
}
|
||||
|
||||
if (this.indexGpuBuffer != null)
|
||||
{
|
||||
this.indexGpuBuffer.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-237
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.postProcessing;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhFarFadeRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFarFadeRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Fades out DH's far clip plane
|
||||
*/
|
||||
public class BlazeDhFarFadeRenderer implements IDhFarFadeRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeDhFarFadeRenderer INSTANCE = new BlazeDhFarFadeRenderer();
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
private final BlazeTextureWrapper dhFadeColorTextureWrapper = BlazeTextureWrapper.createColor("dh_far_fade_color_texture");
|
||||
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
|
||||
private final BlazeTextureWrapper dhFadeDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_far_fade_depth_texture");
|
||||
|
||||
private final BlazeTextureViewWrapper mcColorTextureViewWrapper = new BlazeTextureViewWrapper();
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhFarFadeRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("far_fade");
|
||||
|
||||
pipelineBuilder.withVertexShader("fade/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("fade/blaze/dh_fade");
|
||||
|
||||
pipelineBuilder.withSampler("uMcColorTexture");
|
||||
|
||||
pipelineBuilder.withSampler("uDhDepthTexture");
|
||||
pipelineBuilder.withSampler("uDhColorTexture");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("fragUniformBlock");
|
||||
|
||||
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
|
||||
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFadeRenderer");
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderParams)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
|
||||
if (BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty()
|
||||
|| BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// textures
|
||||
this.dhFadeColorTextureWrapper.tryCreateOrResize();
|
||||
this.mcColorTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
|
||||
|
||||
this.dhFadeDepthTextureWrapper.tryCreateOrResize();
|
||||
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putFloat() // uStartFadeBlockDistance
|
||||
.putFloat() // uEndFadeBlockDistance
|
||||
.putMat4f() // uDhInvMvmProj
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
float dhFarClipDistance = RenderUtil.getFarClipPlaneDistanceInBlocks();
|
||||
float fadeStartDistance = dhFarClipDistance * 0.5f;
|
||||
float fadeEndDistance = dhFarClipDistance * 0.9f;
|
||||
|
||||
|
||||
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(renderParams.mcProjectionMatrix);
|
||||
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(renderParams.mcModelViewMatrix);
|
||||
|
||||
Mat4f inverseDhMvmProjMatrix = new Mat4f(dhProjectionMatrix);
|
||||
inverseDhMvmProjMatrix.multiply(dhModelViewMatrix);
|
||||
inverseDhMvmProjMatrix.invert();
|
||||
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putFloat(fadeStartDistance) // uStartFadeBlockDistance
|
||||
.putFloat(fadeEndDistance) // uEndFadeBlockDistance
|
||||
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
this.renderFadeToTexture();
|
||||
BlazeDhCopyRenderer.INSTANCE.render(this.dhFadeColorTextureWrapper, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper);
|
||||
|
||||
}
|
||||
|
||||
private void renderFadeToTexture()
|
||||
{
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
this.dhFadeColorTextureWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.dhFadeDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
// MC texture
|
||||
renderPass.bindTexture("uMcColorTexture", this.mcColorTextureViewWrapper.textureView, this.mcColorTextureViewWrapper.textureSampler);
|
||||
|
||||
// DH textures
|
||||
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
|
||||
renderPass.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureSampler);
|
||||
|
||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
|
||||
}
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:McFadeRenderer"; }
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-362
@@ -1,362 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.postProcessing;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhFogRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.DestFactor;
|
||||
import com.mojang.blaze3d.platform.SourceFactor;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiFogColorMode;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogDirection;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiHeightFogMixMode;
|
||||
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhFogRenderer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Renders fog onto the LODs.
|
||||
*/
|
||||
public class BlazeDhFogRenderer implements IDhFogRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeDhFogRenderer INSTANCE = new BlazeDhFogRenderer();
|
||||
|
||||
|
||||
private BlazeDhApplyRenderer applyRenderer;
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
private final BlazeTextureWrapper fogColorTextureWrapper = BlazeTextureWrapper.createColor("dh_fog_color_texture");
|
||||
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
|
||||
private final BlazeTextureWrapper fogDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_fog_depth_texture");
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhFogRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
|
||||
|
||||
this.applyRenderer = new BlazeDhApplyRenderer(
|
||||
"fog_apply_to_dh",
|
||||
new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ONE_MINUS_SRC_ALPHA),
|
||||
"apply/blaze/vert", "apply/blaze/frag"
|
||||
);
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("fog_render");
|
||||
|
||||
pipelineBuilder.withVertexShader("fog/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("fog/blaze/frag");
|
||||
|
||||
pipelineBuilder.withSampler("uDhDepthTexture");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("fragUniformBlock");
|
||||
|
||||
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
|
||||
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFogRenderer");
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderParams)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
|
||||
if (BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty()
|
||||
|| BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.fogColorTextureWrapper.tryCreateOrResize();
|
||||
this.fogDepthTextureWrapper.tryCreateOrResize();
|
||||
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
|
||||
// fog uniforms
|
||||
.putVec4() // uFogColor
|
||||
.putFloat() //uFogScale
|
||||
.putFloat() //uFogVerticalScale
|
||||
// only used for debugging
|
||||
.putInt() //uFogDebugMode // 1 = render everything with fog color // 7 = use debug rendering
|
||||
.putInt() //uFogFalloffType
|
||||
|
||||
// fog config
|
||||
.putFloat() // uFarFogStart
|
||||
.putFloat() // uFarFogLength
|
||||
.putFloat() // uFarFogMin
|
||||
.putFloat() // uFarFogRange
|
||||
.putFloat() // uFarFogDensity
|
||||
|
||||
// height fog config
|
||||
.putFloat() // uHeightFogStart
|
||||
.putFloat() // uHeightFogLength
|
||||
.putFloat() // uHeightFogMin
|
||||
.putFloat() // uHeightFogRange
|
||||
.putFloat() // uHeightFogDensity
|
||||
|
||||
// ??
|
||||
.putInt() // uHeightFogEnabled
|
||||
.putInt() // uHeightFogFalloffType
|
||||
.putInt() // uHeightBasedOnCamera
|
||||
.putFloat() // uHeightFogBaseHeight
|
||||
.putInt() // uHeightFogAppliesUp
|
||||
.putInt() // uHeightFogAppliesDown
|
||||
.putInt() // uUseSphericalFog
|
||||
.putInt() // uHeightFogMixingMode
|
||||
.putFloat() // uCameraBlockYPos
|
||||
|
||||
.putMat4f() // uInvMvmProj
|
||||
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
|
||||
int lodDrawDistance = Config.Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius.get() * LodUtil.CHUNK_WIDTH;
|
||||
|
||||
|
||||
Mat4f inverseMvmProjMatrix = new Mat4f(renderParams.dhMvmProjMatrix);
|
||||
inverseMvmProjMatrix.invert();
|
||||
|
||||
if (renderParams.dhMvmProjMatrix == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Color fogColor = this.getFogColor(renderParams.partialTicks);
|
||||
|
||||
// fog config
|
||||
float farFogStart = Config.Client.Advanced.Graphics.Fog.farFogStart.get();
|
||||
float farFogEnd = Config.Client.Advanced.Graphics.Fog.farFogEnd.get();
|
||||
float farFogMin = Config.Client.Advanced.Graphics.Fog.farFogMin.get();
|
||||
float farFogMax = Config.Client.Advanced.Graphics.Fog.farFogMax.get();
|
||||
float farFogDensity = Config.Client.Advanced.Graphics.Fog.farFogDensity.get();
|
||||
|
||||
// override fog if underwater
|
||||
if (MC_RENDER.isFogStateSpecial())
|
||||
{
|
||||
// hide everything behind fog
|
||||
farFogStart = 0.0f;
|
||||
farFogEnd = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
// height config
|
||||
EDhApiHeightFogMixMode heightFogMixingMode = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMixMode.get();
|
||||
boolean heightFogEnabled = heightFogMixingMode != EDhApiHeightFogMixMode.SPHERICAL && heightFogMixingMode != EDhApiHeightFogMixMode.CYLINDRICAL;
|
||||
boolean useSphericalFog = heightFogMixingMode == EDhApiHeightFogMixMode.SPHERICAL;
|
||||
EDhApiHeightFogDirection heightFogCameraDirection = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDirection.get();
|
||||
|
||||
float heightFogStart = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogStart.get();
|
||||
float heightFogEnd = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogEnd.get();
|
||||
float heightFogMin = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMin.get();
|
||||
float heightFogMax = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogMax.get();
|
||||
float heightFogDensity = Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogDensity.get();
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
|
||||
// fog uniforms
|
||||
.putVec4(
|
||||
fogColor.getRed() / 255.0f,
|
||||
fogColor.getGreen() / 255.0f,
|
||||
fogColor.getBlue() / 255.0f,
|
||||
fogColor.getAlpha() / 255.0f) // uFogColor
|
||||
.putFloat(1.f / lodDrawDistance) //uFogScale
|
||||
.putFloat(1.f / MC.getWrappedClientLevel().getMaxHeight()) //uFogVerticalScale
|
||||
// only used for debugging
|
||||
.putInt(0) //uFogDebugMode // 1 = render everything with fog color // 7 = use debug rendering
|
||||
.putInt(Config.Client.Advanced.Graphics.Fog.farFogFalloff.get().value) //uFogFalloffType
|
||||
|
||||
// fog config
|
||||
.putFloat(farFogStart) // uFarFogStart
|
||||
.putFloat(farFogEnd - farFogStart) // uFarFogLength
|
||||
.putFloat(farFogMin) // uFarFogMin
|
||||
.putFloat(farFogMax - farFogMin) // uFarFogRange
|
||||
.putFloat(farFogDensity) // uFarFogDensity
|
||||
|
||||
// height fog config
|
||||
.putFloat(heightFogStart) // uHeightFogStart
|
||||
.putFloat(heightFogEnd - heightFogStart) // uHeightFogLength
|
||||
.putFloat(heightFogMin) // uHeightFogMin
|
||||
.putFloat(heightFogMax - heightFogMin) // uHeightFogRange
|
||||
.putFloat(heightFogDensity) // uHeightFogDensity
|
||||
|
||||
// ??
|
||||
.putInt(heightFogEnabled ? 1 : 0) // uHeightFogEnabled
|
||||
.putInt(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogFalloff.get().value) // uHeightFogFalloffType
|
||||
.putInt(heightFogCameraDirection.basedOnCamera ? 1 : 0) // uHeightBasedOnCamera
|
||||
.putFloat(Config.Client.Advanced.Graphics.Fog.HeightFog.heightFogBaseHeight.get()) // uHeightFogBaseHeight
|
||||
.putInt(heightFogCameraDirection.fogAppliesUp ? 1 : 0) // uHeightFogAppliesUp
|
||||
.putInt(heightFogCameraDirection.fogAppliesDown ? 1 : 0) // uHeightFogAppliesDown
|
||||
.putInt(useSphericalFog ? 1 : 0) // uUseSphericalFog
|
||||
.putInt(heightFogMixingMode.value) // uHeightFogMixingMode
|
||||
.putFloat((float)MC_RENDER.getCameraExactPosition().y) // uCameraBlockYPos
|
||||
|
||||
.putMat4f(inverseMvmProjMatrix.createJomlMatrix()) // uInvMvmProj
|
||||
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
this.renderFogToTexture();
|
||||
this.applyRenderer.render(this.fogColorTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.texture);
|
||||
|
||||
}
|
||||
|
||||
private Color getFogColor(float partialTicks)
|
||||
{
|
||||
Color fogColor;
|
||||
|
||||
if (Config.Client.Advanced.Graphics.Fog.colorMode.get() == EDhApiFogColorMode.USE_SKY_COLOR)
|
||||
{
|
||||
fogColor = MC_RENDER.getSkyColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
fogColor = MC_RENDER.getFogColor(partialTicks);
|
||||
}
|
||||
|
||||
return fogColor;
|
||||
}
|
||||
|
||||
private void renderFogToTexture()
|
||||
{
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
this.fogColorTextureWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.fogDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
|
||||
|
||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
|
||||
}
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:McFogRenderer"; }
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.postProcessing;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhSsaoRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.DestFactor;
|
||||
import com.mojang.blaze3d.platform.SourceFactor;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhApplyRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhSsaoRenderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/** Renders SSAO to the DH LODs. */
|
||||
public class BlazeDhSsaoRenderer implements IDhSsaoRenderer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeDhSsaoRenderer INSTANCE = new BlazeDhSsaoRenderer();
|
||||
|
||||
|
||||
private BlazeDhApplyRenderer applyRenderer;
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
private GpuBuffer applyFragUniformBuffer;
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
private final BlazeTextureWrapper ssaoColorTextureWrapper = BlazeTextureWrapper.createColor("dh_ssao_color_texture");
|
||||
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
|
||||
private final BlazeTextureWrapper ssaoDepthTextureWrapper = BlazeTextureWrapper.createDepth("dh_ssao_depth_texture");
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhSsaoRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
this.applyRenderer = new BlazeDhApplyRenderer(
|
||||
"ssao_apply_to_dh",
|
||||
new BlendFunction(SourceFactor.ZERO, DestFactor.SRC_ALPHA, SourceFactor.ZERO, DestFactor.ONE),
|
||||
"apply/blaze/vert", "ssao/blaze/apply",
|
||||
/*uniforms*/ new String[] { "applyFragUniformBlock" }
|
||||
);
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("ssao_render");
|
||||
|
||||
pipelineBuilder.withVertexShader("ssao/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("ssao/blaze/frag");
|
||||
|
||||
pipelineBuilder.withSampler("uDhDepthTexture");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("fragUniformBlock");
|
||||
|
||||
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
|
||||
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McSsao");
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderParams)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
|
||||
if (BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty()
|
||||
|| BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// textures
|
||||
this.ssaoColorTextureWrapper.tryCreateOrResize();
|
||||
this.ssaoDepthTextureWrapper.tryCreateOrResize();
|
||||
|
||||
// frag uniforms
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putInt() // uSampleCount\
|
||||
|
||||
.putFloat() // uRadius
|
||||
.putFloat() // uStrength
|
||||
.putFloat() // uMinLight
|
||||
.putFloat() // uBias
|
||||
.putFloat() // uFadeDistanceInBlocks
|
||||
|
||||
.putMat4f() // uInvProj
|
||||
.putMat4f() // uProj
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
Mat4f projMatrix = new Mat4f(renderParams.dhProjectionMatrix);
|
||||
Mat4f invertedProjMatrix = new Mat4f(renderParams.dhProjectionMatrix);
|
||||
invertedProjMatrix.invert();
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putInt(6) // uSampleCount
|
||||
|
||||
.putFloat(4.0f) // uRadius
|
||||
.putFloat(0.2f) // uStrength
|
||||
.putFloat(0.25f) // uMinLight
|
||||
.putFloat(0.02f) // uBias
|
||||
.putFloat(1_600.0f) // uFadeDistanceInBlocks
|
||||
|
||||
.putMat4f(invertedProjMatrix.createJomlMatrix())
|
||||
.putMat4f(projMatrix.createJomlMatrix())
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
// apply frag uniforms
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putVec2() // uViewSize
|
||||
.putInt() // uBlurRadius
|
||||
.putFloat() // uNearClipPlane
|
||||
.putFloat() // uFarClipPlane
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
float viewWidth = (float)MC_RENDER.getTargetFramebufferViewportWidth();
|
||||
float viewHeight = (float)MC_RENDER.getTargetFramebufferViewportHeight();
|
||||
|
||||
float nearClipPlane = RenderUtil.getNearClipPlaneInBlocks();
|
||||
float farClipPlane = RenderUtil.getFarClipPlaneDistanceInBlocks();
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putVec2(viewWidth, viewHeight) // uViewSize
|
||||
.putInt(2) // uBlurRadius
|
||||
.putFloat(nearClipPlane) // uNearClipPlane
|
||||
.putFloat(farClipPlane) // uFarClipPlane
|
||||
.get()
|
||||
;
|
||||
|
||||
this.applyFragUniformBuffer = BlazeUniformUtil.createBuffer("applyFragUniformBlock", uniformBufferSize, this.applyFragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.applyFragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
this.renderSsaoToTexture();
|
||||
|
||||
this.applyRenderer.setUniform("applyFragUniformBlock", this.applyFragUniformBuffer);
|
||||
this.applyRenderer.render(this.ssaoColorTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.texture, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.texture);
|
||||
|
||||
}
|
||||
|
||||
private void renderSsaoToTexture()
|
||||
{
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
this.ssaoColorTextureWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.ssaoDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
|
||||
|
||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol
|
||||
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
|
||||
}
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:McSsaoRenderer"; }
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-267
@@ -1,267 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.postProcessing;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeVanillaFadeRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.common.render.blaze.BlazeDhMetaRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.apply.BlazeDhCopyRenderer;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazePostProcessUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeUniformUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.RenderUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhVanillaFadeRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Fades the vanilla chunks
|
||||
* into DH's LODs.
|
||||
*/
|
||||
public class BlazeVanillaFadeRenderer implements IDhVanillaFadeRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeVanillaFadeRenderer INSTANCE = new BlazeVanillaFadeRenderer();
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
private GpuBuffer fragUniformBuffer;
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
public final BlazeTextureWrapper fadeColorTextureWrapper = BlazeTextureWrapper.createColor("DhVanillaFadeColorTexture");
|
||||
/** We don't want to actually write any depth data, but blaze3D complains if we don't bind a depth texture. */
|
||||
private final BlazeTextureWrapper fadeDepthTextureWrapper = BlazeTextureWrapper.createDepth("DhVanillaFadeDepthTexture");
|
||||
|
||||
|
||||
public final BlazeTextureViewWrapper mcDepthTextureWrapper = new BlazeTextureViewWrapper();
|
||||
public final BlazeTextureViewWrapper mcColorTextureWrapper = new BlazeTextureViewWrapper();
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeVanillaFadeRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withPolygonMode(RenderPipelineBuilderWrapper.EDhPolygonMode.FILL);
|
||||
pipelineBuilder.withName("vanilla_fade");
|
||||
|
||||
pipelineBuilder.withVertexShader("fade/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("fade/blaze/vanilla_fade");
|
||||
|
||||
pipelineBuilder.withSampler("uMcDepthTexture");
|
||||
pipelineBuilder.withSampler("uCombinedMcDhColorTexture");
|
||||
|
||||
pipelineBuilder.withSampler("uDhDepthTexture");
|
||||
pipelineBuilder.withSampler("uDhColorTexture");
|
||||
|
||||
pipelineBuilder.withUniformBuffer("fragUniformBlock");
|
||||
|
||||
pipelineBuilder.withVertexFormat(BlazePostProcessUtil.createVertexFormat());
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLE_FAN);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
|
||||
this.vboGpuBuffer = BlazePostProcessUtil.createAndUploadScreenVertexData("McFadeRenderer");
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderParams)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
if (BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.isEmpty()
|
||||
|| BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// textures
|
||||
this.fadeColorTextureWrapper.tryCreateOrResize();
|
||||
this.fadeDepthTextureWrapper.tryCreateOrResize();
|
||||
|
||||
this.mcDepthTextureWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getDepthTexture());
|
||||
this.mcColorTextureWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
|
||||
|
||||
|
||||
{
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putInt() // uOnlyRenderLods
|
||||
.putFloat() // uStartFadeBlockDistance
|
||||
.putFloat() // uEndFadeBlockDistance
|
||||
.putFloat() // uMaxLevelHeight
|
||||
.putMat4f() // uDhInvMvmProj
|
||||
.putMat4f() // uMcInvMvmProj
|
||||
.get();
|
||||
|
||||
|
||||
// create data //
|
||||
|
||||
float dhNearClipDistance = RenderUtil.getNearClipPlaneInBlocks();
|
||||
// this added value prevents the near clip plane and discard circle from touching, which looks bad
|
||||
dhNearClipDistance += 16f;
|
||||
|
||||
// measured in blocks
|
||||
// these multipliers in James' tests should provide a fairly smooth transition
|
||||
// without having underdraw issues
|
||||
float fadeStartDistance = dhNearClipDistance * 1.5f;
|
||||
float fadeEndDistance = dhNearClipDistance * 1.9f;
|
||||
|
||||
|
||||
Mat4f inverseMcModelViewProjectionMatrix = new Mat4f(renderParams.mcProjectionMatrix);
|
||||
inverseMcModelViewProjectionMatrix.multiply(renderParams.mcModelViewMatrix);
|
||||
inverseMcModelViewProjectionMatrix.invert();
|
||||
Mat4f inverseMcMvmProjMatrix = inverseMcModelViewProjectionMatrix;
|
||||
|
||||
|
||||
Mat4f dhProjectionMatrix = RenderUtil.createLodProjectionMatrix(renderParams.mcProjectionMatrix);
|
||||
Mat4f dhModelViewMatrix = RenderUtil.createLodModelViewMatrix(renderParams.mcModelViewMatrix);
|
||||
|
||||
Mat4f inverseDhModelViewProjectionMatrix = new Mat4f(dhProjectionMatrix);
|
||||
inverseDhModelViewProjectionMatrix.multiply(dhModelViewMatrix);
|
||||
inverseDhModelViewProjectionMatrix.invert();
|
||||
Mat4f inverseDhMvmProjMatrix = inverseDhModelViewProjectionMatrix;
|
||||
|
||||
|
||||
|
||||
// upload data //
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(uniformBufferSize);
|
||||
buffer.order(ByteOrder.nativeOrder());
|
||||
buffer = Std140Builder.intoBuffer(buffer)
|
||||
.putInt(Config.Client.Advanced.Debugging.lodOnlyMode.get() ? 1 : 0) // uOnlyRenderLods
|
||||
.putFloat(fadeStartDistance) // uStartFadeBlockDistance
|
||||
.putFloat(fadeEndDistance) // uEndFadeBlockDistance
|
||||
.putFloat(renderParams.clientLevelWrapper.getMaxHeight()) // uMaxLevelHeight
|
||||
.putMat4f(inverseDhMvmProjMatrix.createJomlMatrix()) // uDhInvMvmProj
|
||||
.putMat4f(inverseMcMvmProjMatrix.createJomlMatrix()) // uMcInvMvmProj
|
||||
.get()
|
||||
;
|
||||
|
||||
this.fragUniformBuffer = BlazeUniformUtil.createBuffer("fragUniformBlock", uniformBufferSize, this.fragUniformBuffer);
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.fragUniformBuffer, 0, uniformBufferSize);
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, buffer);
|
||||
}
|
||||
|
||||
|
||||
this.renderFadeToTexture();
|
||||
BlazeDhCopyRenderer.INSTANCE.render(this.fadeColorTextureWrapper, this.mcColorTextureWrapper);
|
||||
|
||||
}
|
||||
|
||||
private void renderFadeToTexture()
|
||||
{
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
this.fadeColorTextureWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.fadeDepthTextureWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
renderPass.bindTexture("uMcDepthTexture", this.mcDepthTextureWrapper.textureView, this.mcDepthTextureWrapper.textureSampler);
|
||||
renderPass.bindTexture("uCombinedMcDhColorTexture", this.mcColorTextureWrapper.textureView, this.mcColorTextureWrapper.textureSampler);
|
||||
|
||||
renderPass.bindTexture("uDhDepthTexture", BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhDepthTextureWrapper.textureSampler);
|
||||
renderPass.bindTexture("uDhColorTexture", BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureView, BlazeDhMetaRenderer.INSTANCE.dhColorTextureWrapper.textureSampler);
|
||||
|
||||
renderPass.setUniform("fragUniformBlock", this.fragUniformBuffer);
|
||||
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer); // vertex buffer can only be "0" lol
|
||||
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 4);
|
||||
}
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:McFadeRenderer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-189
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.blaze.test;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhTestTriangleRenderer {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderPass;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.seibel.distanthorizons.common.render.blaze.util.BlazeDhVertexFormatUtil;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.RenderPipelineBuilderWrapper;
|
||||
import com.seibel.distanthorizons.common.render.blaze.wrappers.texture.BlazeTextureViewWrapper;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTestTriangleRenderer;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
#if MC_VER <= MC_1_21_11
|
||||
#else
|
||||
import com.mojang.blaze3d.pipeline.DepthStencilState;
|
||||
import com.mojang.blaze3d.platform.CompareOp;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Renders the OpenGL/Vulkan triangle
|
||||
* to the center of the screen to confirm DH's
|
||||
* apply shader is running correctly
|
||||
*/
|
||||
public class BlazeDhTestTriangleRenderer implements IDhTestTriangleRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
public static final BlazeDhTestTriangleRenderer INSTANCE = new BlazeDhTestTriangleRenderer();
|
||||
|
||||
private RenderPipeline pipeline;
|
||||
private boolean init = false;
|
||||
|
||||
public final BlazeTextureViewWrapper mcColorTextureViewWrapper = new BlazeTextureViewWrapper();
|
||||
public final BlazeTextureViewWrapper mcDepthTextureViewWrapper = new BlazeTextureViewWrapper();
|
||||
|
||||
private GpuBuffer vboGpuBuffer;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private BlazeDhTestTriangleRenderer() { }
|
||||
|
||||
private void tryInit()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
RenderPipelineBuilderWrapper pipelineBuilder = new RenderPipelineBuilderWrapper();
|
||||
{
|
||||
pipelineBuilder.withFaceCulling(false);
|
||||
pipelineBuilder.withDepthWrite(false);
|
||||
pipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
pipelineBuilder.withColorWrite(true);
|
||||
pipelineBuilder.withoutBlend();
|
||||
pipelineBuilder.withName("triangle_test");
|
||||
|
||||
pipelineBuilder.withVertexShader("test/blaze/vert");
|
||||
pipelineBuilder.withFragmentShader("test/blaze/frag");
|
||||
|
||||
VertexFormat vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
|
||||
.add("vColor", BlazeDhVertexFormatUtil.RGBA_FLOAT_COLOR)
|
||||
.build();
|
||||
pipelineBuilder.withVertexFormat(vertexFormat);
|
||||
|
||||
pipelineBuilder.withVertexMode(RenderPipelineBuilderWrapper.EDhVertexMode.TRIANGLES);
|
||||
}
|
||||
this.pipeline = pipelineBuilder.build();
|
||||
|
||||
this.uploadVertexData();
|
||||
}
|
||||
private void uploadVertexData()
|
||||
{
|
||||
// vertices for the OpenGL/Vulkan Triangle
|
||||
float[] vertices = new float[]
|
||||
{
|
||||
// PosX,Y, ColorR,G,B,A
|
||||
-0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
};
|
||||
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX;
|
||||
int size = vertices.length * Float.BYTES;
|
||||
this.vboGpuBuffer = GPU_DEVICE.createBuffer(this::getRenderPassName, usage, size);
|
||||
|
||||
{
|
||||
int offset = 0;
|
||||
int length = vertices.length * Float.BYTES;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vboGpuBuffer, offset, length);
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * Float.BYTES);
|
||||
// Fill buffer with vertices.
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asFloatBuffer().put(vertices);
|
||||
byteBuffer.rewind();
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, byteBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderParams)
|
||||
{
|
||||
this.tryInit();
|
||||
|
||||
this.mcColorTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getColorTexture());
|
||||
this.mcDepthTextureViewWrapper.tryWrap(Minecraft.getInstance().getMainRenderTarget().getDepthTexture());
|
||||
|
||||
try (RenderPass renderPass = COMMAND_ENCODER.createRenderPass(
|
||||
this::getRenderPassName,
|
||||
this.mcColorTextureViewWrapper.textureView,
|
||||
/*optionalClearColorAsInt*/ OptionalInt.empty(),
|
||||
this.mcDepthTextureViewWrapper.textureView,
|
||||
/*optionalDepthValueAsDouble*/ OptionalDouble.empty()))
|
||||
{
|
||||
renderPass.setVertexBuffer(0, this.vboGpuBuffer);
|
||||
renderPass.setPipeline(this.pipeline);
|
||||
renderPass.draw(/*indexStart*/ 0, /*indexCount*/ 3);
|
||||
}
|
||||
}
|
||||
private String getRenderPassName() { return "distantHorizons:DhTestRenderer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.util;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeDhVertexFormatUtil {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexFormatElement;
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiRenderApi;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IVersionConstants;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @see LodQuadBuilder
|
||||
*/
|
||||
@SuppressWarnings("DataFlowIssue") // ignore null setter warnings in the static constructor (those will only be null if the render API is GL and in that case we should never use these objects)
|
||||
public class BlazeDhVertexFormatUtil
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
|
||||
@NotNull public static final VertexFormatElement SCREEN_POS;
|
||||
@NotNull public static final VertexFormatElement RGBA_FLOAT_COLOR;
|
||||
|
||||
@NotNull public static final VertexFormatElement SHORT_XYZ_POS;
|
||||
@NotNull public static final VertexFormatElement BYTE_PAD;
|
||||
/** contains light and micro-offset */
|
||||
@NotNull public static final VertexFormatElement META;
|
||||
@NotNull public static final VertexFormatElement RGBA_UBYTE_COLOR;
|
||||
@NotNull public static final VertexFormatElement IRIS_MATERIAL;
|
||||
@NotNull public static final VertexFormatElement IRIS_NORMAL;
|
||||
|
||||
@NotNull public static final VertexFormatElement FLOAT_XYZ_POS;
|
||||
|
||||
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
EDhApiRenderApi renderingApi = Config.Client.Advanced.Graphics.Experimental.renderingApi.get();
|
||||
if (renderingApi == EDhApiRenderApi.AUTO)
|
||||
{
|
||||
IVersionConstants versionConstants = SingletonInjector.INSTANCE.get(IVersionConstants.class);
|
||||
renderingApi = versionConstants.getDefaultRenderingApi();
|
||||
}
|
||||
|
||||
boolean register = (renderingApi == EDhApiRenderApi.BLAZE_3D);
|
||||
if (register)
|
||||
{
|
||||
LOGGER.debug("Attempting to register ["+VertexFormatElement.class.getSimpleName()+"]...");
|
||||
|
||||
try
|
||||
{
|
||||
#if MC_VER <= MC_1_21_11
|
||||
SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.POSITION, /*count*/ 2);
|
||||
RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.COLOR, /*count*/ 4);
|
||||
|
||||
SHORT_XYZ_POS = VertexFormatElement.register(/*id*/24, /*index*/0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.POSITION, /*count*/ 3);
|
||||
BYTE_PAD = VertexFormatElement.register(/*id*/25, /*index*/0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, /*count*/ 1);
|
||||
|
||||
META = VertexFormatElement.register(/*id*/26, /*index*/0, VertexFormatElement.Type.USHORT, VertexFormatElement.Usage.GENERIC, /*count*/ 1);
|
||||
RGBA_UBYTE_COLOR = VertexFormatElement.register(/*id*/27, /*index*/0, VertexFormatElement.Type.UBYTE, VertexFormatElement.Usage.COLOR, /*count*/ 4);
|
||||
IRIS_MATERIAL = VertexFormatElement.register(/*id*/28, /*index*/0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, /*count*/ 1);
|
||||
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, VertexFormatElement.Type.BYTE, VertexFormatElement.Usage.GENERIC, /*count*/ 1);
|
||||
|
||||
FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, VertexFormatElement.Type.FLOAT, VertexFormatElement.Usage.POSITION, /*count*/ 3);
|
||||
#else
|
||||
SCREEN_POS = VertexFormatElement.register(/*id*/22, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 2);
|
||||
RGBA_FLOAT_COLOR = VertexFormatElement.register(/*id*/23, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 4);
|
||||
|
||||
SHORT_XYZ_POS = VertexFormatElement.register(/*id*/24, /*index*/0, VertexFormatElement.Type.USHORT, false, /*count*/ 3);
|
||||
BYTE_PAD = VertexFormatElement.register(/*id*/25, /*index*/0, VertexFormatElement.Type.BYTE, false, /*count*/ 1);
|
||||
|
||||
META = VertexFormatElement.register(/*id*/26, /*index*/0, VertexFormatElement.Type.USHORT, false, /*count*/ 1);
|
||||
RGBA_UBYTE_COLOR = VertexFormatElement.register(/*id*/27, /*index*/0, VertexFormatElement.Type.UBYTE, true, /*count*/ 4);
|
||||
IRIS_MATERIAL = VertexFormatElement.register(/*id*/28, /*index*/0, VertexFormatElement.Type.BYTE, false, /*count*/ 1);
|
||||
IRIS_NORMAL = VertexFormatElement.register(/*id*/29, /*index*/0, VertexFormatElement.Type.BYTE, false, /*count*/ 1);
|
||||
|
||||
FLOAT_XYZ_POS = VertexFormatElement.register(/*id*/30, /*index*/0, VertexFormatElement.Type.FLOAT, false, /*count*/ 3);
|
||||
#endif
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
String message = "Unable to register one or more ["+VertexFormatElement.class.getSimpleName()+"] this is likely caused by another mod registering their own custom ["+VertexFormatElement.class.getSimpleName()+"]'s. This should be fixed in the next major Minecraft version.";
|
||||
|
||||
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
|
||||
mc.crashMinecraft(message, new Exception(message, e));
|
||||
|
||||
// here to make the compiler happy, the process should shut down before this
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
LOGGER.debug("Successfully registered ["+VertexFormatElement.class.getSimpleName()+"].");
|
||||
}
|
||||
else
|
||||
{
|
||||
// set to null so we can fail fast with a null pointer if we ever attempt to incorrectly use these
|
||||
SCREEN_POS = null;
|
||||
RGBA_FLOAT_COLOR = null;
|
||||
|
||||
SHORT_XYZ_POS = null;
|
||||
BYTE_PAD = null;
|
||||
|
||||
META = null;
|
||||
RGBA_UBYTE_COLOR = null;
|
||||
IRIS_MATERIAL = null;
|
||||
IRIS_NORMAL = null;
|
||||
|
||||
FLOAT_XYZ_POS = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.util;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazePostProcessUtil {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/** Contains code that's used by all post-processing effects. */
|
||||
public class BlazePostProcessUtil
|
||||
{
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
// vertices for a full-screen quad
|
||||
private static final float[] VERTICES = new float[]
|
||||
{
|
||||
// PosX,Y,
|
||||
-1f, -1f,
|
||||
1f, -1f,
|
||||
1f, 1f,
|
||||
-1f, 1f,
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public static GpuBuffer createAndUploadScreenVertexData(String name)
|
||||
{
|
||||
Supplier<String> labelSupplier = () -> "distantHorizons:"+name;
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX;
|
||||
int size = VERTICES.length * Float.BYTES;
|
||||
GpuBuffer vboGpuBuffer = GPU_DEVICE.createBuffer(labelSupplier, usage, size);
|
||||
|
||||
{
|
||||
int length = VERTICES.length * Float.BYTES;
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(vboGpuBuffer, /*offset*/ 0, length);
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(VERTICES.length * Float.BYTES);
|
||||
// Fill buffer with vertices.
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
byteBuffer.asFloatBuffer().put(VERTICES);
|
||||
byteBuffer.rewind();
|
||||
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, byteBuffer);
|
||||
}
|
||||
|
||||
return vboGpuBuffer;
|
||||
}
|
||||
|
||||
public static VertexFormat createVertexFormat()
|
||||
{
|
||||
VertexFormat vertexFormat = VertexFormat.builder()
|
||||
.add("vPosition", BlazeDhVertexFormatUtil.SCREEN_POS)
|
||||
.build();
|
||||
return vertexFormat;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.util;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeUniformUtil {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
|
||||
public class BlazeUniformUtil
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
|
||||
public static GpuBuffer createBuffer(String uniformName, int size, GpuBuffer vboGpuBuffer)
|
||||
{
|
||||
// create VBO if needed
|
||||
if (vboGpuBuffer == null
|
||||
|| vboGpuBuffer.size() < size)
|
||||
{
|
||||
if (vboGpuBuffer != null)
|
||||
{
|
||||
vboGpuBuffer.close();
|
||||
}
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX
|
||||
| GpuBuffer.USAGE_UNIFORM;
|
||||
vboGpuBuffer = GPU_DEVICE.createBuffer(() -> uniformName, usage, size);
|
||||
}
|
||||
|
||||
return vboGpuBuffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-351
@@ -1,351 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.wrappers;
|
||||
|
||||
import com.mojang.blaze3d.pipeline.BlendFunction;
|
||||
import com.mojang.blaze3d.pipeline.ColorTargetState;
|
||||
import com.mojang.blaze3d.pipeline.DepthStencilState;
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline;
|
||||
import com.mojang.blaze3d.platform.CompareOp;
|
||||
import com.mojang.blaze3d.platform.PolygonMode;
|
||||
import com.mojang.blaze3d.shaders.UniformType;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
public class RenderPipelineBuilderWrapper
|
||||
{
|
||||
public static final String NAME_PREFIX = "distanthorizons:";
|
||||
|
||||
private static final String SHADER_RESOURCE_FOLDER = "assets/distanthorizons/shaders/";
|
||||
|
||||
private static final ClassLoader CLASS_LOADER = RenderPipelineBuilderWrapper.class.getClassLoader();
|
||||
|
||||
|
||||
private final RenderPipeline.Builder blazePipelineBuilder;
|
||||
|
||||
// variables for specific builder options should be put next to their builder methods for simpler organization
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public RenderPipelineBuilderWrapper()
|
||||
{
|
||||
this.blazePipelineBuilder = RenderPipeline.builder();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// building //
|
||||
//==========//
|
||||
//region
|
||||
|
||||
private boolean writeDepth = false;
|
||||
public RenderPipelineBuilderWrapper withDepthWrite(boolean write)
|
||||
{
|
||||
this.writeDepth = write;
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean writeColor = false;
|
||||
public RenderPipelineBuilderWrapper withColorWrite(boolean write)
|
||||
{
|
||||
this.writeColor = write;
|
||||
return this;
|
||||
}
|
||||
|
||||
private BlendFunction blendFunction = null;
|
||||
public RenderPipelineBuilderWrapper withBlend(BlendFunction blendFunction)
|
||||
{
|
||||
this.blendFunction = blendFunction;
|
||||
return this;
|
||||
}
|
||||
public RenderPipelineBuilderWrapper withoutBlend()
|
||||
{
|
||||
this.blendFunction = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
private EDhDepthTest depthTest;
|
||||
public RenderPipelineBuilderWrapper withDepthTest(EDhDepthTest depthTest)
|
||||
{
|
||||
this.depthTest = depthTest;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderPipelineBuilderWrapper withFaceCulling(boolean culling)
|
||||
{
|
||||
this.blazePipelineBuilder.withCull(culling);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderPipelineBuilderWrapper withPolygonMode(EDhPolygonMode dhMode)
|
||||
{
|
||||
PolygonMode blazeMode;
|
||||
switch (dhMode)
|
||||
{
|
||||
case FILL:
|
||||
blazeMode = PolygonMode.FILL;
|
||||
break;
|
||||
case WIREFRAME:
|
||||
blazeMode = PolygonMode.WIREFRAME;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("No polygonMode defined for type ["+dhMode+"].");
|
||||
}
|
||||
|
||||
this.blazePipelineBuilder.withPolygonMode(blazeMode);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderPipelineBuilderWrapper withName(String name) throws IllegalArgumentException
|
||||
{
|
||||
// Identifiers must be of a specific format
|
||||
if (!isValidIdentifier(name))
|
||||
{
|
||||
throw new IllegalArgumentException("Non [a-z0-9/._-] character in name: ["+name+"].");
|
||||
}
|
||||
|
||||
this.blazePipelineBuilder.withLocation(Identifier.parse(NAME_PREFIX + name));
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderPipelineBuilderWrapper withSampler(String name) throws IllegalArgumentException
|
||||
{
|
||||
this.blazePipelineBuilder.withSampler(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderPipelineBuilderWrapper withUniformBuffer(String name) throws IllegalArgumentException
|
||||
{
|
||||
this.blazePipelineBuilder.withUniform(name, UniformType.UNIFORM_BUFFER);
|
||||
return this;
|
||||
}
|
||||
|
||||
private VertexFormat vertexFormat = null;
|
||||
public RenderPipelineBuilderWrapper withVertexFormat(VertexFormat vertexFormat)
|
||||
{
|
||||
this.vertexFormat = vertexFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
private EDhVertexMode vertexMode = null;
|
||||
public RenderPipelineBuilderWrapper withVertexMode(EDhVertexMode vertexMode)
|
||||
{
|
||||
this.vertexMode = vertexMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RenderPipelineBuilderWrapper withVertexShader(String scriptResourcePath) { return this.withShader(EDhShaderType.VERTEX, scriptResourcePath); }
|
||||
public RenderPipelineBuilderWrapper withFragmentShader(String scriptResourcePath) { return this.withShader(EDhShaderType.FRAGMENT, scriptResourcePath); }
|
||||
private RenderPipelineBuilderWrapper withShader(EDhShaderType shaderType, String scriptResourcePath)
|
||||
{
|
||||
String fullShaderResourcePath = SHADER_RESOURCE_FOLDER + scriptResourcePath + shaderType.fileExtension;
|
||||
|
||||
// confirm the shader file exists
|
||||
try (InputStream scriptListInputStream = CLASS_LOADER.getResourceAsStream(fullShaderResourcePath))
|
||||
{
|
||||
if (scriptListInputStream == null)
|
||||
{
|
||||
throw new NullPointerException("Failed to find the SQL Script list file [" + fullShaderResourcePath + "], no auto update scripts can be run.");
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// shouldn't happen, but just in case
|
||||
throw new RuntimeException("Unexpected issue closing resource stream for shader type: ["+shaderType+"] at: ["+fullShaderResourcePath+"], error: ["+e.getMessage()+"].", e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (shaderType == EDhShaderType.VERTEX)
|
||||
{
|
||||
this.blazePipelineBuilder.withVertexShader(Identifier.parse(NAME_PREFIX + scriptResourcePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.blazePipelineBuilder.withFragmentShader(Identifier.parse(NAME_PREFIX + scriptResourcePath));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=====//
|
||||
// end //
|
||||
//=====//
|
||||
//region
|
||||
|
||||
public RenderPipeline build() throws UnsupportedOperationException
|
||||
{
|
||||
// depth/color
|
||||
{
|
||||
#if MC_VER <= MC_1_21_11
|
||||
|
||||
this.blazePipelineBuilder.withDepthWrite(this.writeDepth);
|
||||
this.blazePipelineBuilder.withColorWrite(this.writeColor);
|
||||
|
||||
if (this.blendFunction != null)
|
||||
{
|
||||
this.blazePipelineBuilder.withBlend(this.blendFunction);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.blazePipelineBuilder.withoutBlend();
|
||||
}
|
||||
|
||||
switch (this.depthTest)
|
||||
{
|
||||
case NONE:
|
||||
|
||||
break;
|
||||
case LESS:
|
||||
break;
|
||||
}
|
||||
this.blazepipelineBuilder.withDepthTest(RenderPipelineBuilderWrapper.EDhDepthTest.NONE);
|
||||
|
||||
#else
|
||||
|
||||
CompareOp compareOp;
|
||||
switch (this.depthTest)
|
||||
{
|
||||
case NONE:
|
||||
compareOp = CompareOp.ALWAYS_PASS;
|
||||
break;
|
||||
case LESS:
|
||||
compareOp = CompareOp.LESS_THAN;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("No depth test defined for type ["+this.depthTest+"].");
|
||||
}
|
||||
this.blazePipelineBuilder.withDepthStencilState(new DepthStencilState(compareOp, this.writeDepth));
|
||||
|
||||
this.blazePipelineBuilder.withColorTargetState(
|
||||
new ColorTargetState(
|
||||
Optional.ofNullable(this.blendFunction),
|
||||
this.writeColor ? ColorTargetState.WRITE_ALL : ColorTargetState.WRITE_NONE
|
||||
)
|
||||
);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// vertex format
|
||||
{
|
||||
VertexFormat.Mode blazeVertexMode;
|
||||
switch (this.vertexMode)
|
||||
{
|
||||
case TRIANGLES:
|
||||
blazeVertexMode = VertexFormat.Mode.TRIANGLES;
|
||||
break;
|
||||
case TRIANGLE_FAN:
|
||||
blazeVertexMode = VertexFormat.Mode.TRIANGLE_FAN;
|
||||
break;
|
||||
case LINES:
|
||||
blazeVertexMode = VertexFormat.Mode.DEBUG_LINES;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("No vertex mode defined for type ["+this.vertexMode+"].");
|
||||
}
|
||||
|
||||
this.blazePipelineBuilder.withVertexFormat(vertexFormat, blazeVertexMode);
|
||||
}
|
||||
|
||||
return this.blazePipelineBuilder.build();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
//region
|
||||
|
||||
private static boolean isValidIdentifier(String identifier)
|
||||
{
|
||||
for (int i = 0; i < identifier.length(); i++)
|
||||
{
|
||||
char ch = identifier.charAt(i);
|
||||
if (!isValidNamespaceChar(ch))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private static boolean isValidNamespaceChar(final char ch)
|
||||
{
|
||||
return ch == '_'
|
||||
|| ch == '-'
|
||||
// only lower case characters
|
||||
|| (ch >= 'a' && ch <= 'z')
|
||||
|| (ch >= '0' && ch <= '9')
|
||||
|| ch == '.';
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
//region
|
||||
|
||||
public enum EDhPolygonMode
|
||||
{
|
||||
FILL,
|
||||
WIREFRAME;
|
||||
}
|
||||
|
||||
public enum EDhVertexMode
|
||||
{
|
||||
TRIANGLES,
|
||||
TRIANGLE_FAN,
|
||||
LINES;
|
||||
}
|
||||
|
||||
public enum EDhDepthTest
|
||||
{
|
||||
NONE,
|
||||
LESS;
|
||||
}
|
||||
|
||||
private enum EDhShaderType
|
||||
{
|
||||
FRAGMENT(".fsh"),
|
||||
VERTEX(".vsh");
|
||||
|
||||
|
||||
public final String fileExtension;
|
||||
|
||||
EDhShaderType(String fileExtension)
|
||||
{
|
||||
this.fileExtension = fileExtension;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-219
@@ -1,219 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.wrappers.buffer;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeVertexBufferWrapper {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.IndexBufferBuilder;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class BlazeVertexBufferWrapper implements IVertexBufferWrapper
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final AbstractDhRenderApiDefinition RENDER_DEF = SingletonInjector.INSTANCE.get(AbstractDhRenderApiDefinition.class);
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
private static final AtomicInteger BUFFER_COUNT_REF = new AtomicInteger(0);
|
||||
|
||||
|
||||
public final String name;
|
||||
public String getName() { return this.name; }
|
||||
|
||||
public GpuBuffer vertexGpuBuffer = null;
|
||||
|
||||
public int vertexCount = -1;
|
||||
public int indexCount = -1;
|
||||
public boolean uploaded = false;
|
||||
|
||||
|
||||
private GpuBuffer indexGpuBuffer = null;
|
||||
private static GpuBuffer GLOBAL_INDEX_GPU_BUFFER = null;
|
||||
public GpuBuffer getIndexGpuBuffer()
|
||||
{
|
||||
if (RENDER_DEF.useSingleIbo())
|
||||
{
|
||||
return GLOBAL_INDEX_GPU_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.indexGpuBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
static
|
||||
{
|
||||
if (RENDER_DEF.useSingleIbo())
|
||||
{
|
||||
RenderThreadTaskHandler.INSTANCE.queueRunningOnRenderThread("Global IBO Creation", () ->
|
||||
{
|
||||
int maxSize = LodQuadBuilder.getMaxBufferByteSize();
|
||||
int maxVertexCount = maxSize / LodQuadBuilder.BYTES_PER_VERTEX;
|
||||
int maxQuadCount = (maxVertexCount / 4);
|
||||
ByteBuffer indexBuffer = IndexBufferBuilder.createBuffer(maxQuadCount);
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_INDEX;
|
||||
GLOBAL_INDEX_GPU_BUFFER = GPU_DEVICE.createBuffer(BlazeVertexBufferWrapper::getIndexBufferName, usage, indexBuffer.capacity());
|
||||
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(GLOBAL_INDEX_GPU_BUFFER, /*offset*/ 0, indexBuffer.capacity());
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
|
||||
|
||||
MemoryUtil.memFree(indexBuffer);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public BlazeVertexBufferWrapper(String name) { this.name = name; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// upload //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void uploadVertexBuffer(ByteBuffer vertexBuffer, int vertexCount)
|
||||
{
|
||||
int oldVertexCount = this.vertexCount;
|
||||
|
||||
this.vertexCount = vertexCount;
|
||||
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
|
||||
this.indexCount = (int)(vertexCount * 1.5);
|
||||
this.uploaded = true;
|
||||
|
||||
|
||||
|
||||
if (this.vertexGpuBuffer == null
|
||||
// recreating if the size changes is always necessary (even if we only need a smaller amount)
|
||||
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|
||||
|| oldVertexCount != vertexCount)
|
||||
{
|
||||
if (this.vertexGpuBuffer == null)
|
||||
{
|
||||
BUFFER_COUNT_REF.incrementAndGet();
|
||||
//LOGGER.info("Create, count: ["+BUFFER_COUNT_REF.get()+"]");
|
||||
}
|
||||
|
||||
if (this.vertexGpuBuffer != null)
|
||||
{
|
||||
this.vertexGpuBuffer.close();
|
||||
}
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX;
|
||||
int byteSize = (vertexBuffer.limit() - vertexBuffer.position());
|
||||
this.vertexGpuBuffer = GPU_DEVICE.createBuffer(this::getName, usage, byteSize);
|
||||
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.vertexGpuBuffer, /*offset*/0, byteSize);
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, vertexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadIndexBuffer(ByteBuffer buffer, int vertexCount)
|
||||
{
|
||||
int oldIndexCount = this.indexCount;
|
||||
// 4 vertices per face, but 6 indices (IE 2 triangles) per face, aka need to multiply by 1.5
|
||||
this.indexCount = (int)(vertexCount * 1.5);
|
||||
|
||||
if (RENDER_DEF.useSingleIbo())
|
||||
{
|
||||
// ignore index uploading when running a single IBO
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// recreating if the size changes is always necessary (even if we only need a smaller amount)
|
||||
// due to a bug on Mac where it will attempt to render anything allocated in the buffer
|
||||
if (this.indexGpuBuffer == null
|
||||
|| oldIndexCount != this.indexCount)
|
||||
{
|
||||
if (this.indexGpuBuffer == null)
|
||||
{
|
||||
BUFFER_COUNT_REF.incrementAndGet();
|
||||
}
|
||||
|
||||
if (this.indexGpuBuffer != null)
|
||||
{
|
||||
this.indexGpuBuffer.close();
|
||||
}
|
||||
|
||||
ByteBuffer indexBuffer = IndexBufferBuilder.createBuffer(this.vertexCount);
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_INDEX;
|
||||
this.indexGpuBuffer = GPU_DEVICE.createBuffer(BlazeVertexBufferWrapper::getIndexBufferName, usage, indexBuffer.capacity());
|
||||
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.indexGpuBuffer, /*offset*/ 0, indexBuffer.capacity());
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, indexBuffer);
|
||||
|
||||
MemoryUtil.memFree(indexBuffer);
|
||||
|
||||
}
|
||||
}
|
||||
private static String getIndexBufferName() { return "distantHorizons:LodIndexBuffer"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
if (this.vertexGpuBuffer != null)
|
||||
{
|
||||
BUFFER_COUNT_REF.decrementAndGet();
|
||||
this.vertexGpuBuffer.close();
|
||||
}
|
||||
|
||||
if (this.indexGpuBuffer != null)
|
||||
{
|
||||
BUFFER_COUNT_REF.decrementAndGet();
|
||||
this.indexGpuBuffer.close();
|
||||
}
|
||||
|
||||
//LOGGER.info("Close, count: ["+BUFFER_COUNT_REF.get()+"]");
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-72
@@ -1,72 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.wrappers.texture;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeTextureViewWrapper {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
|
||||
import java.util.OptionalDouble;
|
||||
|
||||
public class BlazeTextureViewWrapper
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
|
||||
public GpuTextureView textureView = null;
|
||||
public GpuSampler textureSampler = null;
|
||||
|
||||
|
||||
|
||||
//=======//
|
||||
// setup //
|
||||
//=======//
|
||||
//region
|
||||
|
||||
/** does nothing if the texture is already wrapped */
|
||||
public void tryWrap(GpuTexture texture)
|
||||
{
|
||||
this.tryRecreateTextureView(texture);
|
||||
this.tryCreateSampler();
|
||||
}
|
||||
private void tryRecreateTextureView(GpuTexture texture)
|
||||
{
|
||||
if (this.textureView == null
|
||||
|| this.textureView.texture() != texture)
|
||||
{
|
||||
if (this.textureView != null)
|
||||
{
|
||||
this.textureView.close();
|
||||
}
|
||||
|
||||
this.textureView = GPU_DEVICE.createTextureView(texture);
|
||||
}
|
||||
}
|
||||
private void tryCreateSampler()
|
||||
{
|
||||
if (this.textureSampler == null)
|
||||
{
|
||||
this.textureSampler = GPU_DEVICE.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.LINEAR, FilterMode.LINEAR, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-167
@@ -1,167 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.wrappers.texture;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeTextureWrapper {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.textures.*;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.util.ColorUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
|
||||
import java.util.OptionalDouble;
|
||||
|
||||
public class BlazeTextureWrapper
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
|
||||
public final String name;
|
||||
public final TextureFormat textureFormat;
|
||||
|
||||
public GpuTexture texture = null;
|
||||
public GpuTextureView textureView = null;
|
||||
public GpuSampler textureSampler = null;
|
||||
|
||||
private int width = -1;
|
||||
private int height = -1;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
//region
|
||||
|
||||
public static BlazeTextureWrapper createDepth(String name) { return new BlazeTextureWrapper(name, TextureFormat.DEPTH32); }
|
||||
public static BlazeTextureWrapper createColor(String name) { return new BlazeTextureWrapper(name, TextureFormat.RGBA8); }
|
||||
|
||||
private BlazeTextureWrapper(String name, TextureFormat textureFormat)
|
||||
{
|
||||
this.name = name;
|
||||
this.textureFormat = textureFormat;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public boolean isEmpty() { return this.texture == null; }
|
||||
|
||||
/** @return -1 if the texture is null */
|
||||
public int getWidth() { return this.width; }
|
||||
/** @return -1 if the texture is null */
|
||||
public int getHeight() { return this.height; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=======//
|
||||
// setup //
|
||||
//=======//
|
||||
//region
|
||||
|
||||
/** does nothing if the texture is already created and the correct size */
|
||||
public void tryCreateOrResize()
|
||||
{
|
||||
this.tryCreateTexture();
|
||||
this.tryCreateSampler();
|
||||
}
|
||||
private void tryCreateTexture()
|
||||
{
|
||||
int viewWidth = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||
int viewHeight = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||
|
||||
if (this.texture == null
|
||||
|| this.width != viewWidth
|
||||
|| this.height != viewHeight)
|
||||
{
|
||||
if (this.texture != null)
|
||||
{
|
||||
this.texture.close();
|
||||
this.textureView.close();
|
||||
}
|
||||
|
||||
this.width = viewWidth;
|
||||
this.height = viewHeight;
|
||||
|
||||
int usage = GpuTexture.USAGE_COPY_DST
|
||||
| GpuTexture.USAGE_TEXTURE_BINDING
|
||||
| GpuTexture.USAGE_COPY_SRC
|
||||
| GpuTexture.USAGE_RENDER_ATTACHMENT;
|
||||
this.texture = GPU_DEVICE.createTexture(this.name,
|
||||
usage,
|
||||
this.textureFormat,
|
||||
viewWidth, viewHeight,
|
||||
/*depthOrLayers*/ 1, /*mipLevels*/ 1
|
||||
);
|
||||
this.textureView = GPU_DEVICE.createTextureView(this.texture);
|
||||
}
|
||||
}
|
||||
private void tryCreateSampler()
|
||||
{
|
||||
if (this.textureSampler == null)
|
||||
{
|
||||
this.textureSampler = GPU_DEVICE.createSampler(
|
||||
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, // U,V
|
||||
FilterMode.LINEAR, FilterMode.LINEAR, // minFilter, magFilter
|
||||
1, // maxAnisotropy
|
||||
OptionalDouble.empty() // maxLod
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// clearing //
|
||||
//==========//
|
||||
//region
|
||||
|
||||
/**
|
||||
* Will throw an exception if not a color texture.
|
||||
* @see ColorUtil#argbToInt
|
||||
*/
|
||||
public void clearColor(int clearArgbColor)
|
||||
{
|
||||
if (this.texture != null)
|
||||
{
|
||||
COMMAND_ENCODER.clearColorTexture(this.texture, clearArgbColor);
|
||||
}
|
||||
}
|
||||
|
||||
/** Will throw an exception if not a depth texture. */
|
||||
public void clearDepth(float depth)
|
||||
{
|
||||
if (this.texture != null)
|
||||
{
|
||||
COMMAND_ENCODER.clearDepthTexture(this.texture, depth);
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.wrappers.uniform;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeLodUniformBufferWrapper {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.Std140Builder;
|
||||
import com.mojang.blaze3d.buffers.Std140SizeCalculator;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class BlazeLodUniformBufferWrapper extends BlazeUniformBufferWrapper implements ILodContainerUniformBufferWrapper
|
||||
{
|
||||
|
||||
private boolean uploaded = false;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public BlazeLodUniformBufferWrapper() { super(BlazeLodUniformBufferWrapper.class.getName()); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// upload //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void createUniformData(LodBufferContainer bufferContainer)
|
||||
{
|
||||
Vec3f modelOffset = new Vec3f(
|
||||
(float) (bufferContainer.minCornerBlockPos.getX()),
|
||||
(float) (bufferContainer.minCornerBlockPos.getY()),
|
||||
(float) (bufferContainer.minCornerBlockPos.getZ()));
|
||||
|
||||
// upload data //
|
||||
|
||||
int uniformBufferSize = new Std140SizeCalculator()
|
||||
.putVec3() // uModelOffset
|
||||
.get();
|
||||
|
||||
ByteBuffer buffer = this.getOrCreateBuffer(uniformBufferSize);
|
||||
Std140Builder.intoBuffer(buffer)
|
||||
.putVec3(modelOffset.x, modelOffset.y, modelOffset.z) // uModelOffset
|
||||
.get();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tryUpload()
|
||||
{
|
||||
if (this.uploaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.upload();
|
||||
|
||||
this.uploaded = true;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-130
@@ -1,130 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.blaze.wrappers.uniform;
|
||||
|
||||
#if MC_VER <= MC_1_21_10
|
||||
public class BlazeUniformBufferWrapper {}
|
||||
|
||||
#else
|
||||
|
||||
import com.mojang.blaze3d.buffers.GpuBuffer;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.systems.CommandEncoder;
|
||||
import com.mojang.blaze3d.systems.GpuDevice;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IUniformBufferWrapper;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class BlazeUniformBufferWrapper implements IUniformBufferWrapper
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final GpuDevice GPU_DEVICE = RenderSystem.getDevice();
|
||||
private static final CommandEncoder COMMAND_ENCODER = GPU_DEVICE.createCommandEncoder();
|
||||
|
||||
|
||||
private final String name;
|
||||
|
||||
private int cpuBufferSize = 0;
|
||||
private int gpuBufferSize = 0;
|
||||
|
||||
private ByteBuffer cpuBuffer = null;
|
||||
public GpuBuffer gpuBuffer = null;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public BlazeUniformBufferWrapper(String name) { this.name = name; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
protected ByteBuffer getOrCreateBuffer(int size)
|
||||
{
|
||||
if (this.cpuBuffer == null
|
||||
|| this.cpuBufferSize != size)
|
||||
{
|
||||
this.cpuBuffer = ByteBuffer.allocateDirect(size);
|
||||
this.cpuBuffer.order(ByteOrder.nativeOrder());
|
||||
|
||||
this.cpuBufferSize = size;
|
||||
}
|
||||
|
||||
return this.cpuBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upload() throws IllegalStateException
|
||||
{
|
||||
if (this.cpuBuffer == null)
|
||||
{
|
||||
throw new IllegalStateException("Upload called before buffer was created");
|
||||
}
|
||||
|
||||
if (this.gpuBuffer == null
|
||||
|| this.gpuBufferSize != this.cpuBufferSize)
|
||||
{
|
||||
if (this.gpuBuffer != null)
|
||||
{
|
||||
this.gpuBuffer.close();
|
||||
}
|
||||
|
||||
int usage = GpuBuffer.USAGE_COPY_DST
|
||||
| GpuBuffer.USAGE_VERTEX
|
||||
| GpuBuffer.USAGE_UNIFORM;
|
||||
this.gpuBuffer = GPU_DEVICE.createBuffer(this::getBufferName, usage, this.cpuBufferSize);
|
||||
|
||||
this.gpuBufferSize = this.cpuBufferSize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int byteSize = (this.cpuBuffer.limit() - this.cpuBuffer.position());
|
||||
GpuBufferSlice bufferSlice = new GpuBufferSlice(this.gpuBuffer, /*offset*/0, byteSize);
|
||||
if (!bufferSlice.buffer().isClosed())
|
||||
{
|
||||
COMMAND_ENCODER.writeToBuffer(bufferSlice, this.cpuBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warn("Uploading to buffer ["+this.name+"] failed due to already being closed");
|
||||
}
|
||||
}
|
||||
private String getBufferName() { return this.name; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// base overrides //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
if (this.gpuBuffer != null)
|
||||
{
|
||||
this.gpuBuffer.close();
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
-197
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.openGl;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLIndexBuffer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.shader.GlShaderProgram;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlAbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexPointer;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Handles rendering the wireframe particles
|
||||
* that are used for seeing what the system's doing.
|
||||
*/
|
||||
public class GlDhDebugWireframeRenderer extends AbstractDebugWireframeRenderer
|
||||
{
|
||||
public static GlDhDebugWireframeRenderer INSTANCE = new GlDhDebugWireframeRenderer();
|
||||
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
||||
|
||||
|
||||
|
||||
// rendering setup
|
||||
private GlShaderProgram basicShader;
|
||||
private GLVertexBuffer vertexBuffer;
|
||||
private GLIndexBuffer indexBuffer;
|
||||
private GlAbstractVertexAttribute va;
|
||||
private boolean init = false;
|
||||
|
||||
|
||||
|
||||
/** A box from 0,0,0 to 1,1,1 */
|
||||
private static final float[] BOX_VERTICES = {
|
||||
//region
|
||||
// Pos x y z
|
||||
0, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
0, 1, 1,
|
||||
//endregion
|
||||
};
|
||||
|
||||
private static final int[] BOX_OUTLINE_INDICES = {
|
||||
//region
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
|
||||
4, 5,
|
||||
5, 6,
|
||||
6, 7,
|
||||
7, 4,
|
||||
|
||||
0, 4,
|
||||
1, 5,
|
||||
2, 6,
|
||||
3, 7,
|
||||
//endregion
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private GlDhDebugWireframeRenderer() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
this.va = GlAbstractVertexAttribute.create();
|
||||
this.va.bind();
|
||||
// Pos
|
||||
this.va.setVertexAttribute(0, 0, GlVertexPointer.addVec3Pointer(false));
|
||||
this.va.completeAndCheck(Float.BYTES * 3);
|
||||
this.basicShader = new GlShaderProgram(
|
||||
"assets/distanthorizons/shaders/debug/gl/vert.vert",
|
||||
"assets/distanthorizons/shaders/debug/gl/frag.frag",
|
||||
"vPosition"
|
||||
);
|
||||
this.createBuffer();
|
||||
}
|
||||
|
||||
private void createBuffer()
|
||||
{
|
||||
// box vertices
|
||||
ByteBuffer boxVerticesBuffer = ByteBuffer.allocateDirect(BOX_VERTICES.length * Float.BYTES);
|
||||
boxVerticesBuffer.order(ByteOrder.nativeOrder());
|
||||
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
boxVerticesBuffer.rewind();
|
||||
this.vertexBuffer = new GLVertexBuffer(false);
|
||||
this.vertexBuffer.bind();
|
||||
this.vertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
|
||||
|
||||
|
||||
// outline vertex indexes
|
||||
ByteBuffer boxOutlineBuffer = ByteBuffer.allocateDirect(BOX_OUTLINE_INDICES.length * Integer.BYTES);
|
||||
boxOutlineBuffer.order(ByteOrder.nativeOrder());
|
||||
boxOutlineBuffer.asIntBuffer().put(BOX_OUTLINE_INDICES);
|
||||
boxOutlineBuffer.rewind();
|
||||
this.indexBuffer = new GLIndexBuffer(false);
|
||||
this.indexBuffer.uploadBuffer(boxOutlineBuffer, EDhApiGpuUploadMethod.DATA, BOX_OUTLINE_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderParams)
|
||||
{
|
||||
this.init();
|
||||
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
GLMC.enableDepthTest();
|
||||
|
||||
this.basicShader.bind();
|
||||
this.va.bind();
|
||||
this.va.bindBufferToAllBindingPoints(this.vertexBuffer.getId());
|
||||
|
||||
this.indexBuffer.bind();
|
||||
|
||||
super.render(renderParams);
|
||||
|
||||
// revert to prevent issues with the following passes
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderBox(Box box)
|
||||
{
|
||||
Mat4f boxTransform = Mat4f.createTranslateMatrix(box.minPos.x - this.camPosFloatThisFrame.x, box.minPos.y - this.camPosFloatThisFrame.y, box.minPos.z - this.camPosFloatThisFrame.z);
|
||||
boxTransform.multiply(Mat4f.createScaleMatrix(box.maxPos.x - box.minPos.x, box.maxPos.y - box.minPos.y, box.maxPos.z - box.minPos.z));
|
||||
|
||||
Mat4f transformMatrix = this.dhMvmProjMatrixThisFrame.copy();
|
||||
transformMatrix.multiply(boxTransform);
|
||||
this.basicShader.setUniform(this.basicShader.getUniformLocation("uTransform"), transformMatrix);
|
||||
|
||||
this.basicShader.setUniform(this.basicShader.getUniformLocation("uColor"), box.color);
|
||||
|
||||
GL32.glDrawElements(GL32.GL_LINES, BOX_OUTLINE_INDICES.length, GL32.GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-468
@@ -1,468 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.openGl;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiFramebuffer;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiShaderProgram;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiTextureCreatedParam;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.GlDhFramebuffer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.texture.*;
|
||||
import com.seibel.distanthorizons.common.render.openGl.postProcessing.apply.GlDhApplyShader;
|
||||
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.render.DhApiRenderProxy;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhMetaRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
|
||||
public class GlDhMetaRenderer implements IDhMetaRenderer
|
||||
{
|
||||
public static final DhLogger LOGGER = new DhLoggerBuilder()
|
||||
.fileLevelConfig(Config.Common.Logging.logRendererEventToFile)
|
||||
.build();
|
||||
|
||||
public static final DhLogger RATE_LIMITED_LOGGER = new DhLoggerBuilder()
|
||||
.fileLevelConfig(Config.Common.Logging.logRendererEventToFile)
|
||||
.maxCountPerSecond(4)
|
||||
.build();
|
||||
|
||||
public static final GlDhMetaRenderer INSTANCE = new GlDhMetaRenderer();
|
||||
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
||||
|
||||
|
||||
private int activeFramebufferId = -1;
|
||||
private int activeColorTextureId = -1;
|
||||
private int activeDepthTextureId = -1;
|
||||
private int textureWidth;
|
||||
private int textureHeight;
|
||||
|
||||
|
||||
// framebuffer and texture ID's for this renderer
|
||||
private IDhApiFramebuffer framebuffer;
|
||||
/** will be null if MC's framebuffer is being used since MC already has a color texture */
|
||||
@Nullable
|
||||
private GlDhColorTexture nullableColorTexture;
|
||||
private GlDhDepthTexture depthTexture;
|
||||
/**
|
||||
* If true the {@link GlDhMetaRenderer#framebuffer} is the same as MC's.
|
||||
* This should only be true in the case of Optifine so LODs won't be overwritten when shaders are enabled.
|
||||
*/
|
||||
private boolean usingMcFramebuffer = false;
|
||||
|
||||
private boolean renderObjectsCreated = false;
|
||||
/** used in case there's an API override */
|
||||
public IDhApiShaderProgram shaderProgramForThisFrame;
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// pre render //
|
||||
//============//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void runRenderPassSetup(RenderParams renderParams)
|
||||
{
|
||||
boolean firstPass =
|
||||
(renderParams.renderPass == EDhApiRenderPass.OPAQUE
|
||||
|| renderParams.renderPass == EDhApiRenderPass.OPAQUE_AND_TRANSPARENT);
|
||||
|
||||
if (!this.renderObjectsCreated)
|
||||
{
|
||||
boolean setupSuccess = this.createRenderObjects();
|
||||
if (!setupSuccess)
|
||||
{
|
||||
// shouldn't normally happen, but just in case
|
||||
return;
|
||||
}
|
||||
|
||||
this.renderObjectsCreated = true;
|
||||
}
|
||||
|
||||
this.shaderProgramForThisFrame = GlDhTerrainRenderer.INSTANCE.getTerrainShaderProgram();
|
||||
IDhApiShaderProgram lodShaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
if (lodShaderProgramOverride != null && this.shaderProgramForThisFrame.overrideThisFrame())
|
||||
{
|
||||
this.shaderProgramForThisFrame = lodShaderProgramOverride;
|
||||
}
|
||||
|
||||
|
||||
this.setGLState(renderParams, firstPass);
|
||||
|
||||
this.bindLightmap(renderParams.lightmap);
|
||||
}
|
||||
private void setGLState(
|
||||
DhApiRenderParam renderEventParam,
|
||||
boolean firstPass)
|
||||
{
|
||||
//===================//
|
||||
// framebuffer setup //
|
||||
//===================//
|
||||
|
||||
// get the active framebuffer
|
||||
IDhApiFramebuffer framebuffer = this.framebuffer;
|
||||
IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class);
|
||||
if (framebufferOverride != null && framebufferOverride.overrideThisFrame())
|
||||
{
|
||||
framebuffer = framebufferOverride;
|
||||
}
|
||||
this.setActiveFramebufferId(framebuffer.getId());
|
||||
framebuffer.bind();
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// bindings //
|
||||
//==========//
|
||||
|
||||
// by default draw everything as triangles
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GLMC.enableFaceCulling();
|
||||
|
||||
GLMC.glBlendFunc(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ZERO);
|
||||
|
||||
GL32.glDisable(GL32.GL_SCISSOR_TEST);
|
||||
|
||||
// Enable depth test and depth mask
|
||||
GLMC.enableDepthTest();
|
||||
GLMC.glDepthFunc(GL32.GL_LESS);
|
||||
GLMC.enableDepthMask();
|
||||
|
||||
// This is required for MC versions 1.21.5+
|
||||
// due to MC updating the lightmap by changing the viewport size
|
||||
GL32.glViewport(0, 0, this.textureWidth, this.textureHeight);
|
||||
|
||||
this.shaderProgramForThisFrame.bind();
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// uniforms //
|
||||
//==========//
|
||||
|
||||
IDhApiShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiShaderProgram.class);
|
||||
if (shaderProgramOverride != null)
|
||||
{
|
||||
shaderProgramOverride.fillUniformData(renderEventParam);
|
||||
}
|
||||
|
||||
this.shaderProgramForThisFrame.fillUniformData(renderEventParam);
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// texture setup //
|
||||
//===============//
|
||||
|
||||
// resize the textures if needed
|
||||
if (MC_RENDER.getTargetFramebufferViewportWidth() != this.textureWidth
|
||||
|| MC_RENDER.getTargetFramebufferViewportHeight() != this.textureHeight)
|
||||
{
|
||||
// just resizing the textures doesn't work when Optifine is present,
|
||||
// so recreate the textures with the new size instead
|
||||
this.createAndBindTextures();
|
||||
}
|
||||
|
||||
|
||||
// set the active textures
|
||||
int depthTextureId = this.depthTexture.getTextureId();
|
||||
this.setActiveDepthTextureId(depthTextureId);
|
||||
|
||||
if (this.nullableColorTexture != null)
|
||||
{
|
||||
int colorTextureId = this.nullableColorTexture.getTextureId();
|
||||
this.setActiveColorTextureId(colorTextureId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// get MC's color texture
|
||||
int colorTextureId = GL32.glGetFramebufferAttachmentParameteri(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||
this.setActiveColorTextureId(colorTextureId);
|
||||
}
|
||||
|
||||
|
||||
// needs to be fired after all the textures have been created/bound
|
||||
boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderEventParam);
|
||||
if (clearTextures)
|
||||
{
|
||||
GL32.glClearDepth(1.0);
|
||||
|
||||
float[] clearColorValues = new float[4];
|
||||
GL32.glGetFloatv(GL32.GL_COLOR_CLEAR_VALUE, clearColorValues);
|
||||
GL32.glClearColor(clearColorValues[0], clearColorValues[1], clearColorValues[2], 1.0f);
|
||||
|
||||
if (this.usingMcFramebuffer && framebufferOverride == null)
|
||||
{
|
||||
// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
|
||||
// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
|
||||
framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EGlDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
|
||||
|
||||
// don't clear the color texture, that removes the sky
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else if (firstPass)
|
||||
{
|
||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean createRenderObjects()
|
||||
{
|
||||
if (this.renderObjectsCreated)
|
||||
{
|
||||
LOGGER.warn("Renderer setup called but it has already completed setup!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// GLProxy should have already been created by this point, but just in case create it now
|
||||
GLProxy.getInstance();
|
||||
|
||||
|
||||
|
||||
LOGGER.info("Setting up renderer");
|
||||
|
||||
|
||||
// create or get the frame buffer
|
||||
if (AbstractOptifineAccessor.optifinePresent())
|
||||
{
|
||||
// use MC/Optifine's default Framebuffer so shaders won't remove the LODs
|
||||
int currentFramebufferId = MC_RENDER.getTargetFramebuffer();
|
||||
this.framebuffer = new GlDhFramebuffer(currentFramebufferId);
|
||||
this.usingMcFramebuffer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal use case
|
||||
this.framebuffer = new GlDhFramebuffer();
|
||||
this.usingMcFramebuffer = false;
|
||||
}
|
||||
|
||||
// create and bind the necessary textures
|
||||
this.createAndBindTextures();
|
||||
|
||||
if(this.framebuffer.getStatus() != GL32.GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
// This generally means something wasn't bound, IE missing either the color or depth texture
|
||||
LOGGER.warn("Framebuffer ["+this.framebuffer.getId()+"] isn't complete.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LOGGER.info("Renderer setup complete");
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings( "deprecation" ) // done to ignore DhApiColorDepthTextureCreatedEvent
|
||||
private void createAndBindTextures()
|
||||
{
|
||||
int oldWidth = this.textureWidth;
|
||||
int oldHeight = this.textureHeight;
|
||||
this.textureWidth = MC_RENDER.getTargetFramebufferViewportWidth();
|
||||
this.textureHeight = MC_RENDER.getTargetFramebufferViewportHeight();
|
||||
|
||||
DhApiTextureCreatedParam textureCreatedParam = new DhApiTextureCreatedParam(
|
||||
oldWidth, oldHeight,
|
||||
this.textureWidth, this.textureHeight
|
||||
);
|
||||
|
||||
|
||||
// DhApiColorDepthTextureCreatedEvent needs to be kept around since old versions of Iris need it
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiColorDepthTextureCreatedEvent.class, new DhApiColorDepthTextureCreatedEvent.EventParam(textureCreatedParam));
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeColorDepthTextureCreatedEvent.class, textureCreatedParam);
|
||||
|
||||
|
||||
// also update the framebuffer override if present
|
||||
IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class);
|
||||
|
||||
|
||||
this.depthTexture = new GlDhDepthTexture(this.textureWidth, this.textureHeight, EGlDhDepthBufferFormat.DEPTH32F);
|
||||
this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EGlDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
if (framebufferOverride != null)
|
||||
{
|
||||
framebufferOverride.addDepthAttachment(this.depthTexture.getTextureId(), EGlDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
}
|
||||
|
||||
|
||||
// if we are using MC's frame buffer, a color texture is already present and shouldn't need to be bound
|
||||
if (!this.usingMcFramebuffer)
|
||||
{
|
||||
this.nullableColorTexture = GlDhColorTexture.builder()
|
||||
.setDimensions(this.textureWidth, this.textureHeight)
|
||||
.setInternalFormat(EGlDhInternalTextureFormat.RGBA8)
|
||||
.setPixelType(EGlDhPixelType.UNSIGNED_BYTE)
|
||||
.setPixelFormat(EGlDhPixelFormat.RGBA)
|
||||
.build();
|
||||
|
||||
this.framebuffer.addColorAttachment(0, this.nullableColorTexture.getTextureId());
|
||||
if (framebufferOverride != null)
|
||||
{
|
||||
framebufferOverride.addColorAttachment(0, this.nullableColorTexture.getTextureId());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.nullableColorTexture = null;
|
||||
}
|
||||
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiAfterColorDepthTextureCreatedEvent.class, textureCreatedParam);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// post render //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void runRenderPassCleanup(RenderParams renderParams)
|
||||
{
|
||||
boolean runningDeferredPass = (renderParams.renderPass == EDhApiRenderPass.TRANSPARENT);
|
||||
if (!runningDeferredPass)
|
||||
{
|
||||
//===================//
|
||||
// optifine clean up //
|
||||
//===================//
|
||||
|
||||
if (this.usingMcFramebuffer)
|
||||
{
|
||||
// If MC's framebuffer is being used the depth needs to be cleared to prevent rendering on top of MC.
|
||||
// This should only happen when Optifine shaders are being used.
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.unbindLightmap();
|
||||
this.shaderProgramForThisFrame.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyToMcTexture(RenderParams renderParams) { GlDhApplyShader.INSTANCE.render(renderParams); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// clear textures //
|
||||
//================//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void clearDhDepthAndColorTextures(RenderParams renderParams)
|
||||
{
|
||||
IDhApiFramebuffer framebufferOverride = OverrideInjector.INSTANCE.get(IDhApiFramebuffer.class);
|
||||
|
||||
boolean firstPass =
|
||||
(renderParams.renderPass == EDhApiRenderPass.OPAQUE
|
||||
|| renderParams.renderPass == EDhApiRenderPass.OPAQUE_AND_TRANSPARENT);
|
||||
|
||||
|
||||
|
||||
// needs to be fired after all the textures have been created/bound
|
||||
boolean clearTextures = !ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeTextureClearEvent.class, renderParams);
|
||||
if (clearTextures)
|
||||
{
|
||||
GL32.glClearDepth(1.0);
|
||||
|
||||
float[] clearColorValues = new float[4];
|
||||
GL32.glGetFloatv(GL32.GL_COLOR_CLEAR_VALUE, clearColorValues);
|
||||
GL32.glClearColor(clearColorValues[0], clearColorValues[1], clearColorValues[2], 1.0f);
|
||||
|
||||
if (this.usingMcFramebuffer
|
||||
&& framebufferOverride == null)
|
||||
{
|
||||
//// Due to using MC/Optifine's framebuffer we need to re-bind the depth texture,
|
||||
//// otherwise we'll be writing to MC/Optifine's depth texture which causes rendering issues
|
||||
//this.framebuffer.addDepthAttachment(this.depthTexture.getTextureId(), EDhDepthBufferFormat.DEPTH32F.isCombinedStencil());
|
||||
|
||||
|
||||
// don't clear the color texture, that removes the sky
|
||||
GL32.glClear(GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
else if (firstPass)
|
||||
{
|
||||
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT | GL32.GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===============//
|
||||
// API functions //
|
||||
//===============//
|
||||
//region
|
||||
|
||||
public void setActiveFramebufferId(int id) { this.activeFramebufferId = id; }
|
||||
/** @return -1 if no frame buffer has been bound yet */
|
||||
public int getActiveFramebufferId() { return this.activeFramebufferId; }
|
||||
|
||||
public void setActiveColorTextureId(int id)
|
||||
{
|
||||
this.activeColorTextureId = id;
|
||||
DhApiRenderProxy.activeOpenGlDhColorTextureId = id;
|
||||
}
|
||||
/** @return -1 if no texture has been bound yet */
|
||||
public int getActiveColorTextureId() { return this.activeColorTextureId; }
|
||||
|
||||
public void setActiveDepthTextureId(int id)
|
||||
{
|
||||
this.activeDepthTextureId = id;
|
||||
DhApiRenderProxy.activeOpenGlDhDepthTextureId = id;
|
||||
}
|
||||
/** @return -1 if no texture has been bound yet */
|
||||
public int getActiveDepthTextureId() { return this.activeDepthTextureId; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
//================//
|
||||
// helper methods //
|
||||
//================//
|
||||
//region
|
||||
|
||||
public void bindLightmap(ILightMapWrapper lightMapWrapper)
|
||||
{
|
||||
LightMapWrapper lightMap = (LightMapWrapper)lightMapWrapper;
|
||||
GLMC.glActiveTexture(GL32.GL_TEXTURE0 + LightMapWrapper.GL_BOUND_INDEX);
|
||||
GLMC.glBindTexture(lightMap.getOpenGlId());
|
||||
}
|
||||
|
||||
public void unbindLightmap()
|
||||
{
|
||||
// strange that we don't call "glActiveTexture" here but since it's working James isn't going to change it right now (2026-03-10)
|
||||
GLMC.glBindTexture(0);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.openGl;
|
||||
|
||||
import com.seibel.distanthorizons.common.render.openGl.generic.GlGenericObjectRenderer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.generic.GlGenericObjectVertexContainer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.GlDummyUniformData;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.postProcessing.fade.GlDhFarFadeRenderer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.postProcessing.fade.GlVanillaFadeRenderer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.postProcessing.fog.GlDhFogRenderer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.postProcessing.ssao.GlDhSSAORenderer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
|
||||
import com.seibel.distanthorizons.common.render.openGl.test.GlTestTriangleRenderer;
|
||||
import com.seibel.distanthorizons.core.render.renderer.AbstractDebugWireframeRenderer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.AbstractDhRenderApiDefinition;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IDhGenericObjectVertexBufferContainer;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.ILodContainerUniformBufferWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.objects.IVertexBufferWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.*;
|
||||
|
||||
public class GlDhRenderApiDefinition extends AbstractDhRenderApiDefinition
|
||||
{
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public String getApiName() { return "OpenGL"; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// singletons //
|
||||
//============//
|
||||
//region
|
||||
|
||||
@Override public IDhMetaRenderer getMetaRenderer() { return GlDhMetaRenderer.INSTANCE; }
|
||||
@Override public IDhTerrainRenderer getTerrainRenderer() { return GlDhTerrainRenderer.INSTANCE; }
|
||||
@Override public IDhSsaoRenderer getSsaoRenderer() { return GlDhSSAORenderer.INSTANCE; }
|
||||
@Override public IDhFogRenderer getFogRenderer() { return GlDhFogRenderer.INSTANCE; }
|
||||
@Override public IDhFarFadeRenderer getFarFadeRenderer() { return GlDhFarFadeRenderer.INSTANCE; }
|
||||
@Override public AbstractDebugWireframeRenderer getDebugWireframeRenderer() { return GlDhDebugWireframeRenderer.INSTANCE; }
|
||||
|
||||
@Override public IDhVanillaFadeRenderer getVanillaFadeRenderer() { return GlVanillaFadeRenderer.INSTANCE; }
|
||||
@Override public IDhTestTriangleRenderer getTestTriangleRenderer() { return GlTestTriangleRenderer.INSTANCE; }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// factories //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
@Override public IDhGenericRenderer createGenericRenderer() { return new GlGenericObjectRenderer(); }
|
||||
|
||||
@Override public IVertexBufferWrapper createVboWrapper(String name) { return new GLVertexBuffer(); }
|
||||
@Override public ILodContainerUniformBufferWrapper createLodContainerUniformWrapper() { return new GlDummyUniformData(); }
|
||||
@Override public IDhGenericObjectVertexBufferContainer createGenericVboContainer() { return new GlGenericObjectVertexContainer(); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.openGl;
|
||||
|
||||
import com.seibel.distanthorizons.common.render.openGl.terrain.GlDhTerrainShaderProgram;
|
||||
import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBufferContainer;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.util.objects.SortedArraySet;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhTerrainRenderer;
|
||||
|
||||
public class GlDhTerrainRenderer implements IDhTerrainRenderer
|
||||
{
|
||||
public static final GlDhTerrainRenderer INSTANCE = new GlDhTerrainRenderer();
|
||||
|
||||
private GlDhTerrainShaderProgram terrainShaderProgram = null;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
private GlDhTerrainRenderer() {}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
/** must be called on the render thread the first time so GL can run it's setup */
|
||||
public GlDhTerrainShaderProgram getTerrainShaderProgram()
|
||||
{
|
||||
if (this.terrainShaderProgram == null)
|
||||
{
|
||||
this.terrainShaderProgram = new GlDhTerrainShaderProgram();
|
||||
}
|
||||
|
||||
return this.terrainShaderProgram;
|
||||
}
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//========//
|
||||
// render //
|
||||
//========//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void render(RenderParams renderEventParam, boolean opaquePass, SortedArraySet<LodBufferContainer> bufferContainers, IProfilerWrapper profiler)
|
||||
{
|
||||
this.getTerrainShaderProgram();
|
||||
|
||||
this.terrainShaderProgram.tryInit();
|
||||
this.terrainShaderProgram.render(renderEventParam, opaquePass, bufferContainers, profiler);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-754
@@ -1,754 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.common.render.openGl.generic;
|
||||
|
||||
import com.seibel.distanthorizons.api.enums.config.EDhApiGpuUploadMethod;
|
||||
import com.seibel.distanthorizons.api.enums.rendering.EDhApiBlockMaterial;
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
|
||||
import com.seibel.distanthorizons.api.methods.events.abstractEvents.*;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.GLProxy;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLIndexBuffer;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.buffer.GLVertexBuffer;
|
||||
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftGLWrapper;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.jar.EPlatform;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.logging.f3.F3Screen;
|
||||
import com.seibel.distanthorizons.core.render.RenderParams;
|
||||
import com.seibel.distanthorizons.core.render.renderer.GenericRenderObjectFactory;
|
||||
import com.seibel.distanthorizons.core.render.renderer.RenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3d;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.render.renderPass.IDhGenericRenderer;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
|
||||
import com.seibel.distanthorizons.coreapi.DependencyInjection.OverrideInjector;
|
||||
import com.seibel.distanthorizons.coreapi.ModInfo;
|
||||
import org.lwjgl.opengl.ARBInstancedArrays;
|
||||
import org.lwjgl.opengl.GL32;
|
||||
import org.lwjgl.opengl.GL33;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Handles rendering generic groups of {@link DhApiRenderableBox}.
|
||||
*
|
||||
* @see IDhApiCustomRenderRegister
|
||||
* @see DhApiRenderableBox
|
||||
*/
|
||||
public class GlGenericObjectRenderer implements IDhGenericRenderer
|
||||
{
|
||||
private static final DhLogger LOGGER = new DhLoggerBuilder().build();
|
||||
|
||||
private static final IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
|
||||
private static final MinecraftGLWrapper GLMC = MinecraftGLWrapper.INSTANCE;
|
||||
|
||||
private static final DhApiRenderableBoxGroupShading DEFAULT_SHADING = DhApiRenderableBoxGroupShading.getUnshaded();
|
||||
|
||||
|
||||
/**
|
||||
* Can be used to troubleshoot the renderer.
|
||||
* If enabled several debug objects will render around (0,150,0).
|
||||
*/
|
||||
public static final boolean RENDER_DEBUG_OBJECTS = false;
|
||||
|
||||
|
||||
// rendering setup
|
||||
private boolean init = false;
|
||||
|
||||
private IDhApiGenericObjectShaderProgram instancedShaderProgram;
|
||||
private IDhApiGenericObjectShaderProgram directShaderProgram;
|
||||
private GLVertexBuffer boxVertexBuffer;
|
||||
private GLIndexBuffer boxIndexBuffer;
|
||||
|
||||
private boolean instancedRenderingAvailable;
|
||||
private boolean vertexAttribDivisorSupported;
|
||||
private boolean instancedArraysSupported;
|
||||
|
||||
|
||||
|
||||
private final ConcurrentHashMap<Long, RenderableBoxGroup> boxGroupById = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
|
||||
/** A box from 0,0,0 to 1,1,1 */
|
||||
private static final float[] BOX_VERTICES = {
|
||||
//region
|
||||
// Pos x y z
|
||||
|
||||
// min X, vertical face
|
||||
0, 0, 0,
|
||||
1, 0, 0,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
// max X, vertical face
|
||||
0, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 0, 1,
|
||||
0, 0, 1,
|
||||
|
||||
// min Z, vertical face
|
||||
0, 0, 1,
|
||||
0, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 1, 1,
|
||||
// max Z, vertical face
|
||||
1, 0, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 0,
|
||||
1, 0, 0,
|
||||
|
||||
// min Y, horizontal face
|
||||
0, 0, 1,
|
||||
1, 0, 1,
|
||||
1, 0, 0,
|
||||
0, 0, 0,
|
||||
// max Y, horizontal face
|
||||
0, 1, 1,
|
||||
1, 1, 1,
|
||||
1, 1, 0,
|
||||
0, 1, 0,
|
||||
//endregion
|
||||
};
|
||||
|
||||
|
||||
private static final int[] BOX_INDICES = {
|
||||
//region
|
||||
// min X, vertical face
|
||||
2, 1, 0,
|
||||
0, 3, 2,
|
||||
// max X, vertical face
|
||||
6, 5, 4,
|
||||
4, 7, 6,
|
||||
|
||||
// min Z, vertical face
|
||||
10, 9, 8,
|
||||
8, 11, 10,
|
||||
// max Z, vertical face
|
||||
14, 13, 12,
|
||||
12, 15, 14,
|
||||
|
||||
// min Y, horizontal face
|
||||
18, 17, 16,
|
||||
16, 19, 18,
|
||||
// max Y, horizontal face
|
||||
20, 21, 22,
|
||||
22, 23, 20,
|
||||
//endregion
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
//region
|
||||
|
||||
public GlGenericObjectRenderer() { }
|
||||
|
||||
public void init()
|
||||
{
|
||||
if (this.init)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.init = true;
|
||||
|
||||
|
||||
|
||||
//===================================//
|
||||
// is instanced rendering available? //
|
||||
//===================================//
|
||||
|
||||
this.vertexAttribDivisorSupported = GLProxy.getInstance().vertexAttribDivisorSupported;
|
||||
this.instancedArraysSupported = GLProxy.getInstance().instancedArraysSupported;
|
||||
boolean isMac = (EPlatform.get() == EPlatform.MACOS);
|
||||
if (isMac)
|
||||
{
|
||||
LOGGER.warn("Generic rendering not supported by Mac. Clouds, beacons, and some other effects will be disabled.");
|
||||
Config.Client.Advanced.Graphics.GenericRendering.enableGenericRendering.setApiValue(false);
|
||||
return;
|
||||
}
|
||||
|
||||
this.instancedRenderingAvailable = (this.vertexAttribDivisorSupported || this.instancedArraysSupported) && !isMac;
|
||||
if (!this.instancedRenderingAvailable)
|
||||
{
|
||||
LOGGER.warn("Instanced rendering not supported by this GPU, falling back to direct rendering. Generic object rendering will be slow and some effects may be disabled.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//======================//
|
||||
// startup the renderer //
|
||||
//======================//
|
||||
|
||||
this.instancedShaderProgram = new GlGenericObjectShaderProgram(true);
|
||||
this.directShaderProgram = new GlGenericObjectShaderProgram(false);
|
||||
|
||||
this.createBuffers();
|
||||
|
||||
if (RENDER_DEBUG_OBJECTS)
|
||||
{
|
||||
this.addGenericDebugObjects();
|
||||
}
|
||||
}
|
||||
private void createBuffers()
|
||||
{
|
||||
// box vertices
|
||||
ByteBuffer boxVerticesBuffer = MemoryUtil.memAlloc(BOX_VERTICES.length * Float.BYTES);
|
||||
boxVerticesBuffer.asFloatBuffer().put(BOX_VERTICES);
|
||||
boxVerticesBuffer.rewind();
|
||||
this.boxVertexBuffer = new GLVertexBuffer(false);
|
||||
this.boxVertexBuffer.bind();
|
||||
this.boxVertexBuffer.uploadBuffer(boxVerticesBuffer, 8, EDhApiGpuUploadMethod.DATA, BOX_VERTICES.length * Float.BYTES);
|
||||
MemoryUtil.memFree(boxVerticesBuffer);
|
||||
|
||||
// box vertex indexes
|
||||
ByteBuffer solidIndexBuffer = MemoryUtil.memAlloc(BOX_INDICES.length * Integer.BYTES);
|
||||
solidIndexBuffer.asIntBuffer().put(BOX_INDICES);
|
||||
solidIndexBuffer.rewind();
|
||||
this.boxIndexBuffer = new GLIndexBuffer(false);
|
||||
this.boxIndexBuffer.uploadBuffer(solidIndexBuffer, EDhApiGpuUploadMethod.DATA, BOX_INDICES.length * Integer.BYTES, GL32.GL_STATIC_DRAW);
|
||||
this.boxIndexBuffer.bind();
|
||||
MemoryUtil.memFree(solidIndexBuffer);
|
||||
}
|
||||
private void addGenericDebugObjects()
|
||||
{
|
||||
GenericRenderObjectFactory factory = GenericRenderObjectFactory.INSTANCE;
|
||||
|
||||
|
||||
// single giant box
|
||||
IDhApiRenderableBoxGroup singleGiantBoxGroup = factory.createForSingleBox(
|
||||
ModInfo.NAME + ":CyanChunkBox",
|
||||
new DhApiRenderableBox(
|
||||
new DhApiVec3d(0,0,0), new DhApiVec3d(16,190,16),
|
||||
new Color(Color.CYAN.getRed(), Color.CYAN.getGreen(), Color.CYAN.getBlue(), 125),
|
||||
EDhApiBlockMaterial.WATER)
|
||||
);
|
||||
singleGiantBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
singleGiantBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.add(singleGiantBoxGroup);
|
||||
|
||||
|
||||
// single slender box
|
||||
IDhApiRenderableBoxGroup singleTallBoxGroup = factory.createForSingleBox(
|
||||
ModInfo.NAME + ":GreenBeacon",
|
||||
new DhApiRenderableBox(
|
||||
new DhApiVec3d(16,0,31), new DhApiVec3d(17,2000,32),
|
||||
new Color(Color.GREEN.getRed(), Color.GREEN.getGreen(), Color.GREEN.getBlue(), 125),
|
||||
EDhApiBlockMaterial.ILLUMINATED)
|
||||
);
|
||||
singleTallBoxGroup.setSkyLight(LodUtil.MAX_MC_LIGHT);
|
||||
singleTallBoxGroup.setBlockLight(LodUtil.MAX_MC_LIGHT);
|
||||
this.add(singleTallBoxGroup);
|
||||
|
||||
|
||||
// absolute box group
|
||||
ArrayList<DhApiRenderableBox> absBoxList = new ArrayList<>();
|
||||
for (int i = 0; i < 18; i++)
|
||||
{
|
||||
absBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(i,150+i,24), new DhApiVec3d(1+i,151+i,25),
|
||||
new Color(Color.ORANGE.getRed(), Color.ORANGE.getGreen(), Color.ORANGE.getBlue()),
|
||||
EDhApiBlockMaterial.LAVA
|
||||
)
|
||||
);
|
||||
}
|
||||
IDhApiRenderableBoxGroup absolutePosBoxGroup = factory.createAbsolutePositionedGroup(ModInfo.NAME + ":OrangeStairs", absBoxList);
|
||||
this.add(absolutePosBoxGroup);
|
||||
|
||||
|
||||
// relative box group
|
||||
ArrayList<DhApiRenderableBox> relBoxList = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i+=2)
|
||||
{
|
||||
relBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(0,i,0), new DhApiVec3d(1,1+i,1),
|
||||
new Color(Color.MAGENTA.getRed(), Color.MAGENTA.getGreen(), Color.MAGENTA.getBlue()),
|
||||
EDhApiBlockMaterial.METAL
|
||||
)
|
||||
);
|
||||
}
|
||||
IDhApiRenderableBoxGroup relativePosBoxGroup = factory.createRelativePositionedGroup(
|
||||
ModInfo.NAME + ":MovingMagentaGroup",
|
||||
new DhApiVec3d(24, 140, 24),
|
||||
relBoxList);
|
||||
relativePosBoxGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
DhApiVec3d pos = relativePosBoxGroup.getOriginBlockPos();
|
||||
pos.x += event.partialTicks / 2;
|
||||
pos.x %= 32;
|
||||
relativePosBoxGroup.setOriginBlockPos(pos);
|
||||
});
|
||||
this.add(relativePosBoxGroup);
|
||||
|
||||
|
||||
// massive relative box group
|
||||
ArrayList<DhApiRenderableBox> massRelBoxList = new ArrayList<>();
|
||||
for (int x = 0; x < 50*2; x+=2)
|
||||
{
|
||||
for (int z = 0; z < 50*2; z+=2)
|
||||
{
|
||||
massRelBoxList.add(new DhApiRenderableBox(
|
||||
new DhApiVec3d(-x, 0, -z), new DhApiVec3d(1-x, 1, 1-z),
|
||||
new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue()),
|
||||
EDhApiBlockMaterial.TERRACOTTA
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
IDhApiRenderableBoxGroup massRelativePosBoxGroup = factory.createRelativePositionedGroup(
|
||||
ModInfo.NAME + ":MassRedGroup",
|
||||
new DhApiVec3d(-25, 140, 0),
|
||||
massRelBoxList);
|
||||
massRelativePosBoxGroup.setPreRenderFunc((event) ->
|
||||
{
|
||||
DhApiVec3d blockPos = massRelativePosBoxGroup.getOriginBlockPos();
|
||||
blockPos.y += event.partialTicks / 4;
|
||||
if (blockPos.y > 150f)
|
||||
{
|
||||
blockPos.y = 140f;
|
||||
|
||||
Color newColor = (massRelativePosBoxGroup.get(0).color == Color.RED) ? Color.RED.darker() : Color.RED;
|
||||
massRelativePosBoxGroup.forEach((box) -> { box.color = newColor; });
|
||||
massRelativePosBoxGroup.triggerBoxChange();
|
||||
}
|
||||
|
||||
massRelativePosBoxGroup.setOriginBlockPos(blockPos);
|
||||
});
|
||||
this.add(massRelativePosBoxGroup);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// registration //
|
||||
//==============//
|
||||
//region
|
||||
|
||||
@Override
|
||||
public void add(IDhApiRenderableBoxGroup iBoxGroup) throws IllegalArgumentException
|
||||
{
|
||||
if (!(iBoxGroup instanceof RenderableBoxGroup))
|
||||
{
|
||||
throw new IllegalArgumentException("Box group must be of type ["+ RenderableBoxGroup.class.getSimpleName()+"], type received: ["+(iBoxGroup != null ? iBoxGroup.getClass() : "NULL")+"].");
|
||||
}
|
||||
RenderableBoxGroup boxGroup = (RenderableBoxGroup) iBoxGroup;
|
||||
if (boxGroup.size() != 0)
|
||||
{
|
||||
// trigger a box change to make sure the initial data is uploaded
|
||||
boxGroup.triggerBoxChange();
|
||||
}
|
||||
|
||||
|
||||
long id = boxGroup.getId();
|
||||
if (this.boxGroupById.containsKey(id))
|
||||
{
|
||||
throw new IllegalArgumentException("A box group with the ID [" + id + "] is already present.");
|
||||
}
|
||||
|
||||
this.boxGroupById.put(id, boxGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDhApiRenderableBoxGroup remove(long id) { return this.boxGroupById.remove(id); }
|
||||
|
||||
public void clear() { this.boxGroupById.clear(); }
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// rendering //
|
||||
//===========//
|
||||
//region
|
||||
|
||||
/**
|
||||
* @param renderingWithSsao
|
||||
* if true that means this render call is happening before the SSAO pass
|
||||
* and any objects rendered in this pass will have SSAO applied to them.
|
||||
*/
|
||||
@Override
|
||||
public void render(RenderParams renderEventParam, IProfilerWrapper profiler, boolean renderingWithSsao)
|
||||
{
|
||||
// generic rendering (both instanced and direct) is extremely unstable on Mac, so don't render anything
|
||||
if (EPlatform.get() == EPlatform.MACOS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// render setup //
|
||||
profiler.push("setup");
|
||||
|
||||
this.init();
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderSetupEvent.class, renderEventParam);
|
||||
|
||||
|
||||
boolean renderWireframe = Config.Client.Advanced.Debugging.renderWireframe.get();
|
||||
if (renderWireframe)
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_LINE);
|
||||
GLMC.disableFaceCulling();
|
||||
}
|
||||
else
|
||||
{
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GLMC.enableFaceCulling();
|
||||
}
|
||||
|
||||
GLMC.enableBlend();
|
||||
GL32.glBlendEquation(GL32.GL_FUNC_ADD);
|
||||
GLMC.glBlendFuncSeparate(GL32.GL_SRC_ALPHA, GL32.GL_ONE_MINUS_SRC_ALPHA, GL32.GL_ONE, GL32.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
IDhApiGenericObjectShaderProgram shaderProgram = this.instancedRenderingAvailable ? this.instancedShaderProgram : this.directShaderProgram;
|
||||
IDhApiGenericObjectShaderProgram shaderProgramOverride = OverrideInjector.INSTANCE.get(IDhApiGenericObjectShaderProgram.class);
|
||||
if (shaderProgramOverride != null && shaderProgram.overrideThisFrame())
|
||||
{
|
||||
shaderProgram = shaderProgramOverride;
|
||||
}
|
||||
|
||||
shaderProgram.bind(renderEventParam);
|
||||
shaderProgram.bindVertexBuffer(this.boxVertexBuffer.getId());
|
||||
|
||||
this.boxIndexBuffer.bind();
|
||||
|
||||
Vec3d camPos = MC_RENDER.getCameraExactPosition();
|
||||
|
||||
|
||||
|
||||
// rendering //
|
||||
|
||||
Collection<RenderableBoxGroup> boxList = this.boxGroupById.values();
|
||||
for (RenderableBoxGroup boxGroup : boxList)
|
||||
{
|
||||
// validation //
|
||||
|
||||
// shouldn't happen, but just in case
|
||||
if (boxGroup == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip boxes that shouldn't render this pass
|
||||
if (boxGroup.ssaoEnabled != renderingWithSsao)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
profiler.popPush("render prep");
|
||||
boxGroup.preRender(renderEventParam); // called even if the group is inactive, so the group can be activate if desired
|
||||
|
||||
// ignore inactive groups
|
||||
if (!boxGroup.active)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// allow API users to cancel this object's rendering
|
||||
boolean cancelRendering = ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericObjectRenderEvent.class, new DhApiBeforeGenericObjectRenderEvent.EventParam(renderEventParam, boxGroup));
|
||||
if (cancelRendering)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// update instanced data if needed
|
||||
if (this.instancedRenderingAvailable)
|
||||
{
|
||||
boxGroup.tryUpdateInstancedDataAsync();
|
||||
|
||||
// skip groups that haven't been uploaded yet
|
||||
if (boxGroup.vertexBufferContainer.getState() != GlGenericObjectVertexContainer.EState.RENDER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// render //
|
||||
|
||||
profiler.popPush("rendering");
|
||||
profiler.push(boxGroup.getResourceLocationNamespace());
|
||||
profiler.push(boxGroup.getResourceLocationPath());
|
||||
if (this.instancedRenderingAvailable)
|
||||
{
|
||||
this.renderBoxGroupInstanced(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.renderBoxGroupDirect(shaderProgram, renderEventParam, boxGroup, camPos, profiler);
|
||||
}
|
||||
profiler.pop(); // resource path
|
||||
profiler.pop(); // resource namespace
|
||||
|
||||
boxGroup.postRender(renderEventParam);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========//
|
||||
// clean up //
|
||||
//==========//
|
||||
|
||||
profiler.popPush("cleanup");
|
||||
|
||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBeforeGenericRenderCleanupEvent.class, renderEventParam);
|
||||
|
||||
if (renderWireframe)
|
||||
{
|
||||
// default back to GL_FILL since all other rendering uses it
|
||||
GL32.glPolygonMode(GL32.GL_FRONT_AND_BACK, GL32.GL_FILL);
|
||||
GLMC.enableFaceCulling();
|
||||
}
|
||||
|
||||
shaderProgram.unbind();
|
||||
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=====================//
|
||||
// instanced rendering //
|
||||
//=====================//
|
||||
//region
|
||||
|
||||
private void renderBoxGroupInstanced(
|
||||
IDhApiGenericObjectShaderProgram shaderProgram, DhApiRenderParam renderEventParam,
|
||||
RenderableBoxGroup boxGroup, Vec3d camPos,
|
||||
IProfilerWrapper profiler)
|
||||
{
|
||||
// update instance data //
|
||||
|
||||
profiler.push("vertex setup");
|
||||
|
||||
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
||||
if (shading == null)
|
||||
{
|
||||
shading = DEFAULT_SHADING;
|
||||
}
|
||||
|
||||
shaderProgram.fillIndirectUniformData(
|
||||
renderEventParam,
|
||||
shading, boxGroup,
|
||||
camPos);
|
||||
|
||||
|
||||
|
||||
// Bind instance data //
|
||||
profiler.popPush("binding");
|
||||
|
||||
GlGenericObjectVertexContainer container = (GlGenericObjectVertexContainer)(boxGroup.vertexBufferContainer);
|
||||
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.color);
|
||||
GL32.glEnableVertexAttribArray(1);
|
||||
GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0);
|
||||
this.vertexAttribDivisor(1, 1);
|
||||
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.scale);
|
||||
GL32.glEnableVertexAttribArray(2);
|
||||
this.vertexAttribDivisor(2, 1);
|
||||
GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
|
||||
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.chunkPos);
|
||||
GL32.glEnableVertexAttribArray(3);
|
||||
this.vertexAttribDivisor(3, 1);
|
||||
GL32.glVertexAttribIPointer(3, 3, GL32.GL_INT, 3 * Integer.BYTES, 0);
|
||||
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.subChunkPos);
|
||||
GL32.glEnableVertexAttribArray(4);
|
||||
this.vertexAttribDivisor(4, 1);
|
||||
GL32.glVertexAttribPointer(4, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0);
|
||||
|
||||
GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, container.material);
|
||||
GL32.glEnableVertexAttribArray(5);
|
||||
this.vertexAttribDivisor(5, 1);
|
||||
GL32.glVertexAttribIPointer(5, 1, GL32.GL_BYTE, Byte.BYTES, 0);
|
||||
|
||||
|
||||
// Draw instanced
|
||||
profiler.popPush("render");
|
||||
if (container.uploadedBoxCount > 0)
|
||||
{
|
||||
GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, container.uploadedBoxCount);
|
||||
}
|
||||
|
||||
|
||||
// Clean up
|
||||
profiler.popPush("cleanup");
|
||||
|
||||
GL32.glDisableVertexAttribArray(1);
|
||||
GL32.glDisableVertexAttribArray(2);
|
||||
GL32.glDisableVertexAttribArray(3);
|
||||
GL32.glDisableVertexAttribArray(4);
|
||||
GL32.glDisableVertexAttribArray(5);
|
||||
|
||||
profiler.pop();
|
||||
}
|
||||
/**
|
||||
* Clean way to handle both {@link GL33#glVertexAttribDivisor} and {@link ARBInstancedArrays#glVertexAttribDivisorARB}
|
||||
* based on which one is supported.
|
||||
*/
|
||||
private void vertexAttribDivisor(int index, int divisor)
|
||||
{
|
||||
if (this.vertexAttribDivisorSupported)
|
||||
{
|
||||
GL33.glVertexAttribDivisor(index, divisor);
|
||||
}
|
||||
else if(this.instancedArraysSupported)
|
||||
{
|
||||
ARBInstancedArrays.glVertexAttribDivisorARB(index, divisor);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("Instanced rendering isn't supported by this machine. Direct rendering should have been used instead.");
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//==================//
|
||||
// direct rendering //
|
||||
//==================//
|
||||
//region
|
||||
|
||||
private void renderBoxGroupDirect(
|
||||
IDhApiGenericObjectShaderProgram shaderProgram,
|
||||
DhApiRenderParam renderEventParam,
|
||||
RenderableBoxGroup boxGroup, Vec3d camPos,
|
||||
IProfilerWrapper profiler)
|
||||
{
|
||||
profiler.popPush("shared uniforms");
|
||||
DhApiRenderableBoxGroupShading shading = boxGroup.shading;
|
||||
if (shading == null)
|
||||
{
|
||||
shading = DhApiRenderableBoxGroupShading.getUnshaded();
|
||||
}
|
||||
|
||||
shaderProgram.fillSharedDirectUniformData(renderEventParam, shading, boxGroup, camPos);
|
||||
|
||||
for (int i = 0; i < boxGroup.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
DhApiRenderableBox box = boxGroup.get(i);
|
||||
if (box != null)
|
||||
{
|
||||
profiler.popPush("direct uniforms");
|
||||
shaderProgram.fillDirectUniformData(renderEventParam, boxGroup, box, camPos);
|
||||
|
||||
profiler.popPush("render");
|
||||
GL32.glDrawElements(GL32.GL_TRIANGLES, BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
// Concurrency issue, the list was modified while rendering
|
||||
// this can probably be ignored.
|
||||
// However, if it does become a problem we can add locks to the box group.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
/** @throws IllegalStateException if {@link #init()} function hasn't been called yet */
|
||||
public boolean getInstancedRenderingAvailable() throws IllegalStateException
|
||||
{
|
||||
if (!this.init)
|
||||
{
|
||||
throw new IllegalStateException("GL initialization hasn't been completed.");
|
||||
}
|
||||
|
||||
return this.instancedRenderingAvailable;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// F3 menu //
|
||||
//=========//
|
||||
//region
|
||||
|
||||
public String getVboRenderDebugMenuString()
|
||||
{
|
||||
// get counts
|
||||
int totalGroupCount = this.boxGroupById.size();
|
||||
int totalBoxCount = 0;
|
||||
|
||||
int activeGroupCount = 0;
|
||||
int activeBoxCount = 0;
|
||||
|
||||
for (long key : this.boxGroupById.keySet())
|
||||
{
|
||||
RenderableBoxGroup renderGroup = this.boxGroupById.get(key);
|
||||
if (renderGroup.active)
|
||||
{
|
||||
activeGroupCount++;
|
||||
activeBoxCount += renderGroup.size();
|
||||
}
|
||||
totalBoxCount += renderGroup.size();
|
||||
}
|
||||
|
||||
|
||||
return "Generic Obj #: " + F3Screen.NUMBER_FORMAT.format(activeGroupCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalGroupCount) + ", " +
|
||||
"Cube #: " + F3Screen.NUMBER_FORMAT.format(activeBoxCount) + "/" + F3Screen.NUMBER_FORMAT.format(totalBoxCount);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
-231
@@ -1,231 +0,0 @@
|
||||
package com.seibel.distanthorizons.common.render.openGl.generic;
|
||||
|
||||
import com.seibel.distanthorizons.api.interfaces.override.rendering.IDhApiGenericObjectShaderProgram;
|
||||
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
|
||||
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3d;
|
||||
import com.seibel.distanthorizons.api.objects.math.DhApiVec3i;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBox;
|
||||
import com.seibel.distanthorizons.api.objects.render.DhApiRenderableBoxGroupShading;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.shader.GlShaderProgram;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlAbstractVertexAttribute;
|
||||
import com.seibel.distanthorizons.common.render.openGl.glObject.vertexAttribute.GlVertexPointer;
|
||||
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
import com.seibel.distanthorizons.core.util.math.Mat4f;
|
||||
import com.seibel.distanthorizons.core.util.math.Vec3f;
|
||||
|
||||
public class GlGenericObjectShaderProgram extends GlShaderProgram implements IDhApiGenericObjectShaderProgram
|
||||
{
|
||||
public static final String VERTEX_SHADER_INSTANCED_PATH = "assets/distanthorizons/shaders/generic/gl/instanced/vert.vert";
|
||||
public static final String VERTEX_SHADER_DIRECT_PATH = "assets/distanthorizons/shaders/generic/gl/direct/vert.vert";
|
||||
public static final String FRAGMENT_SHADER_INSTANCED_PATH = "assets/distanthorizons/shaders/generic/gl/instanced/frag.frag";
|
||||
public static final String FRAGMENT_SHADER_DIRECT_PATH = "assets/distanthorizons/shaders/generic/gl/direct/frag.frag";
|
||||
|
||||
public final GlAbstractVertexAttribute va;
|
||||
|
||||
|
||||
// shader uniforms
|
||||
private final int directShaderTransformUniform;
|
||||
private final int directShaderColorUniform;
|
||||
|
||||
private final int instancedShaderOffsetChunkUniform;
|
||||
private final int instancedShaderOffsetSubChunkUniform;
|
||||
private final int instancedShaderCameraChunkPosUniform;
|
||||
private final int instancedShaderCameraSubChunkPosUniform;
|
||||
private final int instancedShaderProjectionModelViewMatrixUniform;
|
||||
|
||||
private final int lightMapUniform;
|
||||
private final int skyLightUniform;
|
||||
private final int blockLightUniform;
|
||||
|
||||
private final int northShadingUniform;
|
||||
private final int southShadingUniform;
|
||||
private final int eastShadingUniform;
|
||||
private final int westShadingUniform;
|
||||
private final int topShadingUniform;
|
||||
private final int bottomShadingUniform;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public GlGenericObjectShaderProgram(boolean useInstancedRendering)
|
||||
{
|
||||
super(
|
||||
useInstancedRendering ? VERTEX_SHADER_INSTANCED_PATH : VERTEX_SHADER_DIRECT_PATH,
|
||||
useInstancedRendering ? FRAGMENT_SHADER_INSTANCED_PATH : FRAGMENT_SHADER_DIRECT_PATH,
|
||||
"vPosition"
|
||||
);
|
||||
|
||||
this.va = GlAbstractVertexAttribute.create();
|
||||
this.va.bind();
|
||||
// Pos
|
||||
this.va.setVertexAttribute(0, 0, GlVertexPointer.addVec3Pointer(false));
|
||||
this.va.completeAndCheck(Float.BYTES * 3);
|
||||
|
||||
this.directShaderTransformUniform = this.tryGetUniformLocation("uTransform");
|
||||
this.directShaderColorUniform = this.tryGetUniformLocation("uColor");
|
||||
|
||||
this.instancedShaderOffsetChunkUniform = this.tryGetUniformLocation("uOffsetChunk");
|
||||
this.instancedShaderOffsetSubChunkUniform = this.tryGetUniformLocation("uOffsetSubChunk");
|
||||
this.instancedShaderCameraChunkPosUniform = this.tryGetUniformLocation("uCameraPosChunk");
|
||||
this.instancedShaderCameraSubChunkPosUniform = this.tryGetUniformLocation("uCameraPosSubChunk");
|
||||
this.instancedShaderProjectionModelViewMatrixUniform = this.tryGetUniformLocation("uProjectionMvm");
|
||||
|
||||
this.lightMapUniform = this.getUniformLocation("uLightMap");
|
||||
this.skyLightUniform = this.getUniformLocation("uSkyLight");
|
||||
this.blockLightUniform = this.getUniformLocation("uBlockLight");
|
||||
this.northShadingUniform = this.getUniformLocation("uNorthShading");
|
||||
this.southShadingUniform = this.getUniformLocation("uSouthShading");
|
||||
this.eastShadingUniform = this.getUniformLocation("uEastShading");
|
||||
this.westShadingUniform = this.getUniformLocation("uWestShading");
|
||||
this.topShadingUniform = this.getUniformLocation("uTopShading");
|
||||
this.bottomShadingUniform = this.getUniformLocation("uBottomShading");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public void bind(DhApiRenderParam renderEventParam)
|
||||
{
|
||||
super.bind();
|
||||
this.va.bind();
|
||||
}
|
||||
@Override
|
||||
public void unbind()
|
||||
{
|
||||
super.unbind();
|
||||
this.va.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void free()
|
||||
{
|
||||
this.va.free();
|
||||
super.free();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindVertexBuffer(int vbo) { this.va.bindBufferToAllBindingPoints(vbo); }
|
||||
|
||||
@Override
|
||||
public void fillIndirectUniformData(
|
||||
DhApiRenderParam renderParameters,
|
||||
DhApiRenderableBoxGroupShading shading, IDhApiRenderableBoxGroup boxGroup,
|
||||
DhApiVec3d camPos
|
||||
)
|
||||
{
|
||||
Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix);
|
||||
projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix);
|
||||
|
||||
super.bind();
|
||||
|
||||
|
||||
|
||||
|
||||
this.setUniform(this.instancedShaderOffsetChunkUniform,
|
||||
new DhApiVec3i(
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
LodUtil.getChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
));
|
||||
this.setUniform(this.instancedShaderOffsetSubChunkUniform,
|
||||
new Vec3f(
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().x),
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().y),
|
||||
LodUtil.getSubChunkPosFromDouble(boxGroup.getOriginBlockPos().z)
|
||||
));
|
||||
|
||||
this.setUniform(this.instancedShaderCameraChunkPosUniform,
|
||||
new DhApiVec3i(
|
||||
LodUtil.getChunkPosFromDouble(camPos.x),
|
||||
LodUtil.getChunkPosFromDouble(camPos.y),
|
||||
LodUtil.getChunkPosFromDouble(camPos.z)
|
||||
));
|
||||
this.setUniform(this.instancedShaderCameraSubChunkPosUniform,
|
||||
new Vec3f(
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.x),
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.y),
|
||||
LodUtil.getSubChunkPosFromDouble(camPos.z)
|
||||
));
|
||||
|
||||
this.setUniform(this.instancedShaderProjectionModelViewMatrixUniform, projectionMvmMatrix);
|
||||
|
||||
this.setUniform(this.lightMapUniform, LightMapWrapper.GL_BOUND_INDEX);
|
||||
this.setUniform(this.skyLightUniform, boxGroup.getSkyLight());
|
||||
this.setUniform(this.blockLightUniform, boxGroup.getBlockLight());
|
||||
|
||||
|
||||
this.setUniform(this.northShadingUniform, shading.north);
|
||||
this.setUniform(this.southShadingUniform, shading.south);
|
||||
this.setUniform(this.eastShadingUniform, shading.east);
|
||||
this.setUniform(this.westShadingUniform, shading.west);
|
||||
this.setUniform(this.topShadingUniform, shading.top);
|
||||
this.setUniform(this.bottomShadingUniform, shading.bottom);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void fillSharedDirectUniformData(
|
||||
DhApiRenderParam renderParameters,
|
||||
DhApiRenderableBoxGroupShading shading, IDhApiRenderableBoxGroup boxGroup,
|
||||
DhApiVec3d camPos)
|
||||
{
|
||||
|
||||
this.setUniform(this.lightMapUniform, LightMapWrapper.GL_BOUND_INDEX);
|
||||
this.setUniform(this.skyLightUniform, boxGroup.getSkyLight());
|
||||
this.setUniform(this.blockLightUniform, boxGroup.getBlockLight());
|
||||
|
||||
|
||||
this.setUniform(this.northShadingUniform, shading.north);
|
||||
this.setUniform(this.southShadingUniform, shading.south);
|
||||
this.setUniform(this.eastShadingUniform, shading.east);
|
||||
this.setUniform(this.westShadingUniform, shading.west);
|
||||
this.setUniform(this.topShadingUniform, shading.top);
|
||||
this.setUniform(this.bottomShadingUniform, shading.bottom);
|
||||
|
||||
}
|
||||
|
||||
public void fillDirectUniformData(
|
||||
DhApiRenderParam renderParameters,
|
||||
IDhApiRenderableBoxGroup boxGroup, DhApiRenderableBox box,
|
||||
DhApiVec3d camPos)
|
||||
{
|
||||
Mat4f projectionMvmMatrix = new Mat4f(renderParameters.dhProjectionMatrix);
|
||||
projectionMvmMatrix.multiply(renderParameters.dhModelViewMatrix);
|
||||
|
||||
Mat4f boxTransform = Mat4f.createTranslateMatrix(
|
||||
(float) (box.minPos.x + boxGroup.getOriginBlockPos().x - camPos.x),
|
||||
(float) (box.minPos.y + boxGroup.getOriginBlockPos().y - camPos.y),
|
||||
(float) (box.minPos.z + boxGroup.getOriginBlockPos().z - camPos.z));
|
||||
boxTransform.multiply(Mat4f.createScaleMatrix(
|
||||
(float) (box.maxPos.x - box.minPos.x),
|
||||
(float) (box.maxPos.y - box.minPos.y),
|
||||
(float) (box.maxPos.z - box.minPos.z)));
|
||||
projectionMvmMatrix.multiply(boxTransform);
|
||||
this.setUniform(this.directShaderTransformUniform, projectionMvmMatrix);
|
||||
|
||||
this.setUniform(this.directShaderColorUniform, box.color);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getId() { return this.id; }
|
||||
|
||||
/** The base DH render program should always render */
|
||||
@Override
|
||||
public boolean overrideThisFrame() { return true; }
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user