diff --git a/java/libraries/lwjgl/.classpath b/java/libraries/lwjgl/.classpath deleted file mode 100644 index c1249a9da..000000000 --- a/java/libraries/lwjgl/.classpath +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/java/libraries/lwjgl/.project b/java/libraries/lwjgl/.project deleted file mode 100644 index c83f47a87..000000000 --- a/java/libraries/lwjgl/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - processing-lwjgl - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/java/libraries/lwjgl/.settings/org.eclipse.jdt.core.prefs b/java/libraries/lwjgl/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index c3e8e9bd9..000000000 --- a/java/libraries/lwjgl/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,273 +0,0 @@ -#Sat Nov 12 10:56:23 CST 2011 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=18 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=18 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=18 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=36 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=18 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=18 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=1 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=false -org.eclipse.jdt.core.formatter.comment.format_source_code=true -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=true -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert -org.eclipse.jdt.core.formatter.comment.line_length=80 -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=2 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=80 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=space -org.eclipse.jdt.core.formatter.tabulation.size=2 -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true diff --git a/java/libraries/lwjgl/.settings/org.eclipse.jdt.ui.prefs b/java/libraries/lwjgl/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 1a0fe9f9c..000000000 --- a/java/libraries/lwjgl/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,4 +0,0 @@ -#Fri Feb 19 16:20:47 EST 2010 -eclipse.preferences.version=1 -formatter_profile=_processing -formatter_settings_version=11 diff --git a/java/libraries/lwjgl/build.xml b/java/libraries/lwjgl/build.xml deleted file mode 100644 index 9bba1883e..000000000 --- a/java/libraries/lwjgl/build.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/libraries/lwjgl/examples/Form/BrickTower/BrickTower.pde b/java/libraries/lwjgl/examples/Form/BrickTower/BrickTower.pde deleted file mode 100644 index 3307fce3a..000000000 --- a/java/libraries/lwjgl/examples/Form/BrickTower/BrickTower.pde +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Brick Tower - * by Ira Greenberg. - * - * 3D castle tower constructed out of individual bricks. - * Uses the PVector and Cube classes. - */ - -import processing.lwjgl.*; - -float bricksPerLayer = 16.0; -float brickLayers = 18.0; -Cube brick; -float brickWidth = 60, brickHeight = 25, brickDepth = 25; -float radius = 175.0; -float angle = 0; - -void setup(){ - size(640, 360, LWJGL); - brick = new Cube(brickWidth, brickHeight, brickDepth); -} - -void draw(){ - background(0); - float tempX = 0, tempY = 0, tempZ = 0; - fill(182, 62, 29); - noStroke(); - // Add basic light setup - lights(); - translate(width/2, height*1.2, -380); - // Tip tower to see inside - rotateX(radians(-45)); - // Slowly rotate tower - rotateY(frameCount * PI/600); - for (int i = 0; i < brickLayers; i++){ - // Increment rows - tempY-=brickHeight; - // Alternate brick seams - angle = 360.0 / bricksPerLayer * i/2; - for (int j = 0; j < bricksPerLayer; j++){ - tempZ = cos(radians(angle))*radius; - tempX = sin(radians(angle))*radius; - pushMatrix(); - translate(tempX, tempY, tempZ); - rotateY(radians(angle)); - // Add crenelation - if (i==brickLayers-1){ - if (j%2 == 0){ - brick.create(); - } - } - // Create main tower - else { - brick.create(); - } - popMatrix(); - angle += 360.0/bricksPerLayer; - } - } -} diff --git a/java/libraries/lwjgl/examples/Form/BrickTower/Cube.pde b/java/libraries/lwjgl/examples/Form/BrickTower/Cube.pde deleted file mode 100644 index df772c0cf..000000000 --- a/java/libraries/lwjgl/examples/Form/BrickTower/Cube.pde +++ /dev/null @@ -1,68 +0,0 @@ -class Cube { - - PVector[] vertices = new PVector[24]; - PVector[] normals = new PVector[6]; - float w, h, d; - - Cube(){ } - - Cube(float w, float h, float d){ - this.w = w; - this.h = h; - this.d = d; - - // Cube composed of 6 quads - // Front - normals[0] = new PVector(0, 0, 1); - vertices[0] = new PVector(-w/2, -h/2, d/2); - vertices[1] = new PVector(w/2, -h/2, d/2); - vertices[2] = new PVector(w/2, h/2, d/2); - vertices[3] = new PVector(-w/2, h/2, d/2); - - // Left - normals[1] = new PVector(-1, 0, 0); - vertices[4] = new PVector(-w/2, -h/2, d/2); - vertices[5] = new PVector(-w/2, -h/2, -d/2); - vertices[6] = new PVector(-w/2, h/2, -d/2); - vertices[7] = new PVector(-w/2, h/2, d/2); - - // Right - normals[2] = new PVector(1, 0, 0); - vertices[8] = new PVector(w/2, -h/2, d/2); - vertices[9] = new PVector(w/2, -h/2, -d/2); - vertices[10] = new PVector(w/2, h/2, -d/2); - vertices[11] = new PVector(w/2, h/2, d/2); - - // Back - normals[3] = new PVector(0, 0, -1); - vertices[12] = new PVector(-w/2, -h/2, -d/2); - vertices[13] = new PVector(w/2, -h/2, -d/2); - vertices[14] = new PVector(w/2, h/2, -d/2); - vertices[15] = new PVector(-w/2, h/2, -d/2); - - // Top - normals[4] = new PVector(0, 1, 0); - vertices[16] = new PVector(-w/2, -h/2, d/2); - vertices[17] = new PVector(-w/2, -h/2, -d/2); - vertices[18] = new PVector(w/2, -h/2, -d/2); - vertices[19] = new PVector(w/2, -h/2, d/2); - - // Bottom - normals[5] = new PVector(0, 1, 0); - vertices[20] = new PVector(-w/2, h/2, d/2); - vertices[21] = new PVector(-w/2, h/2, -d/2); - vertices[22] = new PVector(w/2, h/2, -d/2); - vertices[23] = new PVector(w/2, h/2, d/2); - } - - void create(){ - for (int i=0; i<6; i++){ - beginShape(QUADS); - normal(normals[i].x, normals[i].y, normals[i].z); - for (int j = 0; j < 4; j++){ - vertex(vertices[j+4*i].x, vertices[j+4*i].y, vertices[j+4*i].z); - } - endShape(); - } - } -} \ No newline at end of file diff --git a/java/libraries/lwjgl/examples/Form/CubicGrid/CubicGrid.pde b/java/libraries/lwjgl/examples/Form/CubicGrid/CubicGrid.pde deleted file mode 100644 index c4b427610..000000000 --- a/java/libraries/lwjgl/examples/Form/CubicGrid/CubicGrid.pde +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Cubic Grid - * by Ira Greenberg. - * - * 3D translucent colored grid uses nested pushMatrix() - * and popMatrix() functions. - */ - -import processing.lwjgl.*; - -float boxSize = 40; -float margin = boxSize*2; -float depth = 400; -color boxFill; - -void setup() { - size(640, 360, LWJGL); - noStroke(); - hint(DISABLE_DEPTH_TEST); -} - -void draw() { - background(255); - - // Center and spin grid - translate(width/2, height/2, -depth); - rotateY(frameCount * 0.01); - rotateX(frameCount * 0.01); - - // Build grid using multiple translations - for (float i =- depth/2+margin; i <= depth/2-margin; i += boxSize){ - pushMatrix(); - for (float j =- height+margin; j <= height-margin; j += boxSize){ - pushMatrix(); - for (float k =- width+margin; k <= width-margin; k += boxSize){ - // Base fill color on counter values, abs function - // ensures values stay within legal range - boxFill = color(abs(i), abs(j), abs(k), 50); - pushMatrix(); - translate(k, j, i); - fill(boxFill); - box(boxSize, boxSize, boxSize); - popMatrix(); - } - popMatrix(); - } - popMatrix(); - } -} - diff --git a/java/libraries/lwjgl/examples/Lights/LightsGL/LightsGL.pde b/java/libraries/lwjgl/examples/Lights/LightsGL/LightsGL.pde deleted file mode 100644 index 706393825..000000000 --- a/java/libraries/lwjgl/examples/Lights/LightsGL/LightsGL.pde +++ /dev/null @@ -1,47 +0,0 @@ -/** - * LightsGL. - * Modified from an example by Simon Greenwold. - * - * Display a box with three different kinds of lights. - */ - -import processing.lwjgl.*; - -void setup() -{ - size(1024, 768, LWJGL); - noStroke(); -} - -void draw() -{ - defineLights(); - background(0); - - for (int x = 0; x <= width; x += 100) { - for (int y = 0; y <= height; y += 100) { - pushMatrix(); - translate(x, y); - rotateY(map(mouseX, 0, width, 0, PI)); - rotateX(map(mouseY, 0, height, 0, PI)); - box(90); - popMatrix(); - } - } -} - -void defineLights() { - // Orange point light on the right - pointLight(150, 100, 0, // Color - 200, -150, 0); // Position - - // Blue directional light from the left - directionalLight(0, 102, 255, // Color - 1, 0, 0); // The x-, y-, z-axis direction - - // Yellow spotlight from the front - spotLight(255, 255, 109, // Color - 0, 40, 200, // Position - 0, -0.5, -0.5, // Direction - PI / 2, 2); // Angle, concentration -} diff --git a/java/libraries/lwjgl/examples/Lights/Reflection/Reflection.pde b/java/libraries/lwjgl/examples/Lights/Reflection/Reflection.pde deleted file mode 100644 index 021b18d0e..000000000 --- a/java/libraries/lwjgl/examples/Lights/Reflection/Reflection.pde +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Reflection - * by Simon Greenwold. - * - * Vary the specular reflection component of a material - * with the horizontal position of the mouse. - */ - -import processing.lwjgl.*; - -void setup() { - size(640, 360, LWJGL); - noStroke(); - colorMode(RGB, 1); - fill(0.4); -} - -void draw() { - background(0); - translate(width / 2, height / 2); - // Set the specular color of lights that follow - lightSpecular(1, 1, 1); - directionalLight(0.8, 0.8, 0.8, 0, 0, -1); - float s = mouseX / float(width); - specular(s, s, s); - sphere(120); -} diff --git a/java/libraries/lwjgl/examples/Lights/Spot/Spot.pde b/java/libraries/lwjgl/examples/Lights/Spot/Spot.pde deleted file mode 100644 index eeba6877a..000000000 --- a/java/libraries/lwjgl/examples/Lights/Spot/Spot.pde +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Spot. - * - * Move the mouse the change the position and concentation - * of a blue spot light. - */ - -import processing.lwjgl.*; - -int concentration = 600; // Try values 1 -> 10000 - -void setup() -{ - //size(200, 200, LWJGL); - size(640, 360, LWJGL); - noStroke(); - fill(204); - sphereDetail(60); -} - -void draw() -{ - background(0); - - // Light the bottom of the sphere - directionalLight(51, 102, 126, 0, -1, 0); - - // Orange light on the upper-right of the sphere - spotLight(204, 153, 0, 360, 160, 600, 0, 0, -1, PI/2, 600); - - // Moving spotlight that follows the mouse - spotLight(102, 153, 204, 360, mouseY, 600, 0, 0, -1, PI/2, 600); - - translate(width/2, height/2, 0); - sphere(120); -} - diff --git a/java/libraries/lwjgl/examples/Performance/CubicGridImmediate/CubicGridImmediate.pde b/java/libraries/lwjgl/examples/Performance/CubicGridImmediate/CubicGridImmediate.pde deleted file mode 100644 index 498d98e5c..000000000 --- a/java/libraries/lwjgl/examples/Performance/CubicGridImmediate/CubicGridImmediate.pde +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Cubic Grid - * by Ira Greenberg. - * - * 3D translucent colored grid uses nested pushMatrix() - * and popMatrix() functions. - */ - -import processing.lwjgl.*; - -float boxSize = 20; -float margin = boxSize*2; -float depth = 400; -color boxFill; - -int fcount, lastm; -float frate; -int fint = 3; - -void setup() { - size(640, 360, LWJGL); - frameRate(120); - noStroke(); -} - -void draw() { - background(255); - - hint(DISABLE_DEPTH_TEST); - - // Center and spin grid - pushMatrix(); - translate(width/2, height/2, -depth); - rotateY(frameCount * 0.01); - rotateX(frameCount * 0.01); - - // Build grid using multiple translations - for (float i =- depth/2+margin; i <= depth/2-margin; i += boxSize){ - for (float j =- height+margin; j <= height-margin; j += boxSize){ - for (float k =- width+margin; k <= width-margin; k += boxSize){ - // Base fill color on counter values, abs function - // ensures values stay within legal range - boxFill = color(abs(i), abs(j), abs(k), 50); - pushMatrix(); - translate(k, j, i); - fill(boxFill); - box(boxSize, boxSize, boxSize); - popMatrix(); - } - } - } - popMatrix(); - - fcount += 1; - int m = millis(); - if (m - lastm > 1000 * fint) { - frate = float(fcount) / fint; - fcount = 0; - lastm = m; - println("fps: " + frate); - } - fill(0); - text("fps: " + frate, 10, 20); -} \ No newline at end of file diff --git a/java/libraries/lwjgl/examples/Performance/CubicGridRetained/CubicGridRetained.pde b/java/libraries/lwjgl/examples/Performance/CubicGridRetained/CubicGridRetained.pde deleted file mode 100644 index fd6147916..000000000 --- a/java/libraries/lwjgl/examples/Performance/CubicGridRetained/CubicGridRetained.pde +++ /dev/null @@ -1,113 +0,0 @@ -import processing.lwjgl.*; - -float boxSize = 20; -float margin = boxSize*2; -float depth = 400; -color boxFill; - -PShape grid; - -int fcount, lastm; -float frate; -int fint = 3; - -void setup() { - size(640, 360, LWJGL); - frameRate(120); - noStroke(); - - grid = createShape(PShape.GROUP); - - // Build grid using multiple translations - for (float i =- depth/2+margin; i <= depth/2-margin; i += boxSize){ - for (float j =- height+margin; j <= height-margin; j += boxSize){ - for (float k =- width+margin; k <= width-margin; k += boxSize){ - // Base fill color on counter values, abs function - // ensures values stay within legal range - boxFill = color(abs(i), abs(j), abs(k), 50); - - PShape cube = createShape(QUADS); - cube.noStroke(); - cube.fill(boxFill); - - float w = boxSize; - float h = boxSize; - float d = boxSize; - float shiftX = k; - float shiftY = j; - float shiftZ = i; - - // Front face - cube.normal(0, 0, 1); - cube.vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ); - - // Back face - cube.normal(0, 0, -1); - cube.vertex(-w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ); - - // Left face - cube.normal(1, 0, 0); - cube.vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ); - - // Right face - cube.normal(-1, 0, 0); - cube.vertex(+w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ); - - // Top face - cube.normal(0, 1, 0); - cube.vertex(-w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, -h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, -h/2 + shiftY, +d/2 + shiftZ); - - // Bottom face - cube.normal(0, -1, 0); - cube.vertex(-w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, +h/2 + shiftY, -d/2 + shiftZ); - cube.vertex(+w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ); - cube.vertex(-w/2 + shiftX, +h/2 + shiftY, +d/2 + shiftZ); - - cube.end(); - grid.addChild(cube); - } - } - } -} - -void draw() { - background(255); - - hint(DISABLE_DEPTH_TEST); - - // Center and spin grid - pushMatrix(); - translate(width/2, height/2, -depth); - rotateY(frameCount * 0.01); - rotateX(frameCount * 0.01); - - shape(grid); - popMatrix(); - - fcount += 1; - int m = millis(); - if (m - lastm > 1000 * fint) { - frate = float(fcount) / fint; - fcount = 0; - lastm = m; - println("fps: " + frate); - } - fill(0); - text("fps: " + frate, 10, 20); -} diff --git a/java/libraries/lwjgl/examples/Performance/DynamicParticlesImmediate/DynamicParticlesImmediate.pde b/java/libraries/lwjgl/examples/Performance/DynamicParticlesImmediate/DynamicParticlesImmediate.pde deleted file mode 100644 index 9807b5c74..000000000 --- a/java/libraries/lwjgl/examples/Performance/DynamicParticlesImmediate/DynamicParticlesImmediate.pde +++ /dev/null @@ -1,120 +0,0 @@ -import processing.lwjgl.*; - -PImage sprite; - -int npartTotal = 10000; -int npartPerFrame = 25; -float speed = 1.0; -float gravity = 0.05; -float partSize = 20; - -int partLifetime; -PVector positions[]; -PVector velocities[]; -int lifetimes[]; - -int fcount, lastm; -float frate; -int fint = 3; - -void setup() { - size(640, 480, LWJGL); - frameRate(240); - - sprite = loadImage("sprite.png"); - - partLifetime = npartTotal / npartPerFrame; - initPositions(); - initVelocities(); - initLifetimes(); - - // Writing to the depth buffer is disabled to avoid rendering - // artifacts due to the fact that the particles are semi-transparent - // but not z-sorted. - hint(DISABLE_DEPTH_MASK); - - // Testing some hints - //hint(DISABLE_TRANSFORM_CACHE); - //hint(ENABLE_ACCURATE_2D); -} - -void draw () { - background(0); - - for (int n = 0; n < npartTotal; n++) { - lifetimes[n]++; - if (lifetimes[n] == partLifetime) { - lifetimes[n] = 0; - } - - if (0 <= lifetimes[n]) { - float opacity = 1.0 - float(lifetimes[n]) / partLifetime; - - if (lifetimes[n] == 0) { - // Re-spawn dead particle - positions[n].x = mouseX; - positions[n].y = mouseY; - - float angle = random(0, TWO_PI); - float s = random(0.5 * speed, 0.5 * speed); - velocities[n].x = s * cos(angle); - velocities[n].y = s * sin(angle); - } else { - positions[n].x += velocities[n].x; - positions[n].y += velocities[n].y; - - velocities[n].y += gravity; - } - drawParticle(positions[n], opacity); - } - } - - fcount += 1; - int m = millis(); - if (m - lastm > 1000 * fint) { - frate = float(fcount) / fint; - fcount = 0; - lastm = m; - println("fps: " + frate); - } -} - -void drawParticle(PVector center, float opacity) { - beginShape(QUAD); - noStroke(); - tint(255, opacity * 255); - texture(sprite); - normal(0, 0, 1); - vertex(center.x - partSize/2, center.y - partSize/2, 0, 0); - vertex(center.x + partSize/2, center.y - partSize/2, sprite.width, 0); - vertex(center.x + partSize/2, center.y + partSize/2, sprite.width, sprite.height); - vertex(center.x - partSize/2, center.y + partSize/2, 0, sprite.height); - endShape(); -} - -void initPositions() { - positions = new PVector[npartTotal]; - for (int n = 0; n < positions.length; n++) { - positions[n] = new PVector(); - } -} - -void initVelocities() { - velocities = new PVector[npartTotal]; - for (int n = 0; n < velocities.length; n++) { - velocities[n] = new PVector(); - } -} - -void initLifetimes() { - // Initializing particles with negative lifetimes so they are added - // progressively into the screen during the first frames of the sketch - lifetimes = new int[npartTotal]; - int t = -1; - for (int n = 0; n < lifetimes.length; n++) { - if (n % npartPerFrame == 0) { - t++; - } - lifetimes[n] = -t; - } -} diff --git a/java/libraries/lwjgl/examples/Performance/DynamicParticlesRetained/DynamicParticlesRetained.pde b/java/libraries/lwjgl/examples/Performance/DynamicParticlesRetained/DynamicParticlesRetained.pde deleted file mode 100644 index 2cc02146a..000000000 --- a/java/libraries/lwjgl/examples/Performance/DynamicParticlesRetained/DynamicParticlesRetained.pde +++ /dev/null @@ -1,111 +0,0 @@ -import processing.lwjgl.*; - -PShape particles; -PImage sprite; - -int npartTotal = 10000; -int npartPerFrame = 25; -float speed = 1.0; -float gravity = 0.05; -float partSize = 20; - -int partLifetime; -PVector velocities[]; -int lifetimes[]; - -int fcount, lastm; -float frate; -int fint = 3; - -void setup() { - size(640, 480, LWJGL); - frameRate(240); - - particles = createShape(PShape.GROUP); - sprite = loadImage("sprite.png"); - - for (int n = 0; n < npartTotal; n++) { - PShape part = createShape(QUAD); - part.noStroke(); - part.texture(sprite); - part.normal(0, 0, 1); - part.vertex(-partSize/2, -partSize/2, 0, 0); - part.vertex(+partSize/2, -partSize/2, sprite.width, 0); - part.vertex(+partSize/2, +partSize/2, sprite.width, sprite.height); - part.vertex(-partSize/2, +partSize/2, 0, sprite.height); - part.end(); - particles.addChild(part); - } - - partLifetime = npartTotal / npartPerFrame; - initVelocities(); - initLifetimes(); - - // Writing to the depth buffer is disabled to avoid rendering - // artifacts due to the fact that the particles are semi-transparent - // but not z-sorted. - hint(DISABLE_DEPTH_MASK); -} - -void draw () { - background(0); - - for (int n = 0; n < particles.getChildCount(); n++) { - PShape part = particles.getChild(n); - - lifetimes[n]++; - if (lifetimes[n] == partLifetime) { - lifetimes[n] = 0; - } - - if (0 <= lifetimes[n]) { - float opacity = 1.0 - float(lifetimes[n]) / partLifetime; - part.tint(255, opacity * 255); - - if (lifetimes[n] == 0) { - // Re-spawn dead particle - part.center(mouseX, mouseY); - float angle = random(0, TWO_PI); - float s = random(0.5 * speed, 0.5 * speed); - velocities[n].x = s * cos(angle); - velocities[n].y = s * sin(angle); - } else { - part.translate(velocities[n].x, velocities[n].y); - velocities[n].y += gravity; - } - } else { - part.tint(0, 0); - } - } - - shape(particles); - - fcount += 1; - int m = millis(); - if (m - lastm > 1000 * fint) { - frate = float(fcount) / fint; - fcount = 0; - lastm = m; - println("fps: " + frate); - } -} - -void initVelocities() { - velocities = new PVector[npartTotal]; - for (int n = 0; n < velocities.length; n++) { - velocities[n] = new PVector(); - } -} - -void initLifetimes() { - // Initializing particles with negative lifetimes so they are added - // progressively into the screen during the first frames of the sketch - lifetimes = new int[npartTotal]; - int t = -1; - for (int n = 0; n < lifetimes.length; n++) { - if (n % npartPerFrame == 0) { - t++; - } - lifetimes[n] = -t; - } -} diff --git a/java/libraries/lwjgl/examples/Performance/Esfera/Esfera.pde b/java/libraries/lwjgl/examples/Performance/Esfera/Esfera.pde deleted file mode 100644 index 29af75df2..000000000 --- a/java/libraries/lwjgl/examples/Performance/Esfera/Esfera.pde +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Esfera - * by David Pena. - * - * Distribucion aleatoria uniforme sobre la superficie de una esfera. - */ - -import processing.lwjgl.*; - -int cuantos = 16000; -pelo[] lista ; -float[] z = new float[cuantos]; -float[] phi = new float[cuantos]; -float[] largos = new float[cuantos]; -float radio = 200; -float rx = 0; -float ry =0; - -void setup() { - size(1024, 768, LWJGL); - radio = height/3.5; - - lista = new pelo[cuantos]; - for (int i=0; i 1000 * fint) { - frate = float(fcount) / fint; - fcount = 0; - lastm = m; - println("fps: " + frate); - } -} - -void drawParticle(PVector center) { - beginShape(QUAD); - noStroke(); - tint(255); - texture(sprite); - normal(0, 0, 1); - vertex(center.x - partSize/2, center.y - partSize/2, center.z, 0, 0); - vertex(center.x + partSize/2, center.y - partSize/2, center.z, sprite.width, 0); - vertex(center.x + partSize/2, center.y + partSize/2, center.z, sprite.width, sprite.height); - vertex(center.x - partSize/2, center.y + partSize/2, center.z, 0, sprite.height); - endShape(); -} - -void initPositions() { - positions = new PVector[npartTotal]; - for (int n = 0; n < positions.length; n++) { - positions[n] = new PVector(random(-500, +500), random(-500, +500), random(-500, +500)); - } -} - diff --git a/java/libraries/lwjgl/examples/Performance/StaticParticlesRetained/StaticParticlesRetained.pde b/java/libraries/lwjgl/examples/Performance/StaticParticlesRetained/StaticParticlesRetained.pde deleted file mode 100644 index 6831ea6c6..000000000 --- a/java/libraries/lwjgl/examples/Performance/StaticParticlesRetained/StaticParticlesRetained.pde +++ /dev/null @@ -1,61 +0,0 @@ -import processing.lwjgl.*; - -PShape particles; -PImage sprite; - -int npartTotal = 50000; -float partSize = 20; - -int fcount, lastm; -float frate; -int fint = 3; - -void setup() { - size(800, 600, LWJGL); - frameRate(240); - - particles = createShape(PShape.GROUP); - sprite = loadImage("sprite.png"); - - for (int n = 0; n < npartTotal; n++) { - float cx = random(-500, +500); - float cy = random(-500, +500); - float cz = random(-500, +500); - - PShape part = createShape(QUAD); - part.noStroke(); - part.tint(255); - part.texture(sprite); - part.normal(0, 0, 1); - part.vertex(cx - partSize/2, cy - partSize/2, cz, 0, 0); - part.vertex(cx + partSize/2, cy - partSize/2, cz, sprite.width, 0); - part.vertex(cx + partSize/2, cy + partSize/2, cz, sprite.width, sprite.height); - part.vertex(cx - partSize/2, cy + partSize/2, cz, 0, sprite.height); - part.end(); - particles.addChild(part); - } - - // Writing to the depth buffer is disabled to avoid rendering - // artifacts due to the fact that the particles are semi-transparent - // but not z-sorted. - hint(DISABLE_DEPTH_MASK); -} - -void draw () { - background(0); - - translate(width/2, height/2); - rotateY(frameCount * 0.01); - - shape(particles); - - fcount += 1; - int m = millis(); - if (m - lastm > 1000 * fint) { - frate = float(fcount) / fint; - fcount = 0; - lastm = m; - println("fps: " + frate); - } -} - diff --git a/java/libraries/lwjgl/examples/Performance/TextRendering/TextRendering.pde b/java/libraries/lwjgl/examples/Performance/TextRendering/TextRendering.pde deleted file mode 100644 index 1d8f8559a..000000000 --- a/java/libraries/lwjgl/examples/Performance/TextRendering/TextRendering.pde +++ /dev/null @@ -1,16 +0,0 @@ -import processing.lwjgl.*; - -public void setup() { - size(800, 600, LWJGL); - fill(0); -} - -public void draw() { - background(255); - for (int i = 0; i < 10000; i++) { - float x = random(width); - float y = random(height); - text("HELLO", x, y); - } - if (frameCount % 10 == 0) println(frameRate); -} diff --git a/java/libraries/lwjgl/library/export.txt b/java/libraries/lwjgl/library/export.txt deleted file mode 100644 index 76b2b519e..000000000 --- a/java/libraries/lwjgl/library/export.txt +++ /dev/null @@ -1,10 +0,0 @@ -# If you want to support more platforms, see the jogl.dev.java.net to get the -# natives libraries for the platform in question (i.e. Solaris). - -name = lwOpenGL - -# In releases later than (but not including) 1.0.9, the applet JAR files -# are downloaded directly from Sun, so that a single version is cached -# on the user's computer, rather than increasing the download size with -# the versions for each platform. -applet = lwopengl.jar diff --git a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderFragNoTex.glsl b/java/libraries/lwjgl/src/processing/lwjgl/FillShaderFragNoTex.glsl deleted file mode 100644 index 29e18414e..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderFragNoTex.glsl +++ /dev/null @@ -1,26 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -varying vec4 vertColor; - -void main() { - gl_FragColor = vertColor; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderFragTex.glsl b/java/libraries/lwjgl/src/processing/lwjgl/FillShaderFragTex.glsl deleted file mode 100644 index 650e90355..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderFragTex.glsl +++ /dev/null @@ -1,31 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform sampler2D textureSampler; - -uniform vec2 texcoordOffset; - -varying vec4 vertColor; -varying vec4 vertTexcoord; - -void main() { - gl_FragColor = texture2D(textureSampler, vertTexcoord.st) * vertColor; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertFull.glsl b/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertFull.glsl deleted file mode 100644 index 6e324d8cf..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertFull.glsl +++ /dev/null @@ -1,135 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform mat4 modelviewMatrix; -uniform mat4 projmodelviewMatrix; -uniform mat3 normalMatrix; -uniform mat4 texcoordMatrix; - -uniform int lightCount; -uniform vec4 lightPosition[8]; -uniform vec3 lightNormal[8]; -uniform vec3 lightAmbient[8]; -uniform vec3 lightDiffuse[8]; -uniform vec3 lightSpecular[8]; -uniform vec3 lightFalloffCoefficients[8]; -uniform vec2 lightSpotParameters[8]; - -attribute vec4 inVertex; -attribute vec4 inColor; -attribute vec3 inNormal; -attribute vec2 inTexcoord; - -attribute vec4 inAmbient; -attribute vec4 inSpecular; -attribute vec4 inEmissive; -attribute float inShine; - -varying vec4 vertColor; -varying vec4 vertTexcoord; - -const float zero_float = 0.0; -const float one_float = 1.0; -const vec3 zero_vec3 = vec3(0); - -float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { - vec3 lpv = lightPos - vertPos; - vec3 dist = vec3(one_float); - dist.z = dot(lpv, lpv); - dist.y = sqrt(dist.z); - return one_float / dot(dist, coeff); -} - -float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { - vec3 lpv = normalize(lightPos - vertPos); - float spotCos = dot(-lightNorm, lpv); - return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); -} - -float lambertFactor(vec3 lightDir, vec3 vecNormal) { - return max(zero_float, dot(lightDir, vecNormal)); -} - -float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) { - vec3 ldp = normalize(lightDir - lightPos); - return pow(max(zero_float, dot(ldp, vecNormal)), shine); -} - -void main() { - // Vertex in clip coordinates - gl_Position = projmodelviewMatrix * inVertex; - - // Vertex in eye coordinates - vec3 ecVertex = vec3(modelviewMatrix * inVertex); - - // Normal vector in eye coordinates - vec3 ecNormal = normalize(normalMatrix * inNormal); - - // Light calculations - vec3 totalAmbient = vec3(0, 0, 0); - vec3 totalDiffuse = vec3(0, 0, 0); - vec3 totalSpecular = vec3(0, 0, 0); - for (int i = 0; i < lightCount; i++) { - vec3 lightPos = lightPosition[i].xyz; - bool isDir = zero_float < lightPosition[i].w; - float spotCos = lightSpotParameters[i].x; - float spotExp = lightSpotParameters[i].y; - - vec3 lightDir; - float falloff; - float spotf; - - if (isDir) { - falloff = one_float; - lightDir = -lightNormal[i]; - } else { - falloff = falloffFactor(lightPos, ecVertex, lightFalloffCoefficients[i]); - lightDir = normalize(lightPos - ecVertex); - } - - spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], - spotCos, spotExp) - : one_float; - - if (any(greaterThan(lightAmbient[i], zero_vec3))) { - totalAmbient += lightAmbient[i] * falloff; - } - - if (any(greaterThan(lightDiffuse[i], zero_vec3))) { - totalDiffuse += lightDiffuse[i] * falloff * spotf * - lambertFactor(lightDir, ecNormal); - } - - if (any(greaterThan(lightSpecular[i], zero_vec3))) { - totalSpecular += lightSpecular[i] * falloff * spotf * - blinnPhongFactor(lightDir, lightPos, ecNormal, inShine); - } - } - - // Calculating final color as result of all lights (plus emissive term) - vertColor = vec4(totalAmbient, 1) * inAmbient + - vec4(totalDiffuse, 1) * inColor + - vec4(totalSpecular, 1) * inSpecular + - inEmissive; - - // Calculating texture coordinates, with r and q set both to one - vertTexcoord = texcoordMatrix * vec4(inTexcoord, 1.0, 1.0); -} diff --git a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertLit.glsl b/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertLit.glsl deleted file mode 100644 index eda80d84d..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertLit.glsl +++ /dev/null @@ -1,130 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform mat4 modelviewMatrix; -uniform mat4 projmodelviewMatrix; -uniform mat3 normalMatrix; - -uniform int lightCount; -uniform vec4 lightPosition[8]; -uniform vec3 lightNormal[8]; -uniform vec3 lightAmbient[8]; -uniform vec3 lightDiffuse[8]; -uniform vec3 lightSpecular[8]; -uniform vec3 lightFalloffCoefficients[8]; -uniform vec2 lightSpotParameters[8]; - -attribute vec4 inVertex; -attribute vec4 inColor; -attribute vec3 inNormal; - -attribute vec4 inAmbient; -attribute vec4 inSpecular; -attribute vec4 inEmissive; -attribute float inShine; - -varying vec4 vertColor; - -const float zero_float = 0.0; -const float one_float = 1.0; -const vec3 zero_vec3 = vec3(0); - -float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { - vec3 lpv = lightPos - vertPos; - vec3 dist = vec3(one_float); - dist.z = dot(lpv, lpv); - dist.y = sqrt(dist.z); - return one_float / dot(dist, coeff); -} - -float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { - vec3 lpv = normalize(lightPos - vertPos); - float spotCos = dot(-lightNorm, lpv); - return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); -} - -float lambertFactor(vec3 lightDir, vec3 vecNormal) { - return max(zero_float, dot(lightDir, vecNormal)); -} - -float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) { - vec3 ldp = normalize(lightDir - lightPos); - return pow(max(zero_float, dot(ldp, vecNormal)), shine); -} - -void main() { - // Vertex in clip coordinates - gl_Position = projmodelviewMatrix * inVertex; - - // Vertex in eye coordinates - vec3 ecVertex = vec3(modelviewMatrix * inVertex); - - // Normal vector in eye coordinates - vec3 ecNormal = normalize(normalMatrix * inNormal); - - // Light calculations - vec3 totalAmbient = vec3(0, 0, 0); - vec3 totalDiffuse = vec3(0, 0, 0); - vec3 totalSpecular = vec3(0, 0, 0); - for (int i = 0; i < lightCount; i++) { - vec3 lightPos = lightPosition[i].xyz; - bool isDir = zero_float < lightPosition[i].w; - float spotCos = lightSpotParameters[i].x; - float spotExp = lightSpotParameters[i].y; - - vec3 lightDir; - float falloff; - float spotf; - - if (isDir) { - falloff = one_float; - lightDir = -lightNormal[i]; - } else { - falloff = falloffFactor(lightPos, ecVertex, lightFalloffCoefficients[i]); - lightDir = normalize(lightPos - ecVertex); - } - - spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], - spotCos, spotExp) - : one_float; - - if (any(greaterThan(lightAmbient[i], zero_vec3))) { - totalAmbient += lightAmbient[i] * falloff; - } - - if (any(greaterThan(lightDiffuse[i], zero_vec3))) { - totalDiffuse += lightDiffuse[i] * falloff * spotf * - lambertFactor(lightDir, ecNormal); - } - - if (any(greaterThan(lightSpecular[i], zero_vec3))) { - totalSpecular += lightSpecular[i] * falloff * spotf * - blinnPhongFactor(lightDir, lightPos, ecNormal, inShine); - } - - } - - // Calculating final color as result of all lights (plus emissive term) - vertColor = vec4(totalAmbient, 1) * inAmbient + - vec4(totalDiffuse, 1) * inColor + - vec4(totalSpecular, 1) * inSpecular + - inEmissive; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertSimple.glsl b/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertSimple.glsl deleted file mode 100644 index 9dd5d2b07..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertSimple.glsl +++ /dev/null @@ -1,33 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform mat4 projmodelviewMatrix; - -attribute vec4 inVertex; -attribute vec4 inColor; - -varying vec4 vertColor; - -void main() { - gl_Position = projmodelviewMatrix * inVertex; - - vertColor = inColor; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertTex.glsl b/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertTex.glsl deleted file mode 100644 index 233422d87..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/FillShaderVertTex.glsl +++ /dev/null @@ -1,37 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform mat4 projmodelviewMatrix; -uniform mat4 texcoordMatrix; - -attribute vec4 inVertex; -attribute vec4 inColor; -attribute vec2 inTexcoord; - -varying vec4 vertColor; -varying vec4 vertTexcoord; - -void main() { - gl_Position = projmodelviewMatrix * inVertex; - - vertColor = inColor; - vertTexcoord = texcoordMatrix * vec4(inTexcoord, 1.0, 1.0); -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/LineShaderFrag.glsl b/java/libraries/lwjgl/src/processing/lwjgl/LineShaderFrag.glsl deleted file mode 100644 index 29e18414e..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/LineShaderFrag.glsl +++ /dev/null @@ -1,26 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -varying vec4 vertColor; - -void main() { - gl_FragColor = vertColor; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/LineShaderVert.glsl b/java/libraries/lwjgl/src/processing/lwjgl/LineShaderVert.glsl deleted file mode 100644 index 650d7ed37..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/LineShaderVert.glsl +++ /dev/null @@ -1,79 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Based on glsl code from the dpix library: - http://gfx.cs.princeton.edu/proj/dpix/ - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform mat4 modelviewMatrix; -uniform mat4 projectionMatrix; - -uniform vec4 viewport; -uniform int perspective; - -attribute vec4 inVertex; -attribute vec4 inColor; -attribute vec4 inDirWidth; - -varying vec4 vertColor; - -vec3 clipToWindow(vec4 clip, vec4 viewport) { - vec3 post_div = clip.xyz / clip.w; - vec2 xypos = (post_div.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw; - return vec3(xypos, post_div.z * 0.5 + 0.5); -} - -vec4 windowToClipVector(vec2 window, vec4 viewport, float clip_w) { - vec2 xypos = (window / viewport.zw) * 2.0; - return vec4(xypos, 0.0, 0.0) * clip_w; -} - -void main() { - vec4 pos_p = inVertex; - vec4 pos_q = vec4(inDirWidth.xyz, 1); - - vec4 v_p = modelviewMatrix * pos_p; - vec4 clip_p = projectionMatrix * v_p; - - vec4 v_q = modelviewMatrix * pos_q; - vec4 clip_q = projectionMatrix * v_q; - - vec3 window_p = clipToWindow(clip_p, viewport); - vec3 window_q = clipToWindow(clip_q, viewport); - vec3 tangent = window_q - window_p; - - float segment_length = length(tangent.xy); - vec2 perp = normalize(vec2(-tangent.y, tangent.x)); - float thickness = inDirWidth.w; - vec2 window_offset = perp * thickness; - - if (0 < perspective) { - // Perspective correction (lines will look thiner as they move away - // from the view position). - gl_Position.xy = clip_p.xy + window_offset.xy; - gl_Position.zw = clip_p.zw; - } else { - // No perspective correction. - float clip_p_w = clip_p.w; - vec4 offset_p = windowToClipVector(window_offset, viewport, clip_p_w); - gl_Position = clip_p + offset_p; - } - - vertColor = inColor; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PFontTexture.java b/java/libraries/lwjgl/src/processing/lwjgl/PFontTexture.java deleted file mode 100644 index 5d39e4ef7..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PFontTexture.java +++ /dev/null @@ -1,354 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2004-08 Ben Fry and Casey Reas - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -package processing.lwjgl; - -import processing.core.PApplet; -import processing.core.PConstants; -import processing.core.PFont; -import processing.core.PImage; - -import java.util.HashMap; - -/** - * All the infrastructure needed for optimized font rendering - * in OpenGL. Basically, this special class is needed because - * fonts in Processing are handled by a separate PImage for each - * gyph. For performance reasons, all these glyphs should be - * stored in a single OpenGL texture (otherwise, rendering a - * string of text would involve binding and unbinding several - * textures. - * PFontTexture manages the correspondence between individual - * glyphs and the large OpenGL texture containing them. Also, - * in the case that the font size is very large, one single - * OpenGL texture might not be enough to store all the glyphs, - * so PFontTexture also takes care of spreading a single font - * over several textures. - * By Andres Colubri - * - */ -class PFontTexture implements PConstants { - protected PApplet parent; - protected PGraphicsLWJGL pg; - protected PGL pgl; - protected PGL.Context context; - protected PFont font; - - protected int maxTexWidth; - protected int maxTexHeight; - protected int offsetX; - protected int offsetY; - protected int lineHeight; - protected PTexture[] textures = null; - protected PImage[] images = null; - protected int currentTex; - protected int lastTex; - protected TextureInfo[] glyphTexinfos; - protected HashMap texinfoMap; - - public PFontTexture(PApplet parent, PFont font, int maxw, int maxh) { - this.parent = parent; - this.font = font; - pg = (PGraphicsLWJGL)parent.g; - pgl = pg.pgl; - context = pgl.getContext(); - - initTexture(maxw, maxh); - } - - - protected void allocate() { - // Nothing to do here: the font textures will allocate - // themselves. - } - - - protected void initTexture(int w, int h) { - maxTexWidth = w; - maxTexHeight = h; - - currentTex = -1; - lastTex = -1; - - addTexture(); - - offsetX = 0; - offsetY = 0; - lineHeight = 0; - - texinfoMap = new HashMap(); - glyphTexinfos = new TextureInfo[font.getGlyphCount()]; - addAllGlyphsToTexture(); - } - - - public boolean addTexture() { - int w, h; - boolean resize; - - w = maxTexWidth; - if (-1 < currentTex && textures[currentTex].glHeight < maxTexHeight) { - // The height of the current texture is less than the maximum, this - // means we can replace it with a larger texture. - h = PApplet.min(2 * textures[currentTex].glHeight, maxTexHeight); - resize = true; - } else { - h = PApplet.min(PGraphicsLWJGL.maxTextureSize, 512, maxTexHeight / 4); - resize = false; - } - - PTexture tex = new PTexture(parent, w, h, new PTexture.Parameters(ARGB, BILINEAR)); - - if (textures == null) { - textures = new PTexture[1]; - textures[0] = tex; - images = new PImage[1]; - images[0] = pg.wrapTexture(tex); - currentTex = 0; - } else if (resize) { - // Replacing old smaller texture with larger one. - // But first we must copy the contents of the older - // texture into the new one. - PTexture tex0 = textures[currentTex]; - tex.put(tex0); - textures[currentTex] = tex; - - images[currentTex].setCache(pg, tex); - images[currentTex].width = tex.width; - images[currentTex].height = tex.height; - } else { - // Adding new texture to the list. - PTexture[] tempTex = textures; - textures = new PTexture[textures.length + 1]; - PApplet.arrayCopy(tempTex, textures, tempTex.length); - textures[tempTex.length] = tex; - currentTex = textures.length - 1; - - PImage[] tempImg = images; - images = new PImage[textures.length + 1]; - PApplet.arrayCopy(tempImg, images, tempImg.length); - images[tempImg.length] = pg.wrapTexture(tex); - } - lastTex = currentTex; - - // Make sure that the current texture is bound. - //tex.bind(); - - return resize; - } - - - public void setFirstTexture() { - setTexture(0); - } - - - public void setTexture(int idx) { - if (0 <= idx && idx < textures.length) { - currentTex = idx; - } - } - - - public PImage getTexture(int idx) { - if (0 <= idx && idx < images.length) { - return images[idx]; - } - return null; - } - - - public PImage getCurrentTexture() { - return getTexture(currentTex); - } - - - // Add all the current glyphs to opengl texture. - public void addAllGlyphsToTexture() { - // loop over current glyphs. - for (int i = 0; i < font.getGlyphCount(); i++) { - addToTexture(i, font.getGlyph(i)); - } - } - - - public void updateGlyphsTexCoords() { - // loop over current glyphs. - for (int i = 0; i < font.getGlyphCount(); i++) { - TextureInfo tinfo = glyphTexinfos[i]; - if (tinfo != null && tinfo.texIndex == currentTex) { - tinfo.updateUV(); - } - } - } - - - public TextureInfo getTexInfo(PFont.Glyph glyph) { - TextureInfo info = texinfoMap.get(glyph); - return info; - } - - - public TextureInfo addToTexture(PFont.Glyph glyph) { - int n = glyphTexinfos.length; - if (n == 0) { - glyphTexinfos = new TextureInfo[1]; - } - addToTexture(n, glyph); - return glyphTexinfos[n]; - } - - - // Adds this glyph to the opengl texture in PFont. - protected void addToTexture(int idx, PFont.Glyph glyph) { - // We add one pixel to avoid issues when sampling the font texture at fractional - // screen positions. I.e.: the pixel on the screen only contains half of the - // font rectangle, so it would sample half of the color from the glyph - // area in the texture, and the other half from the contiguous pixel. If the - // later contains a portion of the neighbor glyph and former doesn't, this - // would result in a shaded pixel when the correct output is blank. - // This is a consequence of putting all the glyphs in a common texture with - // bilinear sampling. - int w = 1 + glyph.width + 1; - int h = 1 + glyph.height + 1; - - // Converting the pixels array from the PImage into a valid RGBA array for OpenGL. - int[] rgba = new int[w * h]; - int t = 0; - int p = 0; - if (PGraphicsLWJGL.BIG_ENDIAN) { - java.util.Arrays.fill(rgba, 0, w, 0xFFFFFF00); // Set the first row to blank pixels. - t = w; - for (int y = 0; y < glyph.height; y++) { - rgba[t++] = 0xFFFFFF00; // Set the leftmost pixel in this row as blank - for (int x = 0; x < glyph.width; x++) { - rgba[t++] = 0xFFFFFF00 | glyph.image.pixels[p++]; - } - rgba[t++] = 0xFFFFFF00; // Set the rightmost pixel in this row as blank - } - java.util.Arrays.fill(rgba, (h - 1) * w, h * w, 0xFFFFFF00); // Set the last row to blank pixels. - } else { - java.util.Arrays.fill(rgba, 0, w, 0x00FFFFFF); // Set the first row to blank pixels. - t = w; - for (int y = 0; y < glyph.height; y++) { - rgba[t++] = 0x00FFFFFF; // Set the leftmost pixel in this row as blank - for (int x = 0; x < glyph.width; x++) { - rgba[t++] = (glyph.image.pixels[p++] << 24) | 0x00FFFFFF; - } - rgba[t++] = 0x00FFFFFF; // Set the rightmost pixel in this row as blank - } - java.util.Arrays.fill(rgba, (h - 1) * w, h * w, 0x00FFFFFF); // Set the last row to blank pixels. - } - - // Is there room for this glyph in the current line? - if (offsetX + w > textures[currentTex].glWidth) { - // No room, go to the next line: - offsetX = 0; - offsetY += lineHeight; - lineHeight = 0; - } - lineHeight = Math.max(lineHeight, h); - - boolean resized = false; - if (offsetY + lineHeight > textures[currentTex].glHeight) { - // We run out of space in the current texture, so we add a new texture: - resized = addTexture(); - if (resized) { - // Because the current texture has been resized, we need to - // update the UV coordinates of all the glyphs associated to it: - updateGlyphsTexCoords(); - } else { - // A new texture has been created. Reseting texture coordinates - // and line. - offsetX = 0; - offsetY = 0; - lineHeight = 0; - } - } - - if (lastTex == -1) { - lastTex = 0; - } - - if (currentTex != lastTex || resized) { - currentTex = idx; - } - - TextureInfo tinfo = new TextureInfo(currentTex, offsetX, offsetY, w, h, rgba); - offsetX += w; - - if (idx == glyphTexinfos.length) { - TextureInfo[] temp = new TextureInfo[glyphTexinfos.length + 1]; - System.arraycopy(glyphTexinfos, 0, temp, 0, glyphTexinfos.length); - glyphTexinfos = temp; - } - - glyphTexinfos[idx] = tinfo; - texinfoMap.put(glyph, tinfo); - } - - - public class TextureInfo { - public int texIndex; - public int width; - public int height; - public int[] crop; - public float u0, u1; - public float v0, v1; - public int[] pixels; - - - public TextureInfo(int tidx, int cropX, int cropY, int cropW, int cropH, int[] pix) { - texIndex = tidx; - crop = new int[4]; - // The region of the texture corresponding to the glyph is surrounded by a - // 1-pixel wide border to avoid artifacts due to bilinear sampling. This is - // why the additions and subtractions to the crop values. - crop[0] = cropX + 1; - crop[1] = cropY + 1 + cropH - 2; - crop[2] = cropW - 2; - crop[3] = -cropH + 2; - pixels = pix; - updateUV(); - updateTex(); - } - - - void updateUV() { - width = textures[texIndex].glWidth; - height = textures[texIndex].glHeight; - u0 = (float)crop[0] / (float)width; - u1 = u0 + (float)crop[2] / (float)width; - v0 = (float)(crop[1] + crop[3]) / (float)height; - v1 = v0 - (float)crop[3] / (float)height; - } - - - void updateTex() { - textures[texIndex].bind(); - textures[texIndex].setTexels(pixels, 0, crop[0] - 1, crop[1] + crop[3] - 1, crop[2] + 2, -crop[3] + 2); - textures[texIndex].unbind(); - } - } -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PFramebuffer.java b/java/libraries/lwjgl/src/processing/lwjgl/PFramebuffer.java deleted file mode 100644 index 036883def..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PFramebuffer.java +++ /dev/null @@ -1,547 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2010 Ben Fry and Casey Reas - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - */ - -package processing.lwjgl; - -import processing.core.PApplet; -import processing.core.PConstants; - -import java.nio.IntBuffer; - -/** - * Encapsulates a Frame Buffer Object for offscreen rendering. - * When created with onscreen == true, it represents the normal - * framebuffer. Needed by the stack mechanism in OPENGL2 to return - * to onscreen rendering after a sequence of pushFramebuffer calls. - * It transparently handles the situations when the FBO extension is - * not available. - * - * By Andres Colubri. - */ -public class PFramebuffer implements PConstants { - protected PApplet parent; - protected PGraphicsLWJGL pg; - protected PGL pgl; - - public int glFboID; - public int glDepthBufferID; - public int glStencilBufferID; - public int glDepthStencilBufferID; - public int glColorBufferMultisampleID; - public int width; - public int height; - - protected int depthBits; - protected int stencilBits; - protected boolean combinedDepthStencil; - - protected boolean multisample; - protected int nsamples; - - protected int numColorBuffers; - protected PTexture[] colorBufferTex; - - protected boolean screenFb; - protected boolean noDepth; - protected boolean fboMode; - - protected PTexture backupTexture; - protected IntBuffer pixelBuffer; - - PFramebuffer(PApplet parent, int w, int h) { - this(parent, w, h, 1, 1, 0, 0, false, false); - } - - PFramebuffer(PApplet parent, int w, int h, boolean screen) { - this(parent, w, h, 1, 1, 0, 0, false, screen); - } - - PFramebuffer(PApplet parent, int w, int h, int samples, int colorBuffers, - int depthBits, int stencilBits, boolean combinedDepthStencil, - boolean screen) { - this.parent = parent; - pg = (PGraphicsLWJGL)parent.g; - pgl = pg.pgl; - - glFboID = 0; - glDepthBufferID = 0; - glStencilBufferID = 0; - glDepthStencilBufferID = 0; - glColorBufferMultisampleID = 0; - - fboMode = PGraphicsLWJGL.fboSupported; - - if (screen) { - // If this framebuffer is used to represent a on-screen buffer, - // then it doesn't make it sense for it to have multisampling, - // color, depth or stencil buffers. - depthBits = stencilBits = samples = colorBuffers = 0; - } - - width = w; - height = h; - - if (1 < samples) { - multisample = true; - nsamples = samples; - } else { - multisample = false; - nsamples = 1; - } - - numColorBuffers = colorBuffers; - colorBufferTex = new PTexture[numColorBuffers]; - for (int i = 0; i < numColorBuffers; i++) { - colorBufferTex[i] = null; - } - - if (depthBits < 1 && stencilBits < 1) { - this.depthBits = 0; - this.stencilBits = 0; - this.combinedDepthStencil = false; - } else { - if (combinedDepthStencil) { - // When combined depth/stencil format is required, the depth and stencil bits - // are overriden and the 24/8 combination for a 32 bits surface is used. - this.depthBits = 24; - this.stencilBits = 8; - this.combinedDepthStencil = true; - } else { - this.depthBits = depthBits; - this.stencilBits = stencilBits; - this.combinedDepthStencil = false; - } - } - - screenFb = screen; - - allocate(); - noDepth = false; - - pixelBuffer = null; - - if (!screenFb && !fboMode) { - // When FBOs are not available, rendering to texture is implemented by saving a portion of - // the screen, doing the "offscreen" rendering on this portion, copying the screen color - // buffer to the texture bound as color buffer to this PFramebuffer object and then drawing - // the backup texture back on the screen. - backupTexture = new PTexture(parent, width, height, new PTexture.Parameters(ARGB, POINT)); - } - } - - - protected void finalize() throws Throwable { - try { - if (glFboID != 0) { - pg.finalizeFrameBufferObject(glFboID); - } - if (glDepthBufferID != 0) { - pg.finalizeRenderBufferObject(glDepthBufferID); - } - if (glStencilBufferID != 0) { - pg.finalizeRenderBufferObject(glStencilBufferID); - } - if (glColorBufferMultisampleID != 0) { - pg.finalizeRenderBufferObject(glColorBufferMultisampleID); - } - if (glDepthStencilBufferID != 0) { - pg.finalizeRenderBufferObject(glDepthStencilBufferID); - } - } finally { - super.finalize(); - } - } - - public void clear() { - pg.pushFramebuffer(); - pg.setFramebuffer(this); - pgl.glClearColor(0, 0, 0, 0); - pgl.glClear(PGL.GL_COLOR_BUFFER_BIT | PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT); - pg.popFramebuffer(); - } - - public void copy(PFramebuffer dest) { - pgl.glBindFramebuffer(PGL.GL_READ_FRAMEBUFFER, this.glFboID); - pgl.glBindFramebuffer(PGL.GL_DRAW_FRAMEBUFFER, dest.glFboID); - pgl.glBlitFramebuffer(0, 0,this.width, this.height, 0, 0, dest.width, dest.height, PGL.GL_COLOR_BUFFER_BIT, PGL.GL_NEAREST); - } - - public void bind() { - if (screenFb) { - if (PGraphicsLWJGL.fboSupported) { - pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, 0); - } - } else if (fboMode) { - pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, glFboID); - } else { - backupScreen(); - - if (0 < numColorBuffers) { - // Drawing the current contents of the first color buffer to emulate - // front-back buffer swap. - pg.drawTexture(colorBufferTex[0].glTarget, colorBufferTex[0].glID, width, height, 0, 0, width, height, 0, 0, width, height); - } - - if (noDepth) { - pgl.glDisable(PGL.GL_DEPTH_TEST); - } - } - } - - public void disableDepthTest() { - noDepth = true; - } - - public void finish() { - if (noDepth) { - // No need to clear depth buffer because depth testing was disabled. - if (pg.hintEnabled(DISABLE_DEPTH_TEST)) { - pgl.glDisable(PGL.GL_DEPTH_TEST); - } else { - pgl.glEnable(PGL.GL_DEPTH_TEST); - } - } - - if (!screenFb && !fboMode) { - copyToColorBuffers(); - restoreBackup(); - if (!noDepth) { - // Reading the contents of the depth buffer is not possible in OpenGL ES: - // http://www.idevgames.com/forum/archive/index.php?t-15828.html - // so if this framebuffer uses depth and is offscreen with no FBOs, then - // the depth buffer is cleared to avoid artifacts when rendering more stuff - // after this offscreen render. - // A consequence of this behavior is that all the offscreen rendering when - // no FBOs are available should be done before any onscreen drawing. - pgl.glClearColor(0, 0, 0, 0); - pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); - } - } - } - - // Saves content of the screen into the backup texture. - public void backupScreen() { - if (pixelBuffer == null) createPixelBuffer(); - pixelBuffer.rewind(); - pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); - copyToTexture(pixelBuffer, backupTexture.glID, backupTexture.glTarget); - } - - // Draws the contents of the backup texture to the screen. - public void restoreBackup() { - pg.drawTexture(backupTexture, 0, 0, width, height, 0, 0, width, height); - } - - // Copies current content of screen to color buffers. - public void copyToColorBuffers() { - if (pixelBuffer == null) createPixelBuffer(); - pixelBuffer.rewind(); - pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); - for (int i = 0; i < numColorBuffers; i++) { - copyToTexture(pixelBuffer, colorBufferTex[i].glID, colorBufferTex[i].glTarget); - } - } - - public void readPixels() { - if (pixelBuffer == null) createPixelBuffer(); - pixelBuffer.rewind(); - pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); - } - - public void getPixels(int[] pixels) { - if (pixelBuffer != null) { - pixelBuffer.get(pixels); - pixelBuffer.rewind(); - } - } - - public IntBuffer getPixelBuffer() { - return pixelBuffer; - } - - public boolean hasDepthBuffer() { - return 0 < depthBits; - } - - public boolean hasStencilBuffer() { - return 0 < stencilBits; - } - - /////////////////////////////////////////////////////////// - - // Color buffer setters. - - - public void setColorBuffer(PTexture tex) { - setColorBuffers(new PTexture[] { tex }, 1); - } - - - public void setColorBuffers(PTexture[] textures) { - setColorBuffers(textures, textures.length); - } - - - public void setColorBuffers(PTexture[] textures, int n) { - if (screenFb) return; - - if (numColorBuffers != PApplet.min(n, textures.length)) { - throw new RuntimeException("Wrong number of textures to set the color buffers."); - } - - for (int i = 0; i < numColorBuffers; i++) { - colorBufferTex[i] = textures[i]; - } - - if (fboMode) { - pg.pushFramebuffer(); - pg.setFramebuffer(this); - - // Making sure nothing is attached. - for (int i = 0; i < numColorBuffers; i++) { - pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, PGL.GL_TEXTURE_2D, 0, 0); - } - - for (int i = 0; i < numColorBuffers; i++) { - pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0); - } - - validateFbo(); - - pg.popFramebuffer(); - } - } - - - /////////////////////////////////////////////////////////// - - // Allocate/release framebuffer. - - - protected void allocate() { - release(); // Just in the case this object is being re-allocated. - - if (screenFb) { - glFboID = 0; - } else if (fboMode) { - //glFboID = ogl.createGLResource(PGraphicsAndroid3D.GL_FRAME_BUFFER); - glFboID = pg.createFrameBufferObject(); - } else { - glFboID = 0; - } - - // create the rest of the stuff... - if (multisample) { - createColorBufferMultisample(); - } - - if (combinedDepthStencil) { - createCombinedDepthStencilBuffer(); - } else { - if (0 < depthBits) { - createDepthBuffer(); - } - if (0 < stencilBits) { - createStencilBuffer(); - } - } - } - - - protected void release() { - if (glFboID != 0) { - pg.finalizeFrameBufferObject(glFboID); - glFboID = 0; - } - if (glDepthBufferID != 0) { - pg.finalizeRenderBufferObject(glDepthBufferID); - glDepthBufferID = 0; - } - if (glStencilBufferID != 0) { - pg.finalizeRenderBufferObject(glStencilBufferID); - glStencilBufferID = 0; - } - if (glColorBufferMultisampleID != 0) { - pg.finalizeRenderBufferObject(glColorBufferMultisampleID); - glColorBufferMultisampleID = 0; - } - if (glDepthStencilBufferID != 0) { - pg.finalizeRenderBufferObject(glDepthStencilBufferID); - glDepthStencilBufferID = 0; - } - } - - - protected void createColorBufferMultisample() { - if (screenFb) return; - - if (fboMode) { - pg.pushFramebuffer(); - pg.setFramebuffer(this); - - glColorBufferMultisampleID = pg.createRenderBufferObject(); - pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glColorBufferMultisampleID); - pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_RGBA8, width, height); - pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0, PGL.GL_RENDERBUFFER, glColorBufferMultisampleID); - - pg.popFramebuffer(); - } - } - - - protected void createCombinedDepthStencilBuffer() { - if (screenFb) return; - - if (width == 0 || height == 0) { - throw new RuntimeException("PFramebuffer: size undefined."); - } - - if (fboMode) { - pg.pushFramebuffer(); - pg.setFramebuffer(this); - - glDepthStencilBufferID = pg.createRenderBufferObject(); - pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthStencilBufferID); - - if (multisample) { - pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_DEPTH24_STENCIL8, width, height); - } else { - pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, PGL.GL_DEPTH24_STENCIL8, width, height); - } - - pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID); - pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID); - - pg.popFramebuffer(); - } - } - - - protected void createDepthBuffer() { - if (screenFb) return; - - if (width == 0 || height == 0) { - throw new RuntimeException("PFramebuffer: size undefined."); - } - - if (fboMode) { - pg.pushFramebuffer(); - pg.setFramebuffer(this); - - glDepthBufferID = pg.createRenderBufferObject(); - pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthBufferID); - - int glConst = PGL.GL_DEPTH_COMPONENT16; - if (depthBits == 16) { - glConst = PGL.GL_DEPTH_COMPONENT16; - } else if (depthBits == 24) { - glConst = PGL.GL_DEPTH_COMPONENT24; - } else if (depthBits == 32) { - glConst = PGL.GL_DEPTH_COMPONENT32; - } - - if (multisample) { - pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height); - } else { - pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height); - } - - pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthBufferID); - - pg.popFramebuffer(); - } - } - - - protected void createStencilBuffer() { - if (screenFb) return; - - if (width == 0 || height == 0) { - throw new RuntimeException("PFramebuffer: size undefined."); - } - - if (fboMode) { - pg.pushFramebuffer(); - pg.setFramebuffer(this); - - glStencilBufferID = pg.createRenderBufferObject(); - pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glStencilBufferID); - - int glConst = PGL.GL_STENCIL_INDEX1; - if (stencilBits == 1) { - glConst = PGL.GL_STENCIL_INDEX1; - } else if (stencilBits == 4) { - glConst = PGL.GL_STENCIL_INDEX4; - } else if (stencilBits == 8) { - glConst = PGL.GL_STENCIL_INDEX8; - } - if (multisample) { - pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height); - } else { - pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height); - } - - pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glStencilBufferID); - - pg.popFramebuffer(); - } - } - - - protected void createPixelBuffer() { - pixelBuffer = IntBuffer.allocate(width * height); - pixelBuffer.rewind(); - } - - /////////////////////////////////////////////////////////// - - // Utilities. - - // Internal copy to texture method. - protected void copyToTexture(IntBuffer buffer, int glid, int gltarget) { - pgl.enableTexturing(gltarget); - pgl.glBindTexture(gltarget, glid); - pgl.glTexSubImage2D(gltarget, 0, 0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer); - pgl.glBindTexture(gltarget, 0); - pgl.disableTexturing(gltarget); - } - - public boolean validateFbo() { - int status = pgl.glCheckFramebufferStatus(PGL.GL_FRAMEBUFFER); - if (status == PGL.GL_FRAMEBUFFER_COMPLETE) { - return true; - } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_FORMATS (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.GL_FRAMEBUFFER_UNSUPPORTED) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_UNSUPPORTED" + Integer.toHexString(status)); - } else { - throw new RuntimeException("PFramebuffer: unknown framebuffer error (" + Integer.toHexString(status) + ")"); - } - } -} diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PGL.java b/java/libraries/lwjgl/src/processing/lwjgl/PGL.java deleted file mode 100644 index ceae6e2a2..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PGL.java +++ /dev/null @@ -1,955 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2010 Ben Fry and Casey Reas - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - */ - -package processing.lwjgl; - -import java.awt.BorderLayout; -import java.awt.Canvas; -import java.nio.Buffer; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; - -import org.lwjgl.BufferUtils; -import org.lwjgl.LWJGLException; -import org.lwjgl.opengl.ARBShaderObjects; -import org.lwjgl.opengl.Display; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL14; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; -import org.lwjgl.util.glu.GLU; -import org.lwjgl.util.glu.GLUtessellator; -import org.lwjgl.util.glu.GLUtessellatorCallbackAdapter; -import org.lwjgl.opengl.GLContext; -import org.lwjgl.opengl.PixelFormat; - -/** - * Processing-OpenGL abstraction layer. - * - */ -public class PGL { - /** Size of a short (in bytes). */ - static final int SIZEOF_SHORT = Short.SIZE / 8; - - /** Size of an int (in bytes). */ - static final int SIZEOF_INT = Integer.SIZE / 8; - - /** Size of a float (in bytes). */ - static final int SIZEOF_FLOAT = Float.SIZE / 8; - - /** Size of a vertex index. */ - static final int SIZEOF_INDEX = SIZEOF_INT; - - /** Type of a vertex index. */ - static final int INDEX_TYPE = GL11.GL_UNSIGNED_INT; - - /** Initial sizes for arrays of input and tessellated data. */ - public static final int DEFAULT_IN_VERTICES = 64; - public static final int DEFAULT_IN_EDGES = 128; - public static final int DEFAULT_IN_TEXTURES = 64; - public static final int DEFAULT_TESS_VERTICES = 64; - public static final int DEFAULT_TESS_INDICES = 128; - - /** Initial sizes for vertex cache used in PShape3D. */ - public static final int DEFAULT_VERTEX_CACHE_SIZE = 512; - - /** Maximum lights by default is 8, the minimum defined by OpenGL. */ - public static final int MAX_LIGHTS = 8; - - /** Maximum number of tessellated vertices, using 2^20 for Mac/PC. */ - public static final int MAX_TESS_VERTICES = 524288; - - /** Maximum number of indices. 2 times the max number of - * vertices to have good room for vertex reuse. */ - public static final int MAX_TESS_INDICES = 2 * MAX_TESS_VERTICES; - - /** Maximum dimension of a texture used to hold font data. **/ - public static final int MAX_FONT_TEX_SIZE = 256; - - /////////////////////////////////////////////////////////////////////////////////// - - // OpenGL constants - - public static final int GL_LESS = GL11.GL_LESS; - public static final int GL_LEQUAL = GL11.GL_LEQUAL; - public static final int GL_CCW = GL11.GL_CCW; - public static final int GL_CW = GL11.GL_CW; - public static final int GL_FRONT = GL11.GL_FRONT; - public static final int GL_BACK = GL11.GL_BACK; - - public static final int GL_VIEWPORT = GL11.GL_VIEWPORT; - - public static final int GL_SCISSOR_TEST = GL11.GL_SCISSOR_TEST; - public static final int GL_DEPTH_TEST = GL11.GL_DEPTH_TEST; - - public static final int GL_COLOR_BUFFER_BIT = GL11.GL_COLOR_BUFFER_BIT; - public static final int GL_DEPTH_BUFFER_BIT = GL11.GL_DEPTH_BUFFER_BIT; - public static final int GL_STENCIL_BUFFER_BIT = GL11.GL_STENCIL_BUFFER_BIT; - - public static final int GL_FUNC_ADD = 0x8006; - public static final int GL_FUNC_MIN = 0x8007; - public static final int GL_FUNC_MAX = 0x8008; - public static final int GL_FUNC_REVERSE_SUBTRACT = 0x800b; - - public static final int GL_TEXTURE_2D = GL11.GL_TEXTURE_2D; - public static final int GL_RGB = GL11.GL_RGB; - public static final int GL_RGBA = GL11.GL_RGBA; - public static final int GL_ALPHA = GL11.GL_ALPHA; - public static final int GL_UNSIGNED_INT = GL11.GL_UNSIGNED_INT; - public static final int GL_UNSIGNED_BYTE = GL11.GL_UNSIGNED_BYTE; - public static final int GL_UNSIGNED_SHORT = GL11.GL_UNSIGNED_SHORT; - public static final int GL_FLOAT = GL11.GL_FLOAT; - - public static final int GL_NEAREST = GL11.GL_NEAREST; - public static final int GL_LINEAR = GL11.GL_LINEAR; - public static final int GL_LINEAR_MIPMAP_LINEAR = GL11.GL_LINEAR_MIPMAP_LINEAR; - - public static final int GL_CLAMP_TO_EDGE = GL12.GL_CLAMP_TO_EDGE; - public static final int GL_REPEAT = GL11.GL_REPEAT; - - public static final int GL_RGBA8 = -1; - public static final int GL_DEPTH24_STENCIL8 = -1; - - public static final int GL_DEPTH_COMPONENT16 = GL14.GL_DEPTH_COMPONENT16; - public static final int GL_DEPTH_COMPONENT24 = GL14.GL_DEPTH_COMPONENT24; - public static final int GL_DEPTH_COMPONENT32 = GL14.GL_DEPTH_COMPONENT32; - - - public static final int GL_STENCIL_INDEX1 = GL30.GL_STENCIL_INDEX1; - public static final int GL_STENCIL_INDEX4 = GL30.GL_STENCIL_INDEX4; - public static final int GL_STENCIL_INDEX8 = GL30.GL_STENCIL_INDEX8; - - public static final int GL_ARRAY_BUFFER = GL15.GL_ARRAY_BUFFER; - public static final int GL_ELEMENT_ARRAY_BUFFER = GL15.GL_ELEMENT_ARRAY_BUFFER; - - public static final int GL_FRAMEBUFFER_COMPLETE = GL30.GL_FRAMEBUFFER_COMPLETE; - public static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL30.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - public static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL30.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; - public static final int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8cd9; - public static final int GL_FRAMEBUFFER_INCOMPLETE_FORMATS = 0x8cda; - public static final int GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = GL30.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; - public static final int GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL30.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; - public static final int GL_FRAMEBUFFER_UNSUPPORTED = GL30.GL_FRAMEBUFFER_UNSUPPORTED; - - public static final int GL_STATIC_DRAW = GL15.GL_STATIC_DRAW; - public static final int GL_DYNAMIC_DRAW = GL15.GL_DYNAMIC_DRAW; - public static final int GL_STREAM_DRAW = GL15.GL_STREAM_DRAW; - - public static final int GL_READ_ONLY = GL15.GL_READ_ONLY; - public static final int GL_WRITE_ONLY = GL15.GL_WRITE_ONLY; - public static final int GL_READ_WRITE = GL15.GL_READ_WRITE; - - public static final int GL_TRIANGLE_FAN = GL11.GL_TRIANGLE_FAN; - public static final int GL_TRIANGLE_STRIP = GL11.GL_TRIANGLE_STRIP; - public static final int GL_TRIANGLES = GL11.GL_TRIANGLES; - - public static final int GL_VENDOR = GL11.GL_VENDOR; - public static final int GL_RENDERER = GL11.GL_RENDERER; - public static final int GL_VERSION = GL11.GL_VERSION; - public static final int GL_EXTENSIONS = GL11.GL_EXTENSIONS; - - public static final int GL_MAX_TEXTURE_SIZE = GL11.GL_MAX_TEXTURE_SIZE; - public static final int GL_ALIASED_LINE_WIDTH_RANGE = GL12.GL_ALIASED_LINE_WIDTH_RANGE; - public static final int GL_ALIASED_POINT_SIZE_RANGE = GL12.GL_ALIASED_POINT_SIZE_RANGE; - public static final int GL_SAMPLES = GL13.GL_SAMPLES; - - public static final int GLU_TESS_WINDING_NONZERO = GLU.GLU_TESS_WINDING_NONZERO; - public static final int GLU_TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD; - - public static final int GL_TEXTURE0 = GL13.GL_TEXTURE0; - public static final int GL_TEXTURE1 = GL13.GL_TEXTURE1; - public static final int GL_TEXTURE2 = GL13.GL_TEXTURE2; - public static final int GL_TEXTURE3 = GL13.GL_TEXTURE3; - public static final int GL_TEXTURE_MIN_FILTER = GL11.GL_TEXTURE_MIN_FILTER; - public static final int GL_TEXTURE_MAG_FILTER = GL11.GL_TEXTURE_MAG_FILTER; - public static final int GL_TEXTURE_WRAP_S = GL11.GL_TEXTURE_WRAP_S; - public static final int GL_TEXTURE_WRAP_T = GL11.GL_TEXTURE_WRAP_T; - - public static final int GL_BLEND = GL11.GL_BLEND; - public static final int GL_ONE = GL11.GL_ONE; - public static final int GL_ZERO = GL11.GL_ZERO; - public static final int GL_SRC_ALPHA = GL11.GL_SRC_ALPHA; - public static final int GL_DST_ALPHA = GL11.GL_DST_ALPHA; - public static final int GL_ONE_MINUS_SRC_ALPHA = GL11.GL_ONE_MINUS_SRC_ALPHA; - public static final int GL_ONE_MINUS_DST_COLOR = GL11.GL_ONE_MINUS_DST_COLOR; - public static final int GL_ONE_MINUS_SRC_COLOR = GL11.GL_ONE_MINUS_SRC_COLOR; - public static final int GL_DST_COLOR = GL11.GL_DST_COLOR; - public static final int GL_SRC_COLOR = GL11.GL_SRC_COLOR; - - public static final int GL_FRAMEBUFFER = GL30.GL_FRAMEBUFFER; - public static final int GL_COLOR_ATTACHMENT0 = GL30.GL_COLOR_ATTACHMENT0; - public static final int GL_RENDERBUFFER = GL30.GL_RENDERBUFFER; - public static final int GL_DEPTH_ATTACHMENT = GL30.GL_DEPTH_ATTACHMENT; - public static final int GL_STENCIL_ATTACHMENT = GL30.GL_STENCIL_ATTACHMENT; - public static final int GL_READ_FRAMEBUFFER = GL30.GL_READ_FRAMEBUFFER; - public static final int GL_DRAW_FRAMEBUFFER = GL30.GL_DRAW_FRAMEBUFFER; - public static final int GL_COLOR_ATTACHMENT1 = GL30.GL_COLOR_ATTACHMENT1; - public static final int GL_COLOR_ATTACHMENT2 = GL30.GL_COLOR_ATTACHMENT2; - public static final int GL_COLOR_ATTACHMENT3 = GL30.GL_COLOR_ATTACHMENT3; - - public static final int GL_VERTEX_SHADER = GL20.GL_VERTEX_SHADER; - public static final int GL_FRAGMENT_SHADER = GL20.GL_FRAGMENT_SHADER; - - public static final int GL_MULTISAMPLE = GL13.GL_MULTISAMPLE; - public static final int GL_POINT_SMOOTH = GL11.GL_POINT_SMOOTH; - public static final int GL_LINE_SMOOTH = GL11.GL_LINE_SMOOTH; - public static final int GL_POLYGON_SMOOTH = GL11.GL_POLYGON_SMOOTH; - - public Canvas canvas; - - public PGraphicsLWJGL pg; - - public GLU glu; - - public boolean initialized; - - /////////////////////////////////////////////////////////////////////////////////// - - // Intialization, finalization - - public PGL(PGraphicsLWJGL pg) { - this.pg = pg; - glu = new GLU(); - initialized = false; - } - - /** - * This static method can be called by applications that use - * Processing+P3D inside their own GUI, so they can initialize - * JOGL2 before anything else. - * According to the JOGL2 documentation, applications shall call - * GLProfile.initSingleton() ASAP, before any other UI invocation. - * In case applications are able to initialize JOGL before any other - * UI action, hey shall invoke this method with beforeUI=true and - * benefit from fast native multithreading support on all platforms - * if possible. - * - */ - static public void startup(boolean beforeUI) { -// try { -// GLProfile.initSingleton(beforeUI); -// } catch (Exception e) { -// e.printStackTrace(); -// } - } - - static public void shutdown() { -// GLProfile.shutdown(); - } - - public void updatePrimary() { -// gl = context.getGL(); -// gl2 = gl.getGL2(); - } - - public void updateOffscreen(PGL primary) { -// gl = primary.gl; -// gl2 = primary.gl2; - } - - - public void initPrimarySurface(int antialias) { - canvas = new Canvas(); - - canvas.setBounds(0, 0, pg.parent.width, pg.parent.height); - canvas.setFocusable(true); - canvas.requestFocus(); - canvas.setIgnoreRepaint(true); - pg.parent.setLayout(new BorderLayout()); - pg.parent.add(canvas, BorderLayout.CENTER); - - try { - Display.setParent(canvas); - PixelFormat format = new PixelFormat(32, 0, 24, 8, antialias); - Display.create(format); - Display.setVSyncEnabled(false); - } catch (LWJGLException e) { - e.printStackTrace(); - } - - canvas.addMouseListener(pg.parent); - canvas.addMouseMotionListener(pg.parent); - canvas.addKeyListener(pg.parent); - canvas.addFocusListener(pg.parent); - - initialized = true; - } - - public void initOffscreenSurface(PGL primary) { -// context = primary.context; -// capabilities = primary.capabilities; -// drawable = null; - initialized = true; - } - - public void updateOffscreenSurface(PGL primary) { -// context = primary.context; -// capabilities = primary.capabilities; -// drawable = null; - } - - /** - * Make the OpenGL rendering context current for this thread. - */ - protected void detainContext() { -// try { -// while (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) { -// Thread.sleep(10); -// } -// } catch (InterruptedException e) { -// e.printStackTrace(); -// } - } - - /** - * Release the context, otherwise the AWT lock on X11 will not be released - */ - public void releaseContext() { -// context.release(); - } - - public void destroyContext() { -// context.destroy(); -// context = null; - } - - /////////////////////////////////////////////////////////////////////////////////// - - // Frame rendering - - public boolean initOnscreenDraw() { -// if (drawable != null) { -// // Call setRealized() after addNotify() has been called -// drawable.setRealized(pg.parent.isDisplayable()); -// if (pg.parent.isDisplayable()) { -// drawable.setRealized(true); -// return true; -// } else { -// return false; // Should have called canDraw() anyway -// } -// } -// return false; - return true; - } - - public void beginOnscreenDraw(boolean clear, int frame) { - } - - public void endOnscreenDraw(boolean clear0) { - Display.update(); -// if (drawable != null) { -// drawable.swapBuffers(); -// } - } - - public void beginOffscreenDraw(boolean clear, int frame) { - } - - public void endOffscreenDraw(boolean clear0) { - } - - public boolean canDraw() { - return pg.parent.isDisplayable(); - } - - public void requestDraw() { - } - - /////////////////////////////////////////////////////////////////////////////////// - - // Caps query - - public String glGetString(int name) { - return GL11.glGetString(name); - } - - public void glGetIntegerv(int name, IntBuffer values) { - GL11.glGetInteger(name, values); - } - - /////////////////////////////////////////////////////////////////////////////////// - - // Enable/disable caps - - public void glEnable(int cap) { - if (-1 < cap) { - GL11.glEnable(cap); - } - } - - public void glDisable(int cap) { - if (-1 < cap) { - GL11.glDisable(cap); - } - } - - /////////////////////////////////////////////////////////////////////////////////// - - // Render control - - public void glFlush() { - GL11.glFlush(); - } - - public void glFinish() { - GL11.glFinish(); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Error handling - - public int glGetError() { - return GL11.glGetError(); - } - - public String glErrorString(int err) { - return GLU.gluErrorString(err); - } - - public String gluErrorString(int err) { - return GLU.gluErrorString(err); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Rendering options - - public void glFrontFace(int mode) { - GL11.glFrontFace(mode); - } - - public void glDepthMask(boolean flag) { - GL11.glDepthMask(flag); - } - - public void glDepthFunc(int func) { - GL11.glDepthFunc(func); - } - - - ///////////////////////////////////////////////////////////////////////////////// - - // Textures - - public void glGenTextures(int n, IntBuffer ids) { - ids.limit(n); - GL11.glGenTextures(ids); - } - - public void glDeleteTextures(int n, IntBuffer ids) { - ids.limit(n); - GL11.glDeleteTextures(ids); - } - - public void glActiveTexture(int unit) { - GL13.glActiveTexture(unit); - } - - public void glBindTexture(int target, int id) { - GL11.glBindTexture(target, id); - } - - public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, IntBuffer data) { - GL11.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data); - } - - public void glTexSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, IntBuffer data) { - GL11.glTexSubImage2D(target, level, xOffset, yOffset, width, height, format, type, data); - } - - public void glTexParameterf(int target, int param, int value) { - GL11.glTexParameterf(target, param, value); - } - - public void glGenerateMipmap(int target) { - GL30.glGenerateMipmap(target); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Vertex Buffers - - public void glGenBuffers(int n, IntBuffer ids) { - ids.limit(n); - GL15.glGenBuffers(ids); - } - - public void glDeleteBuffers(int n, IntBuffer ids) { - ids.limit(n); - GL15.glDeleteBuffers(ids); - } - - public void glBindBuffer(int target, int id) { - GL15.glBindBuffer(target, id); - } - - public void glBufferData(int target, int size, Buffer data, int usage) { - if (data == null) { - FloatBuffer empty = BufferUtils.createFloatBuffer(size); - GL15.glBufferData(target, empty, usage); - } else { - if (data instanceof ByteBuffer) { - GL15.glBufferData(target, (ByteBuffer)data, usage); - } else if (data instanceof IntBuffer) { - GL15.glBufferData(target, (IntBuffer)data, usage); - } else if (data instanceof FloatBuffer) { - GL15.glBufferData(target, (FloatBuffer)data, usage); - } - } - } - - - public void glBufferSubData(int target, int offset, int size, Buffer data) { - if (data instanceof ByteBuffer) { - GL15.glBufferSubData(target, offset, (ByteBuffer)data); - } else if (data instanceof IntBuffer) { - GL15.glBufferSubData(target, offset, (IntBuffer)data); - } else if (data instanceof FloatBuffer) { - GL15.glBufferSubData(target, offset, (FloatBuffer)data); - } - } - - - public void glDrawElements(int mode, int count, int type, int offset) { - GL11.glDrawElements(mode, count, type, offset); - } - - - public void glEnableVertexAttribArray(int loc) { - GL20.glEnableVertexAttribArray(loc); - } - - public void glDisableVertexAttribArray(int loc) { - GL20.glDisableVertexAttribArray(loc); - } - - public void glVertexAttribPointer(int loc, int size, int type, boolean normalized, int stride, int offset) { - GL20.glVertexAttribPointer(loc, size, type, normalized, stride, offset); - } - - - public ByteBuffer glMapBuffer(int target, int access) { - return GL15.glMapBuffer(target, access, null); - } - - public ByteBuffer glMapBufferRange(int target, int offset, int length, int access) { - return GL30.glMapBufferRange(target, offset, length, access, null); - } - - public void glUnmapBuffer(int target) { - GL15.glUnmapBuffer(target); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Framebuffers, renderbuffers - - public void glGenFramebuffers(int n, IntBuffer ids) { - ids.limit(n); - GL30.glGenFramebuffers(ids); - } - - public void glDeleteFramebuffers(int n, IntBuffer ids) { - ids.limit(n); - GL30.glDeleteFramebuffers(ids); - } - - public void glGenRenderbuffers(int n, IntBuffer ids) { - ids.limit(n); - GL30.glGenRenderbuffers(ids); - } - - public void glDeleteRenderbuffers(int n, IntBuffer ids) { - ids.limit(n); - GL30.glDeleteRenderbuffers(ids); - } - - public void glBindFramebuffer(int target, int id) { - GL30.glBindFramebuffer(target, id); - } - - public void glBlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { - GL30.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - } - - public void glFramebufferTexture2D(int target, int attachment, int texTarget, int texId, int level) { - GL30.glFramebufferTexture2D(target, attachment, texTarget, texId, level); - } - - public void glBindRenderbuffer(int target, int id) { - GL30.glBindRenderbuffer(target, id); - } - - public void glRenderbufferStorageMultisample(int target, int samples, int format, int width, int height) { - GL30.glRenderbufferStorageMultisample(target, samples, format, width, height); - } - - public void glRenderbufferStorage(int target, int format, int width, int height) { - GL30.glRenderbufferStorage(target, format, width, height); - } - - public void glFramebufferRenderbuffer(int target, int attachment, int rendbufTarget, int rendbufId) { - GL30.glFramebufferRenderbuffer(target, attachment, rendbufTarget, rendbufId); - } - - public int glCheckFramebufferStatus(int target) { - return GL30.glCheckFramebufferStatus(target); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Shaders - - public int glCreateProgram() { - return GL20.glCreateProgram(); - } - - public void glDeleteProgram(int id) { - GL20.glDeleteProgram(id); - } - - public int glCreateShader(int type) { - return GL20.glCreateShader(type); - } - - public void glDeleteShader(int id) { - GL20.glDeleteShader(id); - } - - public void glLinkProgram(int prog) { - GL20.glLinkProgram(prog); - } - - public void glValidateProgram(int prog) { - GL20.glValidateProgram(prog); - } - - public void glUseProgram(int prog) { - GL20.glUseProgram(prog); - } - - public int glGetAttribLocation(int prog, String name) { - return GL20.glGetAttribLocation(prog, name); - } - - public int glGetUniformLocation(int prog, String name) { - return GL20.glGetUniformLocation(prog, name); - } - - public void glUniform1i(int loc, int value) { - GL20.glUniform1i(loc, value); - } - - public void glUniform1f(int loc, float value) { - GL20.glUniform1f(loc, value); - } - - public void glUniform2f(int loc, float value0, float value1) { - GL20.glUniform2f(loc, value0, value1); - } - - public void glUniform3f(int loc, float value0, float value1, float value2) { - GL20.glUniform3f(loc, value0, value1, value2); - } - - public void glUniform4f(int loc, float value0, float value1, float value2, float value3) { - GL20.glUniform4f(loc, value0, value1, value2, value3); - } - - public void glUniform1fv(int loc, int count, FloatBuffer v) { - GL20.glUniform1(loc, v); - } - - public void glUniform2fv(int loc, int count, FloatBuffer v) { - GL20.glUniform2(loc, v); - } - - public void glUniform3fv(int loc, int count, FloatBuffer v) { - GL20.glUniform3(loc, v); - } - - public void glUniform4fv(int loc, int count, FloatBuffer v) { - GL20.glUniform4(loc, v); - } - - public void glUniformMatrix2fv(int loc, int count, boolean transpose, FloatBuffer mat) { - GL20.glUniformMatrix2(loc, transpose, mat); - } - - public void glUniformMatrix3fv(int loc, int count, boolean transpose, FloatBuffer mat) { - GL20.glUniformMatrix3(loc, transpose, mat); - } - - public void glUniformMatrix4fv(int loc, int count, boolean transpose, FloatBuffer mat) { - GL20.glUniformMatrix4(loc, transpose, mat); - } - - public void glVertexAttrib1f(int loc, float value) { - GL20.glVertexAttrib1f(loc, value); - } - - public void glVertexAttrib2f(int loc, float value0, float value1) { - GL20.glVertexAttrib2f(loc, value0, value1); - } - - public void glVertexAttrib3f(int loc, float value0, float value1, float value2) { - GL20.glVertexAttrib3f(loc, value0, value1, value2); - } - - public void glVertexAttrib4f(int loc, float value0, float value1, float value2, float value3) { - GL20.glVertexAttrib4f(loc, value0, value1, value2, value3); - } - - public void glShaderSource(int id, String source) { - GL20.glShaderSource(id, source); - } - - public void glCompileShader(int id) { - GL20.glCompileShader(id); - } - - public void glAttachShader(int prog, int shader) { - GL20.glAttachShader(prog, shader); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Viewport - - - public void glViewport(int x, int y, int width, int height) { - GL11.glViewport(x, y, width, height); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Clipping (scissor test) - - - public void glScissor(int x, int y, int w, int h) { - GL11.glScissor(x, y, w, h); - } - - - ///////////////////////////////////////////////////////////////////////////////// - - // Blending - - - public void glBlendEquation(int eq) { - GL14.glBlendEquation(eq); - } - - - public void glBlendFunc(int srcFactor, int dstFactor) { - GL11.glBlendFunc(srcFactor, dstFactor); - } - - - ///////////////////////////////////////////////////////////////////////////////// - - // Pixels - - public void setReadBuffer(int buf) { - GL11.glReadBuffer(buf); - } - - public void glReadPixels(int x, int y, int width, int height, int format, int type, IntBuffer buffer) { - GL11.glReadPixels(x, y, width, height, format, type, buffer); - } - - public void setDrawBuffer(int buf) { - GL11.glDrawBuffer(buf); - } - - public void glClearColor(float r, float g, float b, float a) { - GL11.glClearColor(r, g, b, a); - } - - public void glClear(int mask) { - GL11.glClear(mask); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Context interface - - public Context getContext() { - return new Context(null); - } - - public class Context { - protected GLContext context; - - Context(GLContext context) { - this.context = context; - } - - boolean same(GLContext context) { - return true; - //return this.context.hashCode() == context.hashCode(); - } - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Tessellator interface - - public Tessellator createTessellator(TessellatorCallback callback) { - return new Tessellator(callback); - } - - public class Tessellator { - protected GLUtessellator tess; - protected TessellatorCallback callback; - protected GLUCallback gluCallback; - - public Tessellator(TessellatorCallback callback) { - this.callback = callback; - tess = GLU.gluNewTess(); - gluCallback = new GLUCallback(); - - tess.gluTessCallback(GLU.GLU_TESS_BEGIN, gluCallback); - tess.gluTessCallback(GLU.GLU_TESS_END, gluCallback); - tess.gluTessCallback(GLU.GLU_TESS_VERTEX, gluCallback); - tess.gluTessCallback(GLU.GLU_TESS_COMBINE, gluCallback); - tess.gluTessCallback(GLU.GLU_TESS_ERROR, gluCallback); - } - - public void beginPolygon() { - tess.gluTessBeginPolygon(null); - } - - public void endPolygon() { - tess.gluTessEndPolygon(); - } - - public void setWindingRule(int rule) { - tess.gluTessProperty(GLU.GLU_TESS_WINDING_RULE, rule); - } - - public void beginContour() { - tess.gluTessBeginContour(); - } - - public void endContour() { - tess.gluTessEndContour(); - } - - public void addVertex(double[] v) { - tess.gluTessVertex(v, 0, v); - } - - protected class GLUCallback extends GLUtessellatorCallbackAdapter { - public void begin(int type) { - callback.begin(type); - } - - public void end() { - callback.end(); - } - - public void vertex(Object data) { - callback.vertex(data); - } - - public void combine(double[] coords, Object[] data, - float[] weight, Object[] outData) { - callback.combine(coords, data, weight, outData); - } - - public void error(int errnum) { - callback.error(errnum); - } - } - } - - public interface TessellatorCallback { - public void begin(int type); - public void end(); - public void vertex(Object data); - public void combine(double[] coords, Object[] data, - float[] weight, Object[] outData); - public void error(int errnum); - } - - /////////////////////////////////////////////////////////////////////////////////// - - // Utility functions - - public FloatBuffer createFloatBuffer(int size) { - return BufferUtils.createFloatBuffer(size); - } - - public IntBuffer createIntBuffer(int size) { - return BufferUtils.createIntBuffer(size); - } - - public boolean contextIsCurrent(Context other) { - return other.same(null); - } - - static public int makeIndex(int intIdx) { - return intIdx; - } - - public void enableTexturing(int target) { - GL11.glEnable(target); - } - - public void disableTexturing(int target) { - GL11.glDisable(target); - } - - public void initTexture(int target, int width, int height, int format, int type) { - IntBuffer texels = createIntBuffer(width * height); - GL11.glTexSubImage2D(target, 0, 0, 0, width, height, format, type, texels); - } - - public String getShaderLog(int id) { - IntBuffer val = createIntBuffer(1); - ARBShaderObjects.glGetObjectParameterARB(id, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, val); - - int length = val.get(); - - if (length <= 1) { - return ""; - } - - // Some error occurred... - ByteBuffer infoLog = ByteBuffer.allocate(length); - val.flip(); - - ARBShaderObjects.glGetInfoLogARB(id, val, infoLog); - - byte[] infoBytes = new byte[length]; - infoLog.get(infoBytes); - return new String(infoBytes); - } -} diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java b/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java deleted file mode 100644 index a3011a641..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java +++ /dev/null @@ -1,9097 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2004-10 Ben Fry and Casey Reas - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -package processing.lwjgl; - -import processing.core.PApplet; -import processing.core.PFont; -import processing.core.PGraphics; -import processing.core.PImage; -import processing.core.PMatrix; -import processing.core.PMatrix2D; -import processing.core.PMatrix3D; -import processing.core.PShape; -import processing.core.PVector; - -import java.net.URL; -import java.nio.*; -import java.util.EmptyStackException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.Stack; - -/** - * OpenGL renderer. - * - */ -public class PGraphicsLWJGL extends PGraphics { - /** Interface between Processing and OpenGL */ - protected PGL pgl; - - /** The PApplet renderer. For the primary surface, pg == this. */ - protected PGraphicsLWJGL pg; - - // ........................................................ - - // VBOs for immediate rendering: - - public int glFillVertexBufferID; - public int glFillColorBufferID; - public int glFillNormalBufferID; - public int glFillTexCoordBufferID; - public int glFillAmbientBufferID; - public int glFillSpecularBufferID; - public int glFillEmissiveBufferID; - public int glFillShininessBufferID; - public int glFillIndexBufferID; - protected boolean fillVBOsCreated = false; - - public int glLineVertexBufferID; - public int glLineColorBufferID; - public int glLineDirWidthBufferID; - public int glLineIndexBufferID; - protected boolean lineVBOsCreated = false; - - public int glPointVertexBufferID; - public int glPointColorBufferID; - public int glPointSizeBufferID; - public int glPointIndexBufferID; - protected boolean pointVBOsCreated = false; - - // ........................................................ - - // GL parameters - - static protected boolean glParamsRead = false; - - /** Extensions used by Processing */ - static public boolean npotTexSupported; - static public boolean mipmapGeneration; - static public boolean vboSupported; - static public boolean fboSupported; - static public boolean fboMultisampleSupported; - static public boolean blendEqSupported; - - /** Some hardware limits */ - static public int maxTextureSize; - static public float maxPointSize; - static public float maxLineWidth; - - /** OpenGL information strings */ - static public String OPENGL_VENDOR; - static public String OPENGL_RENDERER; - static public String OPENGL_VERSION; - static public String OPENGL_EXTENSIONS; - - // ........................................................ - - // GL objects: - - static protected HashMap glTextureObjects = new HashMap(); - static protected HashMap glVertexBuffers = new HashMap(); - static protected HashMap glFrameBuffers = new HashMap(); - static protected HashMap glRenderBuffers = new HashMap(); - static protected HashMap glslPrograms = new HashMap(); - static protected HashMap glslVertexShaders = new HashMap(); - static protected HashMap glslFragmentShaders = new HashMap(); - - // ........................................................ - - // Shaders - - protected static URL defFillShaderVertSimpleURL = PGraphicsLWJGL.class.getResource("FillShaderVertSimple.glsl"); - protected static URL defFillShaderVertTexURL = PGraphicsLWJGL.class.getResource("FillShaderVertTex.glsl"); - protected static URL defFillShaderVertLitURL = PGraphicsLWJGL.class.getResource("FillShaderVertLit.glsl"); - protected static URL defFillShaderVertFullURL = PGraphicsLWJGL.class.getResource("FillShaderVertFull.glsl"); - protected static URL defFillShaderFragNoTexURL = PGraphicsLWJGL.class.getResource("FillShaderFragNoTex.glsl"); - protected static URL defFillShaderFragTexURL = PGraphicsLWJGL.class.getResource("FillShaderFragTex.glsl"); - protected static URL defLineShaderVertURL = PGraphicsLWJGL.class.getResource("LineShaderVert.glsl"); - protected static URL defLineShaderFragURL = PGraphicsLWJGL.class.getResource("LineShaderFrag.glsl"); - protected static URL defPointShaderVertURL = PGraphicsLWJGL.class.getResource("PointShaderVert.glsl"); - protected static URL defPointShaderFragURL = PGraphicsLWJGL.class.getResource("PointShaderFrag.glsl"); - - protected static FillShaderSimple defFillShaderSimple; - protected static FillShaderTex defFillShaderTex; - protected static FillShaderLit defFillShaderLit; - protected static FillShaderFull defFillShaderFull; - protected static LineShader defLineShader; - protected static PointShader defPointShader; - - protected FillShaderSimple fillShaderSimple; - protected FillShaderTex fillShaderTex; - protected FillShaderLit fillShaderLit; - protected FillShaderFull fillShaderFull; - protected LineShader lineShader; - protected PointShader pointShader; - - // ........................................................ - - // Tessellator, geometry - - protected InGeometry inGeo; - protected TessGeometry tessGeo; - protected int firstTexIndex; - protected TexCache texCache; - protected Tessellator tessellator; - - // ........................................................ - - // Camera: - - /** Camera field of view. */ - public float cameraFOV; - - /** Default position of the camera. */ - public float cameraX, cameraY, cameraZ; - /** Distance of the near and far planes. */ - public float cameraNear, cameraFar; - /** Aspect ratio of camera's view. */ - public float cameraAspect; - - /** Distance between the camera eye and aim point. */ - protected float cameraDepth; - - /** Actual position of the camera. */ - protected float cameraEyeX, cameraEyeY, cameraEyeZ; - - /** Flag to indicate that we are inside beginCamera/endCamera block. */ - protected boolean manipulatingCamera; - - // ........................................................ - - // All the matrices required for camera and geometry transformations. - public PMatrix3D projection; - public PMatrix3D camera; - public PMatrix3D cameraInv; - public PMatrix3D modelview; - public PMatrix3D modelviewInv; - public PMatrix3D projmodelview; - - // To pass to shaders - protected float[] glProjection; - protected float[] glModelview; - protected float[] glProjmodelview; - protected float[] glNormal; - - protected boolean matricesAllocated = false; - - /** - * Marks when changes to the size have occurred, so that the camera - * will be reset in beginDraw(). - */ - protected boolean sizeChanged; - - /** Modelview matrix stack **/ - protected Stack modelviewStack; - - /** Inverse modelview matrix stack **/ - protected Stack modelviewInvStack; - - /** Projection matrix stack **/ - protected Stack projectionStack; - - // ........................................................ - - // Lights: - - public boolean lights; - public int lightCount = 0; - - /** Light types */ - public int[] lightType; - - /** Light positions */ - public float[] lightPosition; - - /** Light direction (normalized vector) */ - public float[] lightNormal; - - /** - * Ambient colors for lights. - */ - public float[] lightAmbient; - - /** - * Diffuse colors for lights. - */ - public float[] lightDiffuse; - - /** - * Specular colors for lights. Internally these are stored as numbers between - * 0 and 1. - */ - public float[] lightSpecular; - - /** Light falloff */ - public float[] lightFalloffCoefficients; - - /** Light spot parameters: Cosine of light spot angle - * and concentration */ - public float[] lightSpotParameters; - - /** Current specular color for lighting */ - public float[] currentLightSpecular; - - /** Current light falloff */ - public float currentLightFalloffConstant; - public float currentLightFalloffLinear; - public float currentLightFalloffQuadratic; - - protected boolean lightsAllocated = false; - - // ........................................................ - - // Blending: - - protected int blendMode; - - // ........................................................ - - // Clipping - - protected boolean clip = false; - - // ........................................................ - - // Text: - - /** Font texture of currently selected font. */ - PFontTexture textTex; - - // ....................................................... - - // Framebuffer stack: - - static protected Stack fbStack; - static protected PFramebuffer screenFramebuffer; - static protected PFramebuffer currentFramebuffer; - - // ....................................................... - - // Offscreen rendering: - - protected PFramebuffer offscreenFramebuffer; - protected PFramebuffer offscreenFramebufferMultisample; - protected boolean offscreenMultisample; - - /** These are public so they can be changed by advanced users. */ - public int offscreenDepthBits = 24; - public int offscreenStencilBits = 8; - - // ........................................................ - - // Utility variables: - - /** True if we are inside a beginDraw()/endDraw() block. */ - protected boolean drawing = false; - - /** Used to detect the occurrence of a frame resize event. */ - protected boolean resized = false; - - /** Stores previous viewport dimensions. */ - protected IntBuffer savedViewport; - protected IntBuffer viewport; - - /** Used to register calls to glClear. */ - protected boolean clearColorBuffer; - protected boolean clearColorBuffer0; - - protected boolean openContour = false; - protected boolean breakShape = false; - protected boolean defaultEdges = false; - protected PImage textureImage0; - - /** To get data from OpenGL. */ - protected IntBuffer getBuffer; - - // ........................................................ - - // Drawing surface: - - /** A handy reference to the PTexture bound to the drawing surface (off or on-screen) */ - protected PTexture texture; - - /** The crop rectangle for texture. It should always be {0, 0, width, height}. */ - protected int[] texCrop; - - /** IntBuffer to go with the pixels[] array. */ - protected IntBuffer pixelBuffer; - - /** 1-pixel get/set buffer. */ - protected IntBuffer getsetBuffer; - - /** 1-pixel get/set texture. */ - protected PTexture getsetTexture; - - // ........................................................ - - // Bezier and Catmull-Rom curves - - protected boolean bezierInited = false; - public int bezierDetail = 20; - protected PMatrix3D bezierDrawMatrix; - - protected boolean curveInited = false; - protected int curveDetail = 20; - public float curveTightness = 0; - - // catmull-rom basis matrix, perhaps with optional s parameter - protected PMatrix3D curveBasisMatrix; - protected PMatrix3D curveDrawMatrix; - - protected PMatrix3D bezierBasisInverse; - protected PMatrix3D curveToBezierMatrix; - - protected float curveVertices[][]; - protected int curveVertexCount; - - // used by both curve and bezier, so just init here - protected PMatrix3D bezierBasisMatrix = - new PMatrix3D(-1, 3, -3, 1, - 3, -6, 3, 0, - -3, 3, 0, 0, - 1, 0, 0, 0); - - // ........................................................ - - // Constants - - protected static int flushMode = FLUSH_WHEN_FULL; - protected int vboMode = PGL.GL_STATIC_DRAW; - - static public float FLOAT_EPS = Float.MIN_VALUE; - // Calculation of the Machine Epsilon for float precision. From: - // http://en.wikipedia.org/wiki/Machine_epsilon#Approximation_using_Java - static { - float eps = 1.0f; - - do { - eps /= 2.0f; - } while ((float)(1.0 + (eps / 2.0)) != 1.0); - - FLOAT_EPS = eps; - } - - /** - * Set to true if the host system is big endian (PowerPC, MIPS, SPARC), false - * if little endian (x86 Intel for Mac or PC). - */ - static public boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - - ////////////////////////////////////////////////////////////// - - - // INIT/ALLOCATE/FINISH - - public PGraphicsLWJGL() { - pgl = new PGL(this); - - getBuffer = pgl.createIntBuffer(16); - viewport = pgl.createIntBuffer(16); - savedViewport = pgl.createIntBuffer(16); - tessellator = new Tessellator(); - - inGeo = newInGeometry(IMMEDIATE); - tessGeo = newTessGeometry(IMMEDIATE); - texCache = newTexCache(); - - glFillVertexBufferID = 0; - glFillColorBufferID = 0; - glFillNormalBufferID = 0; - glFillTexCoordBufferID = 0; - glFillAmbientBufferID = 0; - glFillSpecularBufferID = 0; - glFillEmissiveBufferID = 0; - glFillShininessBufferID = 0; - glFillIndexBufferID = 0; - - glLineVertexBufferID = 0; - glLineColorBufferID = 0; - glLineDirWidthBufferID = 0; - glLineIndexBufferID = 0; - - glPointVertexBufferID = 0; - glPointColorBufferID = 0; - glPointSizeBufferID = 0; - glPointIndexBufferID = 0; - } - - //public void setParent(PApplet parent) // PGraphics - - - public void setPrimary(boolean primary) { - super.setPrimary(primary); - format = ARGB; - } - - - //public void setPath(String path) // PGraphics - - public void setSize(int iwidth, int iheight) { - resized = (0 < width && width != iwidth) || (0 < height && height != iwidth); - - width = iwidth; - height = iheight; - width1 = width - 1; - height1 = height - 1; - - allocate(); - reapplySettings(); - - vertexCheck(); - - // init perspective projection based on new dimensions - cameraFOV = 60 * DEG_TO_RAD; // at least for now - cameraX = width / 2.0f; - cameraY = height / 2.0f; - cameraZ = cameraY / ((float) Math.tan(cameraFOV / 2.0f)); - cameraNear = cameraZ / 10.0f; - cameraFar = cameraZ * 10.0f; - cameraAspect = (float) width / (float) height; - cameraDepth = cameraZ; // eye is at (cameraX, cameraY, cameraZ), aiming at (cameraX, cameraY, 0) - - // set this flag so that beginDraw() will do an update to the camera. - sizeChanged = true; - } - - - /** - * Called by resize(), this handles creating the actual GLCanvas the - * first time around, or simply resizing it on subsequent calls. - * There is no pixel array to allocate for an OpenGL canvas - * because OpenGL's pixel buffer is all handled internally. - */ - protected void allocate() { - super.allocate(); - - if (!matricesAllocated) { - projection = new PMatrix3D(); - camera = new PMatrix3D(); - cameraInv = new PMatrix3D(); - modelview = new PMatrix3D(); - modelviewInv = new PMatrix3D(); - projmodelview = new PMatrix3D(); - matricesAllocated = true; - } - - if (!lightsAllocated) { - lightType = new int[PGL.MAX_LIGHTS]; - lightPosition = new float[4 * PGL.MAX_LIGHTS]; - lightNormal = new float[3 * PGL.MAX_LIGHTS]; - lightAmbient = new float[3 * PGL.MAX_LIGHTS]; - lightDiffuse = new float[3 * PGL.MAX_LIGHTS]; - lightSpecular = new float[3 * PGL.MAX_LIGHTS]; - lightFalloffCoefficients = new float[3 * PGL.MAX_LIGHTS]; - lightSpotParameters = new float[2 * PGL.MAX_LIGHTS]; - currentLightSpecular = new float[3]; - lightsAllocated = true; - } - - if (primarySurface) { - // Allocation of the main renderer, which mainly involves initializing OpenGL. -// if (context == null) { -// initPrimary(); -// } else { -// reapplySettings(); -// } - if (pgl.initialized) { - reapplySettings(); - } - } else { - // Allocation of an offscreen renderer. -// if (context == null) { -// initOffscreen(); -// } else { -// // Updating OpenGL context associated to this offscreen -// // surface, to take into account a context recreation situation. -// updateOffscreenContext(); -// reapplySettings(); -// } - if (pgl.initialized) { - updateOffscreenContext(); - reapplySettings(); - } - } - } - - - public void dispose() { // PGraphics - super.dispose(); - pgl.detainContext(); - deleteFinalizedGLResources(); - pgl.releaseContext(); - PGL.shutdown(); - } - - - // Only for debugging purposes. - public void setFlushMode(int mode) { - PGraphicsLWJGL.flushMode = mode; - } - - - ////////////////////////////////////////////////////////////// - - // RESOURCE HANDLING - - // Texture Objects ------------------------------------------- - - protected int createTextureObject() { - deleteFinalizedTextureObjects(); - - pgl.glGenTextures(1, getBuffer); - int id = getBuffer.get(0); - - if (glTextureObjects.containsKey(id)) { - showWarning("Adding same texture twice"); - } else { - glTextureObjects.put(id, false); - } - - return id; - } - - protected void deleteTextureObject(int id) { - if (glTextureObjects.containsKey(id)) { - getBuffer.put(0, id); - pgl.glDeleteTextures(1, getBuffer); - glTextureObjects.remove(id); - } - } - - protected void deleteAllTextureObjects() { - for (Integer id : glTextureObjects.keySet()) { - getBuffer.put(0, id.intValue()); - pgl.glDeleteTextures(1, getBuffer); - } - glTextureObjects.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeTextureObject(int id) { - if (glTextureObjects.containsKey(id)) { - glTextureObjects.put(id, true); - } else { - showWarning("Trying to finalize non-existing texture"); - } - } - - protected void deleteFinalizedTextureObjects() { - Set finalized = new HashSet(); - - for (Integer id : glTextureObjects.keySet()) { - if (glTextureObjects.get(id)) { - finalized.add(id); - getBuffer.put(0, id.intValue()); - pgl.glDeleteTextures(1, getBuffer); - } - } - - for (Integer id : finalized) { - glTextureObjects.remove(id); - } - } - - // Vertex Buffer Objects ---------------------------------------------- - - protected int createVertexBufferObject() { - deleteFinalizedVertexBufferObjects(); - - pgl.glGenBuffers(1, getBuffer); - int id = getBuffer.get(0); - - if (glVertexBuffers.containsKey(id)) { - showWarning("Adding same VBO twice"); - } else { - glVertexBuffers.put(id, false); - } - - return id; - } - - protected void deleteVertexBufferObject(int id) { - if (glVertexBuffers.containsKey(id)) { - getBuffer.put(0, id); - pgl.glDeleteBuffers(1, getBuffer); - glVertexBuffers.remove(id); - } - } - - protected void deleteAllVertexBufferObjects() { - for (Integer id : glVertexBuffers.keySet()) { - getBuffer.put(0, id.intValue()); - pgl.glDeleteBuffers(1, getBuffer); - } - glVertexBuffers.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeVertexBufferObject(int id) { - if (glVertexBuffers.containsKey(id)) { - glVertexBuffers.put(id, true); - } else { - showWarning("Trying to finalize non-existing VBO"); - } - } - - protected void deleteFinalizedVertexBufferObjects() { - Set finalized = new HashSet(); - - for (Integer id : glVertexBuffers.keySet()) { - if (glVertexBuffers.get(id)) { - finalized.add(id); - getBuffer.put(0, id.intValue()); - pgl.glDeleteBuffers(1, getBuffer); - } - } - - for (Integer id : finalized) { - glVertexBuffers.remove(id); - } - } - - // FrameBuffer Objects ----------------------------------------- - - protected int createFrameBufferObject() { - deleteFinalizedFrameBufferObjects(); - - pgl.glGenFramebuffers(1, getBuffer); - int id = getBuffer.get(0); - - if (glFrameBuffers.containsKey(id)) { - showWarning("Adding same FBO twice"); - } else { - glFrameBuffers.put(id, false); - } - - return id; - } - - protected void deleteFrameBufferObject(int id) { - if (glFrameBuffers.containsKey(id)) { - getBuffer.put(0, id); - pgl.glDeleteFramebuffers(1, getBuffer); - glFrameBuffers.remove(id); - } - } - - protected void deleteAllFrameBufferObjects() { - for (Integer id : glFrameBuffers.keySet()) { - getBuffer.put(0, id.intValue()); - pgl.glDeleteFramebuffers(1, getBuffer); - } - glFrameBuffers.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeFrameBufferObject(int id) { - if (glFrameBuffers.containsKey(id)) { - glFrameBuffers.put(id, true); - } else { - showWarning("Trying to finalize non-existing FBO"); - } - } - - protected void deleteFinalizedFrameBufferObjects() { - Set finalized = new HashSet(); - - for (Integer id : glFrameBuffers.keySet()) { - if (glFrameBuffers.get(id)) { - finalized.add(id); - getBuffer.put(0, id.intValue()); - pgl.glDeleteFramebuffers(1, getBuffer); - } - } - - for (Integer id : finalized) { - glFrameBuffers.remove(id); - } - } - - // RenderBuffer Objects ----------------------------------------------- - - protected int createRenderBufferObject() { - deleteFinalizedRenderBufferObjects(); - - pgl.glDeleteRenderbuffers(1, getBuffer); - int id = getBuffer.get(0); - - if (glRenderBuffers.containsKey(id)) { - showWarning("Adding same renderbuffer twice"); - } else { - glRenderBuffers.put(id, false); - } - - return id; - } - - protected void deleteRenderBufferObject(int id) { - if (glRenderBuffers.containsKey(id)) { - getBuffer.put(0, id); - pgl.glGenRenderbuffers(1, getBuffer); - glRenderBuffers.remove(id); - } - } - - protected void deleteAllRenderBufferObjects() { - for (Integer id : glRenderBuffers.keySet()) { - getBuffer.put(0, id.intValue()); - pgl.glDeleteRenderbuffers(1, getBuffer); - } - glRenderBuffers.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeRenderBufferObject(int id) { - if (glRenderBuffers.containsKey(id)) { - glRenderBuffers.put(id, true); - } else { - showWarning("Trying to finalize non-existing renderbuffer"); - } - } - - protected void deleteFinalizedRenderBufferObjects() { - Set finalized = new HashSet(); - - for (Integer id : glRenderBuffers.keySet()) { - if (glRenderBuffers.get(id)) { - finalized.add(id); - getBuffer.put(0, id.intValue()); - pgl.glDeleteRenderbuffers(1, getBuffer); - } - } - - for (Integer id : finalized) { - glRenderBuffers.remove(id); - } - } - - // GLSL Program Objects ----------------------------------------------- - - protected int createGLSLProgramObject() { - deleteFinalizedGLSLProgramObjects(); - - int id = pgl.glCreateProgram(); - - if (glslPrograms.containsKey(id)) { - showWarning("Adding same glsl program twice"); - } else { - glslPrograms.put(id, false); - } - - return id; - } - - protected void deleteGLSLProgramObject(int id) { - if (glslPrograms.containsKey(id)) { - pgl.glDeleteProgram(id); - glslPrograms.remove(id); - } - } - - protected void deleteAllGLSLProgramObjects() { - for (Integer id : glslPrograms.keySet()) { - pgl.glDeleteProgram(id); - } - glslPrograms.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeGLSLProgramObject(int id) { - if (glslPrograms.containsKey(id)) { - glslPrograms.put(id, true); - } else { - showWarning("Trying to finalize non-existing glsl program"); - } - } - - protected void deleteFinalizedGLSLProgramObjects() { - Set finalized = new HashSet(); - - for (Integer id : glslPrograms.keySet()) { - if (glslPrograms.get(id)) { - finalized.add(id); - pgl.glDeleteProgram(id); - } - } - - for (Integer id : finalized) { - glslPrograms.remove(id); - } - } - - // GLSL Vertex Shader Objects ----------------------------------------------- - - protected int createGLSLVertShaderObject() { - deleteFinalizedGLSLVertShaderObjects(); - - int id = pgl.glCreateShader(PGL.GL_VERTEX_SHADER); - - if (glslVertexShaders.containsKey(id)) { - showWarning("Adding same glsl vertex shader twice"); - } else { - glslVertexShaders.put(id, false); - } - - return id; - } - - protected void deleteGLSLVertShaderObject(int id) { - if (glslVertexShaders.containsKey(id)) { - pgl.glDeleteShader(id); - glslVertexShaders.remove(id); - } - } - - protected void deleteAllGLSLVertShaderObjects() { - for (Integer id : glslVertexShaders.keySet()) { - pgl.glDeleteShader(id); - } - glslVertexShaders.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeGLSLVertShaderObject(int id) { - if (glslVertexShaders.containsKey(id)) { - glslVertexShaders.put(id, true); - } else { - showWarning("Trying to finalize non-existing glsl vertex shader"); - } - } - - protected void deleteFinalizedGLSLVertShaderObjects() { - Set finalized = new HashSet(); - - for (Integer id : glslVertexShaders.keySet()) { - if (glslVertexShaders.get(id)) { - finalized.add(id); - pgl.glDeleteShader(id); - } - } - - for (Integer id : finalized) { - glslVertexShaders.remove(id); - } - } - - // GLSL Fragment Shader Objects ----------------------------------------------- - - - protected int createGLSLFragShaderObject() { - deleteFinalizedGLSLFragShaderObjects(); - - int id = pgl.glCreateShader(PGL.GL_FRAGMENT_SHADER); - - if (glslFragmentShaders.containsKey(id)) { - showWarning("Adding same glsl fragment shader twice"); - } else { - glslFragmentShaders.put(id, false); - } - - return id; - } - - protected void deleteGLSLFragShaderObject(int id) { - if (glslFragmentShaders.containsKey(id)) { - pgl.glDeleteShader(id); - glslFragmentShaders.remove(id); - } - } - - protected void deleteAllGLSLFragShaderObjects() { - for (Integer id : glslFragmentShaders.keySet()) { - pgl.glDeleteShader(id); - } - glslFragmentShaders.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeGLSLFragShaderObject(int id) { - if (glslFragmentShaders.containsKey(id)) { - glslFragmentShaders.put(id, true); - } else { - showWarning("Trying to finalize non-existing glsl fragment shader"); - } - } - - protected void deleteFinalizedGLSLFragShaderObjects() { - Set finalized = new HashSet(); - - for (Integer id : glslFragmentShaders.keySet()) { - if (glslFragmentShaders.get(id)) { - finalized.add(id); - pgl.glDeleteShader(id); - } - } - - for (Integer id : finalized) { - glslFragmentShaders.remove(id); - } - } - - - protected void deleteFinalizedGLResources() { - deleteFinalizedTextureObjects(); - deleteFinalizedVertexBufferObjects(); - deleteFinalizedFrameBufferObjects(); - deleteFinalizedRenderBufferObjects(); - deleteFinalizedGLSLProgramObjects(); - deleteFinalizedGLSLVertShaderObjects(); - deleteFinalizedGLSLFragShaderObjects(); - } - - protected void deleteAllGLResources() { - deleteAllTextureObjects(); - deleteAllVertexBufferObjects(); - deleteAllFrameBufferObjects(); - deleteAllRenderBufferObjects(); - deleteAllGLSLProgramObjects(); - deleteAllGLSLVertShaderObjects(); - deleteAllGLSLFragShaderObjects(); - } - - ////////////////////////////////////////////////////////////// - - // FRAMEBUFFERS - - public void pushFramebuffer() { - fbStack.push(currentFramebuffer); - } - - - public void setFramebuffer(PFramebuffer fbo) { - currentFramebuffer = fbo; - currentFramebuffer.bind(); - } - - - public void popFramebuffer() { - try { - currentFramebuffer.finish(); - currentFramebuffer = fbStack.pop(); - currentFramebuffer.bind(); - } catch (EmptyStackException e) { - PGraphics.showWarning(": Empty framebuffer stack"); - } - } - - ////////////////////////////////////////////////////////////// - - // FRAME RENDERING - -// public GLContext getContext() { -// return context; -// } -// public GLCapabilities getCapabilities() { -// return capabilities; -// } -// public GLProfile getProfile() { -// return profile; -// } -// public GLDrawable getDrawable() { -// return drawable; -// } - - - - protected void releaseResources() { - // First, releasing the resources used by - // the renderer itself. - if (texture != null) { - texture.release(); - texture = null; - } - - if (defFillShaderSimple != null) { - defFillShaderSimple.release(); - defFillShaderSimple = null; - } - - if (defFillShaderLit != null) { - defFillShaderLit.release(); - defFillShaderLit = null; - } - - if (defFillShaderTex != null) { - defFillShaderTex.release(); - defFillShaderTex = null; - } - - if (defFillShaderFull != null) { - defFillShaderFull.release(); - defFillShaderFull = null; - } - - if (defLineShader != null) { - defLineShader.release(); - defLineShader = null; - } - - if (defPointShader != null) { - defPointShader.release(); - defPointShader = null; - } - - if (fillVBOsCreated) { - releaseFillBuffers(); - fillVBOsCreated = false; - } - - if (lineVBOsCreated) { - releaseLineBuffers(); - lineVBOsCreated = false; - } - - if (pointVBOsCreated) { - releasePointBuffers(); - pointVBOsCreated = false; - } - - // Now, releasing the remaining resources - // (from user's objects). - deleteAllGLResources(); - } - - /** - * Destroys current OpenGL context and creates a new one, making sure that all - * the current OpenGL objects remain valid afterward. - */ - public void restartContext() { - releaseResources(); - - pgl.releaseContext(); - pgl.destroyContext(); - restartSurface(); - pgl.detainContext(); - updatePGL(); - } - - protected void createFillBuffers() { - int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT; - int sizei = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_INT; - int sizex = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INDEX; - - glFillVertexBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); - - glFillColorBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - - glFillNormalBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); - - glFillTexCoordBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, vboMode); - - glFillAmbientBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - - glFillSpecularBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - - glFillEmissiveBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - - glFillShininessBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - glFillIndexBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - protected void updateFillBuffers(boolean lit, boolean tex) { - int size = tessGeo.fillVertexCount; - int sizef = size * PGL.SIZEOF_FLOAT; - int sizei = size * PGL.SIZEOF_INT; - - tessGeo.prepareFillVerticesForCopy(); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, tessGeo.fillVertices, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, tessGeo.fillColors, vboMode); - - if (lit) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, tessGeo.fillNormals, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, tessGeo.fillAmbient, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, tessGeo.fillSpecular, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, tessGeo.fillEmissive, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, tessGeo.fillShininess, vboMode); - } - - if (tex) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, tessGeo.fillTexcoords, vboMode); - } - - tessGeo.prepareFillIndicesForCopy(); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.fillIndexCount * PGL.SIZEOF_INDEX, - tessGeo.fillIndices, vboMode); - } - - protected void unbindFillBuffers(boolean lit, boolean tex) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - protected void releaseFillBuffers() { - deleteVertexBufferObject(glFillVertexBufferID); - glFillVertexBufferID = 0; - - deleteVertexBufferObject(glFillColorBufferID); - glFillColorBufferID = 0; - - deleteVertexBufferObject(glFillNormalBufferID); - glFillNormalBufferID = 0; - - deleteVertexBufferObject(glFillTexCoordBufferID); - glFillTexCoordBufferID = 0; - - deleteVertexBufferObject(glFillAmbientBufferID); - glFillAmbientBufferID = 0; - - deleteVertexBufferObject(glFillSpecularBufferID); - glFillSpecularBufferID = 0; - - deleteVertexBufferObject(glFillEmissiveBufferID); - glFillEmissiveBufferID = 0; - - deleteVertexBufferObject(glFillShininessBufferID); - glFillShininessBufferID = 0; - - deleteVertexBufferObject(glFillIndexBufferID); - glFillIndexBufferID = 0; - } - - protected void createLineBuffers() { - int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT; - int sizex = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INDEX; - int sizei = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INT; - - glLineVertexBufferID = createVertexBufferObject(); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); - - glLineColorBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - - glLineDirWidthBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - glLineIndexBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - protected void updateLineBuffers() { - int size = tessGeo.lineVertexCount; - int sizef = size * PGL.SIZEOF_FLOAT; - int sizei = size * PGL.SIZEOF_INT; - - tessGeo.prepareLineVerticesForCopy(); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, tessGeo.lineVertices, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, tessGeo.lineColors, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, tessGeo.lineDirWidths, vboMode); - - tessGeo.prepareLineIndicesForCopy(); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, - tessGeo.lineIndices, vboMode); - } - - protected void unbindLineBuffers() { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - protected void releaseLineBuffers() { - deleteVertexBufferObject(glLineVertexBufferID); - glLineVertexBufferID = 0; - - deleteVertexBufferObject(glLineColorBufferID); - glLineColorBufferID = 0; - - deleteVertexBufferObject(glLineDirWidthBufferID); - glLineDirWidthBufferID = 0; - - deleteVertexBufferObject(glLineIndexBufferID); - glLineIndexBufferID = 0; - } - - protected void createPointBuffers() { - int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT; - int sizex = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INDEX; - int sizei = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INT; - - glPointVertexBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); - - glPointColorBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - - glPointSizeBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - glPointIndexBufferID = createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - protected void updatePointBuffers() { - int size = tessGeo.pointVertexCount; - int sizef = size * PGL.SIZEOF_FLOAT; - int sizei = size * PGL.SIZEOF_INT; - - tessGeo.preparePointVerticesForCopy(); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, tessGeo.pointVertices, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, tessGeo.pointColors, vboMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, tessGeo.pointSizes, vboMode); - - tessGeo.preparePointIndicesForCopy(); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, - tessGeo.pointIndices, vboMode); - } - - protected void unbindPointBuffers() { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - protected void releasePointBuffers() { - deleteVertexBufferObject(glPointVertexBufferID); - glPointVertexBufferID = 0; - - deleteVertexBufferObject(glPointColorBufferID); - glPointColorBufferID = 0; - - deleteVertexBufferObject(glPointSizeBufferID); - glPointSizeBufferID = 0; - - deleteVertexBufferObject(glPointIndexBufferID); - glPointIndexBufferID = 0; - } - - - /** - * OpenGL cannot draw until a proper native peer is available, so this - * returns the value of PApplet.isDisplayable() (inherited from Component). - */ - public boolean canDraw() { - return pgl.canDraw(); - } - - - public void requestDraw() { - pgl.requestDraw(); - } - - - public void beginDraw() { - if (drawing) { - showWarning("P3D: Already called beginDraw()."); - return; - } - - if (primarySurface) { - if (!pgl.initialized) { - initPrimary(); - } - - if (!pgl.initOnscreenDraw()) { - return; - } - pgl.detainContext(); - } else { - if (!pgl.initialized) { - initOffscreen(); - } - - pushFramebuffer(); - if (offscreenMultisample) { - setFramebuffer(offscreenFramebufferMultisample); - pgl.setDrawBuffer(0); - } else { - setFramebuffer(offscreenFramebuffer); - } - } - - updatePGL(); - - if (!glParamsRead) { - getGLParameters(); - } - - if (!settingsInited) { - defaultSettings(); - } - - // We are ready to go! - - report("top beginDraw()"); - - if (!primarySurface) { - pg.saveGLState(); - - // Disabling all lights, so the offscreen renderer can set completely - // new light configuration (otherwise some light configuration from the - // primary renderer might stay). - //pg.disableLights(); - } - - inGeo.clear(); - tessGeo.clear(); - texCache.clear(); - - // Each frame starts with textures disabled. - super.noTexture(); - - // Screen blend is needed for alpha (i.e. fonts) to work. - // Using setDefaultBlend() instead of blendMode() because - // the latter will set the blend mode only if it is different - // from current. - setDefaultBlend(); - - // this is necessary for 3D drawing - if (hints[DISABLE_DEPTH_TEST]) { - pgl.glDisable(PGL.GL_DEPTH_TEST); - } else { - pgl.glEnable(PGL.GL_DEPTH_TEST); - } - // use <= since that's what processing.core does - pgl.glDepthFunc(PGL.GL_LEQUAL); - - if (hints[DISABLE_DEPTH_MASK]) { - pgl.glDepthMask(false); - } else { - pgl.glDepthMask(true); - } - - if (hints[ENABLE_ACCURATE_2D]) { - flushMode = FLUSH_CONTINUOUSLY; - } else { - flushMode = FLUSH_WHEN_FULL; - } - - // setup opengl viewport. - pgl.glGetIntegerv(PGL.GL_VIEWPORT, savedViewport); - viewport.put(0, 0); viewport.put(1, 0); viewport.put(2, width); viewport.put(3, height); - pgl.glViewport(viewport.get(0), viewport.get(1), viewport.get(2), viewport.get(3)); - if (resized) { - // To avoid having garbage in the screen after a resize, - // in the case background is not called in draw(). - background(0); - if (texture != null) { - // The screen texture should be deleted because it - // corresponds to the old window size. - this.removeCache(pg); - this.removeParams(pg); - texture = null; - loadTexture(); - } - resized = false; - } - - if (sizeChanged) { - // defaults to perspective, if the user has setup up their - // own projection, they'll need to fix it after resize anyway. - // this helps the people who haven't set up their own projection. - perspective(); - - // set up the default camera and initializes modelview matrix. - camera(); - - // clear the flag - sizeChanged = false; - } else { - // The camera and projection matrices, saved when calling camera() and frustrum() - // are set as the current modelview and projection matrices. This is done to - // remove any additional modelview transformation (and less likely, projection - // transformations) applied by the user after setting the camera and/or projection - modelview.set(camera); - modelviewInv.set(cameraInv); - calcProjmodelview(); - } - - noLights(); - lightFalloff(1, 0, 0); - lightSpecular(0, 0, 0); - - // because y is flipped - pgl.glFrontFace(PGL.GL_CW); - - // Processing uses only one texture unit. - pgl.glActiveTexture(PGL.GL_TEXTURE0); - - // The current normal vector is set to be parallel to the Z axis. - normalX = normalY = normalZ = 0; - - // Clear depth and stencil buffers. - pgl.glClearColor(0, 0, 0, 0); - pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT); - - if (primarySurface) { - pgl.beginOnscreenDraw(clearColorBuffer, parent.frameCount); - } else { - pgl.beginOffscreenDraw(clearColorBuffer, parent.frameCount); - } - - drawing = true; - - clearColorBuffer0 = clearColorBuffer; - clearColorBuffer = false; - - report("bot beginDraw()"); - } - - - public void endDraw() { - report("top endDraw()"); - - if (flushMode == FLUSH_WHEN_FULL) { - // Flushing any remaining geometry. - flush(); - // TODO: Implement depth sorting (http://code.google.com/p/processing/issues/detail?id=51) - //if (hints[ENABLE_DEPTH_SORT]) { - // flush(); - //} - } - - if (!drawing) { - showWarning("P3D: Cannot call endDraw() before beginDraw()."); - return; - } - - // Restoring previous viewport. - pgl.glViewport(savedViewport.get(0), savedViewport.get(1), savedViewport.get(2), savedViewport.get(3)); - - if (primarySurface) { - pgl.glFlush(); - pgl.endOnscreenDraw(clearColorBuffer0); - pgl.releaseContext(); - } else { - if (offscreenMultisample) { - offscreenFramebufferMultisample.copy(offscreenFramebuffer); - } - popFramebuffer(); - - pgl.endOffscreenDraw(clearColorBuffer0); - - pg.restoreGLState(); - } - - drawing = false; - - report("bot endDraw()"); - } - - - public PGL beginPGL() { - saveGLState(); - return pgl; - } - - - public void endPGL() { - restoreGLState(); - } - - - public void updatePGL() { - if (primarySurface) { - pgl.updatePrimary(); - } else { - pgl.updateOffscreen(pg.pgl); - } - } - - - protected void saveGLState() { - } - - - protected void restoreGLState() { - // Restoring viewport. - pgl.glViewport(viewport.get(0), viewport.get(1), viewport.get(2), viewport.get(3)); - - // Restoring hints. - if (hints[DISABLE_DEPTH_TEST]) { - pgl.glDisable(PGL.GL_DEPTH_TEST); - pgl.glClearColor(0, 0, 0, 0); - pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); - } else { - pgl.glEnable(PGL.GL_DEPTH_TEST); - } - - if (hints[DISABLE_DEPTH_MASK]) { - pgl.glDepthMask(false); - } else { - pgl.glDepthMask(true); - } - - // Restoring blending. - blendMode(blendMode); - - // Some things the user might have changed from OpenGL, - // but we want to make sure they return to the Processing - // defaults (plus these cannot be changed through the API - // so they should remain constant anyways): - pgl.glFrontFace(PGL.GL_CW); - pgl.glDepthFunc(PGL.GL_LEQUAL); - } - - - // Utility function to get ready OpenGL for a specific - // operation, such as grabbing the contents of the color - // buffer. - protected void beginGLOp() { - pgl.detainContext(); - updatePGL(); - } - - - // Pairs-up with beginGLOp(). - protected void endGLOp() { - pgl.releaseContext(); - } - - protected void updateGLProjection() { - if (glProjection == null) { - glProjection = new float[16]; - } - - glProjection[0] = projection.m00; - glProjection[1] = projection.m10; - glProjection[2] = projection.m20; - glProjection[3] = projection.m30; - - glProjection[4] = projection.m01; - glProjection[5] = projection.m11; - glProjection[6] = projection.m21; - glProjection[7] = projection.m31; - - glProjection[8] = projection.m02; - glProjection[9] = projection.m12; - glProjection[10] = projection.m22; - glProjection[11] = projection.m32; - - glProjection[12] = projection.m03; - glProjection[13] = projection.m13; - glProjection[14] = projection.m23; - glProjection[15] = projection.m33; - } - - protected void updateGLModelview() { - if (glModelview == null) { - glModelview = new float[16]; - } - - glModelview[0] = modelview.m00; - glModelview[1] = modelview.m10; - glModelview[2] = modelview.m20; - glModelview[3] = modelview.m30; - - glModelview[4] = modelview.m01; - glModelview[5] = modelview.m11; - glModelview[6] = modelview.m21; - glModelview[7] = modelview.m31; - - glModelview[8] = modelview.m02; - glModelview[9] = modelview.m12; - glModelview[10] = modelview.m22; - glModelview[11] = modelview.m32; - - glModelview[12] = modelview.m03; - glModelview[13] = modelview.m13; - glModelview[14] = modelview.m23; - glModelview[15] = modelview.m33; - } - - protected void calcProjmodelview() { - projmodelview.set(projection); - projmodelview.apply(modelview); - } - - protected void updateGLProjmodelview() { - if (glProjmodelview == null) { - glProjmodelview = new float[16]; - } - - glProjmodelview[0] = projmodelview.m00; - glProjmodelview[1] = projmodelview.m10; - glProjmodelview[2] = projmodelview.m20; - glProjmodelview[3] = projmodelview.m30; - - glProjmodelview[4] = projmodelview.m01; - glProjmodelview[5] = projmodelview.m11; - glProjmodelview[6] = projmodelview.m21; - glProjmodelview[7] = projmodelview.m31; - - glProjmodelview[8] = projmodelview.m02; - glProjmodelview[9] = projmodelview.m12; - glProjmodelview[10] = projmodelview.m22; - glProjmodelview[11] = projmodelview.m32; - - glProjmodelview[12] = projmodelview.m03; - glProjmodelview[13] = projmodelview.m13; - glProjmodelview[14] = projmodelview.m23; - glProjmodelview[15] = projmodelview.m33; - } - - protected void updateGLNormal() { - if (glNormal == null) { - glNormal = new float[9]; - } - - // The normal matrix is the transpose of the inverse of the - // modelview (remember that gl matrices are column-major, - // meaning that elements 0, 1, 2 are the first column, - // 3, 4, 5 the second, etc.: - glNormal[0] = modelviewInv.m00; - glNormal[1] = modelviewInv.m01; - glNormal[2] = modelviewInv.m02; - - glNormal[3] = modelviewInv.m10; - glNormal[4] = modelviewInv.m11; - glNormal[5] = modelviewInv.m12; - - glNormal[6] = modelviewInv.m20; - glNormal[7] = modelviewInv.m21; - glNormal[8] = modelviewInv.m22; - } - - ////////////////////////////////////////////////////////////// - - // SETTINGS - - // protected void checkSettings() - - - protected void defaultSettings() { - super.defaultSettings(); - - manipulatingCamera = false; - - if (fbStack == null) { - fbStack = new Stack(); - - screenFramebuffer = new PFramebuffer(parent, width, height, true); - setFramebuffer(screenFramebuffer); - } - - if (modelviewStack == null) { - modelviewStack = new Stack(); - } - if (modelviewInvStack == null) { - modelviewInvStack = new Stack(); - } - if (projectionStack == null) { - projectionStack = new Stack(); - } - - // easiest for beginners - textureMode(IMAGE); - - // Default material properties - ambient(80); - specular(125); - emissive(0); - shininess(1); - } - - // reapplySettings - - ////////////////////////////////////////////////////////////// - - // HINTS - - public void hint(int which) { - boolean oldValue = hints[PApplet.abs(which)]; - super.hint(which); - boolean newValue = hints[PApplet.abs(which)]; - - if (oldValue == newValue) { - return; - } - - if (which == DISABLE_DEPTH_TEST) { - flush(); - pgl.glDisable(PGL.GL_DEPTH_TEST); - pgl.glClearColor(0, 0, 0, 0); - pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); - - } else if (which == ENABLE_DEPTH_TEST) { - flush(); - pgl.glEnable(PGL.GL_DEPTH_TEST); - - } else if (which == DISABLE_DEPTH_MASK) { - flush(); - pgl.glDepthMask(false); - - } else if (which == ENABLE_DEPTH_MASK) { - flush(); - pgl.glDepthMask(true); - - } else if (which == DISABLE_ACCURATE_2D) { - flush(); - setFlushMode(FLUSH_WHEN_FULL); - - } else if (which == ENABLE_ACCURATE_2D) { - flush(); - setFlushMode(FLUSH_CONTINUOUSLY); - - } else if (which == DISABLE_TEXTURE_CACHE) { - flush(); - - } else if (which == DISABLE_PERSPECTIVE_CORRECTED_LINES) { - if (0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount) { - flush(); - } - - } else if (which == ENABLE_PERSPECTIVE_CORRECTED_LINES) { - if (0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount) { - flush(); - } - - } - - } - - ////////////////////////////////////////////////////////////// - - // SHAPE CREATORS - - - public PShape createShape() { - return createShape(POLYGON); - } - - public PShape createShape(int type) { - PShape3D shape = null; - if (type == PShape.GROUP) { - shape = new PShape3D(parent, PShape.GROUP); - } else if (type == POINTS) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(POINTS); - } else if (type == LINES) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(LINES); - } else if (type == TRIANGLES) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(TRIANGLES); - } else if (type == TRIANGLE_FAN) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(TRIANGLE_FAN); - } else if (type == TRIANGLE_STRIP) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(TRIANGLE_STRIP); - } else if (type == QUADS) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(QUADS); - } else if (type == QUAD_STRIP) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(QUAD_STRIP); - } else if (type == POLYGON) { - shape = new PShape3D(parent, PShape.GEOMETRY); - shape.setKind(POLYGON); - } - return shape; - } - - public PShape createShape(int kind, float... p) { - PShape3D shape = null; - int len = p.length; - - if (kind == POINT) { - if (len != 2) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(POINT); - } else if (kind == LINE) { - if (len != 4) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(LINE); - } else if (kind == TRIANGLE) { - if (len != 6) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(TRIANGLE); - } else if (kind == QUAD) { - if (len != 8) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(QUAD); - } else if (kind == RECT) { - if (len != 4 && len != 5 && len != 8) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(RECT); - } else if (kind == ELLIPSE) { - if (len != 4) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(ELLIPSE); - } else if (kind == ARC) { - if (len != 6) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(ARC); - } else if (kind == BOX) { - if (len != 1 && len != 3) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(BOX); - } else if (kind == SPHERE) { - if (len != 1) { - showWarning("Wrong number of parameters"); - return null; - } - shape = new PShape3D(parent, PShape.PRIMITIVE); - shape.setKind(SPHERE); - } - - if (shape != null) { - shape.setParams(p); - } - - return shape; - } - - ////////////////////////////////////////////////////////////// - - // VERTEX SHAPES - - public void beginShape(int kind) { - shape = kind; - - inGeo.clear(); - - breakShape = false; - defaultEdges = true; - - textureImage0 = textureImage; - // The superclass method is called to avoid an early flush. - super.noTexture(); - - normalMode = NORMAL_MODE_AUTO; - } - - - public void endShape(int mode) { - // Disabled for now. This should be controlled by an additional hint... - if (flushMode == FLUSH_WHEN_FULL && hints[DISABLE_TEXTURE_CACHE] && - textureImage0 != null && textureImage == null) { - // The previous shape had a texture and this one doesn't. So we need to flush - // the textured geometry. - textureImage = textureImage0; - flush(); - textureImage = null; - } - - tessellate(mode); - - if (flushMode == FLUSH_CONTINUOUSLY || - (flushMode == FLUSH_WHEN_FULL && tessGeo.isFull())) { - - if (flushMode == FLUSH_WHEN_FULL && tessGeo.isOverflow()) { - PGraphics.showWarning("P3D: tessellated arrays are overflowing"); - } - - flush(); - } - } - - - public void texture(PImage image) { - if (flushMode == FLUSH_WHEN_FULL && hints[DISABLE_TEXTURE_CACHE] && - image != textureImage0) { - // Changing the texture image, so we need to flush the - // tessellated geometry accumulated until now, so that - // textures are not mixed. - textureImage = textureImage0; - flush(); - } - super.texture(image); - } - - - public void noTexture() { - if (flushMode == FLUSH_WHEN_FULL && hints[DISABLE_TEXTURE_CACHE] && - null != textureImage0) { - // Changing the texture image, so we need to flush the - // tessellated geometry accumulated until now, so that - // textures are not mixed. - textureImage = textureImage0; - flush(); - } - super.noTexture(); - } - - - public void beginContour() { - if (openContour) { - showWarning("P3D: Already called beginContour()."); - return; - } - openContour = true; - } - - - public void endContour() { - if (!openContour) { - showWarning("P3D: Need to call beginContour() first."); - return; - } - openContour = false; - breakShape = true; - } - - - public void vertex(float x, float y) { - vertex(x, y, 0, 0, 0); - } - - - public void vertex(float x, float y, float u, float v) { - vertex(x, y, 0, u, v); - } - - - public void vertex(float x, float y, float z) { - vertex(x, y, z, 0, 0); - } - - - public void vertex(float x, float y, float z, float u, float v) { - vertexImpl(x, y, z, u, v, VERTEX); - } - - - protected void vertexImpl(float x, float y, float z, float u, float v, int code) { - if (inGeo.isFull()) { - PGraphics.showWarning("P3D: Too many vertices, try creating smaller shapes"); - return; - } - - boolean textured = textureImage != null; - int fcolor = 0x00; - if (fill || textured) { - if (!textured) { - fcolor = fillColor; - } else { - if (tint) { - fcolor = tintColor; - } else { - fcolor = 0xffFFFFFF; - } - } - } - - int scolor = 0x00; - float sweight = 0; - if (stroke) { - scolor = strokeColor; - sweight = strokeWeight; - } - - if (breakShape) { - code = PShape.BREAK; - breakShape = false; - } - - if (textured && textureMode == IMAGE) { - u = PApplet.min(1, u / textureImage.width); - v = PApplet.min(1, v / textureImage.height); - } - - inGeo.addVertex(x, y, z, - fcolor, - normalX, normalY, normalZ, - u, v, - scolor, sweight, - ambientColor, specularColor, emissiveColor, shininess, - code); - } - - - public void clip(float a, float b, float c, float d) { - if (imageMode == CORNER) { - if (c < 0) { // reset a negative width - a += c; c = -c; - } - if (d < 0) { // reset a negative height - b += d; d = -d; - } - - clipImpl(a, b, a + c, b + d); - - } else if (imageMode == CORNERS) { - if (c < a) { // reverse because x2 < x1 - float temp = a; a = c; c = temp; - } - if (d < b) { // reverse because y2 < y1 - float temp = b; b = d; d = temp; - } - - clipImpl(a, b, c, d); - - } else if (imageMode == CENTER) { - // c and d are width/height - if (c < 0) c = -c; - if (d < 0) d = -d; - float x1 = a - c/2; - float y1 = b - d/2; - - clipImpl(x1, y1, x1 + c, y1 + d); - } - } - - - protected void clipImpl(float x1, float y1, float x2, float y2) { - flush(); - pgl.glEnable(PGL.GL_SCISSOR_TEST); - - float h = y2 - y1; - pgl.glScissor((int)x1, (int)(height - y1 - h), (int)(x2 - x1), (int)h); - - clip = true; - } - - - public void noClip() { - if (clip) { - flush(); - pgl.glDisable(PGL.GL_SCISSOR_TEST); - clip = false; - } - } - - - ////////////////////////////////////////////////////////////// - - // RENDERING - - // protected void render() - - // protected void sort() - - protected void tessellate(int mode) { - tessellator.setInGeometry(inGeo); - tessellator.setTessGeometry(tessGeo); - tessellator.setFill(fill || textureImage != null); - tessellator.setStroke(stroke); - tessellator.setStrokeWeight(strokeWeight); - tessellator.setStrokeCap(strokeCap); - tessellator.setStrokeJoin(strokeJoin); - - setFirstTexIndex(tessGeo.fillIndexCount); - - if (shape == POINTS) { - tessellator.tessellatePoints(); - } else if (shape == LINES) { - tessellator.tessellateLines(); - } else if (shape == TRIANGLE || shape == TRIANGLES) { - if (stroke && defaultEdges) inGeo.addTrianglesEdges(); - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcTrianglesNormals(); - tessellator.tessellateTriangles(); - } else if (shape == TRIANGLE_FAN) { - if (stroke && defaultEdges) inGeo.addTriangleFanEdges(); - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcTriangleFanNormals(); - tessellator.tessellateTriangleFan(); - } else if (shape == TRIANGLE_STRIP) { - if (stroke && defaultEdges) inGeo.addTriangleStripEdges(); - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcTriangleStripNormals(); - tessellator.tessellateTriangleStrip(); - } else if (shape == QUAD || shape == QUADS) { - if (stroke && defaultEdges) inGeo.addQuadsEdges(); - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcQuadsNormals(); - tessellator.tessellateQuads(); - } else if (shape == QUAD_STRIP) { - if (stroke && defaultEdges) inGeo.addQuadStripEdges(); - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcQuadStripNormals(); - tessellator.tessellateQuadStrip(); - } else if (shape == POLYGON) { - if (stroke && defaultEdges) inGeo.addPolygonEdges(mode == CLOSE); - tessellator.tessellatePolygon(false, mode == CLOSE, normalMode == NORMAL_MODE_AUTO); - } - - setLastTexIndex(tessGeo.lastFillIndex); - } - - protected void setFirstTexIndex(int first) { - firstTexIndex = first; - } - - protected void setLastTexIndex(int last) { - if (textureImage0 != textureImage || texCache.count == 0) { - texCache.addTexture(textureImage, firstTexIndex, last); - } else { - texCache.setLastIndex(last); - } - } - - public void flush() { - boolean hasPoints = 0 < tessGeo.pointVertexCount && 0 < tessGeo.pointIndexCount; - boolean hasLines = 0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount; - boolean hasFill = 0 < tessGeo.fillVertexCount && 0 < tessGeo.fillIndexCount; - - if (hasPoints || hasLines || hasFill) { - - if (flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - // The modelview transformation has been applied already to the - // tessellated vertices, so we set the OpenGL modelview matrix as - // the identity to avoid applying the model transformations twice. - pushMatrix(); - resetMatrix(); - } - - if (hasFill) { - renderFill(); - } - - if (hasPoints) { - renderPoints(); - } - - if (hasLines) { - renderLines(); - } - - if (flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - popMatrix(); - } - } - - tessGeo.clear(); - texCache.clear(); - } - - - protected void renderPoints() { - if (!pointVBOsCreated) { - createPointBuffers(); - pointVBOsCreated = true; - } - updatePointBuffers(); - - PointShader shader = getPointShader(); - shader.start(); - shader.setVertexAttribute(glPointVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); - shader.setColorAttribute(glPointColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setSizeAttribute(glPointSizeBufferID, 2, PGL.GL_FLOAT, 0, 0); - - pgl.glDrawElements(PGL.GL_TRIANGLES, tessGeo.pointIndexCount, PGL.INDEX_TYPE, 0); - - shader.stop(); - unbindPointBuffers(); - } - - protected void renderLines() { - if (!lineVBOsCreated) { - createLineBuffers(); - lineVBOsCreated = true; - } - updateLineBuffers(); - - LineShader shader = getLineShader(); - shader.start(); - shader.setVertexAttribute(glLineVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); - shader.setColorAttribute(glLineColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setDirWidthAttribute(glLineDirWidthBufferID, 4, PGL.GL_FLOAT, 0, 0); - - pgl.glDrawElements(PGL.GL_TRIANGLES, tessGeo.lineIndexCount, PGL.INDEX_TYPE, 0); - - shader.stop(); - unbindLineBuffers(); - } - - - protected void renderFill() { - if (!fillVBOsCreated) { - createFillBuffers(); - fillVBOsCreated = true; - } - updateFillBuffers(lights, texCache.hasTexture); - - texCache.beginRender(); - for (int i = 0; i < texCache.count; i++) { - PTexture tex = texCache.getTexture(i); - - FillShader shader = getFillShader(lights, tex != null); - shader.start(); - - shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); - shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - - if (lights) { - shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0); - shader.setAmbientAttribute(glFillAmbientBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setSpecularAttribute(glFillSpecularBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setEmissiveAttribute(glFillEmissiveBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setShininessAttribute(glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, 0); - } - - if (tex != null) { - shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); - shader.setTexture(tex); - } - - int offset = texCache.firstIndex[i]; - int size = texCache.lastIndex[i] - texCache.firstIndex[i] + 1; - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); - - shader.stop(); - } - texCache.endRender(); - unbindFillBuffers(lights, texCache.hasTexture); - } - - - // Utility function to render current tessellated geometry, under the assumption that - // the texture is already bound. - protected void renderTexFill(PTexture tex) { - if (!fillVBOsCreated) { - createFillBuffers(); - fillVBOsCreated = true; - } - updateFillBuffers(lights, true); - - FillShader shader = getFillShader(lights, true); - shader.start(); - - shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); - shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); - shader.setTexture(tex); - - if (lights) { - shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0); - shader.setAmbientAttribute(glFillAmbientBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setSpecularAttribute(glFillSpecularBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setEmissiveAttribute(glFillEmissiveBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); - shader.setShininessAttribute(glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, 0); - } - - int size = tessGeo.fillIndexCount; - int sizex = size * PGL.SIZEOF_INDEX; - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, tessGeo.fillIndices, vboMode); - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, 0); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - - shader.stop(); - } - - ////////////////////////////////////////////////////////////// - - // PSHAPE RENDERING IN 3D - - public void shape(PShape shape, float x, float y, float z) { - if (shape.isVisible()) { // don't do expensive matrix ops if invisible - pushMatrix(); - - if (shapeMode == CENTER) { - translate(x - shape.getWidth() / 2, y - shape.getHeight() / 2, z - - shape.getDepth() / 2); - - } else if ((shapeMode == CORNER) || (shapeMode == CORNERS)) { - translate(x, y, z); - } - shape.draw(this); - - popMatrix(); - } - } - - public void shape(PShape shape, float x, float y, float z, float c, float d, - float e) { - if (shape.isVisible()) { // don't do expensive matrix ops if invisible - pushMatrix(); - - if (shapeMode == CENTER) { - // x, y and z are center, c, d and e refer to a diameter - translate(x - c / 2f, y - d / 2f, z - e / 2f); - scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth()); - - } else if (shapeMode == CORNER) { - translate(x, y, z); - scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth()); - - } else if (shapeMode == CORNERS) { - // c, d, e are x2/y2/z2, make them into width/height/depth - c -= x; - d -= y; - e -= z; - // then same as above - translate(x, y, z); - scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth()); - } - shape.draw(this); - - popMatrix(); - } - } - - ////////////////////////////////////////////////////////////// - - // BEZIER CURVE VERTICES - - public void bezierDetail(int detail) { - bezierDetail = detail; - - if (bezierDrawMatrix == null) { - bezierDrawMatrix = new PMatrix3D(); - } - - // setup matrix for forward differencing to speed up drawing - pg.splineForward(detail, bezierDrawMatrix); - - // multiply the basis and forward diff matrices together - // saves much time since this needn't be done for each curve - bezierDrawMatrix.apply(pg.bezierBasisMatrix); - } - - public void bezierVertex(float x2, float y2, - float x3, float y3, - float x4, float y4) { - bezierVertex(x2, y2, 0, - x3, y3, 0, - x4, y4, 0); - } - - public void bezierVertex(float x2, float y2, float z2, - float x3, float y3, float z3, - float x4, float y4, float z4) { - bezierInitCheck(); - bezierVertexCheck(); - PMatrix3D draw = bezierDrawMatrix; - - float x1 = inGeo.getLastVertexX(); - float y1 = inGeo.getLastVertexY(); - float z1 = inGeo.getLastVertexZ(); - - float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; - float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; - float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; - - float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; - float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; - float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; - - float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; - float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; - float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; - - for (int j = 0; j < bezierDetail; j++) { - x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3; - y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3; - z1 += zplot1; zplot1 += zplot2; zplot2 += zplot3; - vertexImpl(x1, y1, z1, 0, 0, BEZIER_VERTEX); - } - } - - public void quadraticVertex(float cx, float cy, - float x3, float y3) { - quadraticVertex(cx, cy, 0, - x3, y3, 0); - } - - public void quadraticVertex(float cx, float cy, float cz, - float x3, float y3, float z3) { - float x1 = inGeo.getLastVertexX(); - float y1 = inGeo.getLastVertexY(); - float z1 = inGeo.getLastVertexZ(); - - bezierVertex(x1 + ((cx-x1)*2/3.0f), y1 + ((cy-y1)*2/3.0f), z1 + ((cz-z1)*2/3.0f), - x3 + ((cx-x3)*2/3.0f), y3 + ((cy-y3)*2/3.0f), z3 + ((cz-z3)*2/3.0f), - x3, y3, z3); - } - - protected void bezierInitCheck() { - if (!bezierInited) { - bezierInit(); - } - } - - protected void bezierInit() { - // overkill to be broken out, but better parity with the curve stuff below - bezierDetail(bezierDetail); - bezierInited = true; - } - - protected void bezierVertexCheck() { - if (shape != POLYGON) { - throw new RuntimeException("beginShape() or beginShape(POLYGON) " + - "must be used before bezierVertex() or quadraticVertex()"); - } - if (inGeo.vertexCount == 0) { - throw new RuntimeException("vertex() must be used at least once" + - "before bezierVertex() or quadraticVertex()"); - } - } - - ////////////////////////////////////////////////////////////// - - // CATMULL-ROM CURVE VERTICES - - public void curveDetail(int detail) { - curveDetail = detail; - curveInit(); - } - - public void curveTightness(float tightness) { - curveTightness = tightness; - curveInit(); - } - - public void curveVertex(float x, float y) { - curveVertex(x, y, 0); - } - - public void curveVertex(float x, float y, float z) { - curveVertexCheck(); - float[] vertex = curveVertices[curveVertexCount]; - vertex[X] = x; - vertex[Y] = y; - vertex[Z] = z; - curveVertexCount++; - - // draw a segment if there are enough points - if (curveVertexCount > 3) { - curveVertexSegment(curveVertices[curveVertexCount-4][X], - curveVertices[curveVertexCount-4][Y], - curveVertices[curveVertexCount-4][Z], - curveVertices[curveVertexCount-3][X], - curveVertices[curveVertexCount-3][Y], - curveVertices[curveVertexCount-3][Z], - curveVertices[curveVertexCount-2][X], - curveVertices[curveVertexCount-2][Y], - curveVertices[curveVertexCount-2][Z], - curveVertices[curveVertexCount-1][X], - curveVertices[curveVertexCount-1][Y], - curveVertices[curveVertexCount-1][Z]); - } - - } - - - protected void curveVertexCheck() { - if (shape != POLYGON) { - throw new RuntimeException("You must use createGeometry() or " + - "createGeometry(POLYGON) before curveVertex()"); - } - - // to improve code init time, allocate on first use. - if (curveVertices == null) { - curveVertices = new float[128][3]; - } - - if (curveVertexCount == curveVertices.length) { - // Can't use PApplet.expand() cuz it doesn't do the copy properly - float[][] temp = new float[curveVertexCount << 1][3]; - System.arraycopy(curveVertices, 0, temp, 0, curveVertexCount); - curveVertices = temp; - } - curveInitCheck(); - } - - protected void curveInitCheck() { - if (!curveInited) { - curveInit(); - } - } - - protected void curveInit() { - // allocate only if/when used to save startup time - if (curveDrawMatrix == null) { - curveBasisMatrix = new PMatrix3D(); - curveDrawMatrix = new PMatrix3D(); - curveInited = true; - } - - float s = curveTightness; - curveBasisMatrix.set((s-1)/2f, (s+3)/2f, (-3-s)/2f, (1-s)/2f, - (1-s), (-5-s)/2f, (s+2), (s-1)/2f, - (s-1)/2f, 0, (1-s)/2f, 0, - 0, 1, 0, 0); - - pg.splineForward(curveDetail, curveDrawMatrix); - - if (bezierBasisInverse == null) { - bezierBasisInverse = pg.bezierBasisMatrix.get(); - bezierBasisInverse.invert(); - curveToBezierMatrix = new PMatrix3D(); - } - - // TODO only needed for PGraphicsJava2D? if so, move it there - // actually, it's generally useful for other renderers, so keep it - // or hide the implementation elsewhere. - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - - // multiply the basis and forward diff matrices together - // saves much time since this needn't be done for each curve - curveDrawMatrix.apply(curveBasisMatrix); - } - - /** - * Handle emitting a specific segment of Catmull-Rom curve. This can be - * overridden by subclasses that need more efficient rendering options. - */ - protected void curveVertexSegment(float x1, float y1, float z1, - float x2, float y2, float z2, - float x3, float y3, float z3, - float x4, float y4, float z4) { - float x0 = x2; - float y0 = y2; - float z0 = z2; - - PMatrix3D draw = curveDrawMatrix; - - float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; - float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; - float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; - - float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; - float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; - float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; - - float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; - float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; - float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; - - vertexImpl(x0, y0, z0, 0, 0, CURVE_VERTEX); - for (int j = 0; j < curveDetail; j++) { - x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; - y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; - z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3; - vertexImpl(x0, y0, z0, 0, 0, CURVE_VERTEX); - } - } - - ////////////////////////////////////////////////////////////// - - // SPLINE UTILITY FUNCTIONS (used by both Bezier and Catmull-Rom) - - /** - * Setup forward-differencing matrix to be used for speedy - * curve rendering. It's based on using a specific number - * of curve segments and just doing incremental adds for each - * vertex of the segment, rather than running the mathematically - * expensive cubic equation. - * @param segments number of curve segments to use when drawing - * @param matrix target object for the new matrix - */ - protected void splineForward(int segments, PMatrix3D matrix) { - float f = 1.0f / segments; - float ff = f * f; - float fff = ff * f; - - matrix.set(0, 0, 0, 1, - fff, ff, f, 0, - 6*fff, 2*ff, 0, 0, - 6*fff, 0, 0, 0); - } - - - ////////////////////////////////////////////////////////////// - - // POINT, LINE, TRIANGLE, QUAD - - // Because vertex(x, y) is mapped to vertex(x, y, 0), none of these commands - // need to be overridden from their default implementation in PGraphics. - - // public void point(float x, float y) - - // public void point(float x, float y, float z) - - // public void line(float x1, float y1, float x2, float y2) - - // public void line(float x1, float y1, float z1, - // float x2, float y2, float z2) - - // public void triangle(float x1, float y1, float x2, float y2, - // float x3, float y3) - - // public void quad(float x1, float y1, float x2, float y2, - // float x3, float y3, float x4, float y4) - - ////////////////////////////////////////////////////////////// - - // RECT - - // public void rectMode(int mode) - - // public void rect(float a, float b, float c, float d) - - // protected void rectImpl(float x1, float y1, float x2, float y2) - - ////////////////////////////////////////////////////////////// - - // ELLIPSE - - // public void ellipseMode(int mode) - - - public void ellipse(float a, float b, float c, float d) { - beginShape(TRIANGLE_FAN); - defaultEdges = false; - inGeo.generateEllipse(ellipseMode, a, b, c, d, - fill, fillColor, - stroke, strokeColor, strokeWeight, - ambientColor, specularColor, emissiveColor, shininess); - endShape(); - } - - - // public void ellipse(float a, float b, float c, float d) - - // public void arc(float a, float b, float c, float d, - // float start, float stop) - - ////////////////////////////////////////////////////////////// - - // ARC - - protected void arcImpl(float x, float y, float w, float h, - float start, float stop) { - float hr = w / 2f; - float vr = h / 2f; - - float centerX = x + hr; - float centerY = y + vr; - - if (fill) { - // shut off stroke for a minute - boolean savedStroke = stroke; - stroke = false; - - int startLUT = (int) (0.5f + (start / TWO_PI) * SINCOS_LENGTH); - int stopLUT = (int) (0.5f + (stop / TWO_PI) * SINCOS_LENGTH); - - beginShape(TRIANGLE_FAN); - vertex(centerX, centerY); - int increment = 1; // what's a good algorithm? stopLUT - startLUT; - for (int i = startLUT; i < stopLUT; i += increment) { - int ii = i % SINCOS_LENGTH; - // modulo won't make the value positive - if (ii < 0) ii += SINCOS_LENGTH; - vertex(centerX + cosLUT[ii] * hr, - centerY + sinLUT[ii] * vr); - } - // draw last point explicitly for accuracy - vertex(centerX + cosLUT[stopLUT % SINCOS_LENGTH] * hr, - centerY + sinLUT[stopLUT % SINCOS_LENGTH] * vr); - endShape(); - - stroke = savedStroke; - } - - if (stroke) { - // Almost identical to above, but this uses a LINE_STRIP - // and doesn't include the first (center) vertex. - - boolean savedFill = fill; - fill = false; - - int startLUT = (int) (0.5f + (start / TWO_PI) * SINCOS_LENGTH); - int stopLUT = (int) (0.5f + (stop / TWO_PI) * SINCOS_LENGTH); - - beginShape(); //LINE_STRIP); - int increment = 1; // what's a good algorithm? stopLUT - startLUT; - for (int i = startLUT; i < stopLUT; i += increment) { - int ii = i % SINCOS_LENGTH; - if (ii < 0) ii += SINCOS_LENGTH; - vertex(centerX + cosLUT[ii] * hr, - centerY + sinLUT[ii] * vr); - } - // draw last point explicitly for accuracy - vertex(centerX + cosLUT[stopLUT % SINCOS_LENGTH] * hr, - centerY + sinLUT[stopLUT % SINCOS_LENGTH] * vr); - endShape(); - - fill = savedFill; - } - } - - ////////////////////////////////////////////////////////////// - - // BOX - - // TODO GL and GLUT in GL ES doesn't offer functions to create - // cubes. - - // public void box(float size) - - // public void box(float w, float h, float d) // P3D - - ////////////////////////////////////////////////////////////// - - // SPHERE - - // TODO GL and GLUT in GL ES doesn't offer functions to create - // spheres. - - // public void sphereDetail(int res) - - // public void sphereDetail(int ures, int vres) - - // public void sphere(float r) - - ////////////////////////////////////////////////////////////// - - // BEZIER - - // public float bezierPoint(float a, float b, float c, float d, float t) - - // public float bezierTangent(float a, float b, float c, float d, float t) - - // public void bezierDetail(int detail) - - // public void bezier(float x1, float y1, - // float x2, float y2, - // float x3, float y3, - // float x4, float y4) - - // public void bezier(float x1, float y1, float z1, - // float x2, float y2, float z2, - // float x3, float y3, float z3, - // float x4, float y4, float z4) - - ////////////////////////////////////////////////////////////// - - // CATMULL-ROM CURVES - - // public float curvePoint(float a, float b, float c, float d, float t) - - // public float curveTangent(float a, float b, float c, float d, float t) - - // public void curveDetail(int detail) - - // public void curveTightness(float tightness) - - // public void curve(float x1, float y1, - // float x2, float y2, - // float x3, float y3, - // float x4, float y4) - - // public void curve(float x1, float y1, float z1, - // float x2, float y2, float z2, - // float x3, float y3, float z3, - // float x4, float y4, float z4) - - ////////////////////////////////////////////////////////////// - - // IMAGES - - // public void imageMode(int mode) - - // public void image(PImage image, float x, float y) - - // public void image(PImage image, float x, float y, float c, float d) - - // public void image(PImage image, - // float a, float b, float c, float d, - // int u1, int v1, int u2, int v2) - - // protected void imageImpl(PImage image, - // float x1, float y1, float x2, float y2, - // int u1, int v1, int u2, int v2) - - ////////////////////////////////////////////////////////////// - - // SMOOTH - public void smooth() { - smooth(2); - } - - - public void smooth(int level) { - smooth = true; - - if (antialias != level) { - antialias = level; - if (primarySurface) { - restartContext(); -// throw new PApplet.RendererChangeException(); - } else { - initOffscreen(); - } - } - - pgl.glGetIntegerv(PGL.GL_SAMPLES, getBuffer); - int newAntialias = getBuffer.get(0); - if (antialias != newAntialias) { - antialias = newAntialias; - PApplet.println("Effective multisampling level: " + antialias); - } - - if (antialias < 2) { - pgl.glEnable(PGL.GL_MULTISAMPLE); - pgl.glEnable(PGL.GL_POINT_SMOOTH); - pgl.glEnable(PGL.GL_LINE_SMOOTH); - pgl.glEnable(PGL.GL_POLYGON_SMOOTH); - } - } - - - public void noSmooth() { - smooth = false; - - if (1 < antialias) { - antialias = 0; - if (primarySurface) { - restartContext(); - //throw new PApplet.RendererChangeException(); - } else { - initOffscreen(); - } - } - - pgl.glDisable(PGL.GL_MULTISAMPLE); - pgl.glDisable(PGL.GL_POINT_SMOOTH); - pgl.glDisable(PGL.GL_LINE_SMOOTH); - pgl.glDisable(PGL.GL_POLYGON_SMOOTH); - } - - ////////////////////////////////////////////////////////////// - - // SHAPE - - // public void shapeMode(int mode) - - public void shape(PShape3D shape) { - shape.draw(this); - } - - public void shape(PShape3D shape, float x, float y) { - shape(shape, x, y, 0); - } - - public void shape(PShape3D shape, float x, float y, float z) { - pushMatrix(); - translate(x, y, z); - shape.draw(this); - popMatrix(); - } - - // public void shape(PShape shape, float x, float y, float c, float d) - - ////////////////////////////////////////////////////////////// - - // TEXT SETTINGS - - // public void textAlign(int align) - - // public void textAlign(int alignX, int alignY) - - // public float textAscent() - - // public float textDescent() - - // public void textFont(PFont which) - - // public void textFont(PFont which, float size) - - // public void textLeading(float leading) - - // public void textMode(int mode) - - protected boolean textModeCheck(int mode) { - return mode == MODEL; - } - - // public void textSize(float size) - - // public float textWidth(char c) - - // public float textWidth(String str) - - // protected float textWidthImpl(char buffer[], int start, int stop) - - - ////////////////////////////////////////////////////////////// - - // TEXT IMPL - - // protected void textLineAlignImpl(char buffer[], int start, int stop, - // float x, float y) - - /** - * Implementation of actual drawing for a line of text. - */ - protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { - textTex = (PFontTexture)textFont.getCache(pg); - if (textTex == null) { - textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize); - textFont.setCache(this, textTex); - } else { - if (!pgl.contextIsCurrent(textTex.context)) { - for (int i = 0; i < textTex.textures.length; i++) { - textTex.textures[i].glID = 0; // To avoid finalization (texture objects were already deleted when context changed). - textTex.textures[i] = null; - } - textTex = new PFontTexture(parent, textFont, PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), - PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize)); - textFont.setCache(this, textTex); - } - } - textTex.setFirstTexture(); - - // Saving style parameters modified by text rendering. - int savedTextureMode = textureMode; - boolean savedStroke = stroke; - float savedNormalX = normalX; - float savedNormalY = normalY; - float savedNormalZ = normalZ; - boolean savedTint = tint; - int savedTintColor = tintColor; - int savedBlendMode = blendMode; - - // Setting style used in text rendering. - textureMode = NORMAL; - stroke = false; - normalX = 0; - normalY = 0; - normalZ = 1; - tint = true; - tintColor = fillColor; - - blendMode(BLEND); - - super.textLineImpl(buffer, start, stop, x, y); - - // Restoring original style. - textureMode = savedTextureMode; - stroke = savedStroke; - normalX = savedNormalX; - normalY = savedNormalY; - normalZ = savedNormalZ; - tint = savedTint; - tintColor = savedTintColor; - - // Note that if the user is using a blending mode different from - // BLEND, and has a bunch of continuous text rendering, the performance - // won't be optimal because at the end of each text() call the geometry - // will be flushed when restoring the user's blend. - blendMode(savedBlendMode); - } - - protected void textCharImpl(char ch, float x, float y) { - PFont.Glyph glyph = textFont.getGlyph(ch); - - if (glyph != null) { - PFontTexture.TextureInfo tinfo = textTex.getTexInfo(glyph); - - if (tinfo == null) { - // Adding new glyph to the font texture. - tinfo = textTex.addToTexture(glyph); - } - - if (textMode == MODEL) { - float high = glyph.height / (float) textFont.getSize(); - float bwidth = glyph.width / (float) textFont.getSize(); - float lextent = glyph.leftExtent / (float) textFont.getSize(); - float textent = glyph.topExtent / (float) textFont.getSize(); - - float x1 = x + lextent * textSize; - float y1 = y - textent * textSize; - float x2 = x1 + bwidth * textSize; - float y2 = y1 + high * textSize; - - textCharModelImpl(tinfo, x1, y1, x2, y2); - } - } - } - - - protected void textCharModelImpl(PFontTexture.TextureInfo info, float x0, float y0, - float x1, float y1) { - if (textTex.currentTex != info.texIndex) { - textTex.setTexture(info.texIndex); - } - PImage tex = textTex.getCurrentTexture(); - - beginShape(QUADS); - texture(tex); - vertex(x0, y0, info.u0, info.v0); - vertex(x1, y0, info.u1, info.v0); - vertex(x1, y1, info.u1, info.v1); - vertex(x0, y1, info.u0, info.v1); - endShape(); - } - - - ////////////////////////////////////////////////////////////// - - // MATRIX STACK - - - public void pushMatrix() { - modelviewStack.push(new PMatrix3D(modelview)); - modelviewInvStack.push(new PMatrix3D(modelviewInv)); - } - - - public void popMatrix() { - if (hints[DISABLE_TRANSFORM_CACHE]) { - flush(); - } - PMatrix3D mat; - - mat = modelviewStack.pop(); - modelview.set(mat); - - mat = modelviewInvStack.pop(); - modelviewInv.set(mat); - - calcProjmodelview(); - } - - - ////////////////////////////////////////////////////////////// - - // MATRIX TRANSFORMATIONS - - - public void translate(float tx, float ty) { - translate(tx, ty, 0); - } - - - public void translate(float tx, float ty, float tz) { - if (hints[DISABLE_TRANSFORM_CACHE]) { - flush(); - } - - modelview.translate(tx, ty, tz); - modelviewInv.invTranslate(tx, ty, tz); - projmodelview.translate(tx, ty, tz); - } - - - /** - * Two dimensional rotation. Same as rotateZ (this is identical to a 3D - * rotation along the z-axis) but included for clarity -- it'd be weird for - * people drawing 2D graphics to be using rotateZ. And they might kick our a-- - * for the confusion. - */ - public void rotate(float angle) { - rotateZ(angle); - } - - - public void rotateX(float angle) { - rotate(angle, 1, 0, 0); - } - - - public void rotateY(float angle) { - rotate(angle, 0, 1, 0); - } - - - public void rotateZ(float angle) { - rotate(angle, 0, 0, 1); - } - - - /** - * Rotate around an arbitrary vector, similar to glRotate(), except that it - * takes radians (instead of degrees). - */ - public void rotate(float angle, float v0, float v1, float v2) { - if (hints[DISABLE_TRANSFORM_CACHE]) { - flush(); - } - - modelview.rotate(angle, v0, v1, v2); - modelviewInv.invRotate(angle, v0, v1, v2); - calcProjmodelview(); // Possibly cheaper than doing projmodelview.rotate() - } - - - /** - * Same as scale(s, s, s). - */ - public void scale(float s) { - scale(s, s, s); - } - - - /** - * Same as scale(sx, sy, 1). - */ - public void scale(float sx, float sy) { - scale(sx, sy, 1); - } - - - /** - * Scale in three dimensions. - */ - public void scale(float sx, float sy, float sz) { - if (hints[DISABLE_TRANSFORM_CACHE]) { - flush(); - } - - modelview.scale(sx, sy, sz); - modelviewInv.invScale(sx, sy, sz); - projmodelview.scale(sx, sy, sz); - } - - - public void shearX(float angle) { - float t = (float) Math.tan(angle); - applyMatrix(1, t, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - } - - - public void shearY(float angle) { - float t = (float) Math.tan(angle); - applyMatrix(1, 0, 0, 0, - t, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - } - - - ////////////////////////////////////////////////////////////// - - // MATRIX MORE! - - - public void resetMatrix() { - modelview.reset(); - modelviewInv.reset(); - projmodelview.set(projection); - } - - - public void applyMatrix(PMatrix2D source) { - applyMatrix(source.m00, source.m01, source.m02, - source.m10, source.m11, source.m12); - } - - - public void applyMatrix(float n00, float n01, float n02, - float n10, float n11, float n12) { - applyMatrix(n00, n01, n02, 0, - n10, n11, n12, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - } - - - public void applyMatrix(PMatrix3D source) { - applyMatrix(source.m00, source.m01, source.m02, source.m03, - source.m10, source.m11, source.m12, source.m13, - source.m20, source.m21, source.m22, source.m23, - source.m30, source.m31, source.m32, source.m33); - } - - - /** - * Apply a 4x4 transformation matrix to the modelview stack. - */ - public void applyMatrix(float n00, float n01, float n02, float n03, - float n10, float n11, float n12, float n13, - float n20, float n21, float n22, float n23, - float n30, float n31, float n32, float n33) { - if (hints[DISABLE_TRANSFORM_CACHE]) { - flush(); - } - modelview.apply(n00, n01, n02, n03, - n10, n11, n12, n13, - n20, n21, n22, n23, - n30, n31, n32, n33); - projmodelview.apply(n00, n01, n02, n03, - n10, n11, n12, n13, - n20, n21, n22, n23, - n30, n31, n32, n33); - } - - /* - protected void loadProjection() { - pgl.setProjectionMode(); - loadMatrix(projection); - pgl.setModelviewMode(); - } - - - protected void loadCamera() { - pgl.setModelviewMode(); - loadMatrix(camera); - } - - - protected void loadModelview() { - pgl.setModelviewMode(); - loadMatrix(modelview); - } - - protected void loadMatrix(PMatrix3D pMatrix) { - modelview.set(pMatrix); - } - */ - - ////////////////////////////////////////////////////////////// - - // MATRIX GET/SET/PRINT - - public PMatrix getMatrix() { - return modelview.get(); - } - - // public PMatrix2D getMatrix(PMatrix2D target) - - public PMatrix3D getMatrix(PMatrix3D target) { - if (target == null) { - target = new PMatrix3D(); - } - target.set(modelview); - return target; - } - - // public void setMatrix(PMatrix source) - - public void setMatrix(PMatrix2D source) { - resetMatrix(); - applyMatrix(source); - } - - /** - * Set the current transformation to the contents of the specified source. - */ - public void setMatrix(PMatrix3D source) { - resetMatrix(); - applyMatrix(source); - } - - /** - * Print the current model (or "transformation") matrix. - */ - public void printMatrix() { - modelview.print(); - } - - ////////////////////////////////////////////////////////////// - - // PROJECTION - - - public void pushProjection() { - projectionStack.push(new PMatrix3D(projection)); - } - - - public void popProjection() { - PMatrix3D mat = projectionStack.pop(); - projection.set(mat); - } - - - public void applyProjection(PMatrix3D mat) { - projection.apply(mat); - } - - - public void setProjection(PMatrix3D mat) { - projection.set(mat); - } - - - ////////////////////////////////////////////////////////////// - - // CAMERA - - /** - * Set matrix mode to the camera matrix (instead of the current transformation - * matrix). This means applyMatrix, resetMatrix, etc. will affect the camera. - *

- * Note that the camera matrix is *not* the perspective matrix, it contains - * the values of the modelview matrix immediatly after the latter was - * initialized with ortho() or camera(), or the modelview matrix as result of - * the operations applied between beginCamera()/endCamera(). - *

- * beginCamera() specifies that all coordinate transforms until endCamera() - * should be pre-applied in inverse to the camera transform matrix. Note that - * this is only challenging when a user specifies an arbitrary matrix with - * applyMatrix(). Then that matrix will need to be inverted, which may not be - * possible. But take heart, if a user is applying a non-invertible matrix to - * the camera transform, then he is clearly up to no good, and we can wash our - * hands of those bad intentions. - *

- * begin/endCamera clauses do not automatically reset the camera transform - * matrix. That's because we set up a nice default camera transform in - * setup(), and we expect it to hold through draw(). So we don't reset the - * camera transform matrix at the top of draw(). That means that an - * innocuous-looking clause like - * - *

-   * beginCamera();
-   * translate(0, 0, 10);
-   * endCamera();
-   * 
- * - * at the top of draw(), will result in a runaway camera that shoots - * infinitely out of the screen over time. In order to prevent this, it is - * necessary to call some function that does a hard reset of the camera - * transform matrix inside of begin/endCamera. Two options are - * - *
-   * camera(); // sets up the nice default camera transform
-   * resetMatrix(); // sets up the identity camera transform
-   * 
- * - * So to rotate a camera a constant amount, you might try - * - *
-   * beginCamera();
-   * camera();
-   * rotateY(PI / 8);
-   * endCamera();
-   * 
- */ - public void beginCamera() { - if (manipulatingCamera) { - throw new RuntimeException("beginCamera() cannot be called again " - + "before endCamera()"); - } else { - manipulatingCamera = true; - } - } - - - /** - * Record the current settings into the camera matrix, and set the matrix mode - * back to the current transformation matrix. - *

- * Note that this will destroy any settings to scale(), translate(), or - * whatever, because the final camera matrix will be copied (not multiplied) - * into the modelview. - */ - public void endCamera() { - if (!manipulatingCamera) { - throw new RuntimeException("Cannot call endCamera() " - + "without first calling beginCamera()"); - } - - camera.set(modelview); - cameraInv.set(modelviewInv); - - // all done - manipulatingCamera = false; - } - - - /** - * Set camera to the default settings. - *

- * Processing camera behavior: - *

- * Camera behavior can be split into two separate components, camera - * transformation, and projection. The transformation corresponds to the - * physical location, orientation, and scale of the camera. In a physical - * camera metaphor, this is what can manipulated by handling the camera body - * (with the exception of scale, which doesn't really have a physcial analog). - * The projection corresponds to what can be changed by manipulating the lens. - *

- * We maintain separate matrices to represent the camera transform and - * projection. An important distinction between the two is that the camera - * transform should be invertible, where the projection matrix should not, - * since it serves to map three dimensions to two. It is possible to bake the - * two matrices into a single one just by multiplying them together, but it - * isn't a good idea, since lighting, z-ordering, and z-buffering all demand a - * true camera z coordinate after modelview and camera transforms have been - * applied but before projection. If the camera transform and projection are - * combined there is no way to recover a good camera-space z-coordinate from a - * model coordinate. - *

- * Fortunately, there are no functions that manipulate both camera - * transformation and projection. - *

- * camera() sets the camera position, orientation, and center of the scene. It - * replaces the camera transform with a new one. - *

- * The transformation functions are the same ones used to manipulate the - * modelview matrix (scale, translate, rotate, etc.). But they are bracketed - * with beginCamera(), endCamera() to indicate that they should apply (in - * inverse), to the camera transformation matrix. - */ - public void camera() { - camera(cameraX, cameraY, cameraZ, cameraX, cameraY, 0, 0, 1, 0); - } - - - /** - * More flexible method for dealing with camera(). - *

- * The actual call is like gluLookat. Here's the real skinny on what does - * what: - * - *

-   * camera(); or
-   * camera(ex, ey, ez, cx, cy, cz, ux, uy, uz);
-   * 
- * - * do not need to be called from with beginCamera();/endCamera(); That's - * because they always apply to the camera transformation, and they always - * totally replace it. That means that any coordinate transforms done before - * camera(); in draw() will be wiped out. It also means that camera() always - * operates in untransformed world coordinates. Therefore it is always - * redundant to call resetMatrix(); before camera(); This isn't technically - * true of gluLookat, but it's pretty much how it's used. - *

- * Now, beginCamera(); and endCamera(); are useful if you want to move the - * camera around using transforms like translate(), etc. They will wipe out - * any coordinate system transforms that occur before them in draw(), but they - * will not automatically wipe out the camera transform. This means that they - * should be at the top of draw(). It also means that the following: - * - *

-   * beginCamera();
-   * rotateY(PI / 8);
-   * endCamera();
-   * 
- * - * will result in a camera that spins without stopping. If you want to just - * rotate a small constant amount, try this: - * - *
-   * beginCamera();
-   * camera(); // sets up the default view
-   * rotateY(PI / 8);
-   * endCamera();
-   * 
- * - * That will rotate a little off of the default view. Note that this is - * entirely equivalent to - * - *
-   * camera(); // sets up the default view
-   * beginCamera();
-   * rotateY(PI / 8);
-   * endCamera();
-   * 
- * - * because camera() doesn't care whether or not it's inside a begin/end - * clause. Basically it's safe to use camera() or camera(ex, ey, ez, cx, cy, - * cz, ux, uy, uz) as naked calls because they do all the matrix resetting - * automatically. - */ - public void camera(float eyeX, float eyeY, float eyeZ, - float centerX, float centerY, float centerZ, - float upX, float upY, float upZ) { - if (hints[DISABLE_TRANSFORM_CACHE]) { - flush(); - } - - // Calculating Z vector - float z0 = eyeX - centerX; - float z1 = eyeY - centerY; - float z2 = eyeZ - centerZ; - float mag = PApplet.sqrt(z0 * z0 + z1 * z1 + z2 * z2); - if (mag != 0) { - z0 /= mag; - z1 /= mag; - z2 /= mag; - } - cameraEyeX = eyeX; - cameraEyeY = eyeY; - cameraEyeZ = eyeZ; - cameraDepth = mag; - - // Calculating Y vector - float y0 = upX; - float y1 = upY; - float y2 = upZ; - - // Computing X vector as Y cross Z - float x0 = y1 * z2 - y2 * z1; - float x1 = -y0 * z2 + y2 * z0; - float x2 = y0 * z1 - y1 * z0; - - // Recompute Y = Z cross X - y0 = z1 * x2 - z2 * x1; - y1 = -z0 * x2 + z2 * x0; - y2 = z0 * x1 - z1 * x0; - - // Cross product gives area of parallelogram, which is < 1.0 for - // non-perpendicular unit-length vectors; so normalize x, y here: - mag = PApplet.sqrt(x0 * x0 + x1 * x1 + x2 * x2); - if (mag != 0) { - x0 /= mag; - x1 /= mag; - x2 /= mag; - } - - mag = PApplet.sqrt(y0 * y0 + y1 * y1 + y2 * y2); - if (mag != 0) { - y0 /= mag; - y1 /= mag; - y2 /= mag; - } - - modelview.set(x0, x1, x2, 0, - y0, y1, y2, 0, - z0, z1, z2, 0, - 0, 0, 0, 1); - - float tx = -eyeX; - float ty = -eyeY; - float tz = -eyeZ; - modelview.translate(tx, ty, tz); - - modelviewInv.set(modelview); - modelviewInv.invert(); - - camera.set(modelview); - cameraInv.set(modelviewInv); - - calcProjmodelview(); - } - - - /** - * Print the current camera matrix. - */ - public void printCamera() { - camera.print(); - } - - - ////////////////////////////////////////////////////////////// - - // PROJECTION - - - /** - * Calls ortho() with the proper parameters for Processing's standard - * orthographic projection. - */ - public void ortho() { - ortho(0, width, 0, height, -500, 500); - } - - - /** - * Calls ortho() with the specified size of the viewing volume along - * the X and Z directions. - */ - public void ortho(float left, float right, - float bottom, float top) { - ortho(left, right, bottom, top, -500, 500); - } - - - /** - * Sets orthographic projection. The left, right, bottom and top - * values refer to the top left corner of the screen, not to the - * center or eye of the camera. This is like this because making - * it relative to the camera is not very intuitive if we think - * of the perspective function, which is also independent of the - * camera position. - * - */ - public void ortho(float left, float right, - float bottom, float top, - float near, float far) { - // Flushing geometry with a different perspective configuration. - flush(); - - left -= width/2; - right -= width/2; - - bottom -= height/2; - top -= height/2; - - near += cameraDepth; - far += cameraDepth; - - float x = 2.0f / (right - left); - float y = 2.0f / (top - bottom); - float z = -2.0f / (far - near); - - float tx = -(right + left) / (right - left); - float ty = -(top + bottom) / (top - bottom); - float tz = -(far + near) / (far - near); - - // The minus sign is needed to invert the Y axis. - projection.set(x, 0, 0, tx, - 0, -y, 0, ty, - 0, 0, z, tz, - 0, 0, 0, 1); - } - - - /** - * Calls perspective() with Processing's standard coordinate projection. - *

- * Projection functions: - *

    - *
  • frustrum() - *
  • ortho() - *
  • perspective() - *
- * Each of these three functions completely replaces the projection matrix - * with a new one. They can be called inside setup(), and their effects will - * be felt inside draw(). At the top of draw(), the projection matrix is not - * reset. Therefore the last projection function to be called always - * dominates. On resize, the default projection is always established, which - * has perspective. - *

- * This behavior is pretty much familiar from OpenGL, except where functions - * replace matrices, rather than multiplying against the previous. - *

- */ - public void perspective() { - perspective(cameraFOV, cameraAspect, cameraNear, cameraFar); - } - - - /** - * Similar to gluPerspective(). Implementation based on Mesa's glu.c - */ - public void perspective(float fov, float aspect, float zNear, float zFar) { - float ymax = zNear * (float) Math.tan(fov / 2); - float ymin = -ymax; - float xmin = ymin * aspect; - float xmax = ymax * aspect; - frustum(xmin, xmax, ymin, ymax, zNear, zFar); - } - - - /** - * Same as glFrustum(), except that it wipes out (rather than multiplies - * against) the current perspective matrix. - *

- * Implementation based on the explanation in the OpenGL blue book. - */ - public void frustum(float left, float right, float bottom, float top, - float znear, float zfar) { - // Flushing geometry with a different perspective configuration. - flush(); - - float temp, temp2, temp3, temp4; - temp = 2.0f * znear; - temp2 = right - left; - temp3 = top - bottom; - temp4 = zfar - znear; - - // The minus sign in the temp / temp3 term is to invert the Y axis. - projection.set(temp / temp2, 0, (right + left) / temp2, 0, - 0, -temp / temp3, (top + bottom) / temp3, 0, - 0, 0, (-zfar - znear) / temp4, (-temp * zfar) / temp4, - 0, 0, -1, 1); - - calcProjmodelview(); - } - - - /** - * Print the current projection matrix. - */ - public void printProjection() { - projection.print(); - } - - - ////////////////////////////////////////////////////////////// - - // SCREEN AND MODEL COORDS - - - public float screenX(float x, float y) { - return screenX(x, y, 0); - } - - - public float screenY(float x, float y) { - return screenY(x, y, 0); - } - - - public float screenX(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; - - float ox = projection.m00 * ax + projection.m01 * ay + projection.m02 * az + projection.m03 * aw; - float ow = projection.m30 * ax + projection.m31 * ay + projection.m32 * az + projection.m33 * aw; - - if (ow != 0) { - ox /= ow; - } - float sx = width * (1 + ox) / 2.0f; - return sx; - } - - - public float screenY(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; - - float oy = projection.m10 * ax + projection.m11 * ay + projection.m12 * az + projection.m13 * aw; - float ow = projection.m30 * ax + projection.m31 * ay + projection.m32 * az + projection.m33 * aw; - - if (ow != 0) { - oy /= ow; - } - float sy = height * (1 + oy) / 2.0f; - // Turning value upside down because of Processing's inverted Y axis. - sy = height - sy; - return sy; - } - - - public float screenZ(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; - - float oz = projection.m20 * ax + projection.m21 * ay + projection.m22 * az + projection.m23 * aw; - float ow = projection.m30 * ax + projection.m31 * ay + projection.m32 * az + projection.m33 * aw; - - if (ow != 0) { - oz /= ow; - } - float sz = (oz + 1) / 2.0f; - return sz; - } - - - public float modelX(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; - - float ox = cameraInv.m00 * ax + cameraInv.m01 * ay + cameraInv.m02 * az + cameraInv.m03 * aw; - float ow = cameraInv.m30 * ax + cameraInv.m31 * ay + cameraInv.m32 * az + cameraInv.m33 * aw; - - return (ow != 0) ? ox / ow : ox; - } - - - public float modelY(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; - - float oy = cameraInv.m10 * ax + cameraInv.m11 * ay + cameraInv.m12 * az + cameraInv.m13 * aw; - float ow = cameraInv.m30 * ax + cameraInv.m31 * ay + cameraInv.m32 * az + cameraInv.m33 * aw; - - return (ow != 0) ? oy / ow : oy; - } - - - public float modelZ(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; - - float oz = cameraInv.m20 * ax + cameraInv.m21 * ay + cameraInv.m22 * az + cameraInv.m23 * aw; - float ow = cameraInv.m30 * ax + cameraInv.m31 * ay + cameraInv.m32 * az + cameraInv.m33 * aw; - - return (ow != 0) ? oz / ow : oz; - } - - // STYLES - - // public void pushStyle() - // public void popStyle() - // public void style(PStyle) - // public PStyle getStyle() - // public void getStyle(PStyle) - - ////////////////////////////////////////////////////////////// - - // COLOR MODE - - // public void colorMode(int mode) - // public void colorMode(int mode, float max) - // public void colorMode(int mode, float mx, float my, float mz); - // public void colorMode(int mode, float mx, float my, float mz, float ma); - - ////////////////////////////////////////////////////////////// - - // COLOR CALC - - // protected void colorCalc(int rgb) - // protected void colorCalc(int rgb, float alpha) - // protected void colorCalc(float gray) - // protected void colorCalc(float gray, float alpha) - // protected void colorCalc(float x, float y, float z) - // protected void colorCalc(float x, float y, float z, float a) - // protected void colorCalcARGB(int argb, float alpha) - - ////////////////////////////////////////////////////////////// - - // STROKE CAP/JOIN/WEIGHT - - public void strokeWeight(float weight) { - this.strokeWeight = weight; - } - - public void strokeJoin(int join) { - this.strokeJoin = join; - } - - public void strokeCap(int cap) { - this.strokeCap = cap; - } - - - ////////////////////////////////////////////////////////////// - - // LIGHTING - - /** - * Sets up an ambient and directional light using OpenGL. API taken from - * PGraphics3D. - * - *

-   * The Lighting Skinny:
-   * The way lighting works is complicated enough that it's worth
-   * producing a document to describe it. Lighting calculations proceed
-   * pretty much exactly as described in the OpenGL red book.
-   * Light-affecting material properties:
-   *   AMBIENT COLOR
-   *   - multiplies by light's ambient component
-   *   - for believability this should match diffuse color
-   *   DIFFUSE COLOR
-   *   - multiplies by light's diffuse component
-   *   SPECULAR COLOR
-   *   - multiplies by light's specular component
-   *   - usually less colored than diffuse/ambient
-   *   SHININESS
-   *   - the concentration of specular effect
-   *   - this should be set pretty high (20-50) to see really
-   *     noticeable specularity
-   *   EMISSIVE COLOR
-   *   - constant additive color effect
-   * Light types:
-   *   AMBIENT
-   *   - one color
-   *   - no specular color
-   *   - no direction
-   *   - may have falloff (constant, linear, and quadratic)
-   *   - may have position (which matters in non-constant falloff case)
-   *   - multiplies by a material's ambient reflection
-   *   DIRECTIONAL
-   *   - has diffuse color
-   *   - has specular color
-   *   - has direction
-   *   - no position
-   *   - no falloff
-   *   - multiplies by a material's diffuse and specular reflections
-   *   POINT
-   *   - has diffuse color
-   *   - has specular color
-   *   - has position
-   *   - no direction
-   *   - may have falloff (constant, linear, and quadratic)
-   *   - multiplies by a material's diffuse and specular reflections
-   *   SPOT
-   *   - has diffuse color
-   *   - has specular color
-   *   - has position
-   *   - has direction
-   *   - has cone angle (set to half the total cone angle)
-   *   - has concentration value
-   *   - may have falloff (constant, linear, and quadratic)
-   *   - multiplies by a material's diffuse and specular reflections
-   * Normal modes:
-   * All of the primitives (rect, box, sphere, etc.) have their normals
-   * set nicely. During beginShape/endShape normals can be set by the user.
-   *   AUTO-NORMAL
-   *   - if no normal is set during the shape, we are in auto-normal mode
-   *   - auto-normal calculates one normal per triangle (face-normal mode)
-   *   SHAPE-NORMAL
-   *   - if one normal is set during the shape, it will be used for
-   *     all vertices
-   *   VERTEX-NORMAL
-   *   - if multiple normals are set, each normal applies to
-   *     subsequent vertices
-   *   - (except for the first one, which applies to previous
-   *     and subsequent vertices)
-   * Efficiency consequences:
-   *   There is a major efficiency consequence of position-dependent
-   *   lighting calculations per vertex. (See below for determining
-   *   whether lighting is vertex position-dependent.) If there is no
-   *   position dependency then the only factors that affect the lighting
-   *   contribution per vertex are its colors and its normal.
-   *   There is a major efficiency win if
-   *   1) lighting is not position dependent
-   *   2) we are in AUTO-NORMAL or SHAPE-NORMAL mode
-   *   because then we can calculate one lighting contribution per shape
-   *   (SHAPE-NORMAL) or per triangle (AUTO-NORMAL) and simply multiply it
-   *   into the vertex colors. The converse is our worst-case performance when
-   *   1) lighting is position dependent
-   *   2) we are in AUTO-NORMAL mode
-   *   because then we must calculate lighting per-face * per-vertex.
-   *   Each vertex has a different lighting contribution per face in
-   *   which it appears. Yuck.
-   * Determining vertex position dependency:
-   *   If any of the following factors are TRUE then lighting is
-   *   vertex position dependent:
-   *   1) Any lights uses non-constant falloff
-   *   2) There are any point or spot lights
-   *   3) There is a light with specular color AND there is a
-   *      material with specular color
-   * So worth noting is that default lighting (a no-falloff ambient
-   * and a directional without specularity) is not position-dependent.
-   * We should capitalize.
-   * Simon Greenwold, April 2005
-   * 
- */ - public void lights() { - enableLighting(); - - // need to make sure colorMode is RGB 255 here - int colorModeSaved = colorMode; - colorMode = RGB; - - lightFalloff(1, 0, 0); - lightSpecular(0, 0, 0); - - ambientLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f); - directionalLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f, 0, 0, -1); - - colorMode = colorModeSaved; - } - - /** - * Disables lighting. - */ - public void noLights() { - disableLighting(); - lightCount = 0; - } - - /** - * Add an ambient light based on the current color mode. - */ - public void ambientLight(float r, float g, float b) { - ambientLight(r, g, b, 0, 0, 0); - } - - /** - * Add an ambient light based on the current color mode. This version includes - * an (x, y, z) position for situations where the falloff distance is used. - */ - public void ambientLight(float r, float g, float b, float x, float y, float z) { - enableLighting(); - if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); - } - - lightType[lightCount] = AMBIENT; - - lightPosition(lightCount, x, y, z, false); - lightNormal(lightCount, 0, 0, 0); - - lightAmbient(lightCount, r, g, b); - noLightDiffuse(lightCount); - noLightSpecular(lightCount); - noLightSpot(lightCount); - lightFalloff(lightCount, currentLightFalloffConstant, - currentLightFalloffLinear, - currentLightFalloffQuadratic); - - lightCount++; - } - - public void directionalLight(float r, float g, float b, - float dx, float dy, float dz) { - enableLighting(); - if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); - } - - lightType[lightCount] = DIRECTIONAL; - - lightPosition(lightCount, 0, 0, 0, true); - lightNormal(lightCount, dx, dy, dz); - - noLightAmbient(lightCount); - lightDiffuse(lightCount, r, g, b); - lightSpecular(lightCount, currentLightSpecular[0], - currentLightSpecular[1], - currentLightSpecular[2]); - noLightSpot(lightCount); - noLightFalloff(lightCount); - - lightCount++; - } - - public void pointLight(float r, float g, float b, - float x, float y, float z) { - enableLighting(); - if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); - } - - lightType[lightCount] = POINT; - - lightPosition(lightCount, x, y, z, false); - lightNormal(lightCount, 0, 0, 0); - - noLightAmbient(lightCount); - lightDiffuse(lightCount, r, g, b); - lightSpecular(lightCount, currentLightSpecular[0], - currentLightSpecular[1], - currentLightSpecular[2]); - noLightSpot(lightCount); - lightFalloff(lightCount, currentLightFalloffConstant, - currentLightFalloffLinear, - currentLightFalloffQuadratic); - - lightCount++; - } - - public void spotLight(float r, float g, float b, - float x, float y, float z, - float dx, float dy, float dz, - float angle, float concentration) { - enableLighting(); - if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); - } - - lightType[lightCount] = SPOT; - - lightPosition(lightCount, x, y, z, false); - lightNormal(lightCount, dx, dy, dz); - - noLightAmbient(lightCount); - lightDiffuse(lightCount, r, g, b); - lightSpecular(lightCount, currentLightSpecular[0], - currentLightSpecular[1], - currentLightSpecular[2]); - lightSpot(lightCount, angle, concentration); - lightFalloff(lightCount, currentLightFalloffConstant, - currentLightFalloffLinear, - currentLightFalloffQuadratic); - - lightCount++; - } - - /** - * Set the light falloff rates for the last light that was created. Default is - * lightFalloff(1, 0, 0). - */ - public void lightFalloff(float constant, float linear, float quadratic) { - currentLightFalloffConstant = constant; - currentLightFalloffLinear = linear; - currentLightFalloffQuadratic = quadratic; - } - - /** - * Set the specular color of the last light created. - */ - public void lightSpecular(float x, float y, float z) { - colorCalc(x, y, z); - currentLightSpecular[0] = calcR; - currentLightSpecular[1] = calcG; - currentLightSpecular[2] = calcB; - } - - protected void enableLighting() { - if (!lights) { - flush(); // Flushing non-lit geometry. - lights = true; - } - } - - protected void disableLighting() { - if (lights) { - flush(); // Flushing lit geometry. - lights = false; - } - } - - protected void lightPosition(int num, float x, float y, float z, boolean dir) { - lightPosition[4 * num + 0] = x * modelview.m00 + y * modelview.m01 + z * modelview.m02 + modelview.m03; - lightPosition[4 * num + 1] = x * modelview.m10 + y * modelview.m11 + z * modelview.m12 + modelview.m13; - lightPosition[4 * num + 2] = x * modelview.m20 + y * modelview.m21 + z * modelview.m22 + modelview.m23; - - // Used to inicate if the light is directional or not. - lightPosition[4 * num + 3] = dir ? 1: 0; - } - - protected void lightNormal(int num, float dx, float dy, float dz) { - // Applying normal matrix to the light direction vector, which is the transpose of the inverse of the - // modelview. - float nx = dx * modelviewInv.m00 + dy * modelviewInv.m10 + dz * modelviewInv.m20; - float ny = dx * modelviewInv.m01 + dy * modelviewInv.m11 + dz * modelviewInv.m21; - float nz = dx * modelviewInv.m02 + dy * modelviewInv.m12 + dz * modelviewInv.m22; - - float invn = 1.0f / PApplet.dist(0, 0, 0, nx, ny, nz); - lightNormal[3 * num + 0] = invn * nx; - lightNormal[3 * num + 1] = invn * ny; - lightNormal[3 * num + 2] = invn * nz; - } - - protected void lightAmbient(int num, float r, float g, float b) { - colorCalc(r, g, b); - lightAmbient[3 * num + 0] = calcR; - lightAmbient[3 * num + 1] = calcG; - lightAmbient[3 * num + 2] = calcB; - } - - protected void noLightAmbient(int num) { - lightAmbient[3 * num + 0] = 0; - lightAmbient[3 * num + 1] = 0; - lightAmbient[3 * num + 2] = 0; - } - - protected void lightDiffuse(int num, float r, float g, float b) { - colorCalc(r, g, b); - lightDiffuse[3 * num + 0] = calcR; - lightDiffuse[3 * num + 1] = calcG; - lightDiffuse[3 * num + 2] = calcB; - } - - protected void noLightDiffuse(int num) { - lightDiffuse[3 * num + 0] = 0; - lightDiffuse[3 * num + 1] = 0; - lightDiffuse[3 * num + 2] = 0; - } - - protected void lightSpecular(int num, float r, float g, float b) { - lightSpecular[3 * num + 0] = r; - lightSpecular[3 * num + 1] = g; - lightSpecular[3 * num + 2] = b; - } - - protected void noLightSpecular(int num) { - lightSpecular[3 * num + 0] = 0; - lightSpecular[3 * num + 1] = 0; - lightSpecular[3 * num + 2] = 0; - } - - protected void lightFalloff(int num, float c0, float c1, float c2) { - lightFalloffCoefficients[3 * num + 0] = c0; - lightFalloffCoefficients[3 * num + 1] = c1; - lightFalloffCoefficients[3 * num + 2] = c2; - } - - protected void noLightFalloff(int num) { - lightFalloffCoefficients[3 * num + 0] = 1; - lightFalloffCoefficients[3 * num + 1] = 0; - lightFalloffCoefficients[3 * num + 2] = 0; - } - - protected void lightSpot(int num, float angle, float exponent) { - lightSpotParameters[2 * num + 0] = Math.max(0, PApplet.cos(angle)); - lightSpotParameters[2 * num + 1] = exponent; - } - - protected void noLightSpot(int num) { - lightSpotParameters[2 * num + 0] = 0; - lightSpotParameters[2 * num + 1] = 0; - } - - - ////////////////////////////////////////////////////////////// - - // BACKGROUND - - protected void backgroundImpl(PImage image) { - backgroundImpl(); - set(0, 0, image); - clearColorBuffer = true; - } - - protected void backgroundImpl() { - tessGeo.clear(); - texCache.clear(); - - pgl.glClearColor(0, 0, 0, 0); - pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); - - pgl.glClearColor(backgroundR, backgroundG, backgroundB, 1); - pgl.glClear(PGL.GL_COLOR_BUFFER_BIT); - clearColorBuffer = true; - } - - ////////////////////////////////////////////////////////////// - - // COLOR MODE - - // colorMode() is inherited from PGraphics. - - - ////////////////////////////////////////////////////////////// - - // COLOR METHODS - - // public final int color(int gray) - // public final int color(int gray, int alpha) - // public final int color(int rgb, float alpha) - // public final int color(int x, int y, int z) - - // public final float alpha(int what) - // public final float red(int what) - // public final float green(int what) - // public final float blue(int what) - // public final float hue(int what) - // public final float saturation(int what) - // public final float brightness(int what) - - // public int lerpColor(int c1, int c2, float amt) - // static public int lerpColor(int c1, int c2, float amt, int mode) - - ////////////////////////////////////////////////////////////// - - // BEGINRAW/ENDRAW - - // beginRaw, endRaw() both inherited. - - ////////////////////////////////////////////////////////////// - - // WARNINGS and EXCEPTIONS - - // showWarning() and showException() available from PGraphics. - - /** - * Report on anything from glError(). - * Don't use this inside glBegin/glEnd otherwise it'll - * throw an GL_INVALID_OPERATION error. - */ - public void report(String where) { - if (!hints[DISABLE_OPENGL_ERROR_REPORT]) { - int err = pgl.glGetError(); - if (err != 0) { - String errString = pgl.glErrorString(err); - String msg = "OpenGL error " + err + " at " + where + ": " + errString; - PGraphics.showWarning(msg); - } - } - } - - ////////////////////////////////////////////////////////////// - - // RENDERER SUPPORT QUERIES - - // public boolean displayable() - - // public boolean dimensional() // from P3D - - - /** - * Return true if this renderer supports 2D drawing. Defaults to true. - */ - public boolean is2D() { - return true; - } - - - /** - * Return true if this renderer supports 2D drawing. Defaults to false. - */ - public boolean is3D() { - return true; - } - - - public boolean isGL() { - return true; - } - - - ////////////////////////////////////////////////////////////// - - // PIMAGE METHODS - - // getImage - // setCache, getCache, removeCache - // isModified, setModified - - ////////////////////////////////////////////////////////////// - - // LOAD/UPDATE PIXELS - - public void loadPixels() { - flush(); - - if ((pixels == null) || (pixels.length != width * height)) { - pixels = new int[width * height]; - pixelBuffer = IntBuffer.allocate(pixels.length); - } - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - pixelBuffer.rewind(); - if (primarySurface) { - pgl.setReadBuffer(PGL.GL_FRONT); - } - pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); - - if (notCurrent) { - popFramebuffer(); - } - - pixelBuffer.get(pixels); - - // flip vertically (opengl stores images upside down), - // and swap RGBA components to ARGB (big endian) - int index = 0; - int yindex = (height - 1) * width; - for (int y = 0; y < height / 2; y++) { - if (BIG_ENDIAN) { - for (int x = 0; x < width; x++) { - int temp = pixels[index]; - // ignores alpha component, just sets it opaque - pixels[index] = 0xff000000 | ((pixels[yindex] >> 8) & 0x00ffffff); - pixels[yindex] = 0xff000000 | ((temp >> 8) & 0x00ffffff); - - index++; - yindex++; - } - } else { // LITTLE_ENDIAN, convert ABGR to ARGB - for (int x = 0; x < width; x++) { - int temp = pixels[index]; - - // identical to endPixels because only two - // components are being swapped - pixels[index] = 0xff000000 | ((pixels[yindex] << 16) & 0xff0000) - | (pixels[yindex] & 0xff00) | ((pixels[yindex] >> 16) & 0xff); - - pixels[yindex] = 0xff000000 | ((temp << 16) & 0xff0000) - | (temp & 0xff00) | ((temp >> 16) & 0xff); - - index++; - yindex++; - } - } - yindex -= width * 2; - } - - // When height is an odd number, the middle line needs to be - // endian swapped, but not y-swapped. - // http://dev.processing.org/bugs/show_bug.cgi?id=944 - if ((height % 2) == 1) { - index = (height / 2) * width; - if (BIG_ENDIAN) { - for (int x = 0; x < width; x++) { - // ignores alpha component, just sets it opaque - pixels[index] = 0xff000000 | ((pixels[index] >> 8) & 0x00ffffff); - } - } else { - for (int x = 0; x < width; x++) { - pixels[index] = 0xff000000 | ((pixels[index] << 16) & 0xff0000) - | (pixels[index] & 0xff00) | ((pixels[index] >> 16) & 0xff); - } - } - } - - if (primarySurface) { - // Load texture. - loadTextureImpl(POINT); - pixelsToTexture(); - } - - if (outsideDraw) { - endGLOp(); - } - } - - /** - * Convert native OpenGL format into palatable ARGB format. This function - * leaves alone (ignores) the alpha component. Also flips the image - * vertically, since images are upside-down in GL. - */ - static public void nativeToJavaRGB(PImage image) { - int index = 0; - int yindex = (image.height - 1) * image.width; - for (int y = 0; y < image.height / 2; y++) { - if (BIG_ENDIAN) { - for (int x = 0; x < image.width; x++) { - int temp = image.pixels[index]; - // ignores alpha component, just sets it opaque - image.pixels[index] = 0xff000000 | ((image.pixels[yindex] >> 8) & 0x00ffffff); - image.pixels[yindex] = 0xff000000 | ((temp >> 8) & 0x00ffffff); - index++; - yindex++; - } - } else { // LITTLE_ENDIAN, convert ABGR to ARGB - for (int x = 0; x < image.width; x++) { - int temp = image.pixels[index]; - - // identical to endPixels because only two - // components are being swapped - image.pixels[index] = 0xff000000 - | ((image.pixels[yindex] << 16) & 0xff0000) - | (image.pixels[yindex] & 0xff00) - | ((image.pixels[yindex] >> 16) & 0xff); - - image.pixels[yindex] = 0xff000000 | ((temp << 16) & 0xff0000) - | (temp & 0xff00) | ((temp >> 16) & 0xff); - - index++; - yindex++; - } - } - yindex -= image.width * 2; - } - } - - /** - * Convert native OpenGL format into palatable ARGB format. This function - * leaves alone (ignores) the alpha component. Also flips the image - * vertically, since images are upside-down in GL. - */ - static public void nativeToJavaARGB(PImage image) { - int index = 0; - int yindex = (image.height - 1) * image.width; - for (int y = 0; y < image.height / 2; y++) { - if (BIG_ENDIAN) { - for (int x = 0; x < image.width; x++) { - int temp = image.pixels[index]; - // ignores alpha component, just sets it opaque - image.pixels[index] = (image.pixels[yindex] & 0xff000000) - | ((image.pixels[yindex] >> 8) & 0x00ffffff); - image.pixels[yindex] = (temp & 0xff000000) - | ((temp >> 8) & 0x00ffffff); - index++; - yindex++; - } - } else { // LITTLE_ENDIAN, convert ABGR to ARGB - for (int x = 0; x < image.width; x++) { - int temp = image.pixels[index]; - - // identical to endPixels because only two - // components are being swapped - image.pixels[index] = (image.pixels[yindex] & 0xff000000) - | ((image.pixels[yindex] << 16) & 0xff0000) - | (image.pixels[yindex] & 0xff00) - | ((image.pixels[yindex] >> 16) & 0xff); - - image.pixels[yindex] = (temp & 0xff000000) - | ((temp << 16) & 0xff0000) | (temp & 0xff00) - | ((temp >> 16) & 0xff); - - index++; - yindex++; - } - } - yindex -= image.width * 2; - } - } - - /** - * Convert ARGB (Java/Processing) data to native OpenGL format. This function - * leaves alone (ignores) the alpha component. Also flips the image - * vertically, since images are upside-down in GL. - */ - static public void javaToNativeRGB(PImage image) { - int width = image.width; - int height = image.height; - int pixels[] = image.pixels; - - int index = 0; - int yindex = (height - 1) * width; - for (int y = 0; y < height / 2; y++) { - if (BIG_ENDIAN) { - // and convert ARGB back to opengl RGBA components (big endian) - for (int x = 0; x < image.width; x++) { - int temp = pixels[index]; - /* - * pixels[index] = ((pixels[yindex] >> 24) & 0xff) | ((pixels[yindex] - * << 8) & 0xffffff00); pixels[yindex] = ((temp >> 24) & 0xff) | - * ((temp << 8) & 0xffffff00); - */ - pixels[index] = ((pixels[yindex] << 8) & 0xffffff00) | 0xff; - pixels[yindex] = ((temp << 8) & 0xffffff00) | 0xff; - - index++; - yindex++; - } - - } else { - // convert ARGB back to native little endian ABGR - for (int x = 0; x < width; x++) { - int temp = pixels[index]; - - pixels[index] = 0xff000000 | ((pixels[yindex] << 16) & 0xff0000) - | (pixels[yindex] & 0xff00) | ((pixels[yindex] >> 16) & 0xff); - - pixels[yindex] = 0xff000000 | ((temp << 16) & 0xff0000) - | (temp & 0xff00) | ((temp >> 16) & 0xff); - - index++; - yindex++; - } - } - yindex -= width * 2; - } - } - - /** - * Convert Java ARGB to native OpenGL format. Also flips the image vertically, - * since images are upside-down in GL. - */ - static public void javaToNativeARGB(PImage image) { - int width = image.width; - int height = image.height; - int pixels[] = image.pixels; - - int index = 0; - int yindex = (height - 1) * width; - for (int y = 0; y < height / 2; y++) { - if (BIG_ENDIAN) { - // and convert ARGB back to opengl RGBA components (big endian) - for (int x = 0; x < image.width; x++) { - int temp = pixels[index]; - pixels[index] = ((pixels[yindex] >> 24) & 0xff) - | ((pixels[yindex] << 8) & 0xffffff00); - pixels[yindex] = ((temp >> 24) & 0xff) | ((temp << 8) & 0xffffff00); - - index++; - yindex++; - } - - } else { - // convert ARGB back to native little endian ABGR - for (int x = 0; x < width; x++) { - int temp = pixels[index]; - - pixels[index] = (pixels[yindex] & 0xff000000) - | ((pixels[yindex] << 16) & 0xff0000) | (pixels[yindex] & 0xff00) - | ((pixels[yindex] >> 16) & 0xff); - - pixels[yindex] = (pixels[yindex] & 0xff000000) - | ((temp << 16) & 0xff0000) | (temp & 0xff00) - | ((temp >> 16) & 0xff); - - index++; - yindex++; - } - } - yindex -= width * 2; - } - } - - public void updatePixels() { - // flip vertically (opengl stores images upside down), - - int index = 0; - int yindex = (height - 1) * width; - for (int y = 0; y < height / 2; y++) { - if (BIG_ENDIAN) { - // and convert ARGB back to opengl RGBA components (big endian) - for (int x = 0; x < width; x++) { - int temp = pixels[index]; - - pixels[index] = ((pixels[yindex] << 8) & 0xffffff00) | 0xff; - pixels[yindex] = ((temp << 8) & 0xffffff00) | 0xff; - - index++; - yindex++; - } - - } else { - // convert ARGB back to native little endian ABGR - for (int x = 0; x < width; x++) { - int temp = pixels[index]; - - pixels[index] = 0xff000000 | ((pixels[yindex] << 16) & 0xff0000) - | (pixels[yindex] & 0xff00) | ((pixels[yindex] >> 16) & 0xff); - - pixels[yindex] = 0xff000000 | ((temp << 16) & 0xff0000) - | (temp & 0xff00) | ((temp >> 16) & 0xff); - - index++; - yindex++; - } - } - yindex -= width * 2; - } - - pixelBuffer.rewind(); - pixelBuffer.put(pixels); - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - // Copying pixel buffer to screen texture... - copyToTexture(pixelBuffer); - - // ...and drawing the texture to screen. - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - // If this is an offscreen surface that is not current, then the offscreen framebuffer - // is bound so the texture is drawn to it instead to the main surface. Even if the - // surface in antialiased we don't need to bind the multisample framebuffer, we - // just draw to the regular offscreen framebuffer. - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - drawTexture(); - - if (notCurrent) { - popFramebuffer(); - } - - if (outsideDraw) { - endGLOp(); - } - } - - ////////////////////////////////////////////////////////////// - - // LOAD/UPDATE TEXTURE - - public void loadTexture() { - if (primarySurface) { - if (!drawing) { - beginGLOp(); - } - - loadTextureImpl(POINT); - loadPixels(); - pixelsToTexture(); - - if (!drawing) { - endGLOp(); - } - } - } - - protected void loadTextureImpl(int sampling) { - if (width == 0 || height == 0) return; - if (texture == null) { - PTexture.Parameters params = PTexture.newParameters(ARGB, sampling); - texture = new PTexture(parent, width, height, params); - texture.setFlippedY(true); - this.setCache(pg, texture); - this.setParams(pg, params); - - texCrop = new int[4]; - texCrop[0] = 0; - texCrop[1] = 0; - texCrop[2] = width; - texCrop[3] = height; - } - } - - // Draws wherever it is in the screen texture right now to the screen. - public void updateTexture() { - flush(); - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - drawTexture(); - - if (notCurrent) { - popFramebuffer(); - } - - if (outsideDraw) { - endGLOp(); - } - } - - protected void drawTexture() { - drawTexture(texture, texCrop, 0, 0, width, height); - } - - protected void copyToTexture(IntBuffer buffer) { - copyToTexture(texture, buffer, 0, 0, width, height); - } - - protected void copyFrameToTexture() { - // Make sure that the execution off all the openGL commands is - // finished before loading the texture. - pgl.glFinish(); - loadTexture(); - } - - protected void pixelsToTexture() { - texture.set(pixels); - } - - protected void textureToPixels() { - texture.get(pixels); - } - - ////////////////////////////////////////////////////////////// - - // RESIZE - - public void resize(int wide, int high) { - PGraphics.showMethodWarning("resize"); - } - - ////////////////////////////////////////////////////////////// - - // GET/SET - - public int get(int x, int y) { - flush(); - - if (getsetBuffer == null) { - getsetBuffer = IntBuffer.allocate(1); - } - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - // If the surface is not primary and multisampling is on, then the framebuffer - // will be switched momentarily from offscreenFramebufferMultisample to offscreenFramebuffer. - // This is in fact correct, because the glReadPixels() function doesn't work with - // multisample framebuffer attached as the read buffer. - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - getsetBuffer.rewind(); - if (primarySurface) { - pgl.setReadBuffer(PGL.GL_FRONT); - } - pgl.glReadPixels(x, height - y - 1, 1, 1, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, getsetBuffer); - - if (notCurrent) { - popFramebuffer(); - } - - int getset = getsetBuffer.get(0); - - if (outsideDraw) { - endGLOp(); - } - - if (BIG_ENDIAN) { - return 0xff000000 | ((getset >> 8) & 0x00ffffff); - - } else { - return 0xff000000 | ((getset << 16) & 0xff0000) | (getset & 0xff00) - | ((getset >> 16) & 0xff); - } - } - - // public PImage get(int x, int y, int w, int h) - - protected PImage getImpl(int x, int y, int w, int h) { - flush(); - - PImage newbie = parent.createImage(w, h, ARGB); - - IntBuffer newbieBuffer = IntBuffer.allocate(w * h); - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - newbieBuffer.rewind(); - if (primarySurface) { - pgl.setReadBuffer(PGL.GL_FRONT); - } - - pgl.glReadPixels(x, height - y - h, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, newbieBuffer); - - if (notCurrent) { - popFramebuffer(); - } - - newbie.loadPixels(); - newbieBuffer.get(newbie.pixels); - nativeToJavaARGB(newbie); - return newbie; - } - - public PImage get() { - return get(0, 0, width, height); - } - - // TODO: doesn't appear to work - public void set(int x, int y, int argb) { - flush(); - - int getset = 0; - - if (BIG_ENDIAN) { - // convert ARGB to RGBA - getset = (argb << 8) | 0xff; - } else { - // convert ARGB to ABGR - getset = (argb & 0xff00ff00) | ((argb << 16) & 0xff0000) - | ((argb >> 16) & 0xff); - } - - if (getsetBuffer == null) { - getsetBuffer = IntBuffer.allocate(1); - getsetBuffer.rewind(); - } - - getsetBuffer.put(0, getset); - getsetBuffer.rewind(); - - if (getsetTexture == null) { - getsetTexture = new PTexture(parent, 1, 1, new PTexture.Parameters(ARGB, POINT)); - } - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - copyToTexture(getsetTexture, getsetBuffer, 0, 0, 1, 1); - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - drawTexture(getsetTexture, 0, 0, 1, 1, x, height - y, 1, 1); - - if (notCurrent) { - popFramebuffer(); - } - - if (outsideDraw) { - endGLOp(); - } - } - - /** - * Set an image directly to the screen. - * - */ - public void set(int x, int y, PImage source) { - flush(); - - PTexture tex = getTexture(source); - if (tex != null) { - int w = source.width; - int h = source.height; - - boolean outsideDraw = primarySurface && !drawing; - if (outsideDraw) { - beginGLOp(); - } - - boolean notCurrent = !primarySurface && offscreenFramebuffer != currentFramebuffer; - if (notCurrent) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - - // The crop region and draw rectangle are given like this to take into account - // inverted y-axis in Processin with respect to OpenGL. - drawTexture(tex, 0, 0, w, h, x, height - y, w, -h); - - if (notCurrent) { - popFramebuffer(); - } - - if (outsideDraw) { - endGLOp(); - } - } - } - - ////////////////////////////////////////////////////////////// - - // MASK - - public void mask(int alpha[]) { - PGraphics.showMethodWarning("mask"); - } - - - public void mask(PImage alpha) { - PGraphics.showMethodWarning("mask"); - } - - ////////////////////////////////////////////////////////////// - - // FILTER - - /** - * This is really inefficient and not a good idea in OpenGL. Use get() and - * set() with a smaller image area, or call the filter on an image instead, - * and then draw that. - */ - public void filter(int kind) { - PImage temp = get(); - temp.filter(kind); - set(0, 0, temp); - } - - /** - * This is really inefficient and not a good idea in OpenGL. Use get() and - * set() with a smaller image area, or call the filter on an image instead, - * and then draw that. - */ - public void filter(int kind, float param) { - PImage temp = get(); - temp.filter(kind, param); - set(0, 0, temp); - } - - ////////////////////////////////////////////////////////////// - - /** - * Extremely slow and not optimized, should use GL methods instead. Currently - * calls a beginPixels() on the whole canvas, then does the copy, then it - * calls endPixels(). - */ - // public void copy(int sx1, int sy1, int sx2, int sy2, - // int dx1, int dy1, int dx2, int dy2) - - /** - * TODO - extremely slow and not optimized. Currently calls a beginPixels() on - * the whole canvas, then does the copy, then it calls endPixels(). - */ - // public void copy(PImage src, - // int sx1, int sy1, int sx2, int sy2, - // int dx1, int dy1, int dx2, int dy2) - - ////////////////////////////////////////////////////////////// - - // BLEND - - // static public int blendColor(int c1, int c2, int mode) - - // public void blend(PImage src, - // int sx, int sy, int dx, int dy, int mode) { - // set(dx, dy, PImage.blendColor(src.get(sx, sy), get(dx, dy), mode)); - // } - - /** - * Extremely slow and not optimized, should use GL methods instead. Currently - * calls a beginPixels() on the whole canvas, then does the copy, then it - * calls endPixels(). Please help fix: Bug 941, Bug 942. - */ - // public void blend(int sx1, int sy1, int sx2, int sy2, - // int dx1, int dy1, int dx2, int dy2, int mode) { - // loadPixels(); - // super.blend(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); - // updatePixels(); - // } - - // public void blend(PImage src, - // int sx1, int sy1, int sx2, int sy2, - // int dx1, int dy1, int dx2, int dy2, int mode) { - // loadPixels(); - // super.blend(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); - // updatePixels(); - // } - - /** - * Allows to set custom blend modes for the entire scene, using openGL. - * Reference article about blending modes: - * http://www.pegtop.net/delphi/articles/blendmodes/ - */ - public void blendMode(int mode) { - if (blendMode != mode) { - // Flushing any remaining geometry that uses a different blending - // mode. - flush(); - - blendMode = mode; - pgl.glEnable(PGL.GL_BLEND); - - if (mode == REPLACE) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_ONE, PGL.GL_ZERO); - } else if (mode == BLEND) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_ONE_MINUS_SRC_ALPHA); - } else if (mode == ADD) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_ONE); - } else if (mode == SUBTRACT) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_ONE_MINUS_DST_COLOR, PGL.GL_ZERO); - } else if (mode == LIGHTEST) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_MAX); - } else { - PGraphics.showWarning("This blend mode is not supported"); - return; - } - pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_DST_ALPHA); - } else if (mode == DARKEST) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_MIN); - } else { - PGraphics.showWarning("This blend mode is not supported"); - return; - } - pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_DST_ALPHA); - } else if (mode == DIFFERENCE) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_REVERSE_SUBTRACT); - } else { - PGraphics.showWarning("This blend mode is not supported"); - return; - } - pgl.glBlendFunc(PGL.GL_ONE, PGL.GL_ONE); - } else if (mode == EXCLUSION) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_ONE_MINUS_DST_COLOR, PGL.GL_ONE_MINUS_SRC_COLOR); - } else if (mode == MULTIPLY) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_DST_COLOR, PGL.GL_SRC_COLOR); - } else if (mode == SCREEN) { - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_ONE_MINUS_DST_COLOR, PGL.GL_ONE); - } - // HARD_LIGHT, SOFT_LIGHT, OVERLAY, DODGE, BURN modes cannot be implemented - // in fixed-function pipeline because they require conditional blending and - // non-linear blending equations. - } - } - - protected void setDefaultBlend() { - blendMode = BLEND; - pgl.glEnable(PGL.GL_BLEND); - if (blendEqSupported) { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - } - pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_ONE_MINUS_SRC_ALPHA); - } - - - ////////////////////////////////////////////////////////////// - - // SAVE - - // public void save(String filename) // PImage calls loadPixels() - - ////////////////////////////////////////////////////////////// - - // SHAPE I/O - - protected String[] getSupportedShapeFormats() { - return new String[] { "obj" }; - } - - - protected PShape loadShape(String filename, Object params) { - return null; - //return new PShape3D(parent, filename, (PShape3D.Parameters)params); - } - - - protected PShape createShape(int size, Object params) { - return null; - //return new PShape3D(parent, size, (PShape3D.Parameters)params); - } - - - ////////////////////////////////////////////////////////////// - - // TEXTURE UTILS - - /** - * This utility method returns the texture associated to the renderer's. - * drawing surface, making sure is updated to reflect the current contents - * off the screen (or offscreen drawing surface). - */ - public PTexture getTexture() { - loadTexture(); - return texture; - } - - /** - * This utility method returns the texture associated to the image. - * creating and/or updating it if needed. - * @param img the image to have a texture metadata associated to it - */ - public PTexture getTexture(PImage img) { - PTexture tex = (PTexture)img.getCache(pg); - if (tex == null) { - tex = addTexture(img); - } else { - if (!pgl.contextIsCurrent(tex.context)) { - // The texture was created with a different context. We need - // to recreate it. First, we make sure that the old GL id - // is not used to delete the texture object (it was already - // deleted when the context changed). - tex.glID = 0; - tex = addTexture(img); - // TODO: apply this mechanism to all the Processing objects using - // GL resources (PShape, PShader, PFramebuffer). They will probably - // need the cache thingy as well. - } - - if (img.isModified()) { - if (img.width != tex.width || img.height != tex.height) { - tex.init(img.width, img.height); - } - updateTexture(img, tex); - } - - if (tex.hasBuffers()) { - tex.bufferUpdate(); - } - } - return tex; - } - - - /** - * This utility method returns the texture associated to the image, - * but it doesn't create a new texture if the image has no texture. - * @param img the image to have a texture metadata associated to it - */ - protected PTexture queryTexture(PImage img) { - PTexture tex = (PTexture)img.getCache(pg); - return tex; - } - - - /** - * This utility method creates a texture for the provided image, and adds it - * to the metadata cache of the image. - * @param img the image to have a texture metadata associated to it - */ - protected PTexture addTexture(PImage img) { - PTexture.Parameters params = (PTexture.Parameters)img.getParams(pg); - if (params == null) { - params = PTexture.newParameters(); - img.setParams(pg, params); - } - PTexture tex = new PTexture(img.parent, img.width, img.height, params); - img.loadPixels(); - if (img.pixels != null) tex.set(img.pixels); - img.setCache(pg, tex); - return tex; - } - - protected PImage wrapTexture(PTexture tex) { - // We don't use the PImage(int width, int height, int mode) constructor to - // avoid initializing the pixels array. - PImage img = new PImage(); - img.parent = parent; - img.width = tex.width; - img.height = tex.height; - img.format = ARGB; - img.setCache(pg, tex); - return img; - } - - protected void updateTexture(PImage img, PTexture tex) { - if (tex != null) { - int x = img.getModifiedX1(); - int y = img.getModifiedY1(); - int w = img.getModifiedX2() - x; - int h = img.getModifiedY2() - y; - tex.set(img.pixels, x, y, w, h, img.format); - } - img.setModified(false); - } - - - /** Utility function to render texture. */ - protected void drawTexture(PTexture tex, int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { - int[] crop = {x1, y1, w1, h1}; - drawTexture(tex, crop, x2, y2, w2, h2); - } - - - /** Utility function to render texture. */ - protected void drawTexture(PTexture tex, int[] crop, int x, int y, int w, int h) { - drawTexture(tex.glTarget, tex.glID, tex.glWidth, tex.glHeight, crop, x, y, w, h); - } - - - /** Utility function to render texture. */ - protected void drawTexture(int target, int id, int w, int h, int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { - int[] crop = {x1, y1, w1, h1}; - drawTexture(target, id, w, h, crop, x2, y2, w2, h2); - } - - - /** Utility function to render texture without blend. */ - protected void drawTexture(int target, int id, int tw, int th, int[] crop, int x, int y, int w, int h) { - pgl.enableTexturing(target); - pgl.glBindTexture(target, id); - - int savedBlendMode = blendMode; - blendMode(REPLACE); - - // The texels of the texture replace the color of wherever is on the screen. -// texEnvMode = REPLACE; - - drawTexture(tw, th, crop, x, y, w, h); - - // Returning to the default texture environment mode, MODULATE. - // This allows tinting a texture with the current fragment color. -// texEnvMode = MODULATE; - - pgl.glBindTexture(target, 0); - pgl.disableTexturing(target); - - blendMode(savedBlendMode); - } - - protected void drawTexture(int w, int h, int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) { - int[] crop = {x1, y1, w1, h1}; - drawTexture(w, h, crop, x2, y2, w2, h2); - } - - /** - * Utility function to render currently bound texture using current blend mode. - * Equivalent to: - * glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, crop, 0); - * glDrawTexiOES(x, y, 0, w, h); - * in OpenGL ES. - */ - protected void drawTexture(int tw, int th, int[] crop, int x, int y, int w, int h) { - flush(); - - pgl.glDepthMask(false); - - // TODO: finish this! - /* - - pgl.setProjectionMode(); - pgl.pushMatrix(); - pgl.loadIdentity(); - pgl.setOrthographicProjection(0, width, 0, height, -1, 1); - - pgl.setModelviewMode(); - pgl.pushMatrix(); - pgl.loadIdentity(); - - pgl.translate(x, y, 0); - pgl.scale(w, h, 1); - // Rendering the quad with the appropriate texture coordinates needed for the - // specified crop region - float s0 = (float)crop[0] / tw; - float s1 = (float)(crop[0] + crop[2]) / tw; - float t0 = (float)crop[1] / th; - float t1 = (float)(crop[1] + crop[3]) / th; - drawTexQuad(s0, t0, s1, t1); - - // Restoring matrices. - pgl.setProjectionMode(); - pgl.popMatrix(); - pgl.setModelviewMode(); - pgl.popMatrix(); - - if (hintEnabled(ENABLE_DEPTH_MASK)) { - pgl.enableDepthMask(); - } - - */ - } - - - protected void drawTexQuad() { - drawTexQuad(0, 0, 1, 1); - } - - /** - * Pushes a normalized (1x1) textured quad to the GPU. - */ - protected void drawTexQuad(float u0, float v0, float u1, float v1) { - // TODO: need to fix null thing, test... - stroke = false; - beginShape(QUAD); - vertex(0, 0, u0, v0); - vertex(1, 0, u1, v0); - vertex(1, 1, u1, v1); - vertex(0, 1, u0, v1); - endShape(); - tessellate(OPEN); - renderTexFill(null); // we need the texture object here... - } - - - /** - * Utility function to copy buffer to texture. - */ - protected void copyToTexture(PTexture tex, IntBuffer buffer, int x, int y, int w, int h) { - buffer.rewind(); - pgl.enableTexturing(tex.glTarget); - pgl.glBindTexture(tex.glTarget, tex.glID); - pgl.glTexSubImage2D(tex.glTarget, 0, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer); - pgl.glBindTexture(tex.glTarget, 0); - pgl.disableTexturing(tex.glTarget); - } - - - ////////////////////////////////////////////////////////////// - - // INITIALIZATION ROUTINES - - static public void init() { - PGL.startup(true); - } - - - static public void init(boolean beforeUI) { - PGL.startup(beforeUI); - } - - protected void restartSurface() { - if (primarySurface) { - initPrimary(); - } else { - initOffscreen(); - } - } - - protected void initPrimary() { - pgl.initPrimarySurface(antialias); - pg = this; - } - - protected void initOffscreen() { - // Getting the context and capabilities from the main renderer. - pg = (PGraphicsLWJGL)parent.g; - pgl.initOffscreenSurface(pg.pgl); - - updatePGL(); - loadTextureImpl(BILINEAR); - - // In case of reinitialization (for example, when the smooth level - // is changed), we make sure that all the OpenGL resources associated - // to the surface are released by calling delete(). - if (offscreenFramebuffer != null) { - offscreenFramebuffer = null; - } - if (offscreenFramebufferMultisample != null) { - offscreenFramebufferMultisample = null; - } - - // We need the GL2GL3 profile to access the glRenderbufferStorageMultisample - // function used in multisampled (antialiased) offscreen rendering. - if (PGraphicsLWJGL.fboMultisampleSupported && 1 < antialias) { - int nsamples = antialias; - offscreenFramebufferMultisample = new PFramebuffer(parent, texture.glWidth, texture.glHeight, nsamples, 0, - offscreenDepthBits, offscreenStencilBits, - offscreenDepthBits == 24 && offscreenStencilBits == 8, false); - - offscreenFramebufferMultisample.clear(); - offscreenMultisample = true; - - // The offscreen framebuffer where the multisampled image is finally drawn to doesn't - // need depth and stencil buffers since they are part of the multisampled framebuffer. - offscreenFramebuffer = new PFramebuffer(parent, texture.glWidth, texture.glHeight, 1, 1, - 0, 0, - false, false); - - - } else { - offscreenFramebuffer = new PFramebuffer(parent, texture.glWidth, texture.glHeight, 1, 1, - offscreenDepthBits, offscreenStencilBits, - offscreenDepthBits == 24 && offscreenStencilBits == 8, false); - offscreenMultisample = false; - } - - offscreenFramebuffer.setColorBuffer(texture); - offscreenFramebuffer.clear(); - } - - protected void updateOffscreenContext() { - pgl.updateOffscreenSurface(pg.pgl); - updatePGL(); - } - - protected void getGLParameters() { - OPENGL_VENDOR = pgl.glGetString(PGL.GL_VENDOR); - OPENGL_RENDERER = pgl.glGetString(PGL.GL_RENDERER); - OPENGL_VERSION = pgl.glGetString(PGL.GL_VERSION); - OPENGL_EXTENSIONS = pgl.glGetString(PGL.GL_EXTENSIONS); - - npotTexSupported = -1 < OPENGL_EXTENSIONS.indexOf("texture_non_power_of_two"); - mipmapGeneration = -1 < OPENGL_EXTENSIONS.indexOf("generate_mipmap"); - vboSupported = -1 < OPENGL_EXTENSIONS.indexOf("vertex_buffer_object"); - fboSupported = -1 < OPENGL_EXTENSIONS.indexOf("framebuffer_object"); - fboMultisampleSupported = -1 < OPENGL_EXTENSIONS.indexOf("framebuffer_multisample"); - - try { - pgl.glBlendEquation(PGL.GL_FUNC_ADD); - blendEqSupported = true; - } catch (UnsupportedOperationException e) { - blendEqSupported = false; - } - -// int temp[] = new int[2]; - - pgl.glGetIntegerv(PGL.GL_MAX_TEXTURE_SIZE, getBuffer); - maxTextureSize = getBuffer.get(0); - - pgl.glGetIntegerv(PGL.GL_ALIASED_LINE_WIDTH_RANGE, getBuffer); - maxLineWidth = getBuffer.get(0); - - pgl.glGetIntegerv(PGL.GL_ALIASED_POINT_SIZE_RANGE, getBuffer); - maxPointSize = getBuffer.get(0); - - glParamsRead = true; - } - - ////////////////////////////////////////////////////////////// - - // SHADER HANDLING - - public PShader loadShader(String vertFilename, String fragFilename, int kind) { - if (kind == FILL_SHADER_SIMPLE) { - return new FillShaderSimple(parent, vertFilename, fragFilename); - } else if (kind == FILL_SHADER_LIT) { - return new FillShaderLit(parent, vertFilename, fragFilename); - } else if (kind == FILL_SHADER_TEX) { - return new FillShaderTex(parent, vertFilename, fragFilename); - } else if (kind == FILL_SHADER_FULL) { - return new FillShaderFull(parent, vertFilename, fragFilename); - } else if (kind == LINE_SHADER) { - return new LineShader(parent, vertFilename, fragFilename); - } else if (kind == POINT_SHADER) { - return new PointShader(parent, vertFilename, fragFilename); - } else { - PGraphics.showWarning("Wrong shader type"); - return null; - } - } - - public PShader loadShader(String fragFilename, int kind) { - PShader shader; - if (kind == FILL_SHADER_SIMPLE) { - shader = new FillShaderSimple(parent); - shader.setVertexShader(defFillShaderVertSimpleURL); - } else if (kind == FILL_SHADER_LIT) { - shader = new FillShaderLit(parent); - shader.setVertexShader(defFillShaderVertLitURL); - } else if (kind == FILL_SHADER_TEX) { - shader = new FillShaderTex(parent); - shader.setVertexShader(defFillShaderVertTexURL); - } else if (kind == FILL_SHADER_FULL) { - shader = new FillShaderFull(parent); - shader.setVertexShader(defFillShaderVertFullURL); - } else if (kind == LINE_SHADER) { - shader = new LineShader(parent); - shader.setVertexShader(defLineShaderVertURL); - } else if (kind == POINT_SHADER) { - shader = new PointShader(parent); - shader.setVertexShader(defPointShaderVertURL); - } else { - PGraphics.showWarning("Wrong shader type"); - return null; - } - shader.setFragmentShader(fragFilename); - return shader; - } - - public void setShader(PShader shader, int kind) { - if (kind == FILL_SHADER_SIMPLE) { - fillShaderSimple = (FillShaderSimple) shader; - } else if (kind == FILL_SHADER_LIT) { - fillShaderLit = (FillShaderLit) shader; - } else if (kind == FILL_SHADER_TEX) { - fillShaderTex = (FillShaderTex) shader; - } else if (kind == FILL_SHADER_FULL) { - fillShaderFull = (FillShaderFull) shader; - } else if (kind == LINE_SHADER) { - lineShader = (LineShader) shader; - } else if (kind == POINT_SHADER) { - pointShader = (PointShader) shader; - } else { - PGraphics.showWarning("Wrong shader type"); - } - } - - public void resetShader(int kind) { - if (kind == FILL_SHADER_SIMPLE) { - if (defFillShaderSimple == null) { - defFillShaderSimple = new FillShaderSimple(parent, defFillShaderVertSimpleURL, defFillShaderFragNoTexURL); - } - fillShaderSimple = defFillShaderSimple; - } else if (kind == FILL_SHADER_LIT) { - if (defFillShaderLit == null) { - defFillShaderLit = new FillShaderLit(parent, defFillShaderVertLitURL, defFillShaderFragNoTexURL); - } - fillShaderLit = defFillShaderLit; - } else if (kind == FILL_SHADER_TEX) { - if (defFillShaderTex == null) { - defFillShaderTex = new FillShaderTex(parent, defFillShaderVertTexURL, defFillShaderFragTexURL); - } - fillShaderTex = defFillShaderTex; - } else if (kind == FILL_SHADER_FULL) { - if (defFillShaderFull == null) { - defFillShaderFull = new FillShaderFull(parent, defFillShaderVertFullURL, defFillShaderFragTexURL); - } - fillShaderFull = defFillShaderFull; - } else if (kind == LINE_SHADER) { - if (defLineShader == null) { - defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); - } - lineShader = defLineShader; - } else if (kind == POINT_SHADER) { - if (defPointShader == null) { - defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); - } - pointShader = defPointShader; - } else { - PGraphics.showWarning("Wrong shader type"); - } - } - - protected FillShader getFillShader(boolean lit, boolean tex) { - FillShader shader; - if (lit) { - if (tex) { - if (defFillShaderFull == null) { - defFillShaderFull = new FillShaderFull(parent, defFillShaderVertFullURL, defFillShaderFragTexURL); - } - if (fillShaderFull == null) { - fillShaderFull = defFillShaderFull; - } - shader = fillShaderFull; - } else { - if (defFillShaderLit == null) { - defFillShaderLit = new FillShaderLit(parent, defFillShaderVertLitURL, defFillShaderFragNoTexURL); - } - if (fillShaderLit == null) { - fillShaderLit = defFillShaderLit; - } - shader = fillShaderLit; - } - } else { - if (tex) { - if (defFillShaderTex == null) { - defFillShaderTex = new FillShaderTex(parent, defFillShaderVertTexURL, defFillShaderFragTexURL); - } - if (fillShaderTex == null) { - fillShaderTex = defFillShaderTex; - } - shader = fillShaderTex; - } else { - if (defFillShaderSimple == null) { - defFillShaderSimple = new FillShaderSimple(parent, defFillShaderVertSimpleURL, defFillShaderFragNoTexURL); - } - if (fillShaderSimple == null) { - fillShaderSimple = defFillShaderSimple; - } - shader = fillShaderSimple; - } - } - shader.loadAttributes(); - shader.loadUniforms(); - return shader; - } - - protected LineShader getLineShader() { - if (defLineShader == null) { - defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); - } - if (lineShader == null) { - lineShader = defLineShader; - } - lineShader.loadAttributes(); - lineShader.loadUniforms(); - return lineShader; - } - - protected PointShader getPointShader() { - if (defPointShader == null) { - defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); - } - if (pointShader == null) { - pointShader = defPointShader; - } - pointShader.loadAttributes(); - pointShader.loadUniforms(); - return pointShader; - } - - protected class FillShader extends PShader { - public FillShader(PApplet parent) { - super(parent); - } - - public FillShader(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public FillShader(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadAttributes() { } - public void loadUniforms() { } - - public void setAttribute(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { - if (-1 < loc) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, vboId); - pgl.glVertexAttribPointer(loc, size, type, normalized, stride, offset); - } - } - - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setNormalAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setAmbientAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { } - public void setTexture(PTexture tex) { } - } - - protected class FillShaderSimple extends FillShader { - protected int projmodelviewMatrixLoc; - - protected int inVertexLoc; - protected int inColorLoc; - - public FillShaderSimple(PApplet parent) { - super(parent); - } - - public FillShaderSimple(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public FillShaderSimple(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadAttributes() { - inVertexLoc = getAttribLocation("inVertex"); - inColorLoc = getAttribLocation("inColor"); - } - - public void loadUniforms() { - projmodelviewMatrixLoc = getUniformLocation("projmodelviewMatrix"); - } - - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); - } - - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inColorLoc, vboId, size, type, true, stride, offset); - } - - public void start() { - super.start(); - - if (-1 < inVertexLoc) pgl.glEnableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glEnableVertexAttribArray(inColorLoc); - - updateGLProjmodelview(); - set4x4MatUniform(projmodelviewMatrixLoc, glProjmodelview); - } - - public void stop() { - if (-1 < inVertexLoc) pgl.glDisableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glDisableVertexAttribArray(inColorLoc); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - super.stop(); - } - } - - protected class FillShaderLit extends FillShader { - protected int projmodelviewMatrixLoc; - protected int modelviewMatrixLoc; - protected int normalMatrixLoc; - - protected int lightCountLoc; - protected int lightPositionLoc; - protected int lightNormalLoc; - protected int lightAmbientLoc; - protected int lightDiffuseLoc; - protected int lightSpecularLoc; - protected int lightFalloffCoefficientsLoc; - protected int lightSpotParametersLoc; - - protected int inVertexLoc; - protected int inColorLoc; - protected int inNormalLoc; - - protected int inAmbientLoc; - protected int inSpecularLoc; - protected int inEmissiveLoc; - protected int inShineLoc; - - public FillShaderLit(PApplet parent) { - super(parent); - } - - public FillShaderLit(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public FillShaderLit(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadAttributes() { - inVertexLoc = getAttribLocation("inVertex"); - inColorLoc = getAttribLocation("inColor"); - inNormalLoc = getAttribLocation("inNormal"); - - inAmbientLoc = getAttribLocation("inAmbient"); - inSpecularLoc = getAttribLocation("inSpecular"); - inEmissiveLoc = getAttribLocation("inEmissive"); - inShineLoc = getAttribLocation("inShine"); - } - - public void loadUniforms() { - projmodelviewMatrixLoc = getUniformLocation("projmodelviewMatrix"); - modelviewMatrixLoc = getUniformLocation("modelviewMatrix"); - normalMatrixLoc = getUniformLocation("normalMatrix"); - - lightCountLoc = getUniformLocation("lightCount"); - lightPositionLoc = getUniformLocation("lightPosition"); - lightNormalLoc = getUniformLocation("lightNormal"); - lightAmbientLoc = getUniformLocation("lightAmbient"); - lightDiffuseLoc = getUniformLocation("lightDiffuse"); - lightSpecularLoc = getUniformLocation("lightSpecular"); - lightFalloffCoefficientsLoc = getUniformLocation("lightFalloffCoefficients"); - lightSpotParametersLoc = getUniformLocation("lightSpotParameters"); - } - - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); - } - - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inColorLoc, vboId, size, type, true, stride, offset); - } - - public void setNormalAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inNormalLoc, vboId, size, type, false, stride, offset); - } - - public void setAmbientAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inAmbientLoc, vboId, size, type, true, stride, offset); - } - - public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inSpecularLoc, vboId, size, type, true, stride, offset); - } - - public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inEmissiveLoc, vboId, size, type, true, stride, offset); - } - - public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inShineLoc, vboId, size, type, false, stride, offset); - } - - public void start() { - super.start(); - - if (-1 < inVertexLoc) pgl.glEnableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glEnableVertexAttribArray(inColorLoc); - if (-1 < inNormalLoc) pgl.glEnableVertexAttribArray(inNormalLoc); - - if (-1 < inAmbientLoc) pgl.glEnableVertexAttribArray(inAmbientLoc); - if (-1 < inSpecularLoc) pgl.glEnableVertexAttribArray(inSpecularLoc); - if (-1 < inEmissiveLoc) pgl.glEnableVertexAttribArray(inEmissiveLoc); - if (-1 < inShineLoc) pgl.glEnableVertexAttribArray(inShineLoc); - - updateGLProjmodelview(); - set4x4MatUniform(projmodelviewMatrixLoc, glProjmodelview); - - updateGLModelview(); - set4x4MatUniform(modelviewMatrixLoc, glModelview); - - updateGLNormal(); - set3x3MatUniform(normalMatrixLoc, glNormal); - - setIntUniform(lightCountLoc, lightCount); - set4FloatVecUniform(lightPositionLoc, lightPosition); - set3FloatVecUniform(lightNormalLoc, lightNormal); - set3FloatVecUniform(lightAmbientLoc, lightAmbient); - set3FloatVecUniform(lightDiffuseLoc, lightDiffuse); - set3FloatVecUniform(lightSpecularLoc, lightSpecular); - set3FloatVecUniform(lightFalloffCoefficientsLoc, lightFalloffCoefficients); - set2FloatVecUniform(lightSpotParametersLoc, lightSpotParameters); - } - - public void stop() { - if (-1 < inVertexLoc) pgl.glDisableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glDisableVertexAttribArray(inColorLoc); - if (-1 < inNormalLoc) pgl.glDisableVertexAttribArray(inNormalLoc); - - if (-1 < inAmbientLoc) pgl.glDisableVertexAttribArray(inAmbientLoc); - if (-1 < inSpecularLoc) pgl.glDisableVertexAttribArray(inSpecularLoc); - if (-1 < inEmissiveLoc) pgl.glDisableVertexAttribArray(inEmissiveLoc); - if (-1 < inShineLoc) pgl.glDisableVertexAttribArray(inShineLoc); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - super.stop(); - } - } - - protected class FillShaderTex extends FillShaderSimple { - protected int inTexcoordLoc; - - protected int texcoordMatrixLoc; - protected int texcoordOffsetLoc; - - protected float[] tcmat; - - public FillShaderTex(PApplet parent) { - super(parent); - } - - public FillShaderTex(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public FillShaderTex(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadUniforms() { - super.loadUniforms(); - - texcoordMatrixLoc = getUniformLocation("texcoordMatrix"); - texcoordOffsetLoc = getUniformLocation("texcoordOffset"); - } - - public void loadAttributes() { - super.loadAttributes(); - - inTexcoordLoc = getAttribLocation("inTexcoord"); - } - - public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); - } - - public void setTexture(PTexture tex) { - float scaleu = tex.maxTexCoordU; - float scalev = tex.maxTexCoordV; - float dispu = 0; - float dispv = 0; - - if (tex.isFlippedY()) { - scalev *= -1; - dispv = 1; - } - - if (tcmat == null) { - tcmat = new float[16]; - } - - tcmat[0] = scaleu; tcmat[4] = 0; tcmat[ 8] = 0; tcmat[12] = dispu; - tcmat[1] = 0; tcmat[5] = scalev; tcmat[ 9] = 0; tcmat[13] = dispv; - tcmat[2] = 0; tcmat[6] = 0; tcmat[10] = 0; tcmat[14] = 0; - tcmat[3] = 0; tcmat[7] = 0; tcmat[11] = 0; tcmat[15] = 0; - set4x4MatUniform(texcoordMatrixLoc, tcmat); - - set2FloatUniform(texcoordOffsetLoc, 1.0f / tex.width, 1.0f / tex.height); - } - - public void start() { - super.start(); - - if (-1 < inTexcoordLoc) pgl.glEnableVertexAttribArray(inTexcoordLoc); - } - - public void stop() { - if (-1 < inTexcoordLoc) pgl.glDisableVertexAttribArray(inTexcoordLoc); - - super.stop(); - } - } - - protected class FillShaderFull extends FillShaderLit { - protected int inTexcoordLoc; - - protected int texcoordMatrixLoc; - protected int texcoordOffsetLoc; - - protected float[] tcmat; - - public FillShaderFull(PApplet parent) { - super(parent); - } - - public FillShaderFull(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public FillShaderFull(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadUniforms() { - super.loadUniforms(); - - texcoordMatrixLoc = getUniformLocation("texcoordMatrix"); - texcoordOffsetLoc = getUniformLocation("texcoordOffset"); - } - - public void loadAttributes() { - super.loadAttributes(); - - inTexcoordLoc = getAttribLocation("inTexcoord"); - } - - public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); - } - - public void setTexture(PTexture tex) { - float scaleu = tex.maxTexCoordU; - float scalev = tex.maxTexCoordV; - float dispu = 0; - float dispv = 0; - - if (tex.isFlippedY()) { - scalev *= -1; - dispv = 1; - } - - if (tcmat == null) { - tcmat = new float[16]; - } - - tcmat[0] = scaleu; tcmat[4] = 0; tcmat[ 8] = 0; tcmat[12] = dispu; - tcmat[1] = 0; tcmat[5] = scalev; tcmat[ 9] = 0; tcmat[13] = dispv; - tcmat[2] = 0; tcmat[6] = 0; tcmat[10] = 0; tcmat[14] = 0; - tcmat[3] = 0; tcmat[7] = 0; tcmat[11] = 0; tcmat[15] = 0; - set4x4MatUniform(texcoordMatrixLoc, tcmat); - - set2FloatUniform(texcoordOffsetLoc, 1.0f / tex.width, 1.0f / tex.height); - } - - public void start() { - super.start(); - - if (-1 < inTexcoordLoc) pgl.glEnableVertexAttribArray(inTexcoordLoc); - } - - public void stop() { - if (-1 < inTexcoordLoc) pgl.glDisableVertexAttribArray(inTexcoordLoc); - - super.stop(); - } - } - - protected class LineShader extends PShader { - protected int projectionMatrixLoc; - protected int modelviewMatrixLoc; - - protected int viewportLoc; - protected int perspectiveLoc; - - protected int inVertexLoc; - protected int inColorLoc; - protected int inDirWidthLoc; - - public LineShader(PApplet parent) { - super(parent); - } - - public LineShader(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public LineShader(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadAttributes() { - inVertexLoc = getAttribLocation("inVertex"); - inColorLoc = getAttribLocation("inColor"); - inDirWidthLoc = getAttribLocation("inDirWidth"); - } - - public void loadUniforms() { - projectionMatrixLoc = getUniformLocation("projectionMatrix"); - modelviewMatrixLoc = getUniformLocation("modelviewMatrix"); - - viewportLoc = getUniformLocation("viewport"); - perspectiveLoc = getUniformLocation("perspective"); - } - - public void setAttribute(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, vboId); - pgl.glVertexAttribPointer(loc, size, type, normalized, stride, offset); - } - - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); - } - - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inColorLoc, vboId, size, type, true, stride, offset); - } - - public void setDirWidthAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inDirWidthLoc, vboId, size, type, false, stride, offset); - } - - public void start() { - super.start(); - - if (-1 < inVertexLoc) pgl.glEnableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glEnableVertexAttribArray(inColorLoc); - if (-1 < inDirWidthLoc) pgl.glEnableVertexAttribArray(inDirWidthLoc); - - updateGLProjection(); - set4x4MatUniform(projectionMatrixLoc, glProjection); - - updateGLModelview(); - set4x4MatUniform(modelviewMatrixLoc, glModelview); - - set4FloatUniform(viewportLoc, viewport.get(0), viewport.get(1), viewport.get(2), viewport.get(3)); - - if (hints[ENABLE_PERSPECTIVE_CORRECTED_LINES]) { - setIntUniform(perspectiveLoc, 1); - } else { - setIntUniform(perspectiveLoc, 0); - } - } - - public void stop() { - if (-1 < inVertexLoc) pgl.glDisableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glDisableVertexAttribArray(inColorLoc); - if (-1 < inDirWidthLoc) pgl.glDisableVertexAttribArray(inDirWidthLoc); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - super.stop(); - } - } - - protected class PointShader extends PShader { - protected int projectionMatrixLoc; - protected int modelviewMatrixLoc; - - protected int inVertexLoc; - protected int inColorLoc; - protected int inSizeLoc; - - public PointShader(PApplet parent) { - super(parent); - } - - public PointShader(PApplet parent, String vertFilename, String fragFilename) { - super(parent, vertFilename, fragFilename); - } - - public PointShader(PApplet parent, URL vertURL, URL fragURL) { - super(parent, vertURL, fragURL); - } - - public void loadAttributes() { - inVertexLoc = getAttribLocation("inVertex"); - inColorLoc = getAttribLocation("inColor"); - inSizeLoc = getAttribLocation("inSize"); - } - - public void loadUniforms() { - projectionMatrixLoc = getUniformLocation("projectionMatrix"); - modelviewMatrixLoc = getUniformLocation("modelviewMatrix"); - } - - public void setAttribute(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, vboId); - pgl.glVertexAttribPointer(loc, size, type, normalized, stride, offset); - } - - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); - } - - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inColorLoc, vboId, size, type, true, stride, offset); - } - - public void setSizeAttribute(int vboId, int size, int type, int stride, int offset) { - setAttribute(inSizeLoc, vboId, size, type, false, stride, offset); - } - - public void start() { - super.start(); - - if (-1 < inVertexLoc) pgl.glEnableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glEnableVertexAttribArray(inColorLoc); - if (-1 < inSizeLoc) pgl.glEnableVertexAttribArray(inSizeLoc); - - updateGLProjection(); - set4x4MatUniform(projectionMatrixLoc, glProjection); - - updateGLModelview(); - set4x4MatUniform(modelviewMatrixLoc, glModelview); - } - - public void stop() { - if (-1 < inVertexLoc) pgl.glDisableVertexAttribArray(inVertexLoc); - if (-1 < inColorLoc) pgl.glDisableVertexAttribArray(inColorLoc); - if (-1 < inSizeLoc) pgl.glDisableVertexAttribArray(inSizeLoc); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - super.stop(); - } - } - - ////////////////////////////////////////////////////////////// - - // Input (raw) and Tessellated geometry, tessellator. - - public InGeometry newInGeometry(int mode) { - return new InGeometry(mode); - } - - protected TessGeometry newTessGeometry(int mode) { - return new TessGeometry(mode); - } - - protected TexCache newTexCache() { - return new TexCache(); - } - - // Holds an array of textures and the range of vertex - // indices each texture applies to. - public class TexCache { - protected int count; - protected PImage[] textures; - protected int[] firstIndex; - protected int[] lastIndex; - protected boolean hasTexture; - protected PTexture tex0; - - public TexCache() { - allocate(); - } - - public void allocate() { - textures = new PImage[PGL.DEFAULT_IN_TEXTURES]; - firstIndex = new int[PGL.DEFAULT_IN_TEXTURES]; - lastIndex = new int[PGL.DEFAULT_IN_TEXTURES]; - count = 0; - hasTexture = false; - } - - public void clear() { - java.util.Arrays.fill(textures, 0, count, null); - count = 0; - hasTexture = false; - } - - public void dispose() { - textures = null; - firstIndex = null; - lastIndex = null; - } - - public void beginRender() { - tex0 = null; - } - - public PTexture getTexture(int i) { - PImage img = textures[i]; - PTexture tex = null; - - if (img != null) { - tex = pg.getTexture(img); - if (tex != null) { - tex.bind(); - tex0 = tex; - } - } - if (tex == null && tex0 != null) { - tex0.unbind(); - pgl.disableTexturing(tex0.glTarget); - } - - return tex; - } - - public void endRender() { - if (hasTexture) { - // Unbinding all the textures in the cache. - for (int i = 0; i < count; i++) { - PImage img = textures[i]; - if (img != null) { - PTexture tex = pg.getTexture(img); - if (tex != null) { - tex.unbind(); - } - } - } - // Disabling texturing for each of the targets used - // by textures in the cache. - for (int i = 0; i < count; i++) { - PImage img = textures[i]; - if (img != null) { - PTexture tex = pg.getTexture(img); - if (tex != null) { - pgl.disableTexturing(tex.glTarget); - } - } - } - } - } - - public void addTexture(PImage img, int first, int last) { - textureCheck(); - - textures[count] = img; - firstIndex[count] = first; - lastIndex[count] = last; - - // At least one non-null texture since last reset. - hasTexture |= img != null; - - count++; - } - - public void setLastIndex(int last) { - lastIndex[count - 1] = last; - } - - public void textureCheck() { - if (count == textures.length) { - int newSize = count << 1; - - expandTextures(newSize); - expandFirstIndex(newSize); - expandLastIndex(newSize); - } - } - - public void expandTextures(int n) { - PImage[] temp = new PImage[n]; - PApplet.arrayCopy(textures, 0, temp, 0, count); - textures = temp; - } - - public void expandFirstIndex(int n) { - int[] temp = new int[n]; - PApplet.arrayCopy(firstIndex, 0, temp, 0, count); - firstIndex = temp; - } - - public void expandLastIndex(int n) { - int[] temp = new int[n]; - PApplet.arrayCopy(lastIndex, 0, temp, 0, count); - lastIndex = temp; - } - } - - // Holds the input vertices: xyz coordinates, fill/tint color, - // normal, texture coordinates and stroke color and weight. - public class InGeometry { - int renderMode; - public int vertexCount; - public int edgeCount; - - // Range of vertices that will be processed by the - // tessellator. They can be used in combination with the - // edges array to have the tessellator using only a specific - // range of vertices to generate fill geometry, while the - // line geometry will be read from the edge vertices, which - // could be completely different. - public int firstVertex; - public int lastVertex; - - public int firstEdge; - public int lastEdge; - - public int[] codes; - public float[] vertices; - public int[] colors; - public float[] normals; - public float[] texcoords; - public int[] scolors; - public float[] sweights; - - // Material properties - public int[] ambient; - public int[] specular; - public int[] emissive; - public float[] shininess; - - public int[][] edges; - - // For later, to be used by libraries... - //public float[][] mtexcoords; - //public float[][] attributes; - - public InGeometry(int mode) { - renderMode = mode; - allocate(); - } - - public void clear() { - vertexCount = firstVertex = lastVertex = 0; - edgeCount = firstEdge = lastEdge = 0; - } - - public void allocate() { - codes = new int[PGL.DEFAULT_IN_VERTICES]; - vertices = new float[3 * PGL.DEFAULT_IN_VERTICES]; - colors = new int[PGL.DEFAULT_IN_VERTICES]; - normals = new float[3 * PGL.DEFAULT_IN_VERTICES]; - texcoords = new float[2 * PGL.DEFAULT_IN_VERTICES]; - scolors = new int[PGL.DEFAULT_IN_VERTICES]; - sweights = new float[PGL.DEFAULT_IN_VERTICES]; - ambient = new int[PGL.DEFAULT_IN_VERTICES]; - specular = new int[PGL.DEFAULT_IN_VERTICES]; - emissive = new int[PGL.DEFAULT_IN_VERTICES]; - shininess = new float[PGL.DEFAULT_IN_VERTICES]; - edges = new int[PGL.DEFAULT_IN_EDGES][3]; - clear(); - } - - public void trim() { - if (0 < vertexCount && vertexCount < vertices.length / 3) { - trimVertices(); - trimColors(); - trimNormals(); - trimTexcoords(); - trimStrokeColors(); - trimStrokeWeights(); - trimAmbient(); - trimSpecular(); - trimEmissive(); - trimShininess(); - } - - if (0 < edgeCount && edgeCount < edges.length) { - trimEdges(); - } - } - - public void dispose() { - codes = null; - vertices = null; - colors = null; - normals = null; - texcoords = null; - scolors = null; - scolors = null; - ambient = null; - specular = null; - emissive = null; - shininess = null; - edges = null; - } - - public float getVertexX(int idx) { - return vertices[3 * idx + 0]; - } - - public float getVertexY(int idx) { - return vertices[3 * idx + 1]; - } - - public float getVertexZ(int idx) { - return vertices[3 * idx + 2]; - } - - public float getLastVertexX() { - return vertices[3 * (vertexCount - 1) + 0]; - } - - public float getLastVertexY() { - return vertices[3 * (vertexCount - 1) + 1]; - } - - public float getLastVertexZ() { - return vertices[3 * (vertexCount - 1) + 2]; - } - - public boolean isFull() { - return PGL.MAX_TESS_VERTICES <= vertexCount; - } - - - public int addVertex(float x, float y, - int fcolor, - float u, float v, - int scolor, float sweight, - int am, int sp, int em, float shine, - int code) { - return addVertex(x, y, 0, - fcolor, - 0, 0, 1, - u, v, - scolor, sweight, - am, sp, em, shine, - code); - } - - public int addVertex(float x, float y, - int fcolor, - int scolor, float sweight, - int am, int sp, int em, float shine, - int code) { - return addVertex(x, y, 0, - fcolor, - 0, 0, 1, - 0, 0, - scolor, sweight, - am, sp, em, shine, - code); - } - - public int addVertex(float x, float y, float z, - int fcolor, - float nx, float ny, float nz, - float u, float v, - int scolor, float sweight, - int am, int sp, int em, float shine, - int code) { - vertexCheck(); - int index; - - codes[vertexCount] = code; - - index = 3 * vertexCount; - vertices[index++] = x; - vertices[index++] = y; - vertices[index ] = z; - - colors[vertexCount] = javaToNativeARGB(fcolor); - - index = 3 * vertexCount; - normals[index++] = nx; - normals[index++] = ny; - normals[index ] = nz; - - index = 2 * vertexCount; - texcoords[index++] = u; - texcoords[index ] = v; - - scolors[vertexCount] = javaToNativeARGB(scolor); - sweights[vertexCount] = sweight; - - ambient[vertexCount] = javaToNativeARGB(am); - specular[vertexCount] = javaToNativeARGB(sp); - emissive[vertexCount] = javaToNativeARGB(em); - shininess[vertexCount] = shine; - - lastVertex = vertexCount; - vertexCount++; - - return lastVertex; - } - - public int javaToNativeARGB(int color) { - if (BIG_ENDIAN) { - return ((color >> 24) & 0xff) | ((color << 8) & 0xffffff00); - } else { - return (color & 0xff000000) - | ((color << 16) & 0xff0000) | (color & 0xff00) - | ((color >> 16) & 0xff); - } - } - - public void vertexCheck() { - if (vertexCount == vertices.length / 3) { - int newSize = vertexCount << 1; - - expandCodes(newSize); - expandVertices(newSize); - expandColors(newSize); - expandNormals(newSize); - expandTexcoords(newSize); - expandStrokeColors(newSize); - expandStrokeWeights(newSize); - expandAmbient(newSize); - expandSpecular(newSize); - expandEmissive(newSize); - expandShininess(newSize); - } - } - - public void calcTriangleNormal(int i0, int i1, int i2) { - int index; - - index = 3 * i0; - float x0 = vertices[index++]; - float y0 = vertices[index++]; - float z0 = vertices[index ]; - - index = 3 * i1; - float x1 = vertices[index++]; - float y1 = vertices[index++]; - float z1 = vertices[index ]; - - index = 3 * i2; - float x2 = vertices[index++]; - float y2 = vertices[index++]; - float z2 = vertices[index ]; - - float v12x = x2 - x1; - float v12y = y2 - y1; - float v12z = z2 - z1; - - float v10x = x0 - x1; - float v10y = y0 - y1; - float v10z = z0 - z1; - - // n = v10 x v12 (so the normal points out following the - // clockwise direction along the vertices of the triangle). - float nx = v10y * v12z - v12y * v10z; - float ny = v10z * v12x - v12z * v10x; - float nz = v10x * v12y - v12x * v10y; - float d = PApplet.sqrt(nx * nx + ny * ny + nz * nz); - nx /= d; - ny /= d; - nz /= d; - - index = 3 * i0; - normals[index++] = nx; - normals[index++] = ny; - normals[index ] = nz; - - index = 3 * i1; - normals[index++] = nx; - normals[index++] = ny; - normals[index ] = nz; - - index = 3 * i2; - normals[index++] = nx; - normals[index++] = ny; - normals[index ] = nz; - } - - public int addEdge(int i, int j, boolean start, boolean end) { - edgeCheck(); - - int[] edge = edges[edgeCount]; - edge[0] = i; - edge[1] = j; - - // Possible values for state: - // 0 = middle edge (not start, not end) - // 1 = start edge (start, not end) - // 2 = end edge (not start, end) - // 3 = isolated edge (start, end) - edge[2] = (start ? 1 : 0) + 2 * (end ? 1 : 0); - - lastEdge = edgeCount; - edgeCount++; - - return lastEdge; - } - - public void edgeCheck() { - if (edgeCount == edges.length) { - int newLen = edgeCount << 1; - - int temp[][] = new int[newLen][3]; - PApplet.arrayCopy(edges, 0, temp, 0, edgeCount); - edges = temp; - } - } - - protected void expandCodes(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(codes, 0, temp, 0, vertexCount); - codes = temp; - } - - protected void expandVertices(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(vertices, 0, temp, 0, 3 * vertexCount); - vertices = temp; - } - - protected void expandColors(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(colors, 0, temp, 0, vertexCount); - colors = temp; - } - - protected void expandNormals(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(normals, 0, temp, 0, 3 * vertexCount); - normals = temp; - } - - protected void expandTexcoords(int n) { - float temp[] = new float[2 * n]; - PApplet.arrayCopy(texcoords, 0, temp, 0, 2 * vertexCount); - texcoords = temp; - } - - protected void expandStrokeColors(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(scolors, 0, temp, 0, vertexCount); - scolors = temp; - } - - protected void expandStrokeWeights(int n) { - float temp[] = new float[n]; - PApplet.arrayCopy(sweights, 0, temp, 0, vertexCount); - sweights = temp; - } - - protected void expandAmbient(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(ambient, 0, temp, 0, vertexCount); - ambient = temp; - } - - protected void expandSpecular(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(specular, 0, temp, 0, vertexCount); - specular = temp; - } - - protected void expandEmissive(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(emissive, 0, temp, 0, vertexCount); - emissive = temp; - } - - protected void expandShininess(int n) { - float temp[] = new float[n]; - PApplet.arrayCopy(shininess, 0, temp, 0, vertexCount); - shininess = temp; - } - - protected void trimVertices() { - float temp[] = new float[3 * vertexCount]; - PApplet.arrayCopy(vertices, 0, temp, 0, 3 * vertexCount); - vertices = temp; - } - - protected void trimColors() { - int temp[] = new int[vertexCount]; - PApplet.arrayCopy(colors, 0, temp, 0, vertexCount); - colors = temp; - } - - protected void trimNormals() { - float temp[] = new float[3 * vertexCount]; - PApplet.arrayCopy(normals, 0, temp, 0, 3 * vertexCount); - normals = temp; - } - - protected void trimTexcoords() { - float temp[] = new float[2 * vertexCount]; - PApplet.arrayCopy(texcoords, 0, temp, 0, 2 * vertexCount); - texcoords = temp; - } - - protected void trimStrokeColors() { - int temp[] = new int[vertexCount]; - PApplet.arrayCopy(scolors, 0, temp, 0, vertexCount); - scolors = temp; - } - - protected void trimStrokeWeights() { - float temp[] = new float[vertexCount]; - PApplet.arrayCopy(sweights, 0, temp, 0, vertexCount); - sweights = temp; - } - - protected void trimAmbient() { - int temp[] = new int[vertexCount]; - PApplet.arrayCopy(ambient, 0, temp, 0, vertexCount); - ambient = temp; - } - - protected void trimSpecular() { - int temp[] = new int[vertexCount]; - PApplet.arrayCopy(specular, 0, temp, 0, vertexCount); - specular = temp; - } - - protected void trimEmissive() { - int temp[] = new int[vertexCount]; - PApplet.arrayCopy(emissive, 0, temp, 0, vertexCount); - emissive = temp; - } - - protected void trimShininess() { - float temp[] = new float[vertexCount]; - PApplet.arrayCopy(shininess, 0, temp, 0, vertexCount); - shininess = temp; - } - - protected void trimEdges() { - int temp[][] = new int[edgeCount][3]; - PApplet.arrayCopy(edges, 0, temp, 0, edgeCount); - edges = temp; - } - - public int getNumLineVertices() { - return 4 *(lastEdge - firstEdge + 1); - } - - public int getNumLineIndices() { - return 6 *(lastEdge - firstEdge + 1); - } - - public void calcTrianglesNormals() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 3; i++) { - int i0 = 3 * i + 0; - int i1 = 3 * i + 1; - int i2 = 3 * i + 2; - - calcTriangleNormal(i0, i1, i2); - } - } - - public void addTrianglesEdges() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 3; i++) { - int i0 = 3 * i + 0; - int i1 = 3 * i + 1; - int i2 = 3 * i + 2; - - addEdge(i0, i1, true, false); - addEdge(i1, i2, false, false); - addEdge(i2, i0, false, true); - } - } - - public void calcTriangleFanNormals() { - for (int i = firstVertex + 1; i < lastVertex; i++) { - int i0 = firstVertex; - int i1 = i; - int i2 = i + 1; - - calcTriangleNormal(i0, i1, i2); - } - } - - public void addTriangleFanEdges() { - for (int i = firstVertex + 1; i < lastVertex; i++) { - int i0 = firstVertex; - int i1 = i; - int i2 = i + 1; - - addEdge(i0, i1, true, false); - addEdge(i1, i2, false, false); - addEdge(i2, i0, false, true); - } - } - - public void calcTriangleStripNormals() { - for (int i = firstVertex + 1; i < lastVertex; i++) { - int i1 = i; - int i0, i2; - if (i % 2 == 0) { - i0 = i + 1; - i2 = i - 1; - } else { - i0 = i - 1; - i2 = i + 1; - } - calcTriangleNormal(i0, i1, i2); - } - } - - public void addTriangleStripEdges() { - for (int i = firstVertex + 1; i < lastVertex; i++) { - int i0 = i; - int i1, i2; - if (i % 2 == 0) { - i1 = i - 1; - i2 = i + 1; - } else { - i1 = i + 1; - i2 = i - 1; - } - - addEdge(i0, i1, true, false); - addEdge(i1, i2, false, false); - addEdge(i2, i0, false, true); - } - } - - public void calcQuadsNormals() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 4; i++) { - int i0 = 4 * i + 0; - int i1 = 4 * i + 1; - int i2 = 4 * i + 2; - int i3 = 4 * i + 3; - - calcTriangleNormal(i0, i1, i2); - calcTriangleNormal(i2, i3, i0); - } - } - - public void addQuadsEdges() { - for (int i = 0; i < (lastVertex - firstVertex + 1) / 4; i++) { - int i0 = 4 * i + 0; - int i1 = 4 * i + 1; - int i2 = 4 * i + 2; - int i3 = 4 * i + 3; - - addEdge(i0, i1, true, false); - addEdge(i1, i2, false, false); - addEdge(i2, i3, false, false); - addEdge(i3, i0, false, true); - } - } - - public void calcQuadStripNormals() { - for (int qd = 1; qd < (lastVertex - firstVertex + 1) / 2; qd++) { - int i0 = firstVertex + 2 * (qd - 1); - int i1 = firstVertex + 2 * (qd - 1) + 1; - int i2 = firstVertex + 2 * qd + 1; - int i3 = firstVertex + 2 * qd; - - calcTriangleNormal(i0, i1, i3); - calcTriangleNormal(i3, i2, i0); - } - } - - public void addQuadStripEdges() { - for (int qd = 1; qd < (lastVertex - firstVertex + 1) / 2; qd++) { - int i0 = firstVertex + 2 * (qd - 1); - int i1 = firstVertex + 2 * (qd - 1) + 1; - int i2 = firstVertex + 2 * qd + 1; - int i3 = firstVertex + 2 * qd; - - addEdge(i0, i1, true, false); - addEdge(i1, i2, false, false); - addEdge(i2, i3, false, false); - addEdge(i3, i0, false, true); - } - } - - public void addPolygonEdges(boolean closed) { - // Count number of edge segments in the perimeter. - int edgeCount = 0; - int lnMax = lastVertex - firstVertex + 1; - int first = firstVertex; - int contour0 = first; - if (!closed) lnMax--; - for (int ln = 0; ln < lnMax; ln++) { - int i = first + ln + 1; - if ((i == lnMax || codes[i] == PShape.BREAK) && closed) { - i = first + ln; - } - if (codes[i] != PShape.BREAK) { - edgeCount++; - } - } - - if (0 < edgeCount) { - boolean begin = true; - contour0 = first; - for (int ln = 0; ln < lnMax; ln++) { - int i0 = first + ln; - int i1 = first + ln + 1; - if (codes[i0] == PShape.BREAK) contour0 = i0; - if (i1 == lnMax || codes[i1] == PShape.BREAK) { - // We are at the end of a contour. - if (closed) { - // Draw line to the first vertex of the current contour, - // if the polygon is closed. - i0 = first + ln; - i1 = contour0; - addEdge(i0, i1, begin, true); - } else if (codes[i1] != PShape.BREAK) { - addEdge(i0, i1, begin, false); - } - // We might start a new contour in the next iteration. - begin = true; - } else if (codes[i1] != PShape.BREAK) { - addEdge(i0, i1, begin, false); - } - } - } - } - - // Primitive generation - - public void generateEllipse(int ellipseMode, float a, float b, float c, float d, - boolean fill, int fillColor, - boolean stroke, int strokeColor, float strokeWeight, - int ambient, int specular, int emissive, float shininess) { - float x = a; - float y = b; - float w = c; - float h = d; - - if (ellipseMode == CORNERS) { - w = c - a; - h = d - b; - - } else if (ellipseMode == RADIUS) { - x = a - c; - y = b - d; - w = c * 2; - h = d * 2; - - } else if (ellipseMode == DIAMETER) { - x = a - c/2f; - y = b - d/2f; - } - - if (w < 0) { // undo negative width - x += w; - w = -w; - } - - if (h < 0) { // undo negative height - y += h; - h = -h; - } - - float radiusH = w / 2; - float radiusV = h / 2; - - float centerX = x + radiusH; - float centerY = y + radiusV; - - float sx1 = screenX(x, y); - float sy1 = screenY(x, y); - float sx2 = screenX(x + w, y + h); - float sy2 = screenY(x + w, y + h); - - int accuracy = (int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) / 20); - if (accuracy < 6) { - accuracy = 6; - } - float inc = (float) PGraphicsLWJGL.SINCOS_LENGTH / accuracy; - - if (fill) { - addVertex(centerX, centerY, - fillColor, strokeColor, strokeWeight, - ambient, specular, emissive, shininess, - VERTEX); - } - int idx0, pidx, idx; - idx0 = pidx = idx = 0; - float val = 0; - for (int i = 0; i < accuracy; i++) { - idx = addVertex(centerX + PGraphicsLWJGL.cosLUT[(int) val] * radiusH, - centerY + PGraphicsLWJGL.sinLUT[(int) val] * radiusV, - fillColor, strokeColor, strokeWeight, - ambient, specular, emissive, shininess, - VERTEX); - val = (val + inc) % PGraphicsLWJGL.SINCOS_LENGTH; - - if (0 < i) { - if (stroke) addEdge(pidx, idx, i == 1, false); - } else { - idx0 = idx; - } - - pidx = idx; - } - // Back to the beginning - addVertex(centerX + PGraphicsLWJGL.cosLUT[0] * radiusH, - centerY + PGraphicsLWJGL.sinLUT[0] * radiusV, - fillColor, strokeColor, strokeWeight, - ambient, specular, emissive, shininess, - VERTEX); - if (stroke) addEdge(idx, idx0, false, true); - } - - } - - // Holds tessellated data for fill, line and point geometry. - public class TessGeometry { - int renderMode; - - // Tessellated fill data - public int fillVertexCount; - public int firstFillVertex; - public int lastFillVertex; - public FloatBuffer fillVertices; - public IntBuffer fillColors; - public FloatBuffer fillNormals; - public FloatBuffer fillTexcoords; - - // Fill material properties (fillColor is used - // as the diffuse color when lighting is enabled) - public IntBuffer fillAmbient; - public IntBuffer fillSpecular; - public IntBuffer fillEmissive; - public FloatBuffer fillShininess; - - public int fillIndexCount; - public int firstFillIndex; - public int lastFillIndex; - public IntBuffer fillIndices; - - // Tessellated line data - public int lineVertexCount; - public int firstLineVertex; - public int lastLineVertex; - public FloatBuffer lineVertices; - public IntBuffer lineColors; - public FloatBuffer lineDirWidths; - - public int lineIndexCount; - public int firstLineIndex; - public int lastLineIndex; - public IntBuffer lineIndices; - - // Tessellated point data - public int pointVertexCount; - public int firstPointVertex; - public int lastPointVertex; - public FloatBuffer pointVertices; - public IntBuffer pointColors; - public FloatBuffer pointSizes; - - public int pointIndexCount; - public int firstPointIndex; - public int lastPointIndex; - public IntBuffer pointIndices; - - public boolean isStroked; - - public TessGeometry(int mode) { - renderMode = mode; - allocate(); - } - - public void clear() { - firstFillVertex = lastFillVertex = fillVertexCount = 0; - firstFillIndex = lastFillIndex = fillIndexCount = 0; - - firstLineVertex = lastLineVertex = lineVertexCount = 0; - firstLineIndex = lastLineIndex = lineIndexCount = 0; - - firstPointVertex = lastPointVertex = pointVertexCount = 0; - firstPointIndex = lastPointIndex = pointIndexCount = 0; - - fillVertices.clear(); - fillColors.clear(); - fillNormals.clear(); - fillTexcoords.clear(); - fillAmbient.clear(); - fillSpecular.clear(); - fillEmissive.clear(); - fillShininess.clear(); - fillIndices.clear(); - - lineVertices.clear(); - lineColors.clear(); - lineDirWidths.clear(); - lineIndices.clear(); - - pointVertices.clear(); - pointColors.clear(); - pointSizes.clear(); - pointIndices.clear(); - - isStroked = false; - } - - public void allocate() { - fillVertices = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); - fillColors = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - fillNormals = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); - fillTexcoords = pgl.createFloatBuffer(2 * PGL.DEFAULT_TESS_VERTICES); - fillAmbient = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - fillSpecular = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - fillEmissive = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - fillShininess = pgl.createFloatBuffer(PGL.DEFAULT_TESS_VERTICES); - fillIndices = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - - lineVertices = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); - lineColors = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - lineDirWidths = pgl.createFloatBuffer(4 * PGL.DEFAULT_TESS_VERTICES); - lineIndices = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - - pointVertices = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); - pointColors = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - pointSizes = pgl.createFloatBuffer(2 * PGL.DEFAULT_TESS_VERTICES); - pointIndices = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - - clear(); - } - - public void trim() { - if (0 < fillVertexCount && fillVertexCount < fillVertices.capacity() / 3) { - prepareFillVerticesForCopy(); - trimFillVertices(); - trimFillColors(); - trimFillNormals(); - trimFillTexcoords(); - trimFillAmbient(); - trimFillSpecular(); - trimFillEmissive(); - trimFillShininess(); - } - - if (0 < fillIndexCount && fillIndexCount < fillIndices.capacity()) { - prepareFillIndicesForCopy(); - trimFillIndices(); - } - - if (0 < lineVertexCount && lineVertexCount < lineVertices.capacity() / 3) { - prepareLineVerticesForCopy(); - trimLineVertices(); - trimLineColors(); - trimLineAttributes(); - } - - if (0 < lineIndexCount && lineIndexCount < lineIndices.capacity()) { - prepareLineIndicesForCopy(); - trimLineIndices(); - } - - if (0 < pointVertexCount && pointVertexCount < pointVertices.capacity() / 3) { - preparePointVerticesForCopy(); - trimPointVertices(); - trimPointColors(); - trimPointAttributes(); - } - - if (0 < pointIndexCount && pointIndexCount < pointIndices.capacity()) { - preparePointIndicesForCopy(); - trimPointIndices(); - } - } - - protected void trimFillVertices() { - FloatBuffer temp = pgl.createFloatBuffer(3 * fillVertexCount); - temp.put(fillVertices); - fillVertices = temp; - } - - protected void trimFillColors() { - IntBuffer temp = pgl.createIntBuffer(fillVertexCount); - temp.put(fillColors); - fillColors = temp; - } - - protected void trimFillNormals() { - FloatBuffer temp = pgl.createFloatBuffer(3 * fillVertexCount); - temp.put(fillNormals); - fillNormals = temp; - } - - protected void trimFillTexcoords() { - FloatBuffer temp = pgl.createFloatBuffer(2 * fillVertexCount); - temp.put(fillTexcoords); - fillTexcoords = temp; - } - - protected void trimFillAmbient() { - IntBuffer temp = pgl.createIntBuffer(fillVertexCount); - temp.put(fillAmbient); - fillAmbient = temp; - } - - protected void trimFillSpecular() { - IntBuffer temp = pgl.createIntBuffer(fillVertexCount); - temp.put(fillSpecular); - fillSpecular = temp; - } - - protected void trimFillEmissive() { - IntBuffer temp = pgl.createIntBuffer(fillVertexCount); - temp.put(fillEmissive); - fillEmissive = temp; - } - - protected void trimFillShininess() { - FloatBuffer temp = pgl.createFloatBuffer(fillVertexCount); - temp.put(fillShininess); - fillShininess = temp; - } - - public void trimFillIndices() { - IntBuffer temp = pgl.createIntBuffer(fillIndexCount); - temp.put(fillIndices); - fillIndices = temp; - } - - protected void trimLineVertices() { - FloatBuffer temp = pgl.createFloatBuffer(3 * lineVertexCount); - temp.put(lineVertices); - lineVertices = temp; - } - - protected void trimLineColors() { - IntBuffer temp = pgl.createIntBuffer(lineVertexCount); - temp.put(lineColors); - lineColors = temp; - } - - protected void trimLineAttributes() { - FloatBuffer temp = pgl.createFloatBuffer(4 * lineVertexCount); - temp.put(lineDirWidths); - lineDirWidths = temp; - } - - protected void trimLineIndices() { - IntBuffer temp = pgl.createIntBuffer(lineIndexCount); - temp.put(lineIndices); - lineIndices = temp; - } - - protected void trimPointVertices() { - FloatBuffer temp = pgl.createFloatBuffer(3 * pointVertexCount); - temp.put(pointVertices); - pointVertices = temp; - } - - protected void trimPointColors() { - IntBuffer temp = pgl.createIntBuffer(pointVertexCount); - temp.put(pointColors); - pointColors = temp; - } - - protected void trimPointAttributes() { - FloatBuffer temp = pgl.createFloatBuffer(2 * pointVertexCount); - temp.put(pointSizes); - pointSizes = temp; - } - - protected void trimPointIndices() { - IntBuffer temp = pgl.createIntBuffer(pointIndexCount); - temp.put(pointIndices); - pointIndices = temp; - } - - public void dipose() { - fillVertices = null; - fillColors = null; - fillNormals = null; - fillTexcoords = null; - fillAmbient = null; - fillSpecular = null; - fillEmissive = null; - fillShininess = null; - fillIndices = null; - - lineVertices = null; - lineColors = null; - lineDirWidths = null; - lineIndices = null; - - pointVertices = null; - pointColors = null; - pointSizes = null; - pointIndices = null; - } - - public boolean isFull() { - return PGL.MAX_TESS_VERTICES <= fillVertexCount || - PGL.MAX_TESS_VERTICES <= lineVertexCount || - PGL.MAX_TESS_VERTICES <= pointVertexCount || - PGL.MAX_TESS_INDICES <= fillIndexCount || - PGL.MAX_TESS_INDICES <= fillIndexCount || - PGL.MAX_TESS_INDICES <= fillIndexCount; - } - - public boolean isOverflow() { - return PGL.MAX_TESS_VERTICES < fillVertexCount || - PGL.MAX_TESS_VERTICES < lineVertexCount || - PGL.MAX_TESS_VERTICES < pointVertexCount || - PGL.MAX_TESS_INDICES < fillIndexCount || - PGL.MAX_TESS_INDICES < fillIndexCount || - PGL.MAX_TESS_INDICES < fillIndexCount; - } - - public void addCounts(TessGeometry other) { - fillVertexCount += other.fillVertexCount; - fillIndexCount += other.fillIndexCount; - - lineVertexCount += other.lineVertexCount; - lineIndexCount += other.lineIndexCount; - - pointVertexCount += other.pointVertexCount; - pointIndexCount += other.pointIndexCount; - } - - public void setFirstFill(TessGeometry other) { - firstFillVertex = other.firstFillVertex; - firstFillIndex = other.firstFillIndex; - } - - public void setLastFill(TessGeometry other) { - lastFillVertex = other.lastFillVertex; - lastFillIndex = other.lastFillIndex; - } - - public void setFirstLine(TessGeometry other) { - firstLineVertex = other.firstLineVertex; - firstLineIndex = other.firstLineIndex; - } - - public void setLastLine(TessGeometry other) { - lastLineVertex = other.lastLineVertex; - lastLineIndex = other.lastLineIndex; - } - - public void setFirstPoint(TessGeometry other) { - firstPointVertex = other.firstPointVertex; - firstPointIndex = other.firstPointIndex; - } - - public void setLastPoint(TessGeometry other) { - lastPointVertex = other.lastPointVertex; - lastPointIndex = other.lastPointIndex; - } - - public int setFillVertex(int offset) { - firstFillVertex = 0; - if (0 < offset) { - firstFillVertex = offset + 1; - } - lastFillVertex = firstFillVertex + fillVertexCount - 1; - return lastFillVertex; - } - - public int setFillIndex(int voffset, int ioffset) { - firstFillIndex = 0; - if (0 < ioffset) { - firstFillIndex = ioffset + 1; - } - - if (0 < voffset) { - // The indices are update to take into account all the previous - // shapes in the hierarchy, as the entire geometry will be stored - // contiguously in a single VBO in the root node. - for (int i = 0; i < fillIndexCount; i++) { - fillIndices.position(i); - fillIndices.put(fillIndices.get(i) + voffset); - } - } - - lastFillIndex = firstFillIndex + fillIndexCount - 1; - return lastFillIndex; - } - - public int setLineVertex(int offset) { - firstLineVertex = 0; - if (0 < offset) { - firstLineVertex = offset + 1; - } - lastLineVertex = firstLineVertex + lineVertexCount - 1; - return lastLineVertex; - } - - public int setLineIndex(int voffset, int ioffset) { - firstLineIndex = 0; - if (0 < ioffset) { - firstLineIndex = ioffset + 1; - } - - if (0 < voffset) { - // The indices are update to take into account all the previous - // shapes in the hierarchy, as the entire geometry will be stored - // contiguously in a single VBO in the root node. - for (int i = 0; i < lineIndexCount; i++) { - lineIndices.position(i); - lineIndices.put(lineIndices.get(i) + voffset); - } - } - - lastLineIndex = firstLineIndex + lineIndexCount - 1; - return lastLineIndex; - } - - public int setPointVertex(int offset) { - firstPointVertex = 0; - if (0 < offset) { - firstPointVertex = offset + 1; - } - lastPointVertex = firstPointVertex + pointVertexCount - 1; - return lastPointVertex; - } - - public int setPointIndex(int voffset, int ioffset) { - firstPointIndex = 0; - if (0 < ioffset) { - firstPointIndex = ioffset + 1; - } - - if (0 < voffset) { - // The indices are update to take into account all the previous - // shapes in the hierarchy, as the entire geometry will be stored - // contiguously in a single VBO in the root node. - for (int i = 0; i < pointIndexCount; i++) { - pointIndices.position(i); - pointIndices.put(pointIndices.get(i) + voffset); - } - } - - lastPointIndex = firstPointIndex + pointIndexCount - 1; - return lastPointIndex; - } - - public void fillIndexCheck() { - if (fillIndexCount == fillIndices.capacity()) { - int newSize = fillIndexCount << 1; - expandFillIndices(newSize); - } - } - - public void expandFillIndices(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(fillIndices); - fillIndices = temp; - } - - public void addFillIndex(int idx) { - fillIndexCheck(); - fillIndices.put(fillIndexCount, PGL.makeIndex(idx)); - fillIndexCount++; - lastFillIndex = fillIndexCount - 1; - } - - public void calcFillNormal(int i0, int i1, int i2) { - float[] v0 = new float[3]; - float[] v1 = new float[3]; - float[] v2 = new float[3]; - float[] normal = new float[3]; - - fillVertices.position(3 * i0); - fillVertices.get(v0); - - fillVertices.position(3 * i1); - fillVertices.get(v1); - - fillVertices.position(3 * i2); - fillVertices.get(v2); - - float v12x = v2[0] - v1[0]; - float v12y = v2[1] - v1[1]; - float v12z = v2[2] - v1[2]; - - float v10x = v0[0] - v1[0]; - float v10y = v0[1] - v1[1]; - float v10z = v0[2] - v1[2]; - - normal[0] = v12y * v10z - v10y * v12z; - normal[1] = v12z * v10x - v10z * v12x; - normal[2] = v12x * v10y - v10x * v12y; - float d = PApplet.sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]); - normal[0] /= d; - normal[1] /= d; - normal[2] /= d; - - fillNormals.position(3 * i0); - fillNormals.put(normal); - - fillNormals.position(3 * i1); - fillNormals.put(normal); - - fillNormals.position(3 * i2); - fillNormals.put(normal); - } - - public void fillVertexCheck() { - if (fillVertexCount == fillVertices.capacity() / 3) { - int newSize = fillVertexCount << 1; - prepareFillVerticesForCopy(); - expandFillVertices(newSize); - expandFillColors(newSize); - expandFillNormals(newSize); - expandFillTexcoords(newSize); - expandFillAmbient(newSize); - expandFillSpecular(newSize); - expandFillEmissive(newSize); - expandFillShininess(newSize); - } - } - - public void addFillVertices(int count) { - int oldSize = fillVertices.capacity() / 3; - if (fillVertexCount + count > oldSize) { - int newSize = expandVertSize(oldSize, fillVertexCount + count); - prepareFillVerticesForCopy(); - expandFillVertices(newSize); - expandFillColors(newSize); - expandFillNormals(newSize); - expandFillTexcoords(newSize); - expandFillAmbient(newSize); - expandFillSpecular(newSize); - expandFillEmissive(newSize); - expandFillShininess(newSize); - } - - firstFillVertex = fillVertexCount; - fillVertexCount += count; - lastFillVertex = fillVertexCount - 1; - } - - public void addFillIndices(int count) { - int oldSize = fillIndices.capacity(); - if (fillIndexCount + count > oldSize) { - int newSize = expandIndSize(oldSize, fillIndexCount + count); - prepareFillIndicesForCopy(); - expandFillIndices(newSize); - } - - firstFillIndex = fillIndexCount; - fillIndexCount += count; - lastFillIndex = fillIndexCount - 1; - } - - protected void prepareFillVerticesForCopy() { - prepareFillVerticesForCopy(0, fillVertexCount); - } - - protected void prepareFillIndicesForCopy() { - prepareFillIndicesForCopy(0, fillIndexCount); - } - - protected void prepareFillVerticesForCopy(int start, int count) { - fillVertices.position(3 * start); - fillVertices.limit(3 * count); - - fillColors.position(start); - fillColors.limit(count); - - fillNormals.position(3 * start); - fillNormals.limit(3 * count); - - fillTexcoords.position(2 * start); - fillTexcoords.limit(2 * count); - - fillAmbient.position(start); - fillAmbient.limit(count); - - fillSpecular.position(start); - fillSpecular.limit(count); - - fillEmissive.position(start); - fillEmissive.limit(count); - - fillShininess.position(start); - fillShininess.limit(count); - } - - protected void prepareFillIndicesForCopy(int start, int count) { - fillIndices.position(start); - fillIndices.limit(count); - } - - protected void prepareLineVerticesForCopy() { - prepareLineVerticesForCopy(0, lineVertexCount); - } - - protected void prepareLineIndicesForCopy() { - prepareLineIndicesForCopy(0, lineIndexCount); - } - - protected void prepareLineVerticesForCopy(int start, int count) { - lineVertices.position(3 * start); - lineVertices.limit(3 * count); - - lineColors.position(start); - lineColors.limit(count); - - lineDirWidths.position(4 * start); - lineDirWidths.limit(4 * count); - } - - protected void prepareLineIndicesForCopy(int start, int count) { - lineIndices.position(start); - lineIndices.limit(count); - } - - protected void preparePointVerticesForCopy() { - preparePointVerticesForCopy(0, pointVertexCount); - } - - protected void preparePointIndicesForCopy() { - preparePointIndicesForCopy(0, pointIndexCount); - } - - protected void preparePointVerticesForCopy(int start, int count) { - pointVertices.position(3 * start); - pointVertices.limit(3 * count); - - pointColors.position(start); - pointColors.limit(count); - - pointSizes.position(2 * start); - pointSizes.limit(2 * count); - } - - protected void preparePointIndicesForCopy(int start, int count) { - pointIndices.position(start); - pointIndices.limit(count); - } - - - protected void expandFillVertices(int n) { - FloatBuffer temp = pgl.createFloatBuffer(3 * n); - temp.put(fillVertices); - fillVertices = temp; - } - - protected void expandFillColors(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(fillColors); - fillColors = temp; - } - - protected void expandFillNormals(int n) { - FloatBuffer temp = pgl.createFloatBuffer(3 * n); - temp.put(fillNormals); - fillNormals = temp; - } - - protected void expandFillTexcoords(int n) { - FloatBuffer temp = pgl.createFloatBuffer(2 * n); - temp.put(fillTexcoords); - fillTexcoords = temp; - } - - protected void expandFillAmbient(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(fillAmbient); - fillAmbient = temp; - } - - protected void expandFillSpecular(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(fillSpecular); - fillSpecular = temp; - } - - protected void expandFillEmissive(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(fillEmissive); - fillEmissive = temp; - } - - protected void expandFillShininess(int n) { - FloatBuffer temp = pgl.createFloatBuffer(n); - temp.put(fillShininess); - fillShininess = temp; - } - - public void addLineVertices(int count) { - int oldSize = lineVertices.capacity() / 3; - if (lineVertexCount + count > oldSize) { - int newSize = expandVertSize(oldSize, lineVertexCount + count); - prepareLineVerticesForCopy(); - expandLineVertices(newSize); - expandLineColors(newSize); - expandLineAttributes(newSize); - } - - firstLineVertex = lineVertexCount; - lineVertexCount += count; - lastLineVertex = lineVertexCount - 1; - } - - protected void expandLineVertices(int n) { - FloatBuffer temp = pgl.createFloatBuffer(3 * n); - temp.put(lineVertices); - lineVertices = temp; - } - - protected void expandLineColors(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(lineColors); - lineColors = temp; - } - - protected void expandLineAttributes(int n) { - FloatBuffer temp = pgl.createFloatBuffer(4 * n); - temp.put(lineDirWidths); - lineDirWidths = temp; - } - - public void addLineIndices(int count) { - int oldSize = lineIndices.capacity(); - if (lineIndexCount + count > oldSize) { - int newSize = expandIndSize(oldSize, lineIndexCount + count); - prepareLineIndicesForCopy(); - expandLineIndices(newSize); - } - - firstLineIndex = lineIndexCount; - lineIndexCount += count; - lastLineIndex = lineIndexCount - 1; - } - - protected void expandLineIndices(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(lineIndices); - lineIndices = temp; - } - - public void addPointVertices(int count) { - int oldSize = pointVertices.capacity() / 3; - if (pointVertexCount + count > oldSize) { - int newSize = expandVertSize(oldSize, pointVertexCount + count); - preparePointVerticesForCopy(); - expandPointVertices(newSize); - expandPointColors(newSize); - expandPointAttributes(newSize); - } - - firstPointVertex = pointVertexCount; - pointVertexCount += count; - lastPointVertex = pointVertexCount - 1; - } - - protected void expandPointVertices(int n) { - FloatBuffer temp = pgl.createFloatBuffer(3 * n); - temp.put(pointVertices); - pointVertices = temp; - } - - protected void expandPointColors(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(pointColors); - pointColors = temp; - } - - protected void expandPointAttributes(int n) { - FloatBuffer temp = pgl.createFloatBuffer(2 * n); - temp.put(pointSizes); - pointSizes = temp; - } - - public void addPointIndices(int count) { - int oldSize = pointIndices.capacity(); - if (pointIndexCount + count > oldSize) { - int newSize = expandIndSize(oldSize, pointIndexCount + count); - preparePointIndicesForCopy(); - expandPointIndices(newSize); - } - - firstPointIndex = pointIndexCount; - pointIndexCount += count; - lastPointIndex = pointIndexCount - 1; - } - - protected void expandPointIndices(int n) { - IntBuffer temp = pgl.createIntBuffer(n); - temp.put(pointIndices); - pointIndices = temp; - } - - public void addFillVertex(float x, float y, float z, - int rgba, - float nx, float ny, float nz, - float u, float v, - int am, int sp, int em, float shine) { - fillVertexCheck(); - - float[] vert = new float[3]; - float[] norm = new float[3]; - float[] tcoord = {u, v}; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D mm = modelview; - PMatrix3D nm = modelviewInv; - - vert[0] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - vert[1] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - vert[2] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - - norm[0] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - norm[1] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - norm[2] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; - } else { - vert[0] = x; - vert[1] = y; - vert[2] = z; - - norm[0] = nx; - norm[1] = ny; - norm[2] = nz; - } - fillVertices.position(3 * fillVertexCount); - fillVertices.put(vert); - - fillColors.position(fillVertexCount); - fillColors.put(rgba); - - fillNormals.position(3 * fillVertexCount); - fillNormals.put(norm); - - fillTexcoords.position(2 * fillVertexCount); - fillTexcoords.put(tcoord); - - fillAmbient.position(fillVertexCount); - fillAmbient.put(am); - fillSpecular.position(fillVertexCount); - fillSpecular.put(sp); - fillEmissive.position(fillVertexCount); - fillEmissive.put(em); - fillShininess.position(fillVertexCount); - fillShininess.put(shine); - - fillVertexCount++; - } - - public void addFillVertices(InGeometry in) { - int index; - int i0 = in.firstVertex; - int i1 = in.lastVertex; - int nvert = i1 - i0 + 1; - - addFillVertices(nvert); - - float[] vert = new float[3]; - float[] norm = new float[3]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D mm = modelview; - PMatrix3D nm = modelviewInv; - - for (int i = 0; i < nvert; i++) { - int inIdx = i0 + i; - int tessIdx = firstFillVertex + i; - - index = 3 * inIdx; - float x = in.vertices[index++]; - float y = in.vertices[index++]; - float z = in.vertices[index ]; - - index = 3 * inIdx; - float nx = in.normals[index++]; - float ny = in.normals[index++]; - float nz = in.normals[index ]; - - vert[0] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - vert[1] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - vert[2] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - - norm[0] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - norm[1] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - norm[2] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; - - fillVertices.position(3 * tessIdx); - try { - fillVertices.put(vert); - } catch (java.nio.BufferOverflowException e) { - PApplet.println("mama mia " + 3 * tessIdx + " " + fillVertices.position() + " " + fillVertices.limit() + " " + fillVertices.capacity() + " " + 3 * fillVertexCount); - } - - fillNormals.position(3 * tessIdx); - fillNormals.put(norm); - } - } else { - fillVertices.position(3 * firstFillVertex); - fillVertices.put(in.vertices, 3 * i0, 3 * nvert); - - fillNormals.position(3 * firstFillVertex); - fillNormals.put(in.normals, 3 * i0, 3 * nvert); - } - - fillColors.position(firstFillVertex); - fillColors.put(in.colors, i0, nvert); - - fillTexcoords.position(2 * firstFillVertex); - fillTexcoords.put(in.texcoords, 2 * i0, 2 * nvert); - - fillAmbient.position(firstFillVertex); - fillAmbient.put(in.ambient, i0, nvert); - - fillSpecular.position(firstFillVertex); - fillSpecular.put(in.specular, i0, nvert); - - fillEmissive.position(firstFillVertex); - fillEmissive.put(in.emissive, i0, nvert); - - fillShininess.position(firstFillVertex); - fillShininess.put(in.shininess, i0, nvert); - } - - public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx, int rgba) { - int index; - - index = 3 * inIdx0; - float x0 = in.vertices[index++]; - float y0 = in.vertices[index++]; - float z0 = in.vertices[index ]; - - index = 3 * inIdx1; - float x1 = in.vertices[index++]; - float y1 = in.vertices[index++]; - float z1 = in.vertices[index ]; - - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D mm = modelview; - - float[] vert = { - x0 * mm.m00 + y0 * mm.m01 + z0 * mm.m02 + mm.m03, - x0 * mm.m10 + y0 * mm.m11 + z0 * mm.m12 + mm.m13, - x0 * mm.m20 + y0 * mm.m21 + z0 * mm.m22 + mm.m23 - }; - - float[] attr = { - x1 * mm.m00 + y1 * mm.m01 + z1 * mm.m02 + mm.m03, - x1 * mm.m10 + y1 * mm.m11 + z1 * mm.m12 + mm.m13, - x1 * mm.m20 + y1 * mm.m21 + z1 * mm.m22 + mm.m23 - }; - - lineVertices.position(3 * tessIdx); - lineVertices.put(vert); - - lineDirWidths.position(4 * tessIdx); - lineDirWidths.put(attr); - } else { - lineVertices.position(3 * tessIdx); - lineVertices.put(in.vertices, 3 * inIdx0, 3); - - lineDirWidths.position(4 * tessIdx); - lineDirWidths.put(in.vertices, 3 * inIdx1, 3); - } - - lineColors.position(tessIdx); - lineColors.put(rgba); - } - - public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx) { - putLineVertex(in, inIdx0, inIdx1, tessIdx, in.scolors[inIdx0]); - } - - public void putPointVertex(InGeometry in, int inIdx, int tessIdx) { - int index = 3 * inIdx; - float x = in.vertices[index++]; - float y = in.vertices[index++]; - float z = in.vertices[index ]; - - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D mm = modelview; - - float[] vert = { - x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03, - x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13, - x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23 - }; - - pointVertices.position(3 * tessIdx); - pointVertices.put(vert, 0, 3); - } else { - index = 3 * tessIdx; - pointVertices.position(3 * tessIdx); - pointVertices.put(in.vertices, 3 * inIdx, 3); - } - - pointColors.position(tessIdx); - pointColors.put(in.scolors[inIdx]); - } - - public int expandVertSize(int currSize, int newMinSize) { - int newSize = currSize; - while (newSize < newMinSize) { - newSize <<= 1; - } - return newSize; - } - - public int expandIndSize(int currSize, int newMinSize) { - int newSize = currSize; - while (newSize < newMinSize) { - newSize <<= 1; - } - return newSize; - } - - public void center(float cx, float cy) { - int index; - - // Computing current center - float cx0 = 0; - float cy0 = 0; - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - cx0 += fillVertices.get(index++); - cy0 += fillVertices.get(index ); - } - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - cx0 += lineVertices.get(index++); - cy0 += lineVertices.get(index ); - } - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - cx0 += pointVertices.get(index++); - cy0 += pointVertices.get(index ); - } - int nt = fillVertexCount + lineVertexCount + pointVertexCount; - if (0 < nt) { - cx0 /= nt; - cy0 /= nt; - } - - float[] tvect = { cx - cx0, cy - cy0 }; - - if (0 < fillVertexCount) { - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - for (int j = 0; j < 2; j++) { - float v = fillVertices.get(index + j); - - fillVertices.position(index + j); - //fillVertices.put(v + tvect[j]); - fillVertices.put(v + 100); - } - } - } - - if (0 < lineVertexCount) { - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - for (int j = 0; j < 2; j++) { - lineVertices.position(index + j); - lineVertices.put(lineVertices.get(index + j) + tvect[j]); - } - index = 4 * i; - for (int j = 0; j < 2; j++) { - lineDirWidths.position(index + j); - lineDirWidths.put(lineDirWidths.get(index + j) + tvect[j]); - } - } - } - - if (0 < pointVertexCount) { - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - for (int j = 0; j < 2; j++) { - pointVertices.position(index + j); - pointVertices.put(pointVertices.get(index + j) + tvect[j]); - } - } - } - } - - public void center(float cx, float cy, float cz) { - int index; - - // Computing current center - float cx0 = 0; - float cy0 = 0; - float cz0 = 0; - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - cx0 += fillVertices.get(index++); - cy0 += fillVertices.get(index++); - cz0 += fillVertices.get(index ); - } - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - cx0 += lineVertices.get(index++); - cy0 += lineVertices.get(index++); - cz0 += lineVertices.get(index ); - } - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - cx0 += pointVertices.get(index++); - cy0 += pointVertices.get(index++); - cz0 += pointVertices.get(index ); - } - int nt = fillVertexCount + lineVertexCount + pointVertexCount; - if (0 < nt) { - cx0 /= nt; - cy0 /= nt; - cz0 /= nt; - } - - float[] tvec = {cx - cx0, cy - cy0, cz - cz0}; - - if (0 < fillVertexCount) { - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - for (int j = 0; j < 3; j++) { - fillVertices.position(index + j); - fillVertices.put(fillVertices.get(index + j) + tvec[j]); - } - } - } - - if (0 < lineVertexCount) { - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - for (int j = 0; j < 3; j++) { - lineVertices.position(index + j); - lineVertices.put(lineVertices.get(index + j) + tvec[j]); - } - index = 4 * i; - for (int j = 0; j < 3; j++) { - lineDirWidths.position(index + j); - lineDirWidths.put(lineDirWidths.get(index + j) + tvec[j]); - } - } - } - - if (0 < pointVertexCount) { - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - for (int j = 0; j < 3; j++) { - pointVertices.position(index + j); - pointVertices.put(pointVertices.get(index + j) + tvec[j]); - } - } - } - } - - public int sumVertices(PVector v) { - int index; - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - v.x += fillVertices.get(index++); - v.y += fillVertices.get(index++); - v.z += fillVertices.get(index ); - } - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - v.x += lineVertices.get(index++); - v.y += lineVertices.get(index++); - v.z += lineVertices.get(index ); - } - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - v.x += pointVertices.get(index++); - v.y += pointVertices.get(index++); - v.z += pointVertices.get(index ); - } - int ntot = fillVertexCount + lineVertexCount + pointVertexCount; - return ntot; - } - - - public void applyMatrix(PMatrix2D tr) { - float[] vec0 = new float[2]; - float[] vec1 = new float[2]; - - if (0 < fillVertexCount) { - for (int i = 0; i < fillVertexCount; i++) { - fillVertices.position(3 * i); - fillVertices.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; - fillVertices.position(3 * i); - fillVertices.put(vec1); - - fillNormals.position(3 * i); - fillNormals.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; - fillNormals.position(3 * i); - fillNormals.put(vec1); - } - } - - if (0 < lineVertexCount) { - for (int i = 0; i < lineVertexCount; i++) { - lineVertices.position(3 * i); - lineVertices.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; - lineVertices.position(3 * i); - lineVertices.put(vec1); - - lineDirWidths.position(4 * i); - lineDirWidths.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; - lineDirWidths.position(4 * i); - lineDirWidths.put(vec1, 0, 2); - } - } - - if (0 < pointVertexCount) { - for (int i = 0; i < pointVertexCount; i++) { - pointVertices.position(3 * i); - pointVertices.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; - pointVertices.position(3 * i); - pointVertices.put(vec1, 0, 2); - } - } - } - - public void applyMatrix(PMatrix3D tr) { - float[] vec0 = new float[3]; - float[] vec1 = new float[3]; - - if (0 < fillVertexCount) { - for (int i = 0; i < fillVertexCount; i++) { - fillVertices.position(3 * i); - fillVertices.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02 + tr.m03; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12 + tr.m13; - vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22 + tr.m23; - fillVertices.position(3 * i); - fillVertices.put(vec1); - - fillNormals.position(3 * i); - fillNormals.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; - vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; - fillNormals.position(3 * i); - fillNormals.put(vec1); - } - } - - if (0 < lineVertexCount) { - for (int i = 0; i < lineVertexCount; i++) { - lineVertices.position(3 * i); - lineVertices.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; - vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; - lineVertices.position(3 * i); - lineVertices.put(vec1); - - lineDirWidths.position(4 * i); - lineDirWidths.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; - vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; - lineDirWidths.position(4 * i); - lineDirWidths.put(vec1, 0, 3); - } - } - - if (0 < pointVertexCount) { - for (int i = 0; i < pointVertexCount; i++) { - pointVertices.position(3 * i); - pointVertices.get(vec0); - vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; - vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; - vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; - pointVertices.position(3 * i); - pointVertices.put(vec1); - } - } - } - } - - final static protected int MIN_ACCURACY = 6; - final static protected float sinLUT[]; - final static protected float cosLUT[]; - final static protected float SINCOS_PRECISION = 0.5f; - final static protected int SINCOS_LENGTH = (int) (360f / SINCOS_PRECISION); - static { - sinLUT = new float[SINCOS_LENGTH]; - cosLUT = new float[SINCOS_LENGTH]; - for (int i = 0; i < SINCOS_LENGTH; i++) { - sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION); - cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION); - } - } - final protected float[][] QUAD_SIGNS = { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} }; - - // Generates tessellated geometry given a batch of input vertices. - public class Tessellator { - InGeometry in; - TessGeometry tess; - PGL.Tessellator gluTess; - TessellatorCallback callback; - - boolean fill; - boolean stroke; - float strokeWeight; - int strokeJoin; - int strokeCap; - int bezierDetil = 20; - - public Tessellator() { - callback = new TessellatorCallback(); - gluTess = pgl.createTessellator(callback); - bezierDetil = 20; - } - - public void setInGeometry(InGeometry in) { - this.in = in; - } - - public void setTessGeometry(TessGeometry tess) { - this.tess = tess; - } - - public void setFill(boolean fill) { - this.fill = fill; - } - - public void setStroke(boolean stroke) { - this.stroke = stroke; - } - - public void setStrokeWeight(float weight) { - this.strokeWeight = weight; - } - - public void setStrokeJoin(int strokeJoin) { - this.strokeJoin = strokeJoin; - } - - public void setStrokeCap(int strokeCap) { - this.strokeCap = strokeCap; - } - - public void tessellatePoints() { - if (strokeCap == ROUND) { - tessellateRoundPoints(); - } else { - tessellateSquarePoints(); - } - } - - protected void tessellateRoundPoints() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (stroke && 1 <= nInVert) { - tess.isStroked = true; - - // Each point generates a separate triangle fan. - // The number of triangles of each fan depends on the - // stroke weight of the point. - int nvertTot = 0; - int nindTot = 0; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { - int perim = PApplet.max(MIN_ACCURACY, (int) (TWO_PI * strokeWeight / 20)); - // Number of points along the perimeter plus the center point. - int nvert = perim + 1; - nvertTot += nvert; - nindTot += 3 * (nvert - 1); - } - - checkForFlush(tess.lineVertexCount + nvertTot, tess.lineIndexCount + nindTot); - - tess.addPointVertices(nvertTot); - tess.addPointIndices(nindTot); - int vertIdx = tess.firstPointVertex; - int attribIdx = tess.firstPointVertex; - int indIdx = tess.firstPointIndex; - int firstVert = tess.firstPointVertex; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { - // Creating the triangle fan for each input vertex. - int perim = PApplet.max(MIN_ACCURACY, (int) (TWO_PI * strokeWeight / 20)); - int nvert = perim + 1; - - // All the tessellated vertices are identical to the center point - for (int k = 0; k < nvert; k++) { - tess.putPointVertex(in, i, vertIdx); - vertIdx++; - } - - // The attributes for each tessellated vertex are the displacement along - // the circle perimeter. The point shader will read these attributes and - // displace the vertices in screen coordinates so the circles are always - // camera facing (bilboards) - tess.pointSizes.put(2 * attribIdx + 0, 0); - tess.pointSizes.put(2 * attribIdx + 1, 0); - attribIdx++; - float val = 0; - float inc = (float) SINCOS_LENGTH / perim; - for (int k = 0; k < perim; k++) { - tess.pointSizes.put(2 * attribIdx + 0, 0.5f * cosLUT[(int) val] * strokeWeight); - tess.pointSizes.put(2 * attribIdx + 1, 0.5f * sinLUT[(int) val] * strokeWeight); - val = (val + inc) % SINCOS_LENGTH; - attribIdx++; - } - - // Adding vert0 to take into account the triangles of all - // the preceding points. - for (int k = 1; k < nvert - 1; k++) { - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k + 1)); - } - // Final triangle between the last and first point: - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 1)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + nvert - 1)); - firstVert = vertIdx; - } - } - } - - protected void tessellateSquarePoints() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (stroke && 1 <= nInVert) { - tess.isStroked = true; - - // Each point generates a separate quad. - int quadCount = nInVert; - - // Each quad is formed by 5 vertices, the center one - // is the input vertex, and the other 4 define the - // corners (so, a triangle fan again). - int nvertTot = 5 * quadCount; - // So the quad is formed by 4 triangles, each requires - // 3 indices. - int nindTot = 12 * quadCount; - - checkForFlush(tess.lineVertexCount + nvertTot, tess.lineIndexCount + nindTot); - - tess.addPointVertices(nvertTot); - tess.addPointIndices(nindTot); - int vertIdx = tess.firstPointVertex; - int attribIdx = tess.firstPointVertex; - int indIdx = tess.firstPointIndex; - int firstVert = tess.firstPointVertex; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { - int nvert = 5; - - for (int k = 0; k < nvert; k++) { - tess.putPointVertex(in, i, vertIdx); - vertIdx++; - } - - // The attributes for each tessellated vertex are the displacement along - // the quad corners. The point shader will read these attributes and - // displace the vertices in screen coordinates so the quads are always - // camera facing (bilboards) - tess.pointSizes.put(2 * attribIdx + 0, 0); - tess.pointSizes.put(2 * attribIdx + 1, 0); - attribIdx++; - for (int k = 0; k < 4; k++) { - tess.pointSizes.put(2 * attribIdx + 0, 0.5f * QUAD_SIGNS[k][0] * strokeWeight); - tess.pointSizes.put(2 * attribIdx + 1, 0.5f * QUAD_SIGNS[k][1] * strokeWeight); - attribIdx++; - } - - // Adding firstVert to take into account the triangles of all - // the preceding points. - for (int k = 1; k < nvert - 1; k++) { - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k + 1)); - } - // Final triangle between the last and first point: - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 1)); - tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + nvert - 1)); - firstVert = vertIdx; - } - } - } - - public void tessellateLines() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (stroke && 2 <= nInVert) { - tess.isStroked = true; - - int lineCount = nInVert / 2; - int first = in.firstVertex; - - // Lines are made up of 4 vertices defining the quad. - // Each vertex has its own offset representing the stroke weight. - int nvert = lineCount * 4; - // Each stroke line has 4 vertices, defining 2 triangles, which - // require 3 indices to specify their connectivities. - int nind = lineCount * 2 * 3; - - checkForFlush(tess.lineVertexCount + nvert, tess.lineIndexCount + nvert); - - tess.addLineVertices(nvert); - tess.addLineIndices(nind); - int vcount = tess.firstLineVertex; - int icount = tess.firstLineIndex; - for (int ln = 0; ln < lineCount; ln++) { - int i0 = first + 2 * ln + 0; - int i1 = first + 2 * ln + 1; - addLine(i0, i1, vcount, icount); vcount += 4; icount += 6; - } - } - } - - public void tessellateTriangles() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (fill && 3 <= nInVert) { - int nInInd = nInVert; - checkForFlush(tess.fillVertexCount + nInVert, tess.fillIndexCount + nInInd); - - tess.addFillVertices(in); - - tess.addFillIndices(nInVert); - int idx0 = tess.firstFillIndex; - int offset = tess.firstFillVertex; - for (int i = in.firstVertex; i <= in.lastVertex; i++) { - tess.fillIndices.put(idx0 + i, PGL.makeIndex(offset + i)); - } - } - - if (stroke) { - tess.isStroked = true; - tessellateEdges(); - } - } - - public void tessellateTriangleFan() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (fill && 3 <= nInVert) { - int nInInd = 3 * (nInVert - 2); - checkForFlush(tess.fillVertexCount + nInVert, tess.fillIndexCount + nInInd); - - tess.addFillVertices(in); - - tess.addFillIndices(nInInd); - int idx = tess.firstFillIndex; - int offset = tess.firstFillVertex; - for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { - tess.fillIndices.put(idx++, PGL.makeIndex(offset + in.firstVertex)); - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i)); - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i + 1)); - } - } - - if (stroke) { - tess.isStroked = true; - tessellateEdges(); - } - } - - public void tessellateTriangleStrip() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (fill && 3 <= nInVert) { - int triCount = nInVert - 2; - int nInInd = 3 * triCount; - - checkForFlush(tess.fillVertexCount + nInVert, tess.fillIndexCount + nInInd); - - tess.addFillVertices(in); - - // Each vertex, except the first and last, defines a triangle. - tess.addFillIndices(nInInd); - int idx = tess.firstFillIndex; - int offset = tess.firstFillVertex; - for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i)); - if (i % 2 == 0) { - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i - 1)); - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i + 1)); - } else { - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i + 1)); - tess.fillIndices.put(idx++, PGL.makeIndex(offset + i - 1)); - } - } - } - - if (stroke) { - tess.isStroked = true; - tessellateEdges(); - } - } - - public void tessellateQuads() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (fill && 4 <= nInVert) { - int quadCount = nInVert / 4; - int nInInd = 6 * quadCount; - - checkForFlush(tess.fillVertexCount + nInVert, tess.fillIndexCount + nInInd); - tess.addFillVertices(in); - - tess.addFillIndices(nInInd); - int idx = tess.firstFillIndex; - int offset = tess.firstFillVertex; - for (int qd = 0; qd < quadCount; qd++) { - int i0 = offset + 4 * qd + 0; - int i1 = offset + 4 * qd + 1; - int i2 = offset + 4 * qd + 2; - int i3 = offset + 4 * qd + 3; - - tess.fillIndices.put(idx++, PGL.makeIndex(i0)); - tess.fillIndices.put(idx++, PGL.makeIndex(i1)); - tess.fillIndices.put(idx++, PGL.makeIndex(i3)); - - tess.fillIndices.put(idx++, PGL.makeIndex(i1)); - tess.fillIndices.put(idx++, PGL.makeIndex(i2)); - tess.fillIndices.put(idx++, PGL.makeIndex(i3)); - } - } - - if (stroke) { - tess.isStroked = true; - tessellateEdges(); - } - } - - - public void tessellateQuadStrip() { - int nInVert = in.lastVertex - in.firstVertex + 1; - - if (fill && 4 <= nInVert) { - int quadCount = nInVert / 2 - 1; - int nInInd = 6 * quadCount; - - checkForFlush(tess.fillVertexCount + nInVert, tess.fillIndexCount + nInInd); - tess.addFillVertices(in); - - tess.addFillIndices(nInInd); - int idx = tess.firstFillIndex; - int offset = tess.firstFillVertex; - for (int qd = 1; qd < nInVert / 2; qd++) { - int i0 = offset + 2 * (qd - 1); - int i1 = offset + 2 * (qd - 1) + 1; - int i2 = offset + 2 * qd + 1; - int i3 = offset + 2 * qd; - - tess.fillIndices.put(idx++, PGL.makeIndex(i0)); - tess.fillIndices.put(idx++, PGL.makeIndex(i1)); - tess.fillIndices.put(idx++, PGL.makeIndex(i3)); - - tess.fillIndices.put(idx++, PGL.makeIndex(i1)); - tess.fillIndices.put(idx++, PGL.makeIndex(i2)); - tess.fillIndices.put(idx++, PGL.makeIndex(i3)); - } - } - - if (stroke) { - tess.isStroked = true; - tessellateEdges(); - } - } - - public void tessellatePolygon(boolean solid, boolean closed, boolean calcNormals) { - int nInVert = in.lastVertex - in.firstVertex + 1; - - callback.calcNormals = calcNormals; - - if (fill && 3 <= nInVert) { - checkForFlush(nInVert); - - gluTess.beginPolygon(); - - if (solid) { - // Using NONZERO winding rule for solid polygons. - gluTess.setWindingRule(PGL.GLU_TESS_WINDING_NONZERO); - } else { - // Using ODD winding rule to generate polygon with holes. - gluTess.setWindingRule(PGL.GLU_TESS_WINDING_ODD); - } - - gluTess.beginContour(); - - // Now, iterate over all input data and send to GLU tessellator.. - for (int i = in.firstVertex; i <= in.lastVertex; i++) { - boolean breakPt = in.codes[i] == PShape.BREAK; - if (breakPt) { - gluTess.endContour(); - gluTess.beginContour(); - } - - // Separting colors into individual rgba components for interpolation. - int fa = (in.colors[i] >> 24) & 0xFF; - int fr = (in.colors[i] >> 16) & 0xFF; - int fg = (in.colors[i] >> 8) & 0xFF; - int fb = (in.colors[i] >> 0) & 0xFF; - - int aa = (in.ambient[i] >> 24) & 0xFF; - int ar = (in.ambient[i] >> 16) & 0xFF; - int ag = (in.ambient[i] >> 8) & 0xFF; - int ab = (in.ambient[i] >> 0) & 0xFF; - - int sa = (in.specular[i] >> 24) & 0xFF; - int sr = (in.specular[i] >> 16) & 0xFF; - int sg = (in.specular[i] >> 8) & 0xFF; - int sb = (in.specular[i] >> 0) & 0xFF; - - int ea = (in.emissive[i] >> 24) & 0xFF; - int er = (in.emissive[i] >> 16) & 0xFF; - int eg = (in.emissive[i] >> 8) & 0xFF; - int eb = (in.emissive[i] >> 0) & 0xFF; - - // Vertex data includes coordinates, colors, normals, texture coordinates, and material properties. - double[] vertex = new double[] { in.vertices [3 * i + 0], in.vertices [3 * i + 1], in.vertices[3 * i + 2], - fa, fr, fg, fb, - in.normals [3 * i + 0], in.normals [3 * i + 1], in.normals [3 * i + 2], - in.texcoords[2 * i + 0], in.texcoords[2 * i + 1], - aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, - in.shininess[i] }; - - gluTess.addVertex(vertex); - } - gluTess.endContour(); - - gluTess.endPolygon(); - } - - if (stroke) { - tess.isStroked = true; - tessellateEdges(); - } - } - - // Adding the data that defines a quad starting at vertex i0 and - // ending at i1. - protected void addLine(int i0, int i1, int vcount, int icount) { - tess.putLineVertex(in, i0, i1, vcount); - - tess.lineDirWidths.put(4 * vcount + 3, +strokeWeight); - tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); - - vcount++; - tess.putLineVertex(in, i0, i1, vcount); - tess.lineDirWidths.put(4 * vcount + 3, -strokeWeight); - tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); - - vcount++; - tess.putLineVertex(in, i1, i0, vcount); - tess.lineDirWidths.put(4 * vcount + 3, -strokeWeight); - tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); - - // Starting a new triangle re-using prev vertices. - tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); - tess.lineIndices.put(icount++, PGL.makeIndex(vcount - 1)); - - vcount++; - tess.putLineVertex(in, i1, i0, vcount); - tess.lineDirWidths.put(4 * vcount + 3, +strokeWeight); - tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); - } - - public void tessellateEdges() { - int nInVert = in.getNumLineVertices(); - int nInInd = in.getNumLineIndices(); - - checkForFlush(tess.lineVertexCount + nInVert, tess.lineIndexCount + nInInd); - - tess.addLineVertices(nInVert); - tess.addLineIndices(nInInd); - int vcount = tess.firstLineVertex; - int icount = tess.firstLineIndex; - for (int i = in.firstEdge; i <= in.lastEdge; i++) { - int[] edge = in.edges[i]; - addLine(edge[0], edge[1], vcount, icount); vcount += 4; icount += 6; - } - } - - protected void checkForFlush(int vertCount) { - if (tess.renderMode == IMMEDIATE && PGL.MAX_TESS_VERTICES < vertCount) { - setLastTexIndex(tess.lastFillIndex); - flush(); - setFirstTexIndex(0); - } - } - - protected void checkForFlush(int vertCount, int indCount) { - if (tess.renderMode == IMMEDIATE && (PGL.MAX_TESS_VERTICES < vertCount || - PGL.MAX_TESS_INDICES < indCount)) { - setLastTexIndex(tess.lastFillIndex); - flush(); - setFirstTexIndex(0); - } - } - - protected boolean startEdge(int edge) { - return edge % 2 != 0; - } - - protected boolean endEdge(int edge) { - return 1 < edge; - } - - protected class TessellatorCallback implements PGL.TessellatorCallback { - public boolean calcNormals; - protected int tessFirst; - protected int tessCount; - protected int tessType; - - public void begin(int type) { - tessFirst = tess.fillVertexCount; - tessCount = 0; - - switch (type) { - case PGL.GL_TRIANGLE_FAN: - tessType = TRIANGLE_FAN; - break; - case PGL.GL_TRIANGLE_STRIP: - tessType = TRIANGLE_STRIP; - break; - case PGL.GL_TRIANGLES: - tessType = TRIANGLES; - break; - } - } - - public void end() { - switch (tessType) { - case TRIANGLE_FAN: - for (int i = 1; i < tessCount - 1; i++) { - addIndex(0); - addIndex(i); - addIndex(i + 1); - if (calcNormals) calcTriNormal(0, i, i + 1); - } - break; - case TRIANGLE_STRIP: - for (int i = 1; i < tessCount - 1; i++) { - addIndex(i); - if (i % 2 == 0) { - addIndex(i - 1); - addIndex(i + 1); - if (calcNormals) calcTriNormal(i + 1, i, i - 1); - } else { - addIndex(i + 1); - addIndex(i - 1); - if (calcNormals) calcTriNormal(i - 1, i, i + 1); - } - } - break; - case TRIANGLES: - for (int i = 0; i < tessCount; i++) { - addIndex(i); - } - if (calcNormals) { - for (int tr = 0; tr < tessCount / 3; tr++) { - int i0 = 3 * tr + 0; - int i1 = 3 * tr + 1; - int i2 = 3 * tr + 2; - calcTriNormal(i0, i1, i2); - } - } - break; - } - } - - protected void addIndex(int tessIdx) { - if (tess.fillVertexCount < PGL.MAX_TESS_INDICES) { - tess.addFillIndex(tessFirst + tessIdx); - } else { - throw new RuntimeException("P3D: the tessellator is generating too many indices, reduce complexity of shape."); - } - } - - protected void calcTriNormal(int tessIdx0, int tessIdx1, int tessIdx2) { - tess.calcFillNormal(tessFirst + tessIdx0, tessFirst + tessIdx1, tessFirst + tessIdx2); - } - - public void vertex(Object data) { - if (data instanceof double[]) { - double[] d = (double[]) data; - if (d.length < 25) { - throw new RuntimeException("TessCallback vertex() data is not of length 25"); - } - - if (tess.fillVertexCount < PGL.MAX_TESS_VERTICES) { - - // Combining individual rgba components back into int color values - int fcolor = ((int) d[ 3] << 24) | ((int) d[ 4] << 16) | ((int) d[ 5] << 8) | (int) d[ 6]; - int acolor = ((int) d[12] << 24) | ((int) d[13] << 16) | ((int) d[14] << 8) | (int) d[15]; - int scolor = ((int) d[16] << 24) | ((int) d[17] << 16) | ((int) d[18] << 8) | (int) d[19]; - int ecolor = ((int) d[20] << 24) | ((int) d[21] << 16) | ((int) d[22] << 8) | (int) d[23]; - - tess.addFillVertex((float) d[ 0], (float) d[ 1], (float) d[ 2], - fcolor, - (float) d[ 7], (float) d[ 8], (float) d[ 9], - (float) d[10], (float) d[11], - acolor, scolor, ecolor, - (float) d[24]); - - tessCount++; - } else { - throw new RuntimeException("P3D: the tessellator is generating too many vertices, reduce complexity of shape."); - } - - } else { - throw new RuntimeException("TessCallback vertex() data not understood"); - } - } - - public void error(int errnum) { - String estring = pgl.gluErrorString(errnum); - PGraphics.showWarning("Tessellation Error: " + estring); - } - - /** - * Implementation of the GLU_TESS_COMBINE callback. - * @param coords is the 3-vector of the new vertex - * @param data is the vertex data to be combined, up to four elements. - * This is useful when mixing colors together or any other - * user data that was passed in to gluTessVertex. - * @param weight is an array of weights, one for each element of "data" - * that should be linearly combined for new values. - * @param outData is the set of new values of "data" after being - * put back together based on the weights. it's passed back as a - * single element Object[] array because that's the closest - * that Java gets to a pointer. - */ - public void combine(double[] coords, Object[] data, - float[] weight, Object[] outData) { - double[] vertex = new double[25]; - vertex[0] = coords[0]; - vertex[1] = coords[1]; - vertex[2] = coords[2]; - - // Here w e need to use separate rgba components for correct interpolation... - - // Calculating the rest of the vertex parameters (color, - // normal, texcoords) as the linear combination of the - // combined vertices. - for (int i = 3; i < 25; i++) { - vertex[i] = 0; - for (int j = 0; j < 4; j++) { - double[] vertData = (double[])data[j]; - if (vertData != null) { - vertex[i] += weight[j] * vertData[i]; - } - } - } - - // Normalizing normal vector, since the weighted - // combination of normal vectors is not necessarily - // normal. - double sum = vertex[7] * vertex[7] + - vertex[8] * vertex[8] + - vertex[9] * vertex[9]; - double len = Math.sqrt(sum); - vertex[7] /= len; - vertex[8] /= len; - vertex[9] /= len; - - outData[0] = vertex; - } - } - } -} diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PShader.java b/java/libraries/lwjgl/src/processing/lwjgl/PShader.java deleted file mode 100644 index b36a78da2..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PShader.java +++ /dev/null @@ -1,477 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2010 Ben Fry and Casey Reas - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - */ - -package processing.lwjgl; - -import processing.core.*; - -import java.io.IOException; -import java.net.URL; -import java.nio.FloatBuffer; - -/** - * This class encapsulates a GLSL shader program, including a vertex - * and a fragment shader. Originally based in the code by JohnG - * (http://www.hardcorepawn.com/) - */ -public class PShader { - protected PApplet parent; - protected PGraphicsLWJGL pg; - protected PGL pgl; - - protected URL vertexURL; - protected URL fragmentURL; - - protected String vertexFilename; - protected String fragmentFilename; - - protected int programObject; - protected int vertexShader; - protected int fragmentShader; - - protected FloatBuffer vec1f; - protected FloatBuffer vec2f; - protected FloatBuffer vec3f; - protected FloatBuffer vec4f; - protected FloatBuffer mat2x2; - protected FloatBuffer mat3x3; - protected FloatBuffer mat4x4; - - public PShader() { - parent = null; - pg = null; - pgl = null; - - this.vertexURL = null; - this.fragmentURL = null; - this.vertexFilename = null; - this.fragmentFilename = null; - - programObject = 0; - vertexShader = 0; - fragmentShader = 0; - } - - public PShader(PApplet parent) { - this(); - this.parent = parent; - pg = (PGraphicsLWJGL) parent.g; - pgl = pg.pgl; - } - - /** - * Creates a shader program using the specified vertex and fragment - * shaders. - * - * @param parent PApplet - * @param vertexFN String - * @param fragmentFN String - */ - public PShader(PApplet parent, String vertFilename, String fragFilename) { - this.parent = parent; - pg = (PGraphicsLWJGL) parent.g; - pgl = pg.pgl; - - this.vertexURL = null; - this.fragmentURL = null; - this.vertexFilename = vertFilename; - this.fragmentFilename = fragFilename; - - programObject = 0; - vertexShader = 0; - fragmentShader = 0; - } - - public PShader(PApplet parent, URL vertURL, URL fragURL) { - this.parent = parent; - pg = (PGraphicsLWJGL) parent.g; - pgl = pg.pgl; - - this.vertexURL = vertURL; - this.fragmentURL = fragURL; - this.vertexFilename = null; - this.fragmentFilename = null; - - programObject = 0; - vertexShader = 0; - fragmentShader = 0; - } - - protected void finalize() throws Throwable { - try { - if (vertexShader != 0) { - pg.finalizeGLSLVertShaderObject(vertexShader); - } - if (fragmentShader != 0) { - pg.finalizeGLSLFragShaderObject(fragmentShader); - } - if (programObject != 0) { - pg.finalizeGLSLProgramObject(programObject); - } - } finally { - super.finalize(); - } - } - - public void setVertexShader(String vertFilename) { - this.vertexFilename = vertFilename; - } - - public void setVertexShader(URL vertURL) { - this.vertexURL = vertURL; - } - - public void setFragmentShader(String fragFilename) { - this.fragmentFilename = fragFilename; - } - - public void setFragmentShader(URL fragURL) { - this.fragmentURL = fragURL; - } - - /** - * Starts the execution of the shader program. - */ - public void start() { - init(); - pgl.glUseProgram(programObject); - } - - - /** - * Stops the execution of the shader program. - */ - public void stop() { - pgl.glUseProgram(0); - } - - - /** - * Returns the ID location of the attribute parameter given its name. - * - * @param name String - * @return int - */ - public int getAttribLocation(String name) { - init(); - return pgl.glGetAttribLocation(programObject, name); - } - - - /** - * Returns the ID location of the uniform parameter given its name. - * - * @param name String - * @return int - */ - public int getUniformLocation(String name) { - init(); - return pgl.glGetUniformLocation(programObject, name); - } - - - public void setIntUniform(int loc, int x) { - if (-1 < loc) { - pgl.glUniform1i(loc, x); - } - } - - - public void set1FloatUniform(int loc, float x) { - if (-1 < loc) { - pgl.glUniform1f(loc, x); - } - } - - - public void set2FloatUniform(int loc, float x, float y) { - if (-1 < loc) { - pgl.glUniform2f(loc, x, y); - } - } - - - public void set3FloatUniform(int loc, float x, float y, float z) { - if (-1 < loc) { - pgl.glUniform3f(loc, x, y, z); - } - } - - - public void set4FloatUniform(int loc, float x, float y, float z, float w) { - if (-1 < loc) { - pgl.glUniform4f(loc, x, y, z, w); - } - } - - - public void set1FloatVecUniform(int loc, float[] vec) { - if (-1 < loc) { - if (vec1f == null || vec1f.capacity() != vec.length) { - vec1f = pgl.createFloatBuffer(vec.length); - } - vec1f.rewind(); - vec1f.put(vec); - vec1f.flip(); - pgl.glUniform1fv(loc, vec.length, vec1f); - } - } - - - public void set2FloatVecUniform(int loc, float[] vec) { - if (-1 < loc) { - if (vec2f == null || vec2f.capacity() != vec.length) { - vec2f = pgl.createFloatBuffer(vec.length); - } - vec2f.rewind(); - vec2f.put(vec); - vec2f.flip(); - pgl.glUniform2fv(loc, vec.length / 2, vec2f); - } - } - - - public void set3FloatVecUniform(int loc, float[] vec) { - if (-1 < loc) { - if (vec3f == null || vec3f.capacity() != vec.length) { - vec3f = pgl.createFloatBuffer(vec.length); - } - vec3f.rewind(); - vec3f.put(vec); - vec3f.flip(); - pgl.glUniform3fv(loc, vec.length / 3, vec3f); - } - } - - - public void set4FloatVecUniform(int loc, float[] vec) { - if (-1 < loc) { - if (vec4f == null || vec4f.capacity() != vec.length) { - vec4f = pgl.createFloatBuffer(vec.length); - } - vec4f.rewind(); - vec4f.put(vec); - vec4f.flip(); - pgl.glUniform4fv(loc, vec.length / 4, vec4f); - } - } - - - public void set2x2MatUniform(int loc, float[] mat) { - if (-1 < loc) { - if (mat2x2 == null) { - mat2x2 = pgl.createFloatBuffer(2 * 2); - } - mat2x2.rewind(); - mat2x2.put(mat); - mat2x2.flip(); - pgl.glUniformMatrix2fv(loc, 1, false, mat2x2); - } - } - - - public void set3x3MatUniform(int loc, float[] mat) { - if (-1 < loc) { - if (mat3x3 == null) { - mat3x3 = pgl.createFloatBuffer(3 * 3); - } - mat3x3.rewind(); - mat3x3.put(mat); - mat3x3.flip(); - pgl.glUniformMatrix3fv(loc, 1, false, mat3x3); - } - } - - - public void set4x4MatUniform(int loc, float[] mat) { - if (-1 < loc) { - if (mat4x4 == null) { - mat4x4 = pgl.createFloatBuffer(4 * 4); - } - mat4x4.rewind(); - mat4x4.put(mat); - mat4x4.flip(); - pgl.glUniformMatrix4fv(loc, 1, false, mat4x4); - } - } - - - public void set1FloatAttribute(int loc, float x) { - if (-1 < loc) { - pgl.glVertexAttrib1f(loc, x); - } - } - - - public void set2FloatAttribute(int loc, float x, float y) { - if (-1 < loc) { - pgl.glVertexAttrib2f(loc, x, y); - } - } - - - public void set3FloatAttribute(int loc, float x, float y, float z) { - if (-1 < loc) { - pgl.glVertexAttrib3f(loc, x, y, z); - } - } - - - public void set4FloatAttribute(int loc, float x, float y, float z, float w) { - if (-1 < loc) { - pgl.glVertexAttrib4f(loc, x, y, z, w); - } - } - - protected void init() { - if (programObject == 0) { - programObject = pg.createGLSLProgramObject(); - - if (vertexFilename != null) { - loadVertexShader(vertexFilename); - } else if (vertexURL != null) { - loadVertexShader(vertexURL); - } else { - PGraphics.showException("Vertex shader filenames and URLs are both null!"); - } - - if (fragmentFilename != null) { - loadFragmentShader(fragmentFilename); - } else if (fragmentURL != null) { - loadFragmentShader(fragmentURL); - } else { - PGraphics.showException("Fragment shader filenames and URLs are both null!"); - } - - checkLogInfo("Vertex shader " + vertexFilename + " compilation: ", vertexShader); - checkLogInfo("Fragment shader " + fragmentFilename + " compilation: ", fragmentShader); - - pgl.glLinkProgram(programObject); - pgl.glValidateProgram(programObject); - } - } - - - /** - * Loads and compiles the vertex shader contained in file. - * - * @param file String - */ - protected void loadVertexShader(String filename) { - String shaderSource = PApplet.join(parent.loadStrings(filename), "\n"); - attachVertexShader(shaderSource); - } - - /** - * Loads and compiles the vertex shader contained in the URL. - * - * @param file String - */ - protected void loadVertexShader(URL url) { - try { - String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); - attachVertexShader(shaderSource); - } catch (IOException e) { - PGraphics.showException("Cannot load shader " + url.getFile()); - } - } - - /** - * Loads and compiles the fragment shader contained in file. - * - * @param file String - */ - protected void loadFragmentShader(String filename) { - String shaderSource = PApplet.join(parent.loadStrings(filename), "\n"); - attachFragmentShader(shaderSource); - } - - /** - * Loads and compiles the fragment shader contained in the URL. - * - * @param url URL - */ - protected void loadFragmentShader(URL url) { - try { - String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); - attachFragmentShader(shaderSource); - } catch (IOException e) { - PGraphics.showException("Cannot load shader " + url.getFile()); - } - } - - /** - * @param shaderSource a string containing the shader's code - */ - protected void attachVertexShader(String shaderSource) { - vertexShader = pg.createGLSLVertShaderObject(); - - pgl.glShaderSource(vertexShader, shaderSource); - pgl.glCompileShader(vertexShader); - - pgl.glAttachShader(programObject, vertexShader); - } - - - /** - * @param shaderSource a string containing the shader's code - */ - protected void attachFragmentShader(String shaderSource) { - fragmentShader = pg.createGLSLFragShaderObject(); - - pgl.glShaderSource(fragmentShader, shaderSource); - pgl.glCompileShader(fragmentShader); - - pgl.glAttachShader(programObject, fragmentShader); - } - - - /** - * Check the log error for the opengl object obj. Prints error - * message if needed. - */ - protected void checkLogInfo(String title, int obj) { - String log = pgl.getShaderLog(obj); - if (!log.equals("")) { - System.out.println(title); - System.out.println(log); - } - } - - - protected void release() { - if (vertexShader != 0) { - pg.deleteGLSLVertShaderObject(vertexShader); - vertexShader = 0; - } - if (fragmentShader != 0) { - pg.deleteGLSLFragShaderObject(fragmentShader); - fragmentShader = 0; - } - if (programObject != 0) { - pg.deleteGLSLProgramObject(programObject); - programObject = 0; - } - } -} - diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PShape3D.java b/java/libraries/lwjgl/src/processing/lwjgl/PShape3D.java deleted file mode 100644 index 75cc08398..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PShape3D.java +++ /dev/null @@ -1,4530 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2010 Ben Fry and Casey Reas - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA - */ - -package processing.lwjgl; - -import processing.core.PApplet; -import processing.core.PGraphics; -import processing.core.PImage; -import processing.core.PMatrix; -import processing.core.PMatrix2D; -import processing.core.PMatrix3D; -import processing.core.PShape; -import processing.core.PVector; -import processing.lwjgl.PGraphicsLWJGL.FillShader; -import processing.lwjgl.PGraphicsLWJGL.InGeometry; -import processing.lwjgl.PGraphicsLWJGL.LineShader; -import processing.lwjgl.PGraphicsLWJGL.PointShader; -import processing.lwjgl.PGraphicsLWJGL.TessGeometry; -import processing.lwjgl.PGraphicsLWJGL.Tessellator; - -import java.io.BufferedReader; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Hashtable; - - -// Notes about geometry update in PShape3D. -// 1) When applying a transformation on a group shape -// check if it is more efficient to apply as a gl -// transformation on all the childs, instead of -// propagating the transformation downwards in order -// to calculate the transformation matrices. -// 2) Change the transformation logic, so the matrix is applied -// on the values stored in the vertex cache and not on the -// tessellated vertices. - -/** - * This class holds a 3D model composed of vertices, normals, colors (per vertex) and - * texture coordinates (also per vertex). All this data is stored in Vertex Buffer Objects - * (VBO) in GPU memory for very fast access. - * OBJ loading implemented using code from Saito's OBJLoader library (http://code.google.com/p/saitoobjloader/) - * and OBJReader from Ahmet Kizilay (http://www.openprocessing.org/visuals/?visualID=191). - * By Andres Colubri - * - * - * Other formats to consider: - * AMF: http://en.wikipedia.org/wiki/Additive_Manufacturing_File_Format - * STL: http://en.wikipedia.org/wiki/STL_(file_format) - * OFF: http://en.wikipedia.org/wiki/STL_(file_format) - * DXF: http://en.wikipedia.org/wiki/AutoCAD_DXF - */ - -public class PShape3D extends PShape { - protected PGraphicsLWJGL pg; - protected PGL pgl; - - protected PShape3D root; - protected int glMode; - - protected InGeometry in; - protected TessGeometry tess; - protected Tessellator tessellator; - - protected ArrayList fillIndexData; - protected ArrayList lineIndexData; - protected ArrayList pointIndexData; - - protected HashSet textures; - protected PImage texture; - - // ........................................................ - - // OpenGL buffers - - public int glFillVertexBufferID; - public int glFillColorBufferID; - public int glFillNormalBufferID; - public int glFillTexCoordBufferID; - public int glFillAmbientBufferID; - public int glFillSpecularBufferID; - public int glFillEmissiveBufferID; - public int glFillShininessBufferID; - public int glFillIndexBufferID; - - public int glLineVertexBufferID; - public int glLineColorBufferID; - public int glLineDirWidthBufferID; - public int glLineIndexBufferID; - - public int glPointVertexBufferID; - public int glPointColorBufferID; - public int glPointSizeBufferID; - public int glPointIndexBufferID; - - // ........................................................ - - // Offsets for geometry aggregation and update. - - protected int fillVertCopyOffset; - protected int fillIndCopyOffset; - protected int lineVertCopyOffset; - protected int lineIndCopyOffset; - protected int pointVertCopyOffset; - protected int pointIndCopyOffset; - - protected int lastFillVertexOffset; - protected int lastFillIndexOffset; - protected int firstFillVertexRel; - protected int firstFillVertexAbs; - - protected int lastLineVertexOffset; - protected int lastLineIndexOffset; - protected int firstLineVertexRel; - protected int firstLineVertexAbs; - - protected int lastPointVertexOffset; - protected int lastPointIndexOffset; - protected int firstPointVertexRel; - protected int firstPointVertexAbs; - - // ........................................................ - - // Drawing/rendering state - - protected boolean tessellated; - - boolean modifiedFillVertices; - boolean modifiedFillColors; - boolean modifiedFillNormals; - boolean modifiedFillTexCoords; - boolean modifiedFillAmbient; - boolean modifiedFillSpecular; - boolean modifiedFillEmissive; - boolean modifiedFillShininess; - - boolean modifiedLineVertices; - boolean modifiedLineColors; - boolean modifiedLineAttributes; - - boolean modifiedPointVertices; - boolean modifiedPointColors; - boolean modifiedPointNormals; - boolean modifiedPointAttributes; - - protected VertexCache fillVerticesCache; - protected VertexCache fillColorsCache; - protected VertexCache fillNormalsCache; - protected VertexCache fillTexCoordsCache; - protected VertexCache fillAmbientCache; - protected VertexCache fillSpecularCache; - protected VertexCache fillEmissiveCache; - protected VertexCache fillShininessCache; - - protected VertexCache lineVerticesCache; - protected VertexCache lineColorsCache; - protected VertexCache lineAttributesCache; - - protected VertexCache pointVerticesCache; - protected VertexCache pointColorsCache; - protected VertexCache pointAttributesCache; - - protected boolean isSolid; - protected boolean isClosed; - - protected boolean openContour = false; - protected boolean breakShape = false; - protected boolean shapeEnded = false; - - protected boolean hasFill; - protected boolean hasLines; - protected boolean hasPoints; - - protected boolean applyMatrix; - protected boolean childHasMatrix; - - // ........................................................ - - // Input data - - protected float normalX, normalY, normalZ; - - // normal calculated per triangle - static protected final int NORMAL_MODE_AUTO = 0; - // one normal manually specified per shape - static protected final int NORMAL_MODE_SHAPE = 1; - // normals specified for each shape vertex - static protected final int NORMAL_MODE_VERTEX = 2; - - // Current mode for normals, one of AUTO, SHAPE, or VERTEX - protected int normalMode; - - // ........................................................ - - // Bezier and Catmull-Rom curves - - protected boolean bezierInited = false; - public int bezierDetail = 20; - protected PMatrix3D bezierDrawMatrix; - - protected boolean curveInited = false; - protected int curveDetail = 20; - public float curveTightness = 0; - - // catmull-rom basis matrix, perhaps with optional s parameter - protected PMatrix3D curveBasisMatrix; - protected PMatrix3D curveDrawMatrix; - - protected PMatrix3D bezierBasisInverse; - protected PMatrix3D curveToBezierMatrix; - - protected float curveVertices[][]; - protected int curveVertexCount; - - // ........................................................ - - // Modes inherited from renderer - - protected int textureMode; - protected int rectMode; - protected int ellipseMode; - protected int shapeMode; - protected int imageMode; - - public PShape3D(PApplet parent, int family) { - pg = (PGraphicsLWJGL)parent.g; - pgl = pg.pgl; - - glMode = PGL.GL_STATIC_DRAW; - - glFillVertexBufferID = 0; - glFillColorBufferID = 0; - glFillNormalBufferID = 0; - glFillTexCoordBufferID = 0; - glFillAmbientBufferID = 0; - glFillSpecularBufferID = 0; - glFillEmissiveBufferID = 0; - glFillShininessBufferID = 0; - glFillIndexBufferID = 0; - - glLineVertexBufferID = 0; - glLineColorBufferID = 0; - glLineDirWidthBufferID = 0; - glLineIndexBufferID = 0; - - glPointVertexBufferID = 0; - glPointColorBufferID = 0; - glPointSizeBufferID = 0; - glPointIndexBufferID = 0; - - this.tessellator = pg.tessellator; - this.family = family; - this.root = this; - this.parent = null; - this.tessellated = false; - - if (family == GEOMETRY || family == PRIMITIVE || family == PATH) { - in = pg.newInGeometry(RETAINED); - } - tess = pg.newTessGeometry(RETAINED); - fillIndexData = new ArrayList(); - lineIndexData = new ArrayList(); - pointIndexData = new ArrayList(); - - // Modes are retrieved from the current values in the renderer. - textureMode = pg.textureMode; - rectMode = pg.rectMode; - ellipseMode = pg.ellipseMode; - shapeMode = pg.shapeMode; - imageMode = pg.imageMode; - - colorMode(pg.colorMode, pg.colorModeX, pg.colorModeY, pg.colorModeZ, pg.colorModeA); - - // Initial values for fill, stroke and tint colors are also imported from the renderer. - // This is particular relevant for primitive shapes, since is not possible to set - // their color separately when creating them, and their input vertices are actually - // generated at rendering time, by which the color configuration of the renderer might - // have changed. - fill = pg.fill; - fillColor = pg.fillColor; - - stroke = pg.stroke; - strokeColor = pg.strokeColor; - strokeWeight = pg.strokeWeight; - - tint = pg.tint; - tintColor = pg.tintColor; - - ambientColor = pg.ambientColor; - specularColor = pg.specularColor; - emissiveColor = pg.emissiveColor; - shininess = pg.shininess; - - normalX = normalY = 0; - normalZ = 1; - - normalMode = NORMAL_MODE_AUTO; - } - - - public void setKind(int kind) { - this.kind = kind; - } - - - public void setMode(int mode) { - if (mode == STATIC) { - glMode = PGL.GL_STATIC_DRAW; - } else if (mode == DYNAMIC) { - glMode = PGL.GL_DYNAMIC_DRAW; - } else if (mode == STREAM) { - glMode = PGL.GL_STREAM_DRAW; - } - } - - public void addChild(PShape child) { - if (child instanceof PShape3D) { - if (family == GROUP) { - super.addChild(child); - child.updateRoot(root); - root.tessellated = false; - tessellated = false; - ((PShape3D)child).tessellated = false; - } else { - PGraphics.showWarning("Cannot add child shape to non-group shape."); - } - } else { - PGraphics.showWarning("Shape must be 3D to be added to the group."); - } - } - - public void updateRoot(PShape root) { - this.root = (PShape3D) root; - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D)children[i]; - child.updateRoot(root); - } - } - } - - protected void finalize() throws Throwable { - try { - finalizeFillBuffers(); - finalizeLineBuffers(); - finalizePointBuffers(); - } finally { - super.finalize(); - } - } - - protected void finalizeFillBuffers() { - if (glFillVertexBufferID != 0) { - pg.finalizeVertexBufferObject(glFillVertexBufferID); - } - - if (glFillColorBufferID != 0) { - pg.finalizeVertexBufferObject(glFillColorBufferID); - } - - if (glFillNormalBufferID != 0) { - pg.finalizeVertexBufferObject(glFillNormalBufferID); - } - - if (glFillTexCoordBufferID != 0) { - pg.finalizeVertexBufferObject(glFillTexCoordBufferID); - } - - if (glFillAmbientBufferID != 0) { - pg.finalizeVertexBufferObject(glFillAmbientBufferID); - } - - if (glFillSpecularBufferID != 0) { - pg.finalizeVertexBufferObject(glFillSpecularBufferID); - } - - if (glFillEmissiveBufferID != 0) { - pg.finalizeVertexBufferObject(glFillEmissiveBufferID); - } - - if (glFillShininessBufferID != 0) { - pg.finalizeVertexBufferObject(glFillShininessBufferID); - } - - if (glFillIndexBufferID != 0) { - pg.finalizeVertexBufferObject(glFillIndexBufferID); - } - } - - protected void finalizeLineBuffers() { - if (glLineVertexBufferID != 0) { - pg.finalizeVertexBufferObject(glLineVertexBufferID); - } - - if (glLineColorBufferID != 0) { - pg.finalizeVertexBufferObject(glLineColorBufferID); - } - - if (glLineDirWidthBufferID != 0) { - pg.finalizeVertexBufferObject(glLineDirWidthBufferID); - } - - if (glLineIndexBufferID != 0) { - pg.finalizeVertexBufferObject(glLineIndexBufferID); - } - } - - protected void finalizePointBuffers() { - if (glPointVertexBufferID != 0) { - pg.finalizeVertexBufferObject(glPointVertexBufferID); - } - - if (glPointColorBufferID != 0) { - pg.finalizeVertexBufferObject(glPointColorBufferID); - } - - if (glPointSizeBufferID != 0) { - pg.finalizeVertexBufferObject(glPointSizeBufferID); - } - - if (glPointIndexBufferID != 0) { - pg.finalizeVertexBufferObject(glPointIndexBufferID); - } - } - - /////////////////////////////////////////////////////////// - - // - - // Drawing methods - - - public void textureMode(int mode) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.textureMode(mode); - } - } else { - textureMode = mode; - } - } - - - public void texture(PImage tex) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.texture(tex); - } - } else { - PImage tex0 = texture; - texture = tex; - if (tex0 != tex && parent != null) { - ((PShape3D)parent).removeTexture(tex); - } - if (parent != null) { - ((PShape3D)parent).addTexture(texture); - } - } - } - - - public void noTexture() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.noTexture(); - } - } else { - PImage tex0 = texture; - texture = null; - if (tex0 != null && parent != null) { - ((PShape3D)parent).removeTexture(tex0); - } - } - } - - - protected void addTexture(PImage tex) { - if (textures == null) { - textures = new HashSet(); - } - textures.add(tex); - if (parent != null) { - ((PShape3D)parent).addTexture(tex); - } - } - - - protected void removeTexture(PImage tex) { - if (textures != null) { - boolean childHasIt = false; - - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - if (child.hasTexture(tex)) { - childHasIt = true; - break; - } - } - - if (!childHasIt) { - textures.remove(tex); - if (textures.size() == 0) { - textures = null; - } - } - } - } - - - protected boolean hasTexture(PImage tex) { - if (family == GROUP) { - return textures != null && textures.contains(tex); - } else { - return texture == tex; - } - } - - - public void solid(boolean solid) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.solid(solid); - } - } else { - isSolid = solid; - } - } - - - public void beginContour() { - if (family == GROUP) { - PGraphics.showWarning("Cannot begin contour in GROUP shapes"); - return; - } - - if (openContour) { - PGraphics.showWarning("P3D: Already called beginContour()."); - return; - } - openContour = true; - } - - - public void endContour() { - if (family == GROUP) { - PGraphics.showWarning("Cannot end contour in GROUP shapes"); - return; - } - - if (!openContour) { - PGraphics.showWarning("P3D: Need to call beginContour() first."); - return; - } - openContour = false; - breakShape = true; - } - - - public void vertex(float x, float y) { - vertex(x, y, 0, 0, 0); - } - - - public void vertex(float x, float y, float u, float v) { - vertex(x, y, 0, u, v); - } - - - public void vertex(float x, float y, float z) { - vertex(x, y, z, 0, 0); - } - - - public void vertex(float x, float y, float z, float u, float v) { - vertexImpl(x, y, z, u, v, VERTEX); - } - - - protected void vertexImpl(float x, float y, float z, float u, float v, int code) { - if (in.isFull()) { - PGraphics.showWarning("P3D: Too many vertices, try creating smaller shapes"); - return; - } - - if (family == GROUP) { - PGraphics.showWarning("Cannot add vertices to GROUP shape"); - return; - } - - boolean textured = texture != null; - int fcolor = 0x00; - if (fill || textured) { - if (!textured) { - fcolor = fillColor; - } else { - if (tint) { - fcolor = tintColor; - } else { - fcolor = 0xffFFFFFF; - } - } - } - - if (texture != null && textureMode == IMAGE) { - u = PApplet.min(1, u / texture.width); - v = PApplet.min(1, v / texture.height); - } - - int scolor = 0x00; - float sweight = 0; - if (stroke) { - scolor = strokeColor; - sweight = strokeWeight; - } - - if (breakShape) { - code = BREAK; - breakShape = false; - } - - in.addVertex(x, y, z, - fcolor, - normalX, normalY, normalZ, - u, v, - scolor, sweight, - ambientColor, specularColor, emissiveColor, shininess, - code); - - root.tessellated = false; - tessellated = false; - } - - - public void normal(float nx, float ny, float nz) { - if (family == GROUP) { - PGraphics.showWarning("Cannot set normal in GROUP shape"); - return; - } - - normalX = nx; - normalY = ny; - normalZ = nz; - - // if drawing a shape and the normal hasn't been set yet, - // then we need to set the normals for each vertex so far - if (normalMode == NORMAL_MODE_AUTO) { - // One normal per begin/end shape - normalMode = NORMAL_MODE_SHAPE; - } else if (normalMode == NORMAL_MODE_SHAPE) { - // a separate normal for each vertex - normalMode = NORMAL_MODE_VERTEX; - } - } - - - public void end() { - end(OPEN); - } - - - public void end(int mode) { - if (family == GROUP) { - PGraphics.showWarning("Cannot end GROUP shape"); - return; - } - - // Input arrays are trimmed since they are expanded by doubling their old size, - // which might lead to arrays larger than the vertex counts. - in.trim(); - - isClosed = mode == CLOSE; - root.tessellated = false; - tessellated = false; - shapeEnded = true; - } - - - public void setParams(float[] source) { - if (family != PRIMITIVE) { - PGraphics.showWarning("Parameters can only be set to PRIMITIVE shapes"); - return; - } - - super.setParams(source); - root.tessellated = false; - tessellated = false; - shapeEnded = true; - } - - ////////////////////////////////////////////////////////////// - - // STROKE CAP/JOIN/WEIGHT - - - public void strokeWeight(float weight) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.strokeWeight(weight); - } - } else { - strokeWeight = weight; - } - } - - - public void strokeJoin(int join) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.strokeJoin(join); - } - } else { - strokeJoin = join; - } - } - - - public void strokeCap(int cap) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.strokeCap(cap); - } - } else { - strokeCap = cap; - } - } - - - ////////////////////////////////////////////////////////////// - - // FILL COLOR - - - public void noFill() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.noFill(); - } - } else { - fill = false; - fillColor = 0x0; - updateFillColor(); - } - } - - - public void fill(int rgb) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.fill(rgb); - } - } else { - colorCalc(rgb); - fillFromCalc(); - } - } - - - public void fill(int rgb, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.fill(rgb, alpha); - } - } else { - colorCalc(rgb, alpha); - fillFromCalc(); - } - } - - - public void fill(float gray) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.fill(gray); - } - } else { - colorCalc(gray); - fillFromCalc(); - } - } - - - public void fill(float gray, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.fill(gray, alpha); - } - } else { - colorCalc(gray, alpha); - fillFromCalc(); - } - } - - - public void fill(float x, float y, float z) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.fill(x, y, z); - } - } else { - colorCalc(x, y, z); - fillFromCalc(); - } - } - - - public void fill(float x, float y, float z, float a) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.fill(x, y, z, a); - } - } else { - colorCalc(x, y, z, a); - fillFromCalc(); - } - } - - - protected void fillFromCalc() { - fill = true; - fillColor = calcColor; - updateFillColor(); - } - - - protected void updateFillColor() { - if (!shapeEnded || tess.fillVertexCount == 0 || texture != null) { - return; - } - - updateTesselation(); - - int[] temp = new int[tess.fillVertexCount]; - Arrays.fill(temp, 0, tess.fillVertexCount, fillColor); - tess.fillColors.rewind(); - tess.fillColors.put(temp); - - modifiedFillColors = true; - modified(); - } - - ////////////////////////////////////////////////////////////// - - // STROKE COLOR - - - public void noStroke() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.noStroke(); - } - } else { - stroke = false; - strokeColor = 0x0; - updateStrokeColor(); - } - } - - - public void stroke(int rgb) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.stroke(rgb); - } - } else { - colorCalc(rgb); - strokeFromCalc(); - } - } - - - public void stroke(int rgb, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.stroke(rgb, alpha); - } - } else { - colorCalc(rgb, alpha); - strokeFromCalc(); - } - } - - - public void stroke(float gray) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.stroke(gray); - } - } else { - colorCalc(gray); - strokeFromCalc(); - } - } - - - public void stroke(float gray, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.stroke(gray, alpha); - } - } else { - colorCalc(gray, alpha); - strokeFromCalc(); - } - } - - - public void stroke(float x, float y, float z) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.stroke(x, y, z); - } - } else { - colorCalc(x, y, z); - strokeFromCalc(); - } - } - - - public void stroke(float x, float y, float z, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.stroke(x, y, z, alpha); - } - } else { - colorCalc(x, y, z, alpha); - strokeFromCalc(); - } - } - - - protected void strokeFromCalc() { - stroke = true; - strokeColor = calcColor; - updateStrokeColor(); - } - - - protected void updateStrokeColor() { - if (shapeEnded) { - updateTesselation(); - - if (0 < tess.lineVertexCount) { - int[] temp = new int[tess.lineVertexCount]; - Arrays.fill(temp, 0, tess.lineVertexCount, strokeColor); - tess.lineColors.rewind(); - tess.lineColors.put(temp); - modifiedLineColors = true; - modified(); - } - - if (0 < tess.pointVertexCount) { - int[] temp = new int[tess.pointVertexCount]; - Arrays.fill(temp, 0, tess.pointVertexCount, strokeColor); - tess.pointColors.rewind(); - tess.pointColors.put(temp); - modifiedPointColors = true; - modified(); - } - } - } - - - ////////////////////////////////////////////////////////////// - - // TINT COLOR - - - public void noTint() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.noTint(); - } - } else { - tint = false; - tintColor = 0x0; - updateTintColor(); - } - } - - - public void tint(int rgb) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tint(rgb); - } - } else { - colorCalc(rgb); - tintFromCalc(); - } - } - - - public void tint(int rgb, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tint(rgb, alpha); - } - } else { - colorCalc(rgb, alpha); - tintFromCalc(); - } - } - - - public void tint(float gray) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tint(gray); - } - } else { - colorCalc(gray); - tintFromCalc(); - } - } - - - public void tint(float gray, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tint(gray, alpha); - } - } else { - colorCalc(gray, alpha); - tintFromCalc(); - } - } - - - public void tint(float x, float y, float z) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tint(x, y, z); - } - } else { - colorCalc(x, y, z); - tintFromCalc(); - } - } - - - public void tint(float x, float y, float z, float alpha) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tint(x, y, z, alpha); - } - } else { - colorCalc(x, y, z, alpha); - tintFromCalc(); - } - } - - - protected void tintFromCalc() { - tint = true; - tintColor = calcColor; - updateTintColor(); - } - - - protected void updateTintColor() { - if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { - return; - } - - updateTesselation(); - - int[] temp = new int[tess.fillVertexCount]; - Arrays.fill(temp, 0, tess.fillVertexCount, tintColor); - tess.fillColors.rewind(); - tess.fillColors.put(temp); - - modifiedFillColors = true; - modified(); - } - - ////////////////////////////////////////////////////////////// - - // AMBIENT COLOR - - public void ambient(int rgb) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.ambient(rgb); - } - } else { - colorCalc(rgb); - ambientFromCalc(); - } - } - - - public void ambient(float gray) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.ambient(gray); - } - } else { - colorCalc(gray); - ambientFromCalc(); - } - } - - - public void ambient(float x, float y, float z) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.ambient(x, y, z); - } - } else { - colorCalc(x, y, z); - ambientFromCalc(); - } - } - - protected void ambientFromCalc() { - ambientColor = calcColor; - updateAmbientColor(); - } - - protected void updateAmbientColor() { - if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { - return; - } - - updateTesselation(); - - int[] temp = new int[tess.fillVertexCount]; - Arrays.fill(temp, 0, tess.fillVertexCount, ambientColor); - tess.fillAmbient.rewind(); - tess.fillAmbient.put(temp); - - modifiedFillAmbient = true; - modified(); - } - - ////////////////////////////////////////////////////////////// - - // SPECULAR COLOR - - - public void specular(int rgb) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.specular(rgb); - } - } else { - colorCalc(rgb); - specularFromCalc(); - } - } - - - public void specular(float gray) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.specular(gray); - } - } else { - colorCalc(gray); - specularFromCalc(); - } - } - - - public void specular(float x, float y, float z) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.specular(x, y, z); - } - } else { - colorCalc(x, y, z); - specularFromCalc(); - } - } - - protected void specularFromCalc() { - specularColor = calcColor; - updateSpecularColor(); - } - - protected void updateSpecularColor() { - if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { - return; - } - - updateTesselation(); - - int[] temp = new int[tess.fillVertexCount]; - Arrays.fill(temp, 0, tess.fillVertexCount, specularColor); - tess.fillSpecular.rewind(); - tess.fillSpecular.put(temp); - - modifiedFillSpecular = true; - modified(); - } - - ////////////////////////////////////////////////////////////// - - // EMISSIVE COLOR - - - public void emissive(int rgb) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.emissive(rgb); - } - } else { - colorCalc(rgb); - emissiveFromCalc(); - } - } - - - public void emissive(float gray) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.emissive(gray); - } - } else { - colorCalc(gray); - emissiveFromCalc(); - } - } - - - public void emissive(float x, float y, float z) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.emissive(x, y, z); - } - } else { - colorCalc(x, y, z); - emissiveFromCalc(); - } - } - - protected void emissiveFromCalc() { - emissiveColor = calcColor; - updateEmissiveColor(); - } - - protected void updateEmissiveColor() { - if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { - return; - } - - updateTesselation(); - - int[] temp = new int[tess.fillVertexCount]; - Arrays.fill(temp, 0, tess.fillVertexCount, emissiveColor); - tess.fillEmissive.rewind(); - tess.fillEmissive.put(temp); - - modifiedFillEmissive = true; - modified(); - } - - ////////////////////////////////////////////////////////////// - - // SHININESS - - - public void shininess(float shine) { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.shininess(shine); - } - } else { - shininess = shine; - updateShininessFactor(); - } - } - - - protected void updateShininessFactor() { - if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { - return; - } - - updateTesselation(); - - float[] temp = new float[tess.fillVertexCount]; - Arrays.fill(temp, 0, tess.fillVertexCount, shininess); - tess.fillShininess.rewind(); - tess.fillShininess.put(temp); - - modifiedFillShininess = true; - modified(); - } - - /////////////////////////////////////////////////////////// - - // - - // Geometric transformations - - - protected int updateCenter(PVector vec, int count) { - if (family == GROUP) { - count = updateCenter(vec, count); - } else { - count += tess.sumVertices(vec); - } - return count; - } - - - public void center(float cx, float cy) { - if (family == GROUP) { - PVector center = new PVector(); - - int count = updateCenter(center, 0); - center.x /= count; - center.y /= count; - - float tx = cx - center.x; - float ty = cy - center.y; - - childHasMatrix(); - applyMatrix = true; - super.translate(tx, ty); - } else { - PVector vec = new PVector(); - int count = tess.sumVertices(vec); - vec.x /= count; - vec.y /= count; - - float tx = cx - vec.x; - float ty = cy - vec.y; - - translate(tx, ty); - } - } - - public void center(float cx, float cy, float cz) { - if (family == GROUP) { - PVector center0 = new PVector(); - - int count = updateCenter(center0, 0); - center0.x /= count; - center0.y /= count; - center0.z /= count; - - float tx = cx - center0.x; - float ty = cy - center0.y; - float tz = cz - center0.z; - - childHasMatrix(); - applyMatrix = true; - super.translate(tx, ty, tz); - } else { - PVector vec = new PVector(); - int count = tess.sumVertices(vec); - vec.x /= count; - vec.y /= count; - vec.z /= count; - - float tx = cx - vec.x; - float ty = cy - vec.y; - float tz = cz - vec.z; - - translate(tx, ty, tz); - } - } - - public void translate(float tx, float ty) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.translate(tx, ty); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(2); - matrix.reset(); - matrix.translate(tx, ty); - tess.applyMatrix((PMatrix2D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - public void translate(float tx, float ty, float tz) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.translate(tx, ty, tz); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(3); - matrix.reset(); - matrix.translate(tx, ty, tz); - tess.applyMatrix((PMatrix3D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - - public void rotate(float angle) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.rotate(angle); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(2); - matrix.reset(); - matrix.rotate(angle); - tess.applyMatrix((PMatrix2D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - - } - - public void rotate(float angle, float v0, float v1, float v2) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.rotate(angle, v0, v1, v2); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(3); - matrix.reset(); - matrix.rotate(angle, v0, v1, v2); - tess.applyMatrix((PMatrix3D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - public void scale(float s) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.scale(s); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(2); - matrix.reset(); - matrix.scale(s); - tess.applyMatrix((PMatrix2D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - - public void scale(float x, float y) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.scale(x, y); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(2); - matrix.reset(); - matrix.scale(x, y); - tess.applyMatrix((PMatrix2D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - - public void scale(float x, float y, float z) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.scale(x, y, z); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(3); - matrix.reset(); - matrix.scale(x, y, z); - tess.applyMatrix((PMatrix3D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - - public void applyMatrix(PMatrix source) { - super.applyMatrix(source); - } - - - public void applyMatrix(PMatrix2D source) { - super.applyMatrix(source); - } - - - public void applyMatrix(float n00, float n01, float n02, - float n10, float n11, float n12) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.applyMatrix(n00, n01, n02, - n10, n11, n12); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(2); - matrix.reset(); - matrix.apply(n00, n01, n02, - n10, n11, n12); - tess.applyMatrix((PMatrix2D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - - public void apply(PMatrix3D source) { - applyMatrix(source.m00, source.m01, source.m02, source.m03, - source.m10, source.m11, source.m12, source.m13, - source.m20, source.m21, source.m22, source.m23, - source.m30, source.m31, source.m32, source.m33); - } - - - public void applyMatrix(float n00, float n01, float n02, float n03, - float n10, float n11, float n12, float n13, - float n20, float n21, float n22, float n23, - float n30, float n31, float n32, float n33) { - if (family == GROUP) { - childHasMatrix(); - applyMatrix = true; - super.applyMatrix(n00, n01, n02, n03, - n10, n11, n12, n13, - n20, n21, n22, n23, - n30, n31, n32, n33); - } else { - if (!shapeEnded) { - PGraphics.showWarning("Transformations can be applied only after the shape has been ended."); - return; - } - - checkMatrix(3); - matrix.reset(); - matrix.apply(n00, n01, n02, n03, - n10, n11, n12, n13, - n20, n21, n22, n23, - n30, n31, n32, n33); - tess.applyMatrix((PMatrix3D) matrix); - - modified(); - if (0 < tess.fillVertexCount) { - modifiedFillVertices = true; - modifiedFillNormals = true; - } - if (0 < tess.lineVertexCount) { - modifiedLineVertices = true; - modifiedLineAttributes = true; - } - if (0 < tess.pointVertexCount) { - modifiedPointVertices = true; - modifiedPointNormals = true; - } - - // So the transformation is not applied again when drawing - applyMatrix = false; - } - } - - - public void resetMatrix() { - // TODO - // What to do in the case of geometry shapes? - // In order to properly reset the transformation, - // we need to have the last matrix applied, calculate - // the inverse and apply on the tess object... - //checkMatrix(2); - //matrix.reset(); - } - - - protected void childHasMatrix() { - childHasMatrix = true; - if (parent != null) { - ((PShape3D)parent).childHasMatrix(); - } - } - - /////////////////////////////////////////////////////////// - - // - - // Bezier curves - - public void bezierDetail(int detail) { - bezierDetail = detail; - - if (bezierDrawMatrix == null) { - bezierDrawMatrix = new PMatrix3D(); - } - - // setup matrix for forward differencing to speed up drawing - pg.splineForward(detail, bezierDrawMatrix); - - // multiply the basis and forward diff matrices together - // saves much time since this needn't be done for each curve - bezierDrawMatrix.apply(pg.bezierBasisMatrix); - } - - public void bezierVertex(float x2, float y2, - float x3, float y3, - float x4, float y4) { - bezierVertex(x2, y2, 0, x3, y3, 0, x4, y4, 0); - } - - public void bezierVertex(float x2, float y2, float z2, - float x3, float y3, float z3, - float x4, float y4, float z4) { - bezierInitCheck(); - bezierVertexCheck(); - PMatrix3D draw = bezierDrawMatrix; - - float x1 = in.getLastVertexX(); - float y1 = in.getLastVertexY(); - float z1 = in.getLastVertexZ(); - - float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; - float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; - float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; - - float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; - float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; - float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; - - float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; - float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; - float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; - - for (int j = 0; j < bezierDetail; j++) { - x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3; - y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3; - z1 += zplot1; zplot1 += zplot2; zplot2 += zplot3; - vertexImpl(x1, y1, z1, 0, 0, BEZIER_VERTEX); - } - } - - public void quadraticVertex(float cx, float cy, - float x3, float y3) { - quadraticVertex(cx, cy, 0, - x3, y3, 0); - } - - public void quadraticVertex(float cx, float cy, float cz, - float x3, float y3, float z3) { - float x1 = in.getLastVertexX(); - float y1 = in.getLastVertexY(); - float z1 = in.getLastVertexZ(); - - bezierVertex(x1 + ((cx-x1)*2/3.0f), y1 + ((cy-y1)*2/3.0f), z1 + ((cz-z1)*2/3.0f), - x3 + ((cx-x3)*2/3.0f), y3 + ((cy-y3)*2/3.0f), z3 + ((cz-z3)*2/3.0f), - x3, y3, z3); - } - - protected void bezierInitCheck() { - if (!bezierInited) { - bezierInit(); - } - } - - protected void bezierInit() { - // overkill to be broken out, but better parity with the curve stuff below - bezierDetail(bezierDetail); - bezierInited = true; - } - - protected void bezierVertexCheck() { - if (kind != POLYGON) { - throw new RuntimeException("createGeometry() or createGeometry(POLYGON) " + - "must be used before bezierVertex() or quadraticVertex()"); - } - if (in.vertexCount == 0) { - throw new RuntimeException("vertex() must be used at least once" + - "before bezierVertex() or quadraticVertex()"); - } - } - - /////////////////////////////////////////////////////////// - - // - - // Catmull-Rom curves - - public void curveDetail(int detail) { - curveDetail = detail; - curveInit(); - } - - public void curveTightness(float tightness) { - curveTightness = tightness; - curveInit(); - } - - public void curveVertex(float x, float y) { - curveVertex(x, y, 0); - } - - public void curveVertex(float x, float y, float z) { - curveVertexCheck(); - float[] vertex = curveVertices[curveVertexCount]; - vertex[X] = x; - vertex[Y] = y; - vertex[Z] = z; - curveVertexCount++; - - // draw a segment if there are enough points - if (curveVertexCount > 3) { - curveVertexSegment(curveVertices[curveVertexCount-4][X], - curveVertices[curveVertexCount-4][Y], - curveVertices[curveVertexCount-4][Z], - curveVertices[curveVertexCount-3][X], - curveVertices[curveVertexCount-3][Y], - curveVertices[curveVertexCount-3][Z], - curveVertices[curveVertexCount-2][X], - curveVertices[curveVertexCount-2][Y], - curveVertices[curveVertexCount-2][Z], - curveVertices[curveVertexCount-1][X], - curveVertices[curveVertexCount-1][Y], - curveVertices[curveVertexCount-1][Z]); - } - - } - - protected void curveVertexCheck() { - - if (kind != POLYGON) { - throw new RuntimeException("You must use createGeometry() or " + - "createGeometry(POLYGON) before curveVertex()"); - } - - // to improve code init time, allocate on first use. - if (curveVertices == null) { - curveVertices = new float[128][3]; - } - - if (curveVertexCount == curveVertices.length) { - // Can't use PApplet.expand() cuz it doesn't do the copy properly - float[][] temp = new float[curveVertexCount << 1][3]; - System.arraycopy(curveVertices, 0, temp, 0, curveVertexCount); - curveVertices = temp; - } - curveInitCheck(); - } - - protected void curveInitCheck() { - if (!curveInited) { - curveInit(); - } - } - - protected void curveInit() { - // allocate only if/when used to save startup time - if (curveDrawMatrix == null) { - curveBasisMatrix = new PMatrix3D(); - curveDrawMatrix = new PMatrix3D(); - curveInited = true; - } - - float s = curveTightness; - curveBasisMatrix.set((s-1)/2f, (s+3)/2f, (-3-s)/2f, (1-s)/2f, - (1-s), (-5-s)/2f, (s+2), (s-1)/2f, - (s-1)/2f, 0, (1-s)/2f, 0, - 0, 1, 0, 0); - - pg.splineForward(curveDetail, curveDrawMatrix); - - if (bezierBasisInverse == null) { - bezierBasisInverse = pg.bezierBasisMatrix.get(); - bezierBasisInverse.invert(); - curveToBezierMatrix = new PMatrix3D(); - } - - // TODO only needed for PGraphicsJava2D? if so, move it there - // actually, it's generally useful for other renderers, so keep it - // or hide the implementation elsewhere. - curveToBezierMatrix.set(curveBasisMatrix); - curveToBezierMatrix.preApply(bezierBasisInverse); - - // multiply the basis and forward diff matrices together - // saves much time since this needn't be done for each curve - curveDrawMatrix.apply(curveBasisMatrix); - } - - /** - * Handle emitting a specific segment of Catmull-Rom curve. This can be - * overridden by subclasses that need more efficient rendering options. - */ - protected void curveVertexSegment(float x1, float y1, float z1, - float x2, float y2, float z2, - float x3, float y3, float z3, - float x4, float y4, float z4) { - float x0 = x2; - float y0 = y2; - float z0 = z2; - - PMatrix3D draw = curveDrawMatrix; - - float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4; - float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4; - float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4; - - float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4; - float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4; - float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4; - - float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4; - float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4; - float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4; - - vertexImpl(x0, y0, z0, 0, 0, CURVE_VERTEX); - for (int j = 0; j < curveDetail; j++) { - x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; - y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; - z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3; - vertexImpl(x0, y0, z0, 0, 0, CURVE_VERTEX); - } - } - - - /////////////////////////////////////////////////////////// - - // - - // Methods to access tessellated data. - - - public int firstFillVertex() { - updateTesselation(); - return tess.firstFillVertex; - } - - public int lastFillVertex() { - updateTesselation(); - return tess.lastFillVertex; - } - - public int fillVertexCount() { - updateTesselation(); - return tess.fillVertexCount; - } - - public int firstFillIndex() { - updateTesselation(); - return tess.firstFillIndex; - } - - public int lastFillIndex() { - updateTesselation(); - return tess.lastFillIndex; - } - - public int fillIndexCount() { - updateTesselation(); - return tess.fillIndexCount; - } - - public float[] fillVertices(float[] vertices) { - updateTesselation(); - if (vertices == null || vertices.length != tess.fillVertices.capacity()) { - vertices = new float[tess.fillVertices.capacity()]; - } - tess.fillVertices.rewind(); - tess.fillVertices.get(vertices); - return vertices; - } - - public int[] fillColors(int[] colors) { - updateTesselation(); - if (colors == null || colors.length != tess.fillColors.capacity()) { - colors = new int[tess.fillVertices.capacity()]; - } - tess.fillColors.rewind(); - tess.fillColors.get(colors); - return colors; - } - - public float[] fillNormals(float[] normals) { - updateTesselation(); - if (normals == null || normals.length != tess.fillNormals.capacity()) { - normals = new float[tess.fillNormals.capacity()]; - } - tess.fillNormals.rewind(); - tess.fillNormals.get(normals); - return normals; - } - - public float[] fillTexCoords(float[] texcoords) { - updateTesselation(); - if (texcoords == null || texcoords.length != tess.fillTexcoords.capacity()) { - texcoords = new float[tess.fillTexcoords.capacity()]; - } - tess.fillTexcoords.rewind(); - tess.fillTexcoords.get(texcoords); - return texcoords; - } - - public int[] fillAmbient(int[] ambient) { - updateTesselation(); - if (ambient == null || ambient.length != tess.fillAmbient.capacity()) { - ambient = new int[tess.fillAmbient.capacity()]; - } - tess.fillAmbient.rewind(); - tess.fillAmbient.get(ambient); - return ambient; - } - - public int[] fillSpecular(int[] specular) { - updateTesselation(); - if (specular == null || specular.length != tess.fillSpecular.capacity()) { - specular = new int[tess.fillSpecular.capacity()]; - } - tess.fillSpecular.rewind(); - tess.fillSpecular.get(specular); - return specular; - } - - public int[] fillEmissive(int[] emissive) { - updateTesselation(); - if (emissive == null || emissive.length != tess.fillEmissive.capacity()) { - emissive = new int[tess.fillEmissive.capacity()]; - } - tess.fillEmissive.rewind(); - tess.fillEmissive.get(emissive); - return emissive; - } - - public float[] fillShininess(float[] shininess) { - updateTesselation(); - if (shininess == null || shininess.length != tess.fillShininess.capacity()) { - shininess = new float[tess.fillShininess.capacity()]; - } - tess.fillShininess.rewind(); - tess.fillShininess.get(shininess); - return shininess; - } - - public int[] fillIndices(int[] indices) { - updateTesselation(); - if (indices == null || indices.length != tess.fillIndices.capacity()) { - indices = new int[tess.fillIndices.capacity()]; - } - tess.fillIndices.rewind(); - tess.fillIndices.get(indices); - return indices; - } - - public int firstLineVertex() { - updateTesselation(); - return tess.firstLineVertex; - } - - public int lastLineVertex() { - updateTesselation(); - return tess.lastLineVertex; - } - - public int lineVertexCount() { - updateTesselation(); - return tess.lineVertexCount; - } - - public int firstLineIndex() { - updateTesselation(); - return tess.firstLineIndex; - } - - public int lastLineIndex() { - updateTesselation(); - return tess.lastLineIndex; - } - - public int lineIndexCount() { - updateTesselation(); - return tess.lineIndexCount; - } - - public float[] lineVertices(float[] vertices) { - updateTesselation(); - if (vertices == null || vertices.length != tess.lineVertices.capacity()) { - vertices = new float[tess.lineVertices.capacity()]; - } - tess.lineVertices.rewind(); - tess.lineVertices.get(vertices); - return vertices; - } - - public int[] lineColors(int[] colors) { - updateTesselation(); - if (colors == null || colors.length != tess.lineColors.capacity()) { - colors = new int[tess.lineColors.capacity()]; - } - tess.lineColors.rewind(); - tess.lineColors.get(colors); - return colors; - } - - public float[] lineAttributes(float[] attribs) { - updateTesselation(); - if (attribs == null || attribs.length != tess.lineDirWidths.capacity()) { - attribs = new float[tess.lineDirWidths.capacity()]; - } - tess.lineDirWidths.rewind(); - tess.lineDirWidths.get(attribs); - return attribs; - } - - public int[] lineIndices(int[] indices) { - updateTesselation(); - if (indices == null || indices.length != tess.lineIndices.capacity()) { - indices = new int[tess.lineIndices.capacity()]; - } - tess.lineIndices.rewind(); - tess.lineIndices.get(indices); - return indices; - } - - public int firstPointVertex() { - updateTesselation(); - return tess.firstPointVertex; - } - - public int lastPointVertex() { - updateTesselation(); - return tess.lastPointVertex; - } - - public int pointVertexCount() { - updateTesselation(); - return tess.pointVertexCount; - } - - public int firstPointIndex() { - updateTesselation(); - return tess.firstPointIndex; - } - - public int lastPointIndex() { - updateTesselation(); - return tess.lastPointIndex; - } - - public int pointIndexCount() { - updateTesselation(); - return tess.pointIndexCount; - } - - public float[] pointVertices(float[] vertices) { - updateTesselation(); - if (vertices == null || vertices.length != tess.pointVertices.capacity()) { - vertices = new float[tess.pointVertices.capacity()]; - } - tess.pointVertices.rewind(); - tess.pointVertices.get(vertices); - return vertices; - } - - public int[] pointColors(int[] colors) { - updateTesselation(); - if (colors == null || colors.length != tess.pointColors.capacity()) { - colors = new int[tess.pointColors.capacity()]; - } - tess.pointColors.rewind(); - tess.pointColors.get(colors); - return colors; - } - - public float[] pointAttributes(float[] attribs) { - updateTesselation(); - if (attribs == null || attribs.length != tess.pointSizes.capacity()) { - attribs = new float[tess.pointSizes.capacity()]; - } - tess.pointSizes.rewind(); - tess.pointSizes.get(attribs); - return attribs; - } - - public int[] pointIndices(int[] indices) { - updateTesselation(); - if (indices == null || indices.length != tess.pointIndices.capacity()) { - indices = new int[tess.pointIndices.capacity()]; - } - tess.pointIndices.rewind(); - tess.pointIndices.get(indices); - return indices; - } - - public FloatBuffer mapFillVertices() { - return mapVertexImpl(root.glFillVertexBufferID, 3 * tess.firstFillVertex, 3 * tess.fillVertexCount).asFloatBuffer(); - } - - public void unmapFillVertices() { - unmapVertexImpl(); - } - - public FloatBuffer mapFillColors() { - return mapVertexImpl(root.glFillColorBufferID, 4 * tess.firstFillVertex, 4 * tess.fillVertexCount).asFloatBuffer(); - } - - public void unmapFillColors() { - unmapVertexImpl(); - } - - public FloatBuffer mapFillNormals() { - return mapVertexImpl(root.glFillNormalBufferID, 3 * tess.firstFillVertex, 3 * tess.fillVertexCount).asFloatBuffer(); - } - - public void unmapFillNormals() { - unmapVertexImpl(); - } - - public FloatBuffer mapFillTexCoords() { - return mapVertexImpl(root.glFillTexCoordBufferID, 2 * tess.firstFillVertex, 2 * tess.fillVertexCount).asFloatBuffer(); - } - - public IntBuffer mapFillAmbient() { - return mapVertexImpl(root.glFillAmbientBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); - } - - public void unmapFillAmbient() { - unmapVertexImpl(); - } - - public IntBuffer mapFillSpecular() { - return mapVertexImpl(root.glFillSpecularBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); - } - - public void unmapFillSpecular() { - unmapVertexImpl(); - } - - public IntBuffer mapFillEmissive() { - return mapVertexImpl(root.glFillEmissiveBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); - } - - public void unmapFillEmissive() { - unmapVertexImpl(); - } - - public FloatBuffer mapFillShininess() { - return mapVertexImpl(root.glFillShininessBufferID, tess.firstFillVertex, tess.fillVertexCount).asFloatBuffer(); - } - - public void unmapFillShininess() { - unmapVertexImpl(); - } - - public void unmapFillTexCoords() { - unmapVertexImpl(); - } - - public IntBuffer mapFillIndices() { - return mapIndexImpl(root.glFillIndexBufferID, tess.firstFillIndex, tess.fillIndexCount).asIntBuffer(); - } - - public void unmapFillIndices() { - unmapIndexImpl(); - } - - public FloatBuffer mapLineVertices() { - return mapVertexImpl(root.glLineVertexBufferID, 3 * tess.firstLineVertex, 3 * tess.lineVertexCount).asFloatBuffer(); - } - - public void unmapLineVertices() { - unmapVertexImpl(); - } - - public FloatBuffer mapLineColors() { - return mapVertexImpl(root.glLineColorBufferID, 4 * tess.firstLineVertex, 4 * tess.lineVertexCount).asFloatBuffer(); - } - - public void unmapLineColors() { - unmapVertexImpl(); - } - - public void unmapLineNormals() { - unmapVertexImpl(); - } - - public FloatBuffer mapLineAttributes() { - return mapVertexImpl(root.glLineDirWidthBufferID, 2 * tess.firstLineVertex, 2 * tess.lineVertexCount).asFloatBuffer(); - } - - public void unmapLineAttributes() { - unmapVertexImpl(); - } - - public IntBuffer mapLineIndices() { - return mapIndexImpl(root.glLineIndexBufferID, tess.firstLineIndex, tess.lineIndexCount).asIntBuffer(); - } - - public void unmapLineIndices() { - unmapIndexImpl(); - } - - public FloatBuffer mapPointVertices() { - return mapVertexImpl(root.glPointVertexBufferID, 3 * tess.firstPointVertex, 3 * tess.pointVertexCount).asFloatBuffer(); - } - - public void unmapPointVertices() { - unmapVertexImpl(); - } - - public FloatBuffer mapPointColors() { - return mapVertexImpl(root.glPointColorBufferID, 4 * tess.firstPointVertex, 4 * tess.pointVertexCount).asFloatBuffer(); - } - - public void unmapPointColors() { - unmapVertexImpl(); - } - - public void unmapPointNormals() { - unmapVertexImpl(); - } - - public FloatBuffer mapPointAttributes() { - return mapVertexImpl(root.glPointSizeBufferID, 2 * tess.firstPointVertex, 2 * tess.pointVertexCount).asFloatBuffer(); - } - - public void unmapPointAttributes() { - unmapVertexImpl(); - } - - public IntBuffer mapPointIndices() { - return mapIndexImpl(root.glPointIndexBufferID, tess.firstPointIndex, tess.pointIndexCount).asIntBuffer(); - } - - public void unmapPointIndices() { - unmapIndexImpl(); - } - - protected ByteBuffer mapVertexImpl(int id, int offset, int count) { - updateTesselation(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, id); - ByteBuffer bb; - if (root == this) { - bb = pgl.glMapBuffer(PGL.GL_ARRAY_BUFFER, PGL.GL_READ_WRITE); - } else { - bb = pgl.glMapBufferRange(PGL.GL_ARRAY_BUFFER, offset, count, PGL.GL_READ_WRITE); - } - return bb; - } - - protected void unmapVertexImpl() { - pgl.glUnmapBuffer(PGL.GL_ARRAY_BUFFER); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - protected ByteBuffer mapIndexImpl(int id, int offset, int count) { - updateTesselation(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, id); - ByteBuffer bb; - if (root == this) { - bb = pgl.glMapBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, PGL.GL_READ_WRITE); - } else { - bb = pgl.glMapBufferRange(PGL.GL_ELEMENT_ARRAY_BUFFER, offset, count, PGL.GL_READ_WRITE); - } - return bb; - } - - protected void unmapIndexImpl() { - pgl.glUnmapBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - /////////////////////////////////////////////////////////// - - // - - // Construction methods - - - protected void updateTesselation() { - if (!root.tessellated) { - root.tessellate(); - root.aggregate(); - } - } - - - protected void tessellate() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.tessellate(); - } - } else { - if (!tessellated && shapeEnded) { - tess.clear(); - tessellator.setInGeometry(in); - tessellator.setTessGeometry(tess); - tessellator.setFill(fill || texture != null); - tessellator.setStroke(stroke); - tessellator.setStrokeWeight(strokeWeight); - tessellator.setStrokeCap(strokeCap); - tessellator.setStrokeJoin(strokeJoin); - - if (family == GEOMETRY) { - if (kind == POINTS) { - tessellator.tessellatePoints(); - } else if (kind == LINES) { - tessellator.tessellateLines(); - } else if (kind == TRIANGLE || kind == TRIANGLES) { - if (stroke) in.addTrianglesEdges(); - if (normalMode == NORMAL_MODE_AUTO) in.calcTrianglesNormals(); - tessellator.tessellateTriangles(); - } else if (kind == TRIANGLE_FAN) { - if (stroke) in.addTriangleFanEdges(); - if (normalMode == NORMAL_MODE_AUTO) in.calcTriangleFanNormals(); - tessellator.tessellateTriangleFan(); - } else if (kind == TRIANGLE_STRIP) { - if (stroke) in.addTriangleStripEdges(); - if (normalMode == NORMAL_MODE_AUTO) in.calcTriangleStripNormals(); - tessellator.tessellateTriangleStrip(); - } else if (kind == QUAD || kind == QUADS) { - if (stroke) in.addQuadsEdges(); - if (normalMode == NORMAL_MODE_AUTO) in.calcQuadsNormals(); - tessellator.tessellateQuads(); - } else if (kind == QUAD_STRIP) { - if (stroke) in.addQuadStripEdges(); - if (normalMode == NORMAL_MODE_AUTO) in.calcQuadStripNormals(); - tessellator.tessellateQuadStrip(); - } else if (kind == POLYGON) { - if (stroke) in.addPolygonEdges(isClosed); - tessellator.tessellatePolygon(isSolid, isClosed, normalMode == NORMAL_MODE_AUTO); - } - } else if (family == PRIMITIVE) { - if (kind == POINT) { - tessellatePoint(); - } else if (kind == LINE) { - tessellateLine(); - } else if (kind == TRIANGLE) { - tessellateTriangle(); - } else if (kind == QUAD) { - tessellateQuad(); - } else if (kind == RECT) { - tessellateRect(); - } else if (kind == ELLIPSE) { - tessellateEllipse(); - } else if (kind == ARC) { - tessellateArc(); - } else if (kind == BOX) { - tessellateBox(); - } else if (kind == SPHERE) { - tessellateSphere(); - } - } else if (family == PATH) { - // TODO: Determine if this is necessary, since it is - // equivalent to use POLYGON with fill disabled. - } - - // Tessellated arrays are trimmed since they are expanded by doubling their old size, - // which might lead to arrays larger than the vertex counts. - tess.trim(); - - if (texture != null && parent != null) { - ((PShape3D)parent).addTexture(texture); - } - } - } - - tessellated = true; - modified = false; - } - - - protected void tessellatePoint() { - - } - - - protected void tessellateLine() { - - } - - - protected void tessellateTriangle() { - - } - - - protected void tessellateQuad() { - - } - - - protected void tessellateRect() { - - } - - - protected void tessellateEllipse() { - float a = params[0]; - float b = params[1]; - float c = params[2]; - float d = params[3]; - - in.generateEllipse(ellipseMode, a, b, c, d, - fill, fillColor, - stroke, strokeColor, strokeWeight, - ambientColor, specularColor, emissiveColor, shininess); - - tessellator.tessellateTriangleFan(); - } - - - protected void tessellateArc() { - - } - - - protected void tessellateBox() { - // TODO: move to InGeometry - float w = params[0]; - float h = params[1]; - float d = params[2]; - - float x1 = -w/2f; float x2 = w/2f; - float y1 = -h/2f; float y2 = h/2f; - float z1 = -d/2f; float z2 = d/2f; - - // front - normal(0, 0, 1); - vertex(x1, y1, z1, 0, 0); - vertex(x2, y1, z1, 1, 0); - vertex(x2, y2, z1, 1, 1); - vertex(x1, y2, z1, 0, 1); - - // right - normal(1, 0, 0); - vertex(x2, y1, z1, 0, 0); - vertex(x2, y1, z2, 1, 0); - vertex(x2, y2, z2, 1, 1); - vertex(x2, y2, z1, 0, 1); - - // back - normal(0, 0, -1); - vertex(x2, y1, z2, 0, 0); - vertex(x1, y1, z2, 1, 0); - vertex(x1, y2, z2, 1, 1); - vertex(x2, y2, z2, 0, 1); - - // left - normal(-1, 0, 0); - vertex(x1, y1, z2, 0, 0); - vertex(x1, y1, z1, 1, 0); - vertex(x1, y2, z1, 1, 1); - vertex(x1, y2, z2, 0, 1); - - // top - normal(0, 1, 0); - vertex(x1, y1, z2, 0, 0); - vertex(x2, y1, z2, 1, 0); - vertex(x2, y1, z1, 1, 1); - vertex(x1, y1, z1, 0, 1); - - // bottom - normal(0, -1, 0); - vertex(x1, y2, z1, 0, 0); - vertex(x2, y2, z1, 1, 0); - vertex(x2, y2, z2, 1, 1); - vertex(x1, y2, z2, 0, 1); - - if (stroke) in.addQuadsEdges(); - tessellator.tessellateQuads(); - } - - - protected void tessellateSphere() { - // TODO: move to InGeometry - float r = params[0]; - int nu = pg.sphereDetailU; - int nv = pg.sphereDetailV; - - if ((nu < 3) || (nv < 2)) { - nu = nv = 30; - } - - float startLat = -90; - float startLon = 0.0f; - - float latInc = 180.0f / nu; - float lonInc = 360.0f / nv; - - float phi1, phi2; - float theta1, theta2; - float x0, y0, z0; - float x1, y1, z1; - float x2, y2, z2; - float x3, y3, z3; - float u1, v1, u2, v2, v3; - - for (int col = 0; col < nu; col++) { - phi1 = (startLon + col * lonInc) * DEG_TO_RAD; - phi2 = (startLon + (col + 1) * lonInc) * DEG_TO_RAD; - for (int row = 0; row < nv; row++) { - theta1 = (startLat + row * latInc) * DEG_TO_RAD; - theta2 = (startLat + (row + 1) * latInc) * DEG_TO_RAD; - - x0 = PApplet.cos(phi1) * PApplet.cos(theta1); - x1 = PApplet.cos(phi1) * PApplet.cos(theta2); - x2 = PApplet.cos(phi2) * PApplet.cos(theta2); - - y0 = PApplet.sin(theta1); - y1 = PApplet.sin(theta2); - y2 = PApplet.sin(theta2); - - z0 = PApplet.sin(phi1) * PApplet.cos(theta1); - z1 = PApplet.sin(phi1) * PApplet.cos(theta2); - z2 = PApplet.sin(phi2) * PApplet.cos(theta2); - - x3 = PApplet.cos(phi2) * PApplet.cos(theta1); - y3 = PApplet.sin(theta1); - z3 = PApplet.sin(phi2) * PApplet.cos(theta1); - - u1 = PApplet.map(phi1, TWO_PI, 0, 0, 1); - u2 = PApplet.map(phi2, TWO_PI, 0, 0, 1); - v1 = PApplet.map(theta1, -HALF_PI, HALF_PI, 0, 1); - v2 = PApplet.map(theta2, -HALF_PI, HALF_PI, 0, 1); - v3 = PApplet.map(theta1, -HALF_PI, HALF_PI, 0, 1); - - normal(x0, y0, z0); - vertex(r * x0, r * y0, r * z0, u1, v1); - - normal(x1, y1, z1); - vertex(r * x1, r * y1, r * z1, u1, v2); - - normal(x2, y2, z2); - vertex(r * x2, r * y2, r * z2, u2, v2); - - normal(x0, y0, z0); - vertex(r * x0, r * y0, r * z0, u1, v1); - - normal(x2, y2, z2); - vertex(r * x2, r * y2, r * z2, u2, v2); - - normal(x3, y3, z3); - vertex(r * x3, r * y3, r * z3, u2, v3); - } - } - - if (stroke) in.addTrianglesEdges(); - tessellator.tessellateTriangles(); - } - - - protected void updateGeometry() { - if (root == this && parent == null && modified) { - // Initializing offsets - fillVertCopyOffset = 0; - lineVertCopyOffset = 0; - pointVertCopyOffset = 0; - - updateRootGeometry(); - - // Copying any data remaining in the caches - if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { - root.fillVerticesCache.prepareForCopy(); - root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); - root.fillVerticesCache.reset(); - } - - if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { - root.fillColorsCache.prepareForCopy(); - root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.intData); - root.fillColorsCache.reset(); - } - - if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { - root.fillNormalsCache.prepareForCopy(); - root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); - root.fillNormalsCache.reset(); - } - - if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { - root.fillTexCoordsCache.prepareForCopy(); - root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); - root.fillTexCoordsCache.reset(); - } - - if (root.fillAmbientCache != null && root.fillAmbientCache.hasData()) { - root.fillAmbientCache.prepareForCopy(); - root.copyFillAmbient(root.fillAmbientCache.offset, root.fillAmbientCache.size, root.fillAmbientCache.intData); - root.fillAmbientCache.reset(); - } - - if (root.fillSpecularCache != null && root.fillSpecularCache.hasData()) { - root.fillSpecularCache.prepareForCopy(); - root.copyfillSpecular(root.fillSpecularCache.offset, root.fillSpecularCache.size, root.fillSpecularCache.intData); - root.fillSpecularCache.reset(); - } - - if (root.fillEmissiveCache != null && root.fillEmissiveCache.hasData()) { - root.fillEmissiveCache.prepareForCopy(); - root.copyFillEmissive(root.fillEmissiveCache.offset, root.fillEmissiveCache.size, root.fillEmissiveCache.intData); - root.fillEmissiveCache.reset(); - } - - if (root.fillShininessCache != null && root.fillShininessCache.hasData()) { - root.fillShininessCache.prepareForCopy(); - root.copyFillShininess(root.fillShininessCache.offset, root.fillShininessCache.size, root.fillShininessCache.floatData); - root.fillShininessCache.reset(); - } - - if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { - root.lineVerticesCache.prepareForCopy(); - root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); - root.lineVerticesCache.reset(); - } - - if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { - root.lineColorsCache.prepareForCopy(); - root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.intData); - root.lineColorsCache.reset(); - } - - if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { - root.lineAttributesCache.prepareForCopy(); - root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); - root.lineAttributesCache.reset(); - } - - if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { - root.pointVerticesCache.prepareForCopy(); - root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); - root.pointVerticesCache.reset(); - } - - if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { - root.pointColorsCache.prepareForCopy(); - root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.intData); - root.pointColorsCache.reset(); - } - - if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { - root.pointAttributesCache.prepareForCopy(); - root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); - root.pointAttributesCache.reset(); - } - } - } - - - protected void aggregate() { - if (root == this && parent == null) { - // We recursively calculate the total number of vertices and indices. - lastFillVertexOffset = 0; - lastFillIndexOffset = 0; - firstFillVertexRel = 0; - firstFillVertexAbs = 0; - - lastLineVertexOffset = 0; - lastLineIndexOffset = 0; - firstLineVertexRel = 0; - firstLineVertexAbs = 0; - - lastPointVertexOffset = 0; - lastPointIndexOffset = 0; - firstPointVertexRel = 0; - firstPointVertexAbs = 0; - - aggregateImpl(); - - // Now that we know, we can initialize the buffers with the correct size. - if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { - initFillBuffers(tess.fillVertexCount, tess.fillIndexCount); - fillVertCopyOffset = 0; - fillIndCopyOffset = 0; - copyFillGeometryToRoot(); - } - - if (0 < tess.lineVertexCount && 0 < tess.lineIndexCount) { - initLineBuffers(tess.lineVertexCount, tess.lineIndexCount); - lineVertCopyOffset = 0; - lineIndCopyOffset = 0; - copyLineGeometryToRoot(); - } - - if (0 < tess.pointVertexCount && 0 < tess.pointIndexCount) { - initPointBuffers(tess.pointVertexCount, tess.pointIndexCount); - pointVertCopyOffset = 0; - pointIndCopyOffset = 0; - copyPointGeometryToRoot(); - } - } - } - - - // This method is very important, as it is responsible of - // generating the correct vertex and index values for each - // level of the shape hierarchy. - protected void aggregateImpl() { - if (family == GROUP) { - tess.clear(); - - boolean firstGeom = true; - boolean firstStroke = true; - boolean firstPoint = true; - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.aggregateImpl(); - - tess.addCounts(child.tess); - - if (0 < child.tess.fillVertexCount) { - if (firstGeom) { - tess.setFirstFill(child.tess); - firstGeom = false; - } - tess.setLastFill(child.tess); - } - - if (0 < child.tess.lineVertexCount) { - if (firstStroke) { - tess.setFirstLine(child.tess); - firstStroke = false; - } - tess.setLastLine(child.tess); - } - - if (0 < child.tess.pointVertexCount) { - if (firstPoint) { - tess.setFirstPoint(child.tess); - firstPoint = false; - } - tess.setLastPoint(child.tess); - } - } - - addFillIndexData(); - addLineIndexData(); - addPointIndexData(); - } else { - if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { - if (PGL.MAX_TESS_VERTICES < root.firstFillVertexRel + tess.fillVertexCount) { - root.firstFillVertexRel = 0; - root.firstFillVertexAbs = root.lastFillVertexOffset + 1; - } - root.lastFillVertexOffset = tess.setFillVertex(root.lastFillVertexOffset); - root.lastFillIndexOffset = tess.setFillIndex(root.firstFillVertexRel, root.lastFillIndexOffset); - root.firstFillVertexRel += tess.fillVertexCount; - addFillIndexData(root.firstFillVertexAbs, tess.firstFillIndex, tess.lastFillIndex - tess.firstFillIndex + 1); - } - - if (0 < tess.lineVertexCount && 0 < tess.lineIndexCount) { - if (PGL.MAX_TESS_VERTICES < root.firstLineVertexRel + tess.lineVertexCount) { - root.firstLineVertexRel = 0; - root.firstLineVertexAbs = root.lastLineVertexOffset + 1; - } - root.lastLineVertexOffset = tess.setLineVertex(root.lastLineVertexOffset); - root.lastLineIndexOffset = tess.setLineIndex(root.firstLineVertexRel, root.lastLineIndexOffset); - addLineIndexData(root.firstLineVertexAbs, tess.firstLineIndex, tess.lastLineIndex - tess.firstLineIndex + 1); - } - - if (0 < tess.pointVertexCount && 0 < tess.pointIndexCount) { - if (PGL.MAX_TESS_VERTICES < root.firstPointVertexRel + tess.pointVertexCount) { - root.firstPointVertexRel = 0; - root.firstPointVertexAbs = root.lastPointVertexOffset + 1; - } - root.lastPointVertexOffset = tess.setPointVertex(root.lastPointVertexOffset); - root.lastPointIndexOffset = tess.setPointIndex(root.firstPointVertexRel, root.lastPointIndexOffset); - addPointIndexData(root.firstPointVertexAbs, tess.firstPointIndex, tess.lastPointIndex - tess.firstPointIndex + 1); - } - } - - hasFill = 0 < tess.fillVertexCount && 0 < tess.fillIndexCount; - hasLines = 0 < tess.lineVertexCount && 0 < tess.lineIndexCount; - hasPoints = 0 < tess.pointVertexCount && 0 < tess.pointIndexCount; - } - - // Creates fill index data for a geometry shape. - protected void addFillIndexData(int first, int offset, int size) { - fillIndexData.clear(); - IndexData data = new IndexData(first, offset, size); - fillIndexData.add(data); - } - - // Creates fill index data for a group shape. - protected void addFillIndexData() { - fillIndexData.clear(); - IndexData gdata = null; - - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - - for (int j = 0; j < child.fillIndexData.size(); j++) { - IndexData cdata = child.fillIndexData.get(j); - - if (gdata == null) { - gdata = new IndexData(cdata.first, cdata.offset, cdata.size); - fillIndexData.add(gdata); - } else { - if (gdata.first == cdata.first) { - gdata.size += cdata.size; - } else { - gdata = new IndexData(cdata.first, cdata.offset, cdata.size); - fillIndexData.add(gdata); - } - } - } - - } - } - - // Creates line index data for a geometry shape. - protected void addLineIndexData(int first, int offset, int size) { - lineIndexData.clear(); - IndexData data = new IndexData(first, offset, size); - lineIndexData.add(data); - } - - // Creates line index data for a group shape. - protected void addLineIndexData() { - lineIndexData.clear(); - IndexData gdata = null; - - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - - for (int j = 0; j < child.lineIndexData.size(); j++) { - IndexData cdata = child.lineIndexData.get(j); - - if (gdata == null) { - gdata = new IndexData(cdata.first, cdata.offset, cdata.size); - lineIndexData.add(gdata); - } else { - if (gdata.first == cdata.first) { - gdata.size += cdata.size; - } else { - gdata = new IndexData(cdata.first, cdata.offset, cdata.size); - lineIndexData.add(gdata); - } - } - } - - } - } - - // Creates point index data for a geometry shape. - protected void addPointIndexData(int first, int offset, int size) { - pointIndexData.clear(); - IndexData data = new IndexData(first, offset, size); - pointIndexData.add(data); - } - - // Creates point index data for a group shape. - protected void addPointIndexData() { - pointIndexData.clear(); - IndexData gdata = null; - - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - - for (int j = 0; j < child.pointIndexData.size(); j++) { - IndexData cdata = child.pointIndexData.get(j); - - if (gdata == null) { - gdata = new IndexData(cdata.first, cdata.offset, cdata.size); - pointIndexData.add(gdata); - } else { - if (gdata.first == cdata.first) { - gdata.size += cdata.size; - } else { - gdata = new IndexData(cdata.first, cdata.offset, cdata.size); - pointIndexData.add(gdata); - } - } - } - - } - } - - protected void initFillBuffers(int nvert, int nind) { - int sizef = nvert * PGL.SIZEOF_FLOAT; - int sizei = nvert * PGL.SIZEOF_INT; - int sizex = nind * PGL.SIZEOF_INDEX; - - glFillVertexBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); - - glFillColorBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - - glFillNormalBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); - - glFillTexCoordBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, glMode); - - glFillAmbientBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - - glFillSpecularBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - - glFillEmissiveBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - - glFillShininessBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, glMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - glFillIndexBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - protected void copyFillGeometryToRoot() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.copyFillGeometryToRoot(); - } - } else { - if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { - tess.prepareFillVerticesForCopy(); - root.copyFillGeometry(root.fillVertCopyOffset, tess.fillVertexCount, - tess.fillVertices, tess.fillColors, tess.fillNormals, tess.fillTexcoords, - tess.fillAmbient, tess.fillSpecular, tess.fillEmissive, tess.fillShininess); - root.fillVertCopyOffset += tess.fillVertexCount; - - tess.prepareFillIndicesForCopy(); - root.copyFillIndices(root.fillIndCopyOffset, tess.fillIndexCount, tess.fillIndices); - root.fillIndCopyOffset += tess.fillIndexCount; - } - } - } - - - protected void updateRootGeometry() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.updateRootGeometry(); - } - } else { - - if (0 < tess.fillVertexCount) { - tess.prepareFillVerticesForCopy(); - - if (modifiedFillVertices) { - if (root.fillVerticesCache == null) { - root.fillVerticesCache = new VertexCache(3, true); - } - root.fillVerticesCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillVertices); - modifiedFillVertices = false; - } else if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { - root.fillVerticesCache.prepareForCopy(); - root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); - root.fillVerticesCache.reset(); - } - - if (modifiedFillColors) { - if (root.fillColorsCache == null) { - root.fillColorsCache = new VertexCache(1, false); - } - root.fillColorsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillColors); - modifiedFillColors = false; - } else if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { - root.fillColorsCache.prepareForCopy(); - root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.intData); - root.fillColorsCache.reset(); - } - - if (modifiedFillNormals) { - if (root.fillNormalsCache == null) { - root.fillNormalsCache = new VertexCache(3, true); - } - root.fillNormalsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillNormals); - modifiedFillNormals = false; - } else if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { - root.fillNormalsCache.prepareForCopy(); - root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); - root.fillNormalsCache.reset(); - } - - if (modifiedFillTexCoords) { - if (root.fillTexCoordsCache == null) { - root.fillTexCoordsCache = new VertexCache(2, true); - } - root.fillTexCoordsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillTexcoords); - modifiedFillTexCoords = false; - } else if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { - root.fillTexCoordsCache.prepareForCopy(); - root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); - root.fillTexCoordsCache.reset(); - } - - if (modifiedFillAmbient) { - if (root.fillAmbientCache == null) { - root.fillAmbientCache = new VertexCache(1, false); - } - root.fillAmbientCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillAmbient); - modifiedFillAmbient = false; - } else if (root.fillAmbientCache != null && root.fillAmbientCache.hasData()) { - root.fillAmbientCache.prepareForCopy(); - root.copyFillAmbient(root.fillAmbientCache.offset, root.fillAmbientCache.size, root.fillAmbientCache.intData); - root.fillAmbientCache.reset(); - } - - if (modifiedFillSpecular) { - if (root.fillSpecularCache == null) { - root.fillSpecularCache = new VertexCache(1, false); - } - root.fillSpecularCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillSpecular); - modifiedFillSpecular = false; - } else if (root.fillSpecularCache != null && root.fillSpecularCache.hasData()) { - root.fillSpecularCache.prepareForCopy(); - root.copyfillSpecular(root.fillSpecularCache.offset, root.fillSpecularCache.size, root.fillSpecularCache.intData); - root.fillSpecularCache.reset(); - } - - if (modifiedFillEmissive) { - if (root.fillEmissiveCache == null) { - root.fillEmissiveCache = new VertexCache(1, false); - } - root.fillEmissiveCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillEmissive); - modifiedFillEmissive = false; - } else if (root.fillEmissiveCache != null && root.fillEmissiveCache.hasData()) { - root.fillEmissiveCache.prepareForCopy(); - root.copyFillEmissive(root.fillEmissiveCache.offset, root.fillEmissiveCache.size, root.fillEmissiveCache.intData); - root.fillEmissiveCache.reset(); - } - - if (modifiedFillShininess) { - if (root.fillShininessCache == null) { - root.fillShininessCache = new VertexCache(1, true); - } - root.fillShininessCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillShininess); - modifiedFillShininess = false; - } else if (root.fillShininessCache != null && root.fillShininessCache.hasData()) { - root.fillShininessCache.prepareForCopy(); - root.copyFillShininess(root.fillShininessCache.offset, root.fillShininessCache.size, root.fillShininessCache.floatData); - root.fillShininessCache.reset(); - } - } - - if (0 < tess.lineVertexCount) { - tess.prepareLineVerticesForCopy(); - - if (modifiedLineVertices) { - if (root.lineVerticesCache == null) { - root.lineVerticesCache = new VertexCache(3, true); - } - root.lineVerticesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineVertices); - modifiedLineVertices = false; - } else if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { - root.lineVerticesCache.prepareForCopy(); - root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); - root.lineVerticesCache.reset(); - } - - if (modifiedLineColors) { - if (root.lineColorsCache == null) { - root.lineColorsCache = new VertexCache(1, false); - } - root.lineColorsCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineColors); - modifiedLineColors = false; - } else if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { - root.lineColorsCache.prepareForCopy(); - root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.intData); - root.lineColorsCache.reset(); - } - - if (modifiedLineAttributes) { - if (root.lineAttributesCache == null) { - root.lineAttributesCache = new VertexCache(4, true); - } - root.lineAttributesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineDirWidths); - modifiedLineAttributes = false; - } else if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { - root.lineAttributesCache.prepareForCopy(); - root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); - root.lineAttributesCache.reset(); - } - } - - if (0 < tess.pointVertexCount) { - tess.preparePointVerticesForCopy(); - - if (modifiedPointVertices) { - if (root.pointVerticesCache == null) { - root.pointVerticesCache = new VertexCache(3, true); - } - root.pointVerticesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointVertices); - modifiedPointVertices = false; - } else if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { - root.pointVerticesCache.prepareForCopy(); - root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); - root.pointVerticesCache.reset(); - } - - if (modifiedPointColors) { - if (root.pointColorsCache == null) { - root.pointColorsCache = new VertexCache(1, false); - } - root.pointColorsCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointColors); - modifiedPointColors = false; - } else if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { - root.pointColorsCache.prepareForCopy(); - root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.intData); - root.pointColorsCache.reset(); - } - - if (modifiedPointAttributes) { - if (root.pointAttributesCache == null) { - root.pointAttributesCache = new VertexCache(2, true); - } - root.pointAttributesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointSizes); - modifiedPointAttributes = false; - } else if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { - root.pointAttributesCache.prepareForCopy(); - root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); - root.pointAttributesCache.reset(); - } - } - - root.fillVertCopyOffset += tess.fillVertexCount; - root.lineVertCopyOffset += tess.lineVertexCount; - root.pointVertCopyOffset += tess.pointVertexCount; - } - - modified = false; - } - - - protected void copyFillGeometry(int offset, int size, - FloatBuffer vertices, IntBuffer colors, - FloatBuffer normals, FloatBuffer texcoords, - IntBuffer ambient, IntBuffer specular, IntBuffer emissive, FloatBuffer shininess) { - int offsetf = offset * PGL.SIZEOF_FLOAT; - int offseti = offset * PGL.SIZEOF_INT; - int sizef = size * PGL.SIZEOF_FLOAT; - int sizei = size * PGL.SIZEOF_INT; - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, vertices); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, colors); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, normals); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, texcoords); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, ambient); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, specular); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, emissive); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offsetf, sizef, shininess); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillVertices(int offset, int size, FloatBuffer vertices) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, vertices); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillColors(int offset, int size, IntBuffer colors) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, colors); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillNormals(int offset, int size, FloatBuffer normals) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, normals); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillTexCoords(int offset, int size, FloatBuffer texcoords) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, texcoords); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillAmbient(int offset, int size, IntBuffer ambient) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, ambient); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyfillSpecular(int offset, int size, IntBuffer specular) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, specular); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillEmissive(int offset, int size, IntBuffer emissive) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, emissive); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillShininess(int offset, int size, FloatBuffer shininess) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT, size * PGL.SIZEOF_FLOAT, shininess); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyFillIndices(int offset, int size, IntBuffer indices) { - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, indices); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - protected void initLineBuffers(int nvert, int nind) { - int sizef = nvert * PGL.SIZEOF_FLOAT; - int sizei = nvert * PGL.SIZEOF_INT; - int sizex = nind * PGL.SIZEOF_INDEX; - - glLineVertexBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); - - glLineColorBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - - glLineDirWidthBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, glMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - glLineIndexBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - protected void copyLineGeometryToRoot() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.copyLineGeometryToRoot(); - } - } else { - if (hasLines) { - tess.prepareLineVerticesForCopy(); - root.copyLineGeometry(root.lineVertCopyOffset, tess.lineVertexCount, - tess.lineVertices, tess.lineColors, tess.lineDirWidths); - root.lineVertCopyOffset += tess.lineVertexCount; - - tess.prepareLineIndicesForCopy(); - root.copyLineIndices(root.lineIndCopyOffset, tess.lineIndexCount, tess.lineIndices); - root.lineIndCopyOffset += tess.lineIndexCount; - } - } - } - - - protected void copyLineGeometry(int offset, int size, - FloatBuffer vertices, IntBuffer colors, FloatBuffer attribs) { - int offsetf = offset * PGL.SIZEOF_FLOAT; - int sizef = size * PGL.SIZEOF_FLOAT; - int offseti = offset * PGL.SIZEOF_INT; - int sizei = size * PGL.SIZEOF_INT; - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, vertices); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, colors); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offsetf, 4 * sizef, attribs); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyLineVertices(int offset, int size, FloatBuffer vertices) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, vertices); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyLineColors(int offset, int size, IntBuffer colors) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, colors); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyLineAttributes(int offset, int size, FloatBuffer attribs) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, attribs); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyLineIndices(int offset, int size, IntBuffer indices) { - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); - pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, indices); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - protected void initPointBuffers(int nvert, int nind) { - int sizef = nvert * PGL.SIZEOF_FLOAT; - int sizei = nvert * PGL.SIZEOF_INT; - int sizex = nind * PGL.SIZEOF_INDEX; - - glPointVertexBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); - - glPointColorBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - - glPointSizeBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, glMode); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - - glPointIndexBufferID = pg.createVertexBufferObject(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - protected void copyPointGeometryToRoot() { - if (family == GROUP) { - for (int i = 0; i < childCount; i++) { - PShape3D child = (PShape3D) children[i]; - child.copyPointGeometryToRoot(); - } - } else { - if (hasPoints) { - tess.preparePointVerticesForCopy(); - root.copyPointGeometry(root.pointVertCopyOffset, tess.pointVertexCount, - tess.pointVertices, tess.pointColors, tess.pointSizes); - root.pointVertCopyOffset += tess.pointVertexCount; - - tess.preparePointIndicesForCopy(); - root.copyPointIndices(root.pointIndCopyOffset, tess.pointIndexCount, tess.pointIndices); - root.pointIndCopyOffset += tess.pointIndexCount; - } - } - } - - - protected void copyPointGeometry(int offset, int size, - FloatBuffer vertices, IntBuffer colors, FloatBuffer attribs) { - int offsetf = offset * PGL.SIZEOF_FLOAT; - int sizef = size * PGL.SIZEOF_FLOAT; - int offseti = offset * PGL.SIZEOF_INT; - int sizei = size * PGL.SIZEOF_INT; - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, vertices); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, colors); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, attribs); - - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyPointVertices(int offset, int size, FloatBuffer vertices) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, vertices); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyPointColors(int offset, int size, IntBuffer colors) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, colors); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyPointAttributes(int offset, int size, FloatBuffer attribs) { - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, attribs); - pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); - } - - - protected void copyPointIndices(int offset, int size, IntBuffer indices) { - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); - pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, indices); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - - /////////////////////////////////////////////////////////// - - // - - // Deletion methods - - - protected void release() { - deleteFillBuffers(); - deleteLineBuffers(); - deletePointBuffers(); - } - - - protected void deleteFillBuffers() { - if (glFillVertexBufferID != 0) { - pg.deleteVertexBufferObject(glFillVertexBufferID); - glFillVertexBufferID = 0; - } - - if (glFillColorBufferID != 0) { - pg.deleteVertexBufferObject(glFillColorBufferID); - glFillColorBufferID = 0; - } - - if (glFillNormalBufferID != 0) { - pg.deleteVertexBufferObject(glFillNormalBufferID); - glFillNormalBufferID = 0; - } - - if (glFillTexCoordBufferID != 0) { - pg.deleteVertexBufferObject(glFillTexCoordBufferID); - glFillTexCoordBufferID = 0; - } - - if (glFillAmbientBufferID != 0) { - pg.deleteVertexBufferObject(glFillAmbientBufferID); - glFillAmbientBufferID = 0; - } - - if (glFillSpecularBufferID != 0) { - pg.deleteVertexBufferObject(glFillSpecularBufferID); - glFillSpecularBufferID = 0; - } - - if (glFillEmissiveBufferID != 0) { - pg.deleteVertexBufferObject(glFillEmissiveBufferID); - glFillEmissiveBufferID = 0; - } - - if (glFillShininessBufferID != 0) { - pg.deleteVertexBufferObject(glFillShininessBufferID); - glFillShininessBufferID = 0; - } - - if (glFillIndexBufferID != 0) { - pg.deleteVertexBufferObject(glFillIndexBufferID); - glFillIndexBufferID = 0; - } - } - - - protected void deleteLineBuffers() { - if (glLineVertexBufferID != 0) { - pg.deleteVertexBufferObject(glLineVertexBufferID); - glLineVertexBufferID = 0; - } - - if (glLineColorBufferID != 0) { - pg.deleteVertexBufferObject(glLineColorBufferID); - glLineColorBufferID = 0; - } - - if (glLineDirWidthBufferID != 0) { - pg.deleteVertexBufferObject(glLineDirWidthBufferID); - glLineDirWidthBufferID = 0; - } - - if (glLineIndexBufferID != 0) { - pg.deleteVertexBufferObject(glLineIndexBufferID); - glLineIndexBufferID = 0; - } - } - - - protected void deletePointBuffers() { - if (glPointVertexBufferID != 0) { - pg.deleteVertexBufferObject(glPointVertexBufferID); - glPointVertexBufferID = 0; - } - - if (glPointColorBufferID != 0) { - pg.deleteVertexBufferObject(glPointColorBufferID); - glPointColorBufferID = 0; - } - - if (glPointSizeBufferID != 0) { - pg.deleteVertexBufferObject(glPointSizeBufferID); - glPointSizeBufferID = 0; - } - - if (glPointIndexBufferID != 0) { - pg.deleteVertexBufferObject(glPointIndexBufferID); - glPointIndexBufferID = 0; - } - } - - /////////////////////////////////////////////////////////// - - // - - // Rendering methods - - - public void draw() { - draw(pg); - } - - - public void draw(PGraphics g) { - if (visible) { - - updateTesselation(); - updateGeometry(); - - if (matrix != null && applyMatrix) { - g.pushMatrix(); - g.applyMatrix(matrix); - } - - if (family == GROUP) { - - boolean matrixBelow = childHasMatrix; - boolean diffTexBelow = textures != null && 1 < textures.size(); - - if (matrixBelow || diffTexBelow) { - // Some child shape below this group has a non-null matrix - // transformation assigned to it, so the group cannot - // be drawn in a single render call. - // Or, some child shapes below this group use different - // texture maps, so they cannot rendered in a single call - // either. - - for (int i = 0; i < childCount; i++) { - ((PShape3D) children[i]).draw(g); - } - } else { - // None of the child shapes below this group has a matrix - // transformation applied to them, so we can render everything - // in a single block. - // And all have the same texture applied to them. - PImage tex = null; - if (textures != null && textures.size() == 1) { - tex = (PImage)textures.toArray()[0]; - } - render(tex); - } - - } else { - render(texture); - } - - if (matrix != null) { - g.popMatrix(); - } - } - } - - - // Render the geometry stored in the root shape as VBOs, for the vertices - // corresponding to this shape. Sometimes we can have root == this. - protected void render(PImage texture) { - if (root == null) { - // Some error. Root should never be null. At least it should be this. - return; - } - - if (hasPoints) { - renderPoints(); - } - - if (hasLines) { - renderLines(); - } - - if (hasFill) { - renderFill(texture); - } - } - - - protected void renderPoints() { - PointShader shader = pg.getPointShader(); - shader.start(); - - for (int i = 0; i < pointIndexData.size(); i++) { - IndexData index = (IndexData)pointIndexData.get(i); - int first = index.first; - int offset = index.offset; - int size = index.size; - - shader.setVertexAttribute(root.glPointVertexBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(root.glPointColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - shader.setSizeAttribute(root.glPointSizeBufferID, 2, PGL.GL_FLOAT, 0, 2 * first * PGL.SIZEOF_FLOAT); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, root.glPointIndexBufferID); - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - shader.stop(); - } - - - protected void renderLines() { - LineShader shader = pg.getLineShader(); - shader.start(); - - for (int i = 0; i < lineIndexData.size(); i++) { - IndexData index = (IndexData)lineIndexData.get(i); - int first = index.first; - int offset = index.offset; - int size = index.size; - - shader.setVertexAttribute(root.glLineVertexBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(root.glLineColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - shader.setDirWidthAttribute(root.glLineDirWidthBufferID, 4, PGL.GL_FLOAT, 0, 4 * first * PGL.SIZEOF_FLOAT); - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, root.glLineIndexBufferID); - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - shader.stop(); - } - - - protected void renderFill(PImage textureImage) { - PTexture tex = null; - if (textureImage != null) { - tex = pg.getTexture(textureImage); - if (tex != null) { - pgl.enableTexturing(tex.glTarget); - pgl.glBindTexture(tex.glTarget, tex.glID); - } - } - - FillShader shader = pg.getFillShader(pg.lights, tex != null); - shader.start(); - - for (int i = 0; i < fillIndexData.size(); i++) { - IndexData index = (IndexData)fillIndexData.get(i); - int first = index.first; - int offset = index.offset; - int size = index.size; - - shader.setVertexAttribute(root.glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(root.glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - - if (pg.lights) { - shader.setNormalAttribute(root.glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); - shader.setAmbientAttribute(root.glFillAmbientBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - shader.setSpecularAttribute(root.glFillSpecularBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - shader.setEmissiveAttribute(root.glFillEmissiveBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - shader.setShininessAttribute(root.glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, first * PGL.SIZEOF_FLOAT); - } - - if (tex != null) { - shader.setTexCoordAttribute(root.glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 2 * first * PGL.SIZEOF_FLOAT); - shader.setTexture(tex); - } - - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, root.glFillIndexBufferID); - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - shader.stop(); - - if (tex != null) { - pgl.glBindTexture(tex.glTarget, 0); - pgl.disableTexturing(tex.glTarget); - } - } - - - /////////////////////////////////////////////////////////// - - // - - protected class IndexData { - IndexData(int first, int offset, int size) { - this.first = first; - this.offset = offset; - this.size = size; - } - int first; - int offset; - int size; - } - - /////////////////////////////////////////////////////////// - - // - - // Internal class to store a cache of vertex data used to copy data - // to the VBOs with fewer calls. - protected class VertexCache { - boolean isFloat; - int ncoords; // Number of components per data element - int offset; // Offset (in the dest VBO) to start copying this data to - int size; // Total number of data elements - FloatBuffer floatData; - IntBuffer intData; - - VertexCache(int ncoords, boolean isFloat) { - this.ncoords = ncoords; - this.isFloat = isFloat; - if (isFloat) { - this.floatData = pgl.createFloatBuffer(ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE); - } else { - this.intData = pgl.createIntBuffer(ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE); - } - this.offset = 0; - this.size = 0; - } - - void reset() { - offset = 0; - size = 0; - if (isFloat) { - floatData.clear(); - } else { - intData.clear(); - } - } - - void add(int dataOffset, int dataSize, FloatBuffer newData) { - if (size == 0) { - offset = dataOffset; - } - - int oldSize = floatData.capacity() / ncoords; - if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); - prepareFloatDataForCopy(); - expand(newSize); - } - - floatData.position(ncoords * size); - floatData.put(newData); - - size += dataSize; - } - - void add(int dataOffset, int dataSize, IntBuffer newData) { - if (size == 0) { - offset = dataOffset; - } - - int oldSize = intData.capacity() / ncoords; - if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); - prepareIntDataForCopy(); - expand(newSize); - } - - intData.position(ncoords * size); - intData.put(newData); - - size += dataSize; - } - - void add(int dataOffset, int dataSize, float[] newData, PMatrix tr) { - if (tr instanceof PMatrix2D) { - add(dataOffset, dataSize, newData, (PMatrix2D)tr); - } else if (tr instanceof PMatrix3D) { - add(dataOffset, dataSize, newData, (PMatrix3D)tr); - } - } - - void add(int dataOffset, int dataSize, FloatBuffer newData, PMatrix2D tr) { - if (size == 0) { - offset = dataOffset; - } - - int oldSize = floatData.capacity() / ncoords; - if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); - prepareFloatDataForCopy(); - expand(newSize); - } - - if (2 <= ncoords) { - float[] data0 = new float[2]; - float[] data1 = new float[2]; - for (int i = 0; i < dataSize; i++) { - newData.get(data0); - - data1[0] = data0[0] * tr.m00 + data0[1] * tr.m01 + tr.m02; - data1[1] = data0[0] * tr.m10 + data0[1] * tr.m11 + tr.m12; - floatData.position(ncoords * (size + i)); - floatData.put(data1, 0, 2); - } - } - - size += dataSize; - } - - void add(int dataOffset, int dataSize, FloatBuffer newData, PMatrix3D tr) { - if (size == 0) { - offset = dataOffset; - } - - int oldSize = floatData.capacity() / ncoords; - if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); - prepareIntDataForCopy(); - expand(newSize); - } - - if (3 <= ncoords) { - float[] data0 = new float[3]; - float[] data1 = new float[3]; - for (int i = 0; i < dataSize; i++) { - newData.get(data0); - - data1[0] = data0[0] * tr.m00 + data0[1] * tr.m01 + data0[2] * tr.m02 + tr.m03; - data1[1] = data0[0] * tr.m10 + data0[1] * tr.m11 + data0[2] * tr.m12 + tr.m13; - data1[2] = data0[0] * tr.m20 + data0[1] * tr.m21 + data0[2] * tr.m22 + tr.m23; - - floatData.position(ncoords * (size + i)); - floatData.put(data1); - } - } - - size += dataSize; - } - - void prepareForCopy() { - if (isFloat) { - prepareFloatDataForCopy(); - } else { - prepareIntDataForCopy(); - } - } - - void prepareFloatDataForCopy() { - floatData.position(0); - floatData.limit(ncoords * size); - } - - void prepareIntDataForCopy() { - intData.position(0); - intData.limit(ncoords * size); - } - - void expand(int n) { - if (isFloat) { - expandFloat(n); - } else { - expandInt(n); - } - } - - void expandFloat(int n) { - FloatBuffer temp = pgl.createFloatBuffer(ncoords * n); - temp.put(floatData); - floatData = temp; - } - - void expandInt(int n) { - IntBuffer temp = pgl.createIntBuffer(ncoords * n); - temp.put(intData); - intData = temp; - } - - int expandSize(int currSize, int newMinSize) { - int newSize = currSize; - while (newSize < newMinSize) { - newSize = newSize << 1; - } - return newSize; - } - - boolean hasData() { - return 0 < size; - } - } - - - /////////////////////////////////////////////////////////////////////////// - - // OBJ loading - - - protected BufferedReader getBufferedReader(String filename) { - //BufferedReader retval = papplet.createReader(filename); - BufferedReader retval = null; - if (retval != null) { - return retval; - } else { - PApplet.println("Could not find this file " + filename); - return null; - } - } - - - protected void parseOBJ(BufferedReader reader, ArrayList vertices, ArrayList normals, ArrayList textures, ArrayList faces, ArrayList materials) { - Hashtable mtlTable = new Hashtable(); - int mtlIdxCur = -1; - boolean readv, readvn, readvt; - try { - // Parse the line. - - readv = readvn = readvt = false; - String line; - String gname = "object"; - while ((line = reader.readLine()) != null) { - - // The below patch/hack comes from Carlos Tomas Marti and is a - // fix for single backslashes in Rhino obj files - - // BEGINNING OF RHINO OBJ FILES HACK - // Statements can be broken in multiple lines using '\' at the - // end of a line. - // In regular expressions, the backslash is also an escape - // character. - // The regular expression \\ matches a single backslash. This - // regular expression as a Java string, becomes "\\\\". - // That's right: 4 backslashes to match a single one. - while (line.contains("\\")) { - line = line.split("\\\\")[0]; - final String s = reader.readLine(); - if (s != null) - line += s; - } - // END OF RHINO OBJ FILES HACK - - String[] elements = line.split("\\s+"); - // if not a blank line, process the line. - if (elements.length > 0) { - if (elements[0].equals("v")) { - // vertex - PVector tempv = new PVector(Float.valueOf(elements[1]).floatValue(), Float.valueOf(elements[2]).floatValue(), Float.valueOf(elements[3]).floatValue()); - vertices.add(tempv); - readv = true; - } else if (elements[0].equals("vn")) { - // normal - PVector tempn = new PVector(Float.valueOf(elements[1]).floatValue(), Float.valueOf(elements[2]).floatValue(), Float.valueOf(elements[3]).floatValue()); - normals.add(tempn); - readvn = true; - } else if (elements[0].equals("vt")) { - // uv - PVector tempv = new PVector(Float.valueOf(elements[1]).floatValue(), Float.valueOf(elements[2]).floatValue()); - textures.add(tempv); - readvt = true; - } else if (elements[0].equals("o")) { - // Object name is ignored, for now. - } else if (elements[0].equals("mtllib")) { - if (elements[1] != null) { - parseMTL(getBufferedReader(elements[1]), materials, mtlTable); - } - } else if (elements[0].equals("g")) { - gname = elements[1]; - } else if (elements[0].equals("usemtl")) { - // Getting index of current active material (will be applied on all subsequent faces).. - if (elements[1] != null) { - String mtlname = elements[1]; - if (mtlTable.containsKey(mtlname)) { - Integer tempInt = mtlTable.get(mtlname); - mtlIdxCur = tempInt.intValue(); - } else { - mtlIdxCur = -1; - } - } - } else if (elements[0].equals("f")) { - // Face setting - OBJFace face = new OBJFace(); - face.matIdx = mtlIdxCur; - face.name = gname; - - for (int i = 1; i < elements.length; i++) { - String seg = elements[i]; - - if (seg.indexOf("/") > 0) { - String[] forder = seg.split("/"); - - if (forder.length > 2) { - // Getting vertex and texture and normal indexes. - if (forder[0].length() > 0 && readv) { - face.vertIdx.add(Integer.valueOf(forder[0])); - } - - if (forder[1].length() > 0 && readvt) { - face.texIdx.add(Integer.valueOf(forder[1])); - } - - if (forder[2].length() > 0 && readvn) { - face.normIdx.add(Integer.valueOf(forder[2])); - } - } else if (forder.length > 1) { - // Getting vertex and texture/normal indexes. - if (forder[0].length() > 0 && readv) { - face.vertIdx.add(Integer.valueOf(forder[0])); - } - - if (forder[1].length() > 0) { - if (readvt) { - face.texIdx.add(Integer.valueOf(forder[1])); - } else if (readvn) { - face.normIdx.add(Integer.valueOf(forder[1])); - } - - } - - } else if (forder.length > 0) { - // Getting vertex index only. - if (forder[0].length() > 0 && readv) { - face.vertIdx.add(Integer.valueOf(forder[0])); - } - } - } else { - // Getting vertex index only. - if (seg.length() > 0 && readv) { - face.vertIdx.add(Integer.valueOf(seg)); - } - } - } - - faces.add(face); - - } - } - } - - if (materials.size() == 0) { - // No materials definition so far. Adding one default material. - OBJMaterial defMtl = new OBJMaterial(); - materials.add(defMtl); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - - protected void parseMTL(BufferedReader reader, ArrayList materials, Hashtable materialsHash) { - try { - String line; - OBJMaterial currentMtl = null; - while ((line = reader.readLine()) != null) { - // Parse the line - line = line.trim(); - - String elements[] = line.split("\\s+"); - - if (elements.length > 0) { - // Extract the material data. - - if (elements[0].equals("newmtl")) { - // Starting new material. - String mtlname = elements[1]; - currentMtl = new OBJMaterial(mtlname); - materialsHash.put(mtlname, new Integer(materials.size())); - materials.add(currentMtl); - } else if (elements[0].equals("map_Kd") && elements.length > 1) { - // Loading texture map. - String texname = elements[1]; - //currentMtl.kdMap = papplet.loadImage(texname); - currentMtl.kdMap = null; - } else if (elements[0].equals("Ka") && elements.length > 3) { - // The ambient color of the material - currentMtl.ka.x = Float.valueOf(elements[1]).floatValue(); - currentMtl.ka.y = Float.valueOf(elements[2]).floatValue(); - currentMtl.ka.z = Float.valueOf(elements[3]).floatValue(); - } else if (elements[0].equals("Kd") && elements.length > 3) { - // The diffuse color of the material - currentMtl.kd.x = Float.valueOf(elements[1]).floatValue(); - currentMtl.kd.y = Float.valueOf(elements[2]).floatValue(); - currentMtl.kd.z = Float.valueOf(elements[3]).floatValue(); - } else if (elements[0].equals("Ks") && elements.length > 3) { - // The specular color weighted by the specular coefficient - currentMtl.ks.x = Float.valueOf(elements[1]).floatValue(); - currentMtl.ks.y = Float.valueOf(elements[2]).floatValue(); - currentMtl.ks.z = Float.valueOf(elements[3]).floatValue(); - } else if ((elements[0].equals("d") || elements[0].equals("Tr")) && elements.length > 1) { - // Reading the alpha transparency. - currentMtl.d = Float.valueOf(elements[1]).floatValue(); - } else if (elements[0].equals("Ns") && elements.length > 1) { - // The specular component of the Phong shading model - currentMtl.ns = Float.valueOf(elements[1]).floatValue(); - } - - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - protected void recordOBJ() { -// recordOBJ(objVertices, objNormal, objTexCoords, objFaces, objMaterials); -// objVertices = null; -// objNormal = null; -// objTexCoords = null; -// objFaces = null; -// objMaterials = null; -// -// readFromOBJ = false; - } - - protected void recordOBJ(ArrayList vertices, ArrayList normals, ArrayList textures, ArrayList faces, ArrayList materials) { - int mtlIdxCur = -1; - OBJMaterial mtl = null; - - //pg.saveDrawingState(); - - // The recorded shapes are not merged, they are grouped - // according to the group names found in the OBJ file. - //ogl.mergeRecShapes = false; - - // Using RGB mode for coloring. - pg.colorMode = RGB; - - // Strokes are not used to draw the model. - pg.stroke = false; - - // Normals are automatically computed if not specified in the OBJ file. - //renderer.autoNormal(true); - - // Using normal mode for texture coordinates (i.e.: normalized between 0 and 1). - pg.textureMode = NORMAL; - - //ogl.beginShapeRecorderImpl(); - for (int i = 0; i < faces.size(); i++) { - OBJFace face = faces.get(i); - - // Getting current material. - if (mtlIdxCur != face.matIdx) { - mtlIdxCur = PApplet.max(0, face.matIdx); // To make sure that at least we get the default material. - - mtl = materials.get(mtlIdxCur); - - // Setting colors. - pg.specular(mtl.ks.x * 255.0f, mtl.ks.y * 255.0f, mtl.ks.z * 255.0f); - pg.ambient(mtl.ka.x * 255.0f, mtl.ka.y * 255.0f, mtl.ka.z * 255.0f); - if (pg.fill) { - pg.fill(mtl.kd.x * 255.0f, mtl.kd.y * 255.0f, mtl.kd.z * 255.0f, mtl.d * 255.0f); - } - pg.shininess(mtl.ns); - - if (pg.tint && mtl.kdMap != null) { - // If current material is textured, then tinting the texture using the diffuse color. - pg.tint(mtl.kd.x * 255.0f, mtl.kd.y * 255.0f, mtl.kd.z * 255.0f, mtl.d * 255.0f); - } - } - - // Recording current face. - if (face.vertIdx.size() == 3) { - pg.beginShape(TRIANGLES); // Face is a triangle, so using appropriate shape kind. - } else if (face.vertIdx.size() == 4) { - pg.beginShape(QUADS); // Face is a quad, so using appropriate shape kind. - } else { - pg.beginShape(); - } - - //renderer.shapeName(face.name); - - for (int j = 0; j < face.vertIdx.size(); j++){ - int vertIdx, normIdx; - PVector vert, norms; - - vert = norms = null; - - vertIdx = face.vertIdx.get(j).intValue() - 1; - vert = vertices.get(vertIdx); - - if (j < face.normIdx.size()) { - normIdx = face.normIdx.get(j).intValue() - 1; - if (-1 < normIdx) { - norms = normals.get(normIdx); - } - } - - if (mtl != null && mtl.kdMap != null) { - // This face is textured. - int texIdx; - PVector tex = null; - - if (j < face.texIdx.size()) { - texIdx = face.texIdx.get(j).intValue() - 1; - if (-1 < texIdx) { - tex = textures.get(texIdx); - } - } - - PTexture texMtl = (PTexture)mtl.kdMap.getCache(pg); - if (texMtl != null) { - // Texture orientation in Processing is inverted. - texMtl.setFlippedY(true); - } - pg.texture(mtl.kdMap); - if (norms != null) { - pg.normal(norms.x, norms.y, norms.z); - } - if (tex != null) { - pg.vertex(vert.x, vert.y, vert.z, tex.x, tex.y); - } else { - pg.vertex(vert.x, vert.y, vert.z); - } - } else { - // This face is not textured. - if (norms != null) { - pg.normal(norms.x, norms.y, norms.z); - } - pg.vertex(vert.x, vert.y, vert.z); - } - } - pg.endShape(CLOSE); - } - - // Allocate space for the geometry that the triangulator has generated from the OBJ model. - //setSize(ogl.recordedVertices.size()); -// allocate(); -// initChildrenData(); -// updateElement = -1; - - width = height = depth = 0; -// xmin = ymin = zmin = 10000; -// xmax = ymax = zmax = -10000; - - //ogl.endShapeRecorderImpl(this); - //ogl.endShapeRecorderImpl(null); - - //pg.restoreDrawingState(); - } - - - protected class OBJFace { - ArrayList vertIdx; - ArrayList texIdx; - ArrayList normIdx; - int matIdx; - String name; - - OBJFace() { - vertIdx = new ArrayList(); - texIdx = new ArrayList(); - normIdx = new ArrayList(); - matIdx = -1; - name = ""; - } - } - - protected class OBJMaterial { - String name; - PVector ka; - PVector kd; - PVector ks; - float d; - float ns; - PImage kdMap; - - OBJMaterial() { - this("default"); - } - - OBJMaterial(String name) { - this.name = name; - ka = new PVector(0.5f, 0.5f, 0.5f); - kd = new PVector(0.5f, 0.5f, 0.5f); - ks = new PVector(0.5f, 0.5f, 0.5f); - d = 1.0f; - ns = 0.0f; - kdMap = null; - } - } - - - -} diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PTexture.java b/java/libraries/lwjgl/src/processing/lwjgl/PTexture.java deleted file mode 100644 index ae56bb23f..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PTexture.java +++ /dev/null @@ -1,1137 +0,0 @@ -/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Copyright (c) 2010 Ben Fry and Casey Reas - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License version 2.1 as published by the Free Software Foundation. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -package processing.lwjgl; - -import processing.core.PApplet; -import processing.core.PConstants; -import processing.core.PGraphics; -import processing.core.PImage; - -import java.lang.reflect.Method; -import java.nio.ByteBuffer; -import java.nio.IntBuffer; -import java.util.LinkedList; -import java.util.NoSuchElementException; - -/** - * This class wraps an OpenGL texture. - * By Andres Colubri - * - */ -public class PTexture implements PConstants { - public int width, height; - - protected PApplet parent; // The Processing applet - protected PGraphicsLWJGL pg; // The main renderer - protected PGL pgl; // The interface between Processing and OpenGL. - protected PGL.Context context; // The context that created this texture. - - // These are public but use at your own risk! - public int glID; - public int glTarget; - public int glFormat; - public int glMinFilter; - public int glMagFilter; - public int glWrapS; - public int glWrapT; - public int glWidth; - public int glHeight; - - protected boolean usingMipmaps; - protected float maxTexCoordU; - protected float maxTexCoordV; - - protected boolean flippedX; - protected boolean flippedY; - - protected int[] tempPixels = null; - protected PFramebuffer tempFbo = null; - - protected IntBuffer texels; - - protected Object bufferSource; - protected LinkedList bufferCache = null; - protected Method disposeBufferMethod; - public static final int MAX_BUFFER_CACHE_SIZE = 3; - - //////////////////////////////////////////////////////////// - - // Constructors. - - - /** - * Creates an instance of PTexture with size width x height. The texture is - * initialized (empty) to that size. - * @param parent PApplet - * @param width int - * @param height int - */ - public PTexture(PApplet parent, int width, int height) { - this(parent, width, height, new Parameters()); - } - - - /** - * Creates an instance of PTexture with size width x height and with the specified parameters. - * The texture is initialized (empty) to that size. - * @param parent PApplet - * @param width int - * @param height int - * @param params Parameters - */ - public PTexture(PApplet parent, int width, int height, Object params) { - this.parent = parent; - - pg = (PGraphicsLWJGL)parent.g; - pgl = pg.pgl; - context = pgl.getContext(); - - glID = 0; - - init(width, height, (Parameters)params); - } - - - protected void finalize() throws Throwable { - try { - if (glID != 0) { - pg.finalizeTextureObject(glID); - } - } finally { - super.finalize(); - } - } - - - - //////////////////////////////////////////////////////////// - - // Init, resize methods - - - /** - * Sets the size of the image and texture to width x height. If the texture is already initialized, - * it first destroys the current OpenGL texture object and then creates a new one with the specified - * size. - * @param width int - * @param height int - */ - public void init(int width, int height) { - Parameters params; - if (0 < glID) { - // Re-initializing a pre-existing texture. - // We use the current parameters as default: - params = getParameters(); - } else { - // Just built-in default parameters otherwise: - params = new Parameters(); - } - init(width, height, params); - } - - - /** - * Sets the size of the image and texture to width x height, and the parameters of the texture to params. - * If the texture is already initialized, it first destroys the current OpenGL texture object and then creates - * a new one with the specified size. - * @param width int - * @param height int - * @param params GLTextureParameters - */ - public void init(int width, int height, Parameters params) { - setParameters(params); - setSize(width, height); - allocate(); - } - - - public void resize(int wide, int high) { - // Marking the texture object as finalized so it is deleted - // when creating the new texture. - release(); - - // Creating new texture with the appropriate size. - PTexture tex = new PTexture(parent, wide, high, getParameters()); - - // Copying the contents of this texture into tex. - tex.set(this); - - // Now, overwriting "this" with tex. - copyObject(tex); - - // Nullifying some utility objects so they are recreated with the appropriate - // size when needed. - tempPixels = null; - tempFbo = null; - } - - - /** - * Returns true if the texture has been initialized. - * @return boolean - */ - public boolean available() { - return 0 < glID; - } - - - //////////////////////////////////////////////////////////// - - // Set methods - - - public void set(PImage img) { - PTexture tex = (PTexture)img.getCache(pg); - set(tex); - } - - - public void set(PImage img, int x, int y, int w, int h) { - PTexture tex = (PTexture)img.getCache(pg); - set(tex, x, y, w, h); - } - - - public void set(PTexture tex) { - copyTexels(tex, 0, 0, tex.width, tex.height, true); - } - - - public void set(PTexture tex, int x, int y, int w, int h) { - copyTexels(tex, x, y, w, h, true); - } - - - public void set(int[] pixels) { - set(pixels, 0, 0, width, height, ARGB); - } - - - public void set(int[] pixels, int format) { - set(pixels, 0, 0, width, height, format); - } - - - public void set(int[] pixels, int x, int y, int w, int h) { - set(pixels, x, y, w, h, ARGB); - } - - - public void set(int[] pixels, int x, int y, int w, int h, int format) { - if (pixels == null) { - pixels = null; - PGraphics.showWarning("The pixels array is null."); - return; - } - if (pixels.length != w * h) { - PGraphics.showWarning("The pixels array has the wrong length. It should be " + w * h); - return; - } - - pgl.enableTexturing(glTarget); - pgl.glBindTexture(glTarget, glID); - - if (usingMipmaps) { - if (PGraphicsLWJGL.mipmapGeneration) { - // Automatic mipmap generation. - int[] rgbaPixels = new int[w * h]; - convertToRGBA(pixels, rgbaPixels, format, w, h); - setTexels(rgbaPixels, x, y, w, h); - pgl.glGenerateMipmap(glTarget); - rgbaPixels = null; - } else { - // TODO: Manual mipmap generation. - // Open source implementation of gluBuild2DMipmaps here: - // http://code.google.com/p/glues/source/browse/trunk/glues/source/glues_mipmap.c - } - } else { - int[] rgbaPixels = new int[w * h]; - convertToRGBA(pixels, rgbaPixels, format, w, h); - setTexels(rgbaPixels, x, y, w, h); - rgbaPixels = null; - } - - pgl.glBindTexture(glTarget, 0); - pgl.disableTexturing(glTarget); - } - - - //////////////////////////////////////////////////////////// - - // Get methods - - - /** - * Copy texture to pixels. Involves video memory to main memory transfer (slow). - */ - public void get(int[] pixels) { - // TODO: here is ok to create a new pixels array, or an error/warning - // should be thrown instead? - if ((pixels == null) || (pixels.length != width * height)) { - pixels = new int[width * height]; - } - - int size = glWidth * glHeight; - - if (tempFbo == null) { - tempFbo = new PFramebuffer(parent, glWidth, glHeight); - } - - if (PGraphicsLWJGL.fboSupported) { - // Attaching the texture to the color buffer of a FBO, binding the FBO and reading the pixels - // from the current draw buffer (which is the color buffer of the FBO). - tempFbo.setColorBuffer(this); - pg.pushFramebuffer(); - pg.setFramebuffer(tempFbo); - tempFbo.readPixels(); - pg.popFramebuffer(); - } else { - // Here we don't have FBOs, so the method above is of no use. What we do instead is - // to draw the texture to the screen framebuffer, and then grab the pixels from there. - pg.pushFramebuffer(); - pg.setFramebuffer(tempFbo); - pg.drawTexture(this, 0, 0, glWidth, glHeight, 0, 0, glWidth, glHeight); - tempFbo.readPixels(); - pg.popFramebuffer(); - } - - if (tempPixels == null) { - tempPixels = new int[size]; - } - tempFbo.getPixels(tempPixels); - - convertToARGB(tempPixels, pixels); - if (flippedX) flipArrayOnX(pixels, 1); - if (flippedY) flipArrayOnY(pixels, 1); - } - - - //////////////////////////////////////////////////////////// - - // Put methods (the source texture is not resized to cover the entire - // destination). - - - public void put(PTexture tex) { - copyTexels(tex, 0, 0, tex.width, tex.height, false); - } - - - public void put(PTexture tex, int x, int y, int w, int h) { - copyTexels(tex, x, y, w, h, false); - } - - - //////////////////////////////////////////////////////////// - - // Get OpenGL parameters - - /** - * Returns true or false whether or not the texture is using mipmaps. - * @return boolean - */ - public boolean usingMipmaps() { - return usingMipmaps; - } - - - /** - * Returns the maximum possible value for the texture coordinate U (horizontal). - * @return float - */ - public float getMaxTexCoordU() { - return maxTexCoordU; - } - - - /** - * Returns the maximum possible value for the texture coordinate V (vertical). - * @return float - */ - public float getMaxTexCoordV() { - return maxTexCoordV; - } - - - /** - * Returns true if the texture is flipped along the horizontal direction. - * @return boolean; - */ - public boolean isFlippedX() { - return flippedX; - } - - - /** - * Sets the texture as flipped or not flipped on the horizontal direction. - * @param v boolean; - */ - public void setFlippedX(boolean v) { - flippedX = v; - } - - - /** - * Returns true if the texture is flipped along the vertical direction. - * @return boolean; - */ - public boolean isFlippedY() { - return flippedY; - } - - - /** - * Sets the texture as flipped or not flipped on the vertical direction. - * @param v boolean; - */ - public void setFlippedY(boolean v) { - flippedY = v; - } - - //////////////////////////////////////////////////////////// - - // Bind/unbind - - public void bind() { - pgl.enableTexturing(glTarget); - pgl.glBindTexture(glTarget, glID); - } - - public void unbind() { - pgl.enableTexturing(glTarget); - pgl.glBindTexture(glTarget, 0); - } - - //////////////////////////////////////////////////////////// - - // Buffer sink interface. - - - public void setBufferSource(Object source) { - bufferSource = source; - getSourceMethods(); - } - - - public void copyBufferFromSource(Object natRef, ByteBuffer byteBuf, int w, int h) { - if (bufferCache == null) { - bufferCache = new LinkedList(); - } - - if (bufferCache.size() + 1 <= MAX_BUFFER_CACHE_SIZE) { - bufferCache.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h)); - } else { - // The buffer cache reached the maximum size, so we just dispose the new buffer. - try { - disposeBufferMethod.invoke(bufferSource, new Object[] { natRef }); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - - public boolean hasBuffers() { - return bufferSource != null && bufferCache != null && 0 < bufferCache.size(); - } - - - protected boolean bufferUpdate() { - BufferData data = null; - try { - data = bufferCache.remove(0); - } catch (NoSuchElementException ex) { - PGraphics.showWarning("PTexture: don't have pixel data to copy to texture"); - } - - if (data != null) { - if ((data.w != width) || (data.h != height)) { - init(data.w, data.h); - } - bind(); - setTexels(data.rgbBuf, 0, 0, width, height); - unbind(); - - data.dispose(); - - return true; - } else { - return false; - } - } - - - protected void getSourceMethods() { - try { - disposeBufferMethod = bufferSource.getClass().getMethod("disposeBuffer", new Class[] { Object.class }); - } catch (Exception e) { - throw new RuntimeException("PTexture: provided source object doesn't have a disposeBuffer method."); - } - } - - //////////////////////////////////////////////////////////// - - // Utilities - - // bit shifting this might be more efficient - protected int nextPowerOfTwo(int val) { - int ret = 1; - while (ret < val) { - ret <<= 1; - } - return ret; - } - - - /** - * Flips intArray along the X axis. - * @param intArray int[] - * @param mult int - */ - protected void flipArrayOnX(int[] intArray, int mult) { - int index = 0; - int xindex = mult * (width - 1); - for (int x = 0; x < width / 2; x++) { - for (int y = 0; y < height; y++) { - int i = index + mult * y * width; - int j = xindex + mult * y * width; - - for (int c = 0; c < mult; c++) { - int temp = intArray[i]; - intArray[i] = intArray[j]; - intArray[j] = temp; - - i++; - j++; - } - - } - index += mult; - xindex -= mult; - } - } - - - /** - * Flips intArray along the Y axis. - * @param intArray int[] - * @param mult int - */ - protected void flipArrayOnY(int[] intArray, int mult) { - int index = 0; - int yindex = mult * (height - 1) * width; - for (int y = 0; y < height / 2; y++) { - for (int x = 0; x < mult * width; x++) { - int temp = intArray[index]; - intArray[index] = intArray[yindex]; - intArray[yindex] = temp; - - index++; - yindex++; - } - yindex -= mult * width * 2; - } - } - - - /** - * Reorders a pixel array in the given format into the order required by OpenGL (RGBA). - * Both arrays are assumed to be of the same length. The width and height parameters - * are used in the YUV420 to RBGBA conversion. - * @param intArray int[] - * @param tIntArray int[] - * @param arrayFormat int - * @param w int - * @param h int - */ - protected void convertToRGBA(int[] intArray, int[] tIntArray, int arrayFormat, int w, int h) { - if (PGraphicsLWJGL.BIG_ENDIAN) { - switch (arrayFormat) { - case ALPHA: - - // Converting from xxxA into RGBA. RGB is set to white - // (0xFFFFFF, i.e.: (255, 255, 255)) - for (int i = 0; i< intArray.length; i++) { - tIntArray[i] = 0xFFFFFF00 | intArray[i]; - } - break; - - case RGB: - - // Converting xRGB into RGBA. A is set to 0xFF (255, full opacity). - for (int i = 0; i< intArray.length; i++) { - int pixel = intArray[i]; - tIntArray[i] = (pixel << 8) | 0xFF; - } - break; - - case ARGB: - - // Converting ARGB into RGBA. Shifting RGB to 8 bits to the left, - // and bringing A to the first byte. - for (int i = 0; i< intArray.length; i++) { - int pixel = intArray[i]; - tIntArray[i] = (pixel << 8) | ((pixel >> 24) & 0xFF); - } - break; - } - - } else { - // LITTLE_ENDIAN - // ARGB native, and RGBA opengl means ABGR on windows - // for the most part just need to swap two components here - // the sun.cpu.endian here might be "false", oddly enough.. - // (that's why just using an "else", rather than check for "little") - - switch (arrayFormat) { - case ALPHA: - - // Converting xxxA into ARGB, with RGB set to white. - for (int i = 0; i< intArray.length; i++) { - tIntArray[i] = (intArray[i] << 24) | 0x00FFFFFF; - } - break; - - case RGB: - - // We need to convert xRGB into ABGR, - // so R and B must be swapped, and the x just made 0xFF. - for (int i = 0; i< intArray.length; i++) { - int pixel = intArray[i]; - tIntArray[i] = 0xFF000000 | - ((pixel & 0xFF) << 16) | - ((pixel & 0xFF0000) >> 16) | - (pixel & 0x0000FF00); - } - break; - - case ARGB: - - // We need to convert ARGB into ABGR, - // so R and B must be swapped, A and G just brought back in. - for (int i = 0; i < intArray.length; i++) { - int pixel = intArray[i]; - tIntArray[i] = ((pixel & 0xFF) << 16) | - ((pixel & 0xFF0000) >> 16) | - (pixel & 0xFF00FF00); - } - break; - - } - - } - } - - - /** - * Reorders a pixel array in a given format into ARGB. The input array must be - * of size width * height, while the output array must be of glWidth * glHeight. - * @param intArray int[] - * @param intArray int[] - * @param arrayFormat int - */ - protected void convertToARGB(int[] intArray, int[] tIntArray, int arrayFormat) { - int t = 0; - int p = 0; - int pixel; - - switch (arrayFormat) { - case ALPHA: - - // xxxA to ARGB, setting RGB to black. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - pixel = intArray[p++]; - tIntArray[t++] = (pixel << 24) & 0xFF000000; - } - t += glWidth - width; - } - - break; - - case RGB: - - // xRGB to ARGB, setting A to be 0xFF. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - pixel = intArray[p++]; - tIntArray[t++] = pixel | 0xFF000000; - } - t += glWidth - width; - } - - break; - - case ARGB: - - // ARGB to ARGB, where the source is smaller than the destination. - for (int y = 0; y < height; y++) { - PApplet.arrayCopy(intArray, width * y, tIntArray, glWidth * y, width); - } - - break; - - } - - } - - - /** - * Reorders an OpenGL pixel array (RGBA) into ARGB. The input array must be - * of size glWidth * glHeight, while the resulting array of size width * height. - * @param intArray int[] - * @param intArray int[] - */ - protected void convertToARGB(int[] intArray, int[] tIntArray) { - int t = 0; - int p = 0; - if (PGraphicsLWJGL.BIG_ENDIAN) { - - // RGBA to ARGB conversion: shifting RGB 8 bits to the right, - // and placing A 24 bits to the left. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - int pixel = intArray[p++]; - tIntArray[t++] = (pixel >> 8) | ((pixel << 24) & 0xFF000000); - } - p += glWidth - width; - } - - } else { - - // We have to convert ABGR into ARGB, so R and B must be swapped, - // A and G just brought back in. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - int pixel = intArray[p++]; - tIntArray[t++] = ((pixel & 0xFF) << 16) | - ((pixel & 0xFF0000) >> 16) | - (pixel & 0xFF00FF00); - - } - p += glWidth - width; - } - - } - } - - - /////////////////////////////////////////////////////////// - - // Allocate/release texture. - - - protected void setSize(int w, int h) { - width = w; - height = h; - - if (PGraphicsLWJGL.npotTexSupported) { - glWidth = w; - glHeight = h; - } else { - glWidth = nextPowerOfTwo(w); - glHeight = nextPowerOfTwo(h); - } - - if ((glWidth > PGraphicsLWJGL.maxTextureSize) || (glHeight > PGraphicsLWJGL.maxTextureSize)) { - glWidth = glHeight = 0; - throw new RuntimeException("Image width and height cannot be" + - " larger than " + PGraphicsLWJGL.maxTextureSize + - " with this graphics card."); - } - - // If non-power-of-two textures are not supported, and the specified width or height - // is non-power-of-two, then glWidth (glHeight) will be greater than w (h) because it - // is chosen to be the next power of two, and this quotient will give the appropriate - // maximum texture coordinate value given this situation. - maxTexCoordU = (float)width / glWidth; - maxTexCoordV = (float)height / glHeight; - } - - - /** - * Allocates the opengl texture object. - */ - protected void allocate() { - release(); // Just in the case this object is being re-allocated. - - pgl.enableTexturing(glTarget); - - glID = pg.createTextureObject(); - - pgl.glBindTexture(glTarget, glID); - pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter); - pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter); - pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS); - pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT); - - // First, we use glTexImage2D to set the full size of the texture (glW/glH might be diff - // from w/h in the case that the GPU doesn't support NPOT textures) - pgl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null); - - // Makes sure that the texture buffer in video memory doesn't contain any garbage. - pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE); - - pgl.glBindTexture(glTarget, 0); - pgl.disableTexturing(glTarget); - } - - - /** - * Marks the texture object for deletion. - */ - protected void release() { - if (glID != 0) { - pg.finalizeTextureObject(glID); - glID = 0; - } - } - - - /////////////////////////////////////////////////////////// - - // Utilities. - - - // Copies source texture tex into this. - protected void copyTexels(PTexture tex, int x, int y, int w, int h, boolean scale) { - if (tex == null) { - throw new RuntimeException("PTexture: source texture is null"); - } - - if (tempFbo == null) { - tempFbo = new PFramebuffer(parent, glWidth, glHeight); - } - - // This texture is the color (destination) buffer of the FBO. - tempFbo.setColorBuffer(this); - tempFbo.disableDepthTest(); - - // FBO copy: - pg.pushFramebuffer(); - pg.setFramebuffer(tempFbo); - if (scale) { - // Rendering tex into "this", and scaling the source rectangle - // to cover the entire destination region. - pg.drawTexture(tex, x, y, w, h, 0, 0, width, height); - } else { - // Rendering tex into "this" but without scaling so the contents - // of the source texture fall in the corresponding texels of the - // destination. - pg.drawTexture(tex, x, y, w, h, x, y, w, h); - } - pg.popFramebuffer(); - } - - protected void setTexels(int[] pix, int x, int y, int w, int h) { - setTexels(pix, 0, x, y, w, h); - } - - protected void setTexels(IntBuffer buffer, int x, int y, int w, int h) { - setTexels(buffer, 0, x, y, w, h); - } - - protected void setTexels(int[] pix, int level, int x, int y, int w, int h) { - if (texels == null || texels.capacity() != width * height) { - texels = pgl.createIntBuffer(width * height); - } - texels.position(0); - texels.limit(pix.length); - texels.put(pix); - texels.flip(); - pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, texels); - } - - protected void setTexels(IntBuffer buffer, int level, int x, int y, int w, int h) { - pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer); - } - - protected void copyObject(PTexture src) { - // The OpenGL texture of this object is replaced with the one from the source object, - // so we delete the former to avoid resource wasting. - release(); - - width = src.width; - height = src.height; - - parent = src.parent; - pg = src.pg; - - glID = src.glID; - glTarget = src.glTarget; - glFormat = src.glFormat; - glMinFilter = src.glMinFilter; - glMagFilter = src.glMagFilter; - - glWidth= src.glWidth; - glHeight = src.glHeight; - - usingMipmaps = src.usingMipmaps; - maxTexCoordU = src.maxTexCoordU; - maxTexCoordV = src.maxTexCoordV; - - flippedX = src.flippedX; - flippedY = src.flippedY; - } - - /////////////////////////////////////////////////////////// - - // Parameter handling - - - public Parameters getParameters() { - Parameters res = new Parameters(); - - if (glTarget == PGL.GL_TEXTURE_2D) { - res.target = TEXTURE2D; - } - - if (glFormat == PGL.GL_RGB) { - res.format = RGB; - } else if (glFormat == PGL.GL_RGBA) { - res.format = ARGB; - } else if (glFormat == PGL.GL_ALPHA) { - res.format = ALPHA; - } - - if (glMinFilter == PGL.GL_NEAREST) { - res.sampling = POINT; - } else if (glMinFilter == PGL.GL_LINEAR) { - res.sampling = BILINEAR; - } else if (glMinFilter == PGL.GL_LINEAR_MIPMAP_LINEAR) { - res.sampling = TRILINEAR; - } - - if (glWrapS == PGL.GL_CLAMP_TO_EDGE) { - res.wrapU = CLAMP; - } else if (glWrapS == PGL.GL_REPEAT) { - res.wrapU = REPEAT; - } - - if (glWrapT == PGL.GL_CLAMP_TO_EDGE) { - res.wrapV = CLAMP; - } else if (glWrapT == PGL.GL_REPEAT) { - res.wrapV = REPEAT; - } - - return res; - } - - - /** - * Sets texture target and internal format according to the target and type specified. - * @param target int - * @param params GLTextureParameters - */ - protected void setParameters(Parameters params) { - if (params.target == TEXTURE2D) { - glTarget = PGL.GL_TEXTURE_2D; - } else { - throw new RuntimeException("OPENGL2: Unknown texture target"); - } - - if (params.format == RGB) { - glFormat = PGL.GL_RGB; - } else if (params.format == ARGB) { - glFormat = PGL.GL_RGBA; - } else if (params.format == ALPHA) { - glFormat = PGL.GL_ALPHA; - } else { - throw new RuntimeException("OPENGL2: Unknown texture format"); - } - - if (params.sampling == POINT) { - glMagFilter = PGL.GL_NEAREST; - glMinFilter = PGL.GL_NEAREST; - } else if (params.sampling == BILINEAR) { - glMagFilter = PGL.GL_LINEAR; - glMinFilter = PGL.GL_LINEAR; - } else if (params.sampling == TRILINEAR) { - glMagFilter = PGL.GL_LINEAR; - glMinFilter = PGL.GL_LINEAR_MIPMAP_LINEAR; - } else { - throw new RuntimeException("OPENGL2: Unknown texture filtering mode"); - } - - if (params.wrapU == CLAMP) { - glWrapS = PGL.GL_CLAMP_TO_EDGE; - } else if (params.wrapU == REPEAT) { - glWrapS = PGL.GL_REPEAT; - } else { - throw new RuntimeException("OPENGL2: Unknown wrapping mode"); - } - - if (params.wrapV == CLAMP) { - glWrapT = PGL.GL_CLAMP_TO_EDGE; - } else if (params.wrapV == REPEAT) { - glWrapT = PGL.GL_REPEAT; - } else { - throw new RuntimeException("OPENGL2: Unknown wrapping mode"); - } - - usingMipmaps = glMinFilter == PGL.GL_LINEAR_MIPMAP_LINEAR; - - flippedX = false; - flippedY = false; - } - - - /////////////////////////////////////////////////////////////////////////// - - // Parameters object - - - static public Parameters newParameters() { - return new Parameters(); - } - - - static public Parameters newParameters(int format) { - return new Parameters(format); - } - - - static public Parameters newParameters(int format, int sampling) { - return new Parameters(format, sampling); - } - - - static public Parameters newParameters(Parameters params) { - return new Parameters(params); - } - - - /** - * This class stores the parameters for a texture: target, internal format, minimization filter - * and magnification filter. - */ - static public class Parameters { - /** - * Texture target. - */ - public int target; - - /** - * Texture internal format. - */ - public int format; - - /** - * Texture filtering (POINT, BILINEAR or TRILINEAR). - */ - public int sampling; - - /** - * Wrapping mode along U. - */ - public int wrapU; - - /** - * Wrapping mode along V. - */ - public int wrapV; - - /** - * Creates an instance of GLTextureParameters, setting all the parameters to default values. - */ - public Parameters() { - this.target = TEXTURE2D; - this.format = ARGB; - this.sampling = BILINEAR; - this.wrapU = CLAMP; - this.wrapV = CLAMP; - } - - public Parameters(int format) { - this.target = TEXTURE2D; - this.format = format; - this.sampling = BILINEAR; - this.wrapU = CLAMP; - this.wrapV = CLAMP; - } - - public Parameters(int format, int sampling) { - this.target = TEXTURE2D; - this.format = format; - this.sampling = sampling; - this.wrapU = CLAMP; - this.wrapV = CLAMP; - } - - public Parameters(Parameters src) { - this.target = src.target; - this.format = src.format; - this.sampling = src.sampling; - this.wrapU = src.wrapU; - this.wrapV = src.wrapV; - } - - public void set(int format) { - this.format = format; - } - - public void set(int format, int sampling) { - this.format = format; - this.sampling = sampling; - } - - public void set(Parameters src) { - this.target = src.target; - this.format = src.format; - this.sampling = src.sampling; - this.wrapU = src.wrapU; - this.wrapV = src.wrapV; - } - } - - /** - * This class stores a buffer copied from the buffer source. - * - */ - protected class BufferData { - int w, h; - // Native buffer object. - Object natBuf; - // Buffer viewed as int. - IntBuffer rgbBuf; - - BufferData(Object nat, IntBuffer rgb, int w, int h) { - natBuf = nat; - rgbBuf = rgb; - this.w = w; - this.h = h; - } - - void dispose() { - try { - // Disposing the native buffer. - disposeBufferMethod.invoke(bufferSource, new Object[] { natBuf }); - natBuf = null; - rgbBuf = null; - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PointShaderFrag.glsl b/java/libraries/lwjgl/src/processing/lwjgl/PointShaderFrag.glsl deleted file mode 100644 index 29e18414e..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PointShaderFrag.glsl +++ /dev/null @@ -1,26 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -varying vec4 vertColor; - -void main() { - gl_FragColor = vertColor; -} \ No newline at end of file diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PointShaderVert.glsl b/java/libraries/lwjgl/src/processing/lwjgl/PointShaderVert.glsl deleted file mode 100644 index 9e2195306..000000000 --- a/java/libraries/lwjgl/src/processing/lwjgl/PointShaderVert.glsl +++ /dev/null @@ -1,37 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library 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; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -uniform mat4 projectionMatrix; -uniform mat4 modelviewMatrix; - -attribute vec4 inVertex; -attribute vec4 inColor; -attribute vec2 inSize; - -varying vec4 vertColor; - -void main() { - vec4 pos = modelviewMatrix * inVertex; - pos.xy += inSize.xy; - gl_Position = projectionMatrix * pos; - - vertColor = inColor; -} \ No newline at end of file