Merge remote-tracking branch 'upstream/master' into fix_fb_depth24stencil8
This commit is contained in:
commit
4fdde38bc2
BIN
jme3-android-native/libs/openalsoft/arm64-v8a/libopenalsoftjme.so
Executable file
BIN
jme3-android-native/libs/openalsoft/arm64-v8a/libopenalsoftjme.so
Executable file
Binary file not shown.
BIN
jme3-android-native/libs/openalsoft/armeabi-v7a/libopenalsoftjme.so
Normal file → Executable file
BIN
jme3-android-native/libs/openalsoft/armeabi-v7a/libopenalsoftjme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/openalsoft/armeabi/libopenalsoftjme.so
Normal file → Executable file
BIN
jme3-android-native/libs/openalsoft/armeabi/libopenalsoftjme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/openalsoft/mips/libopenalsoftjme.so
Normal file → Executable file
BIN
jme3-android-native/libs/openalsoft/mips/libopenalsoftjme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/openalsoft/mips64/libopenalsoftjme.so
Executable file
BIN
jme3-android-native/libs/openalsoft/mips64/libopenalsoftjme.so
Executable file
Binary file not shown.
BIN
jme3-android-native/libs/openalsoft/x86/libopenalsoftjme.so
Normal file → Executable file
BIN
jme3-android-native/libs/openalsoft/x86/libopenalsoftjme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/openalsoft/x86_64/libopenalsoftjme.so
Executable file
BIN
jme3-android-native/libs/openalsoft/x86_64/libopenalsoftjme.so
Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/arm64-v8a/libstbijme.so
Executable file
BIN
jme3-android-native/libs/stb_image/arm64-v8a/libstbijme.so
Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/armeabi-v7a/libstbijme.so
Normal file → Executable file
BIN
jme3-android-native/libs/stb_image/armeabi-v7a/libstbijme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/armeabi/libstbijme.so
Normal file → Executable file
BIN
jme3-android-native/libs/stb_image/armeabi/libstbijme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/mips/libstbijme.so
Normal file → Executable file
BIN
jme3-android-native/libs/stb_image/mips/libstbijme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/mips64/libstbijme.so
Executable file
BIN
jme3-android-native/libs/stb_image/mips64/libstbijme.so
Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/x86/libstbijme.so
Normal file → Executable file
BIN
jme3-android-native/libs/stb_image/x86/libstbijme.so
Normal file → Executable file
Binary file not shown.
BIN
jme3-android-native/libs/stb_image/x86_64/libstbijme.so
Executable file
BIN
jme3-android-native/libs/stb_image/x86_64/libstbijme.so
Executable file
Binary file not shown.
@ -1,9 +1,5 @@
|
|||||||
// OpenAL Soft r1.15.1
|
// OpenAL Soft r1.16
|
||||||
//String openALSoftUrl = 'http://repo.or.cz/w/openal-soft.git/snapshot/9b6a226da55a987cb883f425eeb568776ea12c8d.zip'
|
String openALSoftUrl = 'http://repo.or.cz/w/openal-soft.git/snapshot/e5016f814a265ed592a88acea95cf912c4bfdf12.zip'
|
||||||
// OpenAL Soft r1.15.1 + Android OpenSL Support
|
|
||||||
String openALSoftUrl = 'http://repo.or.cz/w/openal-soft.git/snapshot/be25e6802dacad78876c6fa1d6a5c63797b8a9ed.zip'
|
|
||||||
// OpenAL Soft r1.15.1 latest build (at the time)
|
|
||||||
//String openALSoftUrl = 'http://repo.or.cz/w/openal-soft.git/snapshot/3f5914e0949ee12b504ee7254990e007ff8057ef.zip'
|
|
||||||
String openALSoftZipFile = 'OpenALSoft.zip'
|
String openALSoftZipFile = 'OpenALSoft.zip'
|
||||||
|
|
||||||
// OpenAL Soft directory the download is extracted into
|
// OpenAL Soft directory the download is extracted into
|
||||||
@ -81,22 +77,23 @@ task generateOpenAlSoftHeaders(dependsOn: copyJmeOpenALSoft) << {
|
|||||||
String classes = ""
|
String classes = ""
|
||||||
.concat("com.jme3.audio.android.AndroidOpenALSoftAudioRenderer, ")
|
.concat("com.jme3.audio.android.AndroidOpenALSoftAudioRenderer, ")
|
||||||
// println "openalsoft classes = " + classes
|
// println "openalsoft classes = " + classes
|
||||||
// println "openalsoft destDir = " + destDir
|
// println "openalsoft destDir = " + destDirPath
|
||||||
// println "openalsoft classpath = " + project.projectClassPath
|
// println "openalsoft classpath = " + project.projectClassPath
|
||||||
|
|
||||||
ant.javah(
|
exec {
|
||||||
classpath: project.projectClassPath,
|
executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah')
|
||||||
destdir: destDirPath,
|
args '-d', destDirPath
|
||||||
class: classes
|
args '-classpath', project.projectClassPath
|
||||||
)
|
args "com.jme3.audio.android.AndroidOpenALSoftAudioRenderer"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task buildOpenAlSoftNativeLib(type: Exec, dependsOn: generateOpenAlSoftHeaders) {
|
task buildOpenAlSoftNativeLib(type: Exec, dependsOn: generateOpenAlSoftHeaders) {
|
||||||
// println "openalsoft build dir: " + openalsoftBuildDir
|
// println "openalsoft build dir: " + openalsoftBuildDir
|
||||||
// println "ndkCommandPath: " + project.ndkCommandPath
|
// println "ndkCommandPath: " + project.ndkCommandPath
|
||||||
args 'TARGET_PLATFORM=android-9'
|
|
||||||
workingDir openalsoftBuildDir
|
workingDir openalsoftBuildDir
|
||||||
executable rootProject.ndkCommandPath
|
executable rootProject.ndkCommandPath
|
||||||
|
args '-j8'
|
||||||
}
|
}
|
||||||
|
|
||||||
task updatePreCompiledOpenAlSoftLibs(type: Copy, dependsOn: buildOpenAlSoftNativeLib) {
|
task updatePreCompiledOpenAlSoftLibs(type: Copy, dependsOn: buildOpenAlSoftNativeLib) {
|
||||||
|
@ -1,58 +1,68 @@
|
|||||||
TARGET_PLATFORM := android-9
|
TARGET_PLATFORM := android-9
|
||||||
|
|
||||||
ROOT_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
########################################################################################################
|
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_MODULE := openalsoftjme
|
LOCAL_MODULE := openalsoftjme
|
||||||
LOCAL_ARM_MODE := arm
|
|
||||||
LOCAL_PATH := $(ROOT_PATH)
|
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include $(LOCAL_PATH)/OpenAL32/Include
|
|
||||||
|
|
||||||
LOCAL_CFLAGS := -ffast-math -DAL_BUILD_LIBRARY -DAL_ALEXT_PROTOTYPES
|
LOCAL_C_INCLUDES += $(LOCAL_PATH) $(LOCAL_PATH)/include \
|
||||||
LOCAL_LDLIBS := -llog -Wl,-s
|
$(LOCAL_PATH)/OpenAL32/Include $(LOCAL_PATH)/Alc
|
||||||
LOCAL_LDLIBS += -lOpenSLES
|
|
||||||
# LOCAL_CFLAGS += -DPOST_FROYO #-I$(ANDROID_NDK_ROOT)/platforms/android-9/arch-arm/usr/include/
|
|
||||||
# LOCAL_LDLIBS += -ldl -L$(ANDROID_NDK_ROOT)/platforms/android-9/arch-arm/usr/lib/
|
|
||||||
|
|
||||||
LOCAL_SRC_FILES := OpenAL32/alAuxEffectSlot.c \
|
LOCAL_CFLAGS := -std=c99 -ffast-math -DAL_BUILD_LIBRARY -DAL_ALEXT_PROTOTYPES
|
||||||
OpenAL32/alBuffer.c \
|
LOCAL_LDLIBS := -lOpenSLES -llog -Wl,-s
|
||||||
OpenAL32/alEffect.c \
|
|
||||||
OpenAL32/alError.c \
|
LOCAL_SRC_FILES := Alc/backends/opensl.c \
|
||||||
OpenAL32/alExtension.c \
|
Alc/backends/loopback.c \
|
||||||
OpenAL32/alFilter.c \
|
Alc/backends/wave.c \
|
||||||
OpenAL32/alListener.c \
|
Alc/backends/base.c \
|
||||||
OpenAL32/alSource.c \
|
Alc/backends/null.c \
|
||||||
OpenAL32/alState.c \
|
Alc/ALc.c \
|
||||||
OpenAL32/alThunk.c \
|
Alc/helpers.c \
|
||||||
Alc/ALc.c \
|
Alc/bs2b.c \
|
||||||
Alc/ALu.c \
|
Alc/alcRing.c \
|
||||||
Alc/alcConfig.c \
|
Alc/effects/chorus.c \
|
||||||
Alc/alcDedicated.c \
|
Alc/effects/flanger.c \
|
||||||
Alc/alcEcho.c \
|
Alc/effects/dedicated.c \
|
||||||
Alc/alcModulator.c \
|
Alc/effects/reverb.c \
|
||||||
Alc/alcReverb.c \
|
Alc/effects/distortion.c \
|
||||||
Alc/alcRing.c \
|
Alc/effects/autowah.c \
|
||||||
Alc/alcThread.c \
|
Alc/effects/equalizer.c \
|
||||||
Alc/bs2b.c \
|
Alc/effects/modulator.c \
|
||||||
Alc/helpers.c \
|
Alc/effects/echo.c \
|
||||||
Alc/panning.c \
|
Alc/effects/compressor.c \
|
||||||
Alc/hrtf.c \
|
Alc/effects/null.c \
|
||||||
Alc/mixer.c \
|
Alc/alcConfig.c \
|
||||||
Alc/mixer_c.c \
|
Alc/ALu.c \
|
||||||
Alc/backends/loopback.c \
|
Alc/mixer_c.c \
|
||||||
Alc/backends/null.c \
|
Alc/panning.c \
|
||||||
Alc/backends/opensl.c \
|
Alc/hrtf.c \
|
||||||
com_jme3_audio_android_AndroidOpenALSoftAudioRenderer.cpp
|
Alc/mixer.c \
|
||||||
# Alc/backends/alsa.c \
|
Alc/midi/soft.c \
|
||||||
# Alc/backends/android.c \
|
Alc/midi/sf2load.c \
|
||||||
# Alc/alcChorus.c \
|
Alc/midi/dummy.c \
|
||||||
# Alc/alcFlanger.c \
|
Alc/midi/fluidsynth.c \
|
||||||
# Alc/mixer_c.c \
|
Alc/midi/base.c \
|
||||||
# Alc/backends/loopback.c \
|
common/uintmap.c \
|
||||||
# Alc/backends/null.c \
|
common/atomic.c \
|
||||||
|
common/threads.c \
|
||||||
|
common/rwlock.c \
|
||||||
|
OpenAL32/alBuffer.c \
|
||||||
|
OpenAL32/alPreset.c \
|
||||||
|
OpenAL32/alListener.c \
|
||||||
|
OpenAL32/alEffect.c \
|
||||||
|
OpenAL32/alExtension.c \
|
||||||
|
OpenAL32/alThunk.c \
|
||||||
|
OpenAL32/alMidi.c \
|
||||||
|
OpenAL32/alSoundfont.c \
|
||||||
|
OpenAL32/alFontsound.c \
|
||||||
|
OpenAL32/alAuxEffectSlot.c \
|
||||||
|
OpenAL32/alError.c \
|
||||||
|
OpenAL32/alFilter.c \
|
||||||
|
OpenAL32/alSource.c \
|
||||||
|
OpenAL32/alState.c \
|
||||||
|
OpenAL32/sample_cvt.c \
|
||||||
|
com_jme3_audio_android_AndroidOpenALSoftAudioRenderer.cpp
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
|
APP_PLATFORM := android-9
|
||||||
APP_OPTIM := release
|
APP_OPTIM := release
|
||||||
APP_ABI := all
|
APP_ABI := all
|
||||||
#APP_ABI := armeabi-v7a
|
|
||||||
|
@ -1,97 +1,89 @@
|
|||||||
#ifndef CONFIG_H
|
/* API declaration export attribute */
|
||||||
#define CONFIG_H
|
#define AL_API __attribute__((visibility("protected")))
|
||||||
|
#define ALC_API __attribute__((visibility("protected")))
|
||||||
|
|
||||||
/* Define to the library version */
|
/* Define to the library version */
|
||||||
#define ALSOFT_VERSION "1.15.1"
|
#define ALSOFT_VERSION "1.16.0"
|
||||||
|
|
||||||
#define ALIGN(x) __attribute__ ((aligned(x)))
|
#ifdef IN_IDE_PARSER
|
||||||
|
/* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
|
||||||
|
* recent versions (at least 4.5.1) do recognize GCC's __restrict. */
|
||||||
|
#define restrict __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define if we have the Android backend */
|
/* Define any available alignment declaration */
|
||||||
/* #define HAVE_ANDROID 1 */
|
#define ALIGN(x) __attribute__((aligned(x)))
|
||||||
|
|
||||||
|
/* Define if we have the C11 aligned_alloc function */
|
||||||
|
/* #undef HAVE_ALIGNED_ALLOC */
|
||||||
|
|
||||||
|
/* Define if we have the posix_memalign function */
|
||||||
|
/* #undef HAVE_POSIX_MEMALIGN */
|
||||||
|
|
||||||
|
/* Define if we have the _aligned_malloc function */
|
||||||
|
/* #undef HAVE__ALIGNED_MALLOC */
|
||||||
|
|
||||||
|
/* Define if we have SSE CPU extensions */
|
||||||
|
/* #undef HAVE_SSE */
|
||||||
|
/* #undef HAVE_SSE2 */
|
||||||
|
/* #undef HAVE_SSE4_1 */
|
||||||
|
|
||||||
|
/* Define if we have ARM Neon CPU extensions */
|
||||||
|
/* #undef HAVE_NEON */
|
||||||
|
|
||||||
|
/* Define if we have FluidSynth support */
|
||||||
|
/* #undef HAVE_FLUIDSYNTH */
|
||||||
|
|
||||||
/* Define if we have the ALSA backend */
|
/* Define if we have the ALSA backend */
|
||||||
/* #define HAVE_ALSA */
|
/* #undef HAVE_ALSA */
|
||||||
|
|
||||||
/* Define if we have the OSS backend */
|
/* Define if we have the OSS backend */
|
||||||
/* #cmakedefine HAVE_OSS */
|
/* #undef HAVE_OSS */
|
||||||
|
|
||||||
/* Define if we have the Solaris backend */
|
/* Define if we have the Solaris backend */
|
||||||
/* #cmakedefine HAVE_SOLARIS */
|
/* #undef HAVE_SOLARIS */
|
||||||
|
|
||||||
/* Define if we have the SndIO backend */
|
/* Define if we have the SndIO backend */
|
||||||
/* #cmakedefine HAVE_SNDIO */
|
/* #undef HAVE_SNDIO */
|
||||||
|
|
||||||
|
/* Define if we have the QSA backend */
|
||||||
|
/* #undef HAVE_QSA */
|
||||||
|
|
||||||
/* Define if we have the MMDevApi backend */
|
/* Define if we have the MMDevApi backend */
|
||||||
/* #cmakedefine HAVE_MMDEVAPI */
|
/* #undef HAVE_MMDEVAPI */
|
||||||
|
|
||||||
/* Define if we have the DSound backend */
|
/* Define if we have the DSound backend */
|
||||||
/* #cmakedefine HAVE_DSOUND */
|
/* #undef HAVE_DSOUND */
|
||||||
|
|
||||||
/* Define if we have the Windows Multimedia backend */
|
/* Define if we have the Windows Multimedia backend */
|
||||||
/* #cmakedefine HAVE_WINMM */
|
/* #undef HAVE_WINMM */
|
||||||
|
|
||||||
/* Define if we have the PortAudio backend */
|
/* Define if we have the PortAudio backend */
|
||||||
/* #cmakedefine HAVE_PORTAUDIO */
|
/* #undef HAVE_PORTAUDIO */
|
||||||
|
|
||||||
/* Define if we have the PulseAudio backend */
|
/* Define if we have the PulseAudio backend */
|
||||||
/* #cmakedefine HAVE_PULSEAUDIO */
|
/* #undef HAVE_PULSEAUDIO */
|
||||||
|
|
||||||
/* Define if we have the CoreAudio backend */
|
/* Define if we have the CoreAudio backend */
|
||||||
/* #cmakedefine HAVE_COREAUDIO */
|
/* #undef HAVE_COREAUDIO */
|
||||||
|
|
||||||
/* Define if we have the OpenSL backend */
|
/* Define if we have the OpenSL backend */
|
||||||
#define HAVE_OPENSL /* THIS BACKEND WORKS ON >=2.3 Android!! */
|
#define HAVE_OPENSL
|
||||||
|
|
||||||
/* Define if we have the Wave Writer backend */
|
/* Define if we have the Wave Writer backend */
|
||||||
/* #cmakedefine HAVE_WAVE */
|
#define HAVE_WAVE
|
||||||
|
|
||||||
/* Define if we have dlfcn.h */
|
|
||||||
#define HAVE_DLFCN_H
|
|
||||||
|
|
||||||
/* Define if we have the stat function */
|
/* Define if we have the stat function */
|
||||||
#define HAVE_STAT
|
#define HAVE_STAT
|
||||||
|
|
||||||
/* Define if we have the powf function */
|
/* Define if we have the lrintf function */
|
||||||
/* #define HAVE_POWF 1 */
|
#define HAVE_LRINTF
|
||||||
|
|
||||||
/* Define if we have the sqrtf function */
|
|
||||||
/* #define HAVE_SQRTF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the cosf function */
|
|
||||||
/* #define HAVE_COSF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the sinf function */
|
|
||||||
/* #define HAVE_SINF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the acosf function */
|
|
||||||
/* #define HAVE_ACOSF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the asinf function */
|
|
||||||
/* #define HAVE_ASINF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the atanf function */
|
|
||||||
/* #define HAVE_ATANF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the atan2f function */
|
|
||||||
/* #define HAVE_ATAN2F 1 */
|
|
||||||
|
|
||||||
/* Define if we have the fabsf function */
|
|
||||||
/* #define HAVE_FABSF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the log10f function */
|
|
||||||
/* #define HAVE_LOG10F 1 */
|
|
||||||
|
|
||||||
/* Define if we have the floorf function */
|
|
||||||
/* #define HAVE_FLOORF 1 */
|
|
||||||
|
|
||||||
/* Define if we have the strtof function */
|
/* Define if we have the strtof function */
|
||||||
#define HAVE_STRTOF
|
/* #undef HAVE_STRTOF */
|
||||||
|
|
||||||
/* Define if we have stdint.h */
|
|
||||||
#define HAVE_STDINT_H
|
|
||||||
|
|
||||||
/* Define if we have the __int64 type */
|
/* Define if we have the __int64 type */
|
||||||
/* #cmakedefine HAVE___INT64 */
|
/* #undef HAVE___INT64 */
|
||||||
|
|
||||||
/* Define to the size of a long int type */
|
/* Define to the size of a long int type */
|
||||||
#define SIZEOF_LONG 4
|
#define SIZEOF_LONG 4
|
||||||
@ -99,49 +91,113 @@
|
|||||||
/* Define to the size of a long long int type */
|
/* Define to the size of a long long int type */
|
||||||
#define SIZEOF_LONG_LONG 8
|
#define SIZEOF_LONG_LONG 8
|
||||||
|
|
||||||
|
/* Define if we have C99 variable-length array support */
|
||||||
|
#define HAVE_C99_VLA
|
||||||
|
|
||||||
|
/* Define if we have C99 _Bool support */
|
||||||
|
#define HAVE_C99_BOOL
|
||||||
|
|
||||||
|
/* Define if we have C11 _Static_assert support */
|
||||||
|
#define HAVE_C11_STATIC_ASSERT
|
||||||
|
|
||||||
|
/* Define if we have C11 _Alignas support */
|
||||||
|
/* #undef HAVE_C11_ALIGNAS */
|
||||||
|
|
||||||
|
/* Define if we have C11 _Atomic support */
|
||||||
|
/* #undef HAVE_C11_ATOMIC */
|
||||||
|
|
||||||
/* Define if we have GCC's destructor attribute */
|
/* Define if we have GCC's destructor attribute */
|
||||||
#define HAVE_GCC_DESTRUCTOR
|
#define HAVE_GCC_DESTRUCTOR
|
||||||
|
|
||||||
/* Define if we have GCC's format attribute */
|
/* Define if we have GCC's format attribute */
|
||||||
#define HAVE_GCC_FORMAT
|
#define HAVE_GCC_FORMAT
|
||||||
|
|
||||||
|
/* Define if we have stdint.h */
|
||||||
|
#define HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define if we have stdbool.h */
|
||||||
|
#define HAVE_STDBOOL_H
|
||||||
|
|
||||||
|
/* Define if we have stdalign.h */
|
||||||
|
/* #undef HAVE_STDALIGN_H */
|
||||||
|
|
||||||
|
/* Define if we have windows.h */
|
||||||
|
/* #undef HAVE_WINDOWS_H */
|
||||||
|
|
||||||
|
/* Define if we have dlfcn.h */
|
||||||
|
#define HAVE_DLFCN_H
|
||||||
|
|
||||||
/* Define if we have pthread_np.h */
|
/* Define if we have pthread_np.h */
|
||||||
/* #cmakedefine HAVE_PTHREAD_NP_H */
|
/* #undef HAVE_PTHREAD_NP_H */
|
||||||
|
|
||||||
/* Define if we have arm_neon.h */
|
/* Define if we have alloca.h */
|
||||||
/* #cmakedefine HAVE_ARM_NEON_H */
|
/* #undef HAVE_ALLOCA_H */
|
||||||
|
|
||||||
|
/* Define if we have malloc.h */
|
||||||
|
#define HAVE_MALLOC_H
|
||||||
|
|
||||||
|
/* Define if we have ftw.h */
|
||||||
|
/* #undef HAVE_FTW_H */
|
||||||
|
|
||||||
|
/* Define if we have io.h */
|
||||||
|
/* #undef HAVE_IO_H */
|
||||||
|
|
||||||
|
/* Define if we have strings.h */
|
||||||
|
#define HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define if we have cpuid.h */
|
||||||
|
/* #undef HAVE_CPUID_H */
|
||||||
|
|
||||||
|
/* Define if we have intrin.h */
|
||||||
|
/* #undef HAVE_INTRIN_H */
|
||||||
|
|
||||||
|
/* Define if we have sys/sysconf.h */
|
||||||
|
#define HAVE_SYS_SYSCONF_H
|
||||||
|
|
||||||
/* Define if we have guiddef.h */
|
/* Define if we have guiddef.h */
|
||||||
/* #cmakedefine HAVE_GUIDDEF_H */
|
/* #undef HAVE_GUIDDEF_H */
|
||||||
|
|
||||||
/* Define if we have guiddef.h */
|
/* Define if we have initguid.h */
|
||||||
/* #cmakedefine HAVE_INITGUID_H */
|
/* #undef HAVE_INITGUID_H */
|
||||||
|
|
||||||
/* Define if we have ieeefp.h */
|
/* Define if we have ieeefp.h */
|
||||||
/* #cmakedefine HAVE_IEEEFP_H */
|
/* #undef HAVE_IEEEFP_H */
|
||||||
|
|
||||||
/* Define if we have float.h */
|
/* Define if we have float.h */
|
||||||
/* #cmakedefine HAVE_FLOAT_H */
|
#define HAVE_FLOAT_H
|
||||||
|
|
||||||
/* Define if we have fpu_control.h */
|
|
||||||
/* #cmakedefine HAVE_FPU_CONTROL_H */
|
|
||||||
|
|
||||||
/* Define if we have fenv.h */
|
/* Define if we have fenv.h */
|
||||||
#define HAVE_FENV_H
|
#define HAVE_FENV_H
|
||||||
|
|
||||||
/* Define if we have fesetround() */
|
/* Define if we have GCC's __get_cpuid() */
|
||||||
/* #cmakedefine HAVE_FESETROUND */
|
/* #undef HAVE_GCC_GET_CPUID */
|
||||||
|
|
||||||
|
/* Define if we have the __cpuid() intrinsic */
|
||||||
|
/* #undef HAVE_CPUID_INTRINSIC */
|
||||||
|
|
||||||
/* Define if we have _controlfp() */
|
/* Define if we have _controlfp() */
|
||||||
/* #cmakedefine HAVE__CONTROLFP */
|
/* #undef HAVE__CONTROLFP */
|
||||||
|
|
||||||
|
/* Define if we have __control87_2() */
|
||||||
|
/* #undef HAVE___CONTROL87_2 */
|
||||||
|
|
||||||
|
/* Define if we have ftw() */
|
||||||
|
/* #undef HAVE_FTW */
|
||||||
|
|
||||||
|
/* Define if we have _wfindfirst() */
|
||||||
|
/* #undef HAVE__WFINDFIRST */
|
||||||
|
|
||||||
/* Define if we have pthread_setschedparam() */
|
/* Define if we have pthread_setschedparam() */
|
||||||
#define HAVE_PTHREAD_SETSCHEDPARAM
|
#define HAVE_PTHREAD_SETSCHEDPARAM
|
||||||
|
|
||||||
/* Define if we have the restrict keyword */
|
/* Define if we have pthread_setname_np() */
|
||||||
/* #cmakedefine HAVE_RESTRICT 1 */
|
#define HAVE_PTHREAD_SETNAME_NP
|
||||||
|
|
||||||
/* Define if we have the __restrict keyword */
|
/* Define if we have pthread_set_name_np() */
|
||||||
#define RESTRICT __restrict
|
/* #undef HAVE_PTHREAD_SET_NAME_NP */
|
||||||
|
|
||||||
#endif
|
/* Define if we have pthread_mutexattr_setkind_np() */
|
||||||
|
/* #undef HAVE_PTHREAD_MUTEXATTR_SETKIND_NP */
|
||||||
|
|
||||||
|
/* Define if we have pthread_mutex_timedlock() */
|
||||||
|
/* #undef HAVE_PTHREAD_MUTEX_TIMEDLOCK */
|
@ -1,13 +1,15 @@
|
|||||||
|
TARGET_PLATFORM := android-9
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_MODULE := stbijme
|
LOCAL_MODULE := stbijme
|
||||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
|
||||||
LOCAL_CFLAGS += -O2
|
|
||||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
|
||||||
LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,, $(wildcard $(LOCAL_PATH)/*.c))
|
|
||||||
|
|
||||||
#adds zlib
|
LOCAL_C_INCLUDES += $(LOCAL_PATH)
|
||||||
LOCAL_LDLIBS += -lz -llog
|
|
||||||
|
LOCAL_LDLIBS := -lz -llog -Wl,-s
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := com_jme3_texture_plugins_AndroidNativeImageLoader.c
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
|
APP_PLATFORM := android-9
|
||||||
APP_OPTIM := release
|
APP_OPTIM := release
|
||||||
APP_ABI := all
|
APP_ABI := all
|
||||||
#APP_ABI := armeabi-v7a
|
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#define STBI_HEADER_FILE_ONLY
|
|
||||||
#include "stb_image.c"
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
typedef unsigned int uint32;
|
typedef unsigned int uint32;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// stb_image url for download
|
// stb_image url for download
|
||||||
String stbiUrl = 'http://www.nothings.org/stb_image.c'
|
String stbiUrl = 'https://raw.githubusercontent.com/nothings/stb/master/stb_image.h'
|
||||||
String stbiDownloadTarget = 'stb_image.c'
|
String stbiDownloadTarget = 'stb_image.h'
|
||||||
|
|
||||||
// stb_image is not downloaded. The single source file is included in the repo
|
// stb_image is not downloaded. The single source file is included in the repo
|
||||||
String stbiFolder = 'stb_image'
|
String stbiFolder = 'stb_image'
|
||||||
@ -63,20 +63,21 @@ task generateStbiHeaders(dependsOn: copyStbiJmeFiles) << {
|
|||||||
// println "stb_image destDir = " + destDir
|
// println "stb_image destDir = " + destDir
|
||||||
// println "stb_image classpath = " + project.projectClassPath
|
// println "stb_image classpath = " + project.projectClassPath
|
||||||
|
|
||||||
ant.javah(
|
exec {
|
||||||
classpath: project.projectClassPath,
|
executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah')
|
||||||
destdir: destDirPath,
|
args '-d', destDirPath
|
||||||
class: classes
|
args '-classpath', project.projectClassPath
|
||||||
)
|
args "com.jme3.texture.plugins.AndroidNativeImageLoader"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task buildStbiNativeLib(type: Exec, dependsOn: generateStbiHeaders) {
|
task buildStbiNativeLib(type: Exec, dependsOn: generateStbiHeaders) {
|
||||||
// println "stb_image build dir: " + buildLibDir
|
// println "stb_image build dir: " + stbiBuildDir
|
||||||
// println "ndkCommandPath: " + project.ndkCommandPath
|
// println "ndkCommandPath: " + rootProject.ndkCommandPath
|
||||||
args 'TARGET_PLATFORM=android-9'
|
|
||||||
workingDir stbiBuildDir
|
workingDir stbiBuildDir
|
||||||
executable rootProject.ndkCommandPath
|
executable rootProject.ndkCommandPath
|
||||||
|
args '-j8'
|
||||||
}
|
}
|
||||||
|
|
||||||
task updatePreCompiledStbiLibs(type: Copy, dependsOn: buildStbiNativeLib) {
|
task updatePreCompiledStbiLibs(type: Copy, dependsOn: buildStbiNativeLib) {
|
||||||
|
@ -6,6 +6,7 @@ import android.content.DialogInterface;
|
|||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.NinePatchDrawable;
|
import android.graphics.drawable.NinePatchDrawable;
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
@ -21,7 +22,6 @@ import com.jme3.input.android.AndroidSensorJoyInput;
|
|||||||
import com.jme3.input.controls.TouchListener;
|
import com.jme3.input.controls.TouchListener;
|
||||||
import com.jme3.input.controls.TouchTrigger;
|
import com.jme3.input.controls.TouchTrigger;
|
||||||
import com.jme3.input.event.TouchEvent;
|
import com.jme3.input.event.TouchEvent;
|
||||||
import com.jme3.renderer.android.AndroidGLSurfaceView;
|
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import com.jme3.system.SystemListener;
|
import com.jme3.system.SystemListener;
|
||||||
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
|
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
|
||||||
@ -195,7 +195,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
|
|||||||
*/
|
*/
|
||||||
protected int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
|
protected int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
|
||||||
protected OGLESContext ctx;
|
protected OGLESContext ctx;
|
||||||
protected AndroidGLSurfaceView view = null;
|
protected GLSurfaceView view = null;
|
||||||
protected boolean isGLThreadPaused = true;
|
protected boolean isGLThreadPaused = true;
|
||||||
protected ImageView splashImageView = null;
|
protected ImageView splashImageView = null;
|
||||||
protected FrameLayout frameLayout = null;
|
protected FrameLayout frameLayout = null;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
package com.jme3.input.android;
|
package com.jme3.input.android;
|
||||||
|
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import com.jme3.input.RawInputListener;
|
import com.jme3.input.RawInputListener;
|
||||||
@ -41,7 +42,6 @@ import com.jme3.input.event.KeyInputEvent;
|
|||||||
import com.jme3.input.event.MouseButtonEvent;
|
import com.jme3.input.event.MouseButtonEvent;
|
||||||
import com.jme3.input.event.MouseMotionEvent;
|
import com.jme3.input.event.MouseMotionEvent;
|
||||||
import com.jme3.input.event.TouchEvent;
|
import com.jme3.input.event.TouchEvent;
|
||||||
import com.jme3.renderer.android.AndroidGLSurfaceView;
|
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -67,7 +67,7 @@ public class AndroidInputHandler implements TouchInput {
|
|||||||
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
private AndroidGLSurfaceView view;
|
private GLSurfaceView view;
|
||||||
private AndroidTouchHandler touchHandler;
|
private AndroidTouchHandler touchHandler;
|
||||||
private AndroidKeyHandler keyHandler;
|
private AndroidKeyHandler keyHandler;
|
||||||
private AndroidGestureHandler gestureHandler;
|
private AndroidGestureHandler gestureHandler;
|
||||||
@ -112,7 +112,7 @@ public class AndroidInputHandler implements TouchInput {
|
|||||||
if (gestureHandler != null) {
|
if (gestureHandler != null) {
|
||||||
gestureHandler.setView(view);
|
gestureHandler.setView(view);
|
||||||
}
|
}
|
||||||
this.view = (AndroidGLSurfaceView)view;
|
this.view = (GLSurfaceView)view;
|
||||||
}
|
}
|
||||||
|
|
||||||
public View getView() {
|
public View getView() {
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
package com.jme3.renderer.android;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.opengl.GLSurfaceView;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>AndroidGLSurfaceView</code> is derived from GLSurfaceView
|
|
||||||
* @author iwgeric
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class AndroidGLSurfaceView extends GLSurfaceView {
|
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(AndroidGLSurfaceView.class.getName());
|
|
||||||
|
|
||||||
public AndroidGLSurfaceView(Context ctx, AttributeSet attribs) {
|
|
||||||
super(ctx, attribs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AndroidGLSurfaceView(Context ctx) {
|
|
||||||
super(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2012 jMonkeyEngine
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.jme3.system.android;
|
|
||||||
|
|
||||||
import com.jme3.system.Timer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>AndroidTimer</code> is a System.nanoTime implementation of <code>Timer</code>.
|
|
||||||
*/
|
|
||||||
public class AndroidTimer extends Timer {
|
|
||||||
|
|
||||||
//private static final long TIMER_RESOLUTION = 1000L;
|
|
||||||
//private static final float INVERSE_TIMER_RESOLUTION = 1f/1000L;
|
|
||||||
private static final long TIMER_RESOLUTION = 1000000000L;
|
|
||||||
private static final float INVERSE_TIMER_RESOLUTION = 1f/1000000000L;
|
|
||||||
|
|
||||||
private long startTime;
|
|
||||||
private long previousTime;
|
|
||||||
private float tpf;
|
|
||||||
private float fps;
|
|
||||||
|
|
||||||
public AndroidTimer() {
|
|
||||||
//startTime = System.currentTimeMillis();
|
|
||||||
startTime = System.nanoTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the time in seconds. The timer starts
|
|
||||||
* at 0.0 seconds.
|
|
||||||
*
|
|
||||||
* @return the current time in seconds
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public float getTimeInSeconds() {
|
|
||||||
return getTime() * INVERSE_TIMER_RESOLUTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTime() {
|
|
||||||
//return System.currentTimeMillis() - startTime;
|
|
||||||
return System.nanoTime() - startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getResolution() {
|
|
||||||
return TIMER_RESOLUTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getFrameRate() {
|
|
||||||
return fps;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getTimePerFrame() {
|
|
||||||
return tpf;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
tpf = (getTime() - previousTime) * (1.0f / TIMER_RESOLUTION);
|
|
||||||
fps = 1.0f / tpf;
|
|
||||||
previousTime = getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
//startTime = System.currentTimeMillis();
|
|
||||||
startTime = System.nanoTime();
|
|
||||||
previousTime = getTime();
|
|
||||||
}
|
|
||||||
}
|
|
@ -47,13 +47,11 @@ import android.view.ViewGroup.LayoutParams;
|
|||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import com.jme3.input.*;
|
import com.jme3.input.*;
|
||||||
import com.jme3.input.android.AndroidInput;
|
|
||||||
import com.jme3.input.android.AndroidSensorJoyInput;
|
import com.jme3.input.android.AndroidSensorJoyInput;
|
||||||
import com.jme3.input.android.AndroidInputHandler;
|
import com.jme3.input.android.AndroidInputHandler;
|
||||||
import com.jme3.input.controls.SoftTextDialogInputListener;
|
import com.jme3.input.controls.SoftTextDialogInputListener;
|
||||||
import com.jme3.input.dummy.DummyKeyInput;
|
import com.jme3.input.dummy.DummyKeyInput;
|
||||||
import com.jme3.input.dummy.DummyMouseInput;
|
import com.jme3.input.dummy.DummyMouseInput;
|
||||||
import com.jme3.renderer.android.AndroidGLSurfaceView;
|
|
||||||
import com.jme3.renderer.android.OGLESShaderRenderer;
|
import com.jme3.renderer.android.OGLESShaderRenderer;
|
||||||
import com.jme3.system.*;
|
import com.jme3.system.*;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@ -80,11 +78,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
|||||||
protected AndroidInputHandler androidInput;
|
protected AndroidInputHandler androidInput;
|
||||||
protected int minFrameDuration = 0; // No FPS cap
|
protected int minFrameDuration = 0; // No FPS cap
|
||||||
protected JoyInput androidSensorJoyInput = null;
|
protected JoyInput androidSensorJoyInput = null;
|
||||||
/**
|
|
||||||
* EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 |
|
|
||||||
* EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
|
|
||||||
*/
|
|
||||||
protected int clientOpenGLESVersion = 1;
|
|
||||||
|
|
||||||
public OGLESContext() {
|
public OGLESContext() {
|
||||||
}
|
}
|
||||||
@ -103,12 +96,17 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
|||||||
*
|
*
|
||||||
* @return GLSurfaceView The newly created view
|
* @return GLSurfaceView The newly created view
|
||||||
*/
|
*/
|
||||||
public AndroidGLSurfaceView createView() {
|
public GLSurfaceView createView() {
|
||||||
AndroidGLSurfaceView view;
|
Context appContext = JmeAndroidSystem.getActivity().getApplication();
|
||||||
int buildVersion = Build.VERSION.SDK_INT;
|
|
||||||
|
ActivityManager am = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
||||||
|
if (info.reqGlEsVersion < 0x20000) {
|
||||||
|
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
|
||||||
|
}
|
||||||
|
|
||||||
// Start to set up the view
|
// Start to set up the view
|
||||||
view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity().getApplication());
|
GLSurfaceView view = new GLSurfaceView(appContext);
|
||||||
if (androidInput == null) {
|
if (androidInput == null) {
|
||||||
androidInput = new AndroidInputHandler();
|
androidInput = new AndroidInputHandler();
|
||||||
}
|
}
|
||||||
@ -117,19 +115,10 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
|||||||
|
|
||||||
// setEGLContextClientVersion must be set before calling setRenderer
|
// setEGLContextClientVersion must be set before calling setRenderer
|
||||||
// this means it cannot be set in AndroidConfigChooser (too late)
|
// this means it cannot be set in AndroidConfigChooser (too late)
|
||||||
int rawOpenGLESVersion = getOpenGLESVersion();
|
view.setEGLContextClientVersion(2);
|
||||||
// logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}",
|
|
||||||
// new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16});
|
|
||||||
if (rawOpenGLESVersion < 0x20000) {
|
|
||||||
throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
|
|
||||||
} else {
|
|
||||||
clientOpenGLESVersion = 2;
|
|
||||||
view.setEGLContextClientVersion(clientOpenGLESVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.setFocusableInTouchMode(true);
|
view.setFocusableInTouchMode(true);
|
||||||
view.setFocusable(true);
|
view.setFocusable(true);
|
||||||
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
|
|
||||||
|
|
||||||
// setFormat must be set before AndroidConfigChooser is called by the surfaceview.
|
// setFormat must be set before AndroidConfigChooser is called by the surfaceview.
|
||||||
// if setFormat is called after ConfigChooser is called, then execution
|
// if setFormat is called after ConfigChooser is called, then execution
|
||||||
@ -160,24 +149,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
|||||||
// Not destroying and recreating the EGL context
|
// Not destroying and recreating the EGL context
|
||||||
// will help with resume time by reusing the existing context to avoid
|
// will help with resume time by reusing the existing context to avoid
|
||||||
// reloading all the OpenGL objects.
|
// reloading all the OpenGL objects.
|
||||||
if (buildVersion >= 11) {
|
if (Build.VERSION.SDK_INT >= 11) {
|
||||||
view.setPreserveEGLContextOnPause(true);
|
view.setPreserveEGLContextOnPause(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Get the OpenGL ES version
|
|
||||||
* @return version returns the int value of the GLES version
|
|
||||||
*/
|
|
||||||
public int getOpenGLESVersion() {
|
|
||||||
ActivityManager am =
|
|
||||||
(ActivityManager) JmeAndroidSystem.getActivity().getApplication().getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
ConfigurationInfo info = am.getDeviceConfigurationInfo();
|
|
||||||
logger.log(Level.FINE, "OpenGL Version {0}:", info.getGlEsVersion());
|
|
||||||
return info.reqGlEsVersion;
|
|
||||||
// return (info.reqGlEsVersion >= 0x20000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// renderer:initialize
|
// renderer:initialize
|
||||||
@Override
|
@Override
|
||||||
@ -207,7 +184,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
timer = new AndroidTimer();
|
timer = new NanoTimer();
|
||||||
renderer = new OGLESShaderRenderer();
|
renderer = new OGLESShaderRenderer();
|
||||||
|
|
||||||
renderer.initialize();
|
renderer.initialize();
|
||||||
|
@ -42,7 +42,6 @@ import com.jme3.material.TechniqueDef.LightMode;
|
|||||||
import com.jme3.material.TechniqueDef.ShadowMode;
|
import com.jme3.material.TechniqueDef.ShadowMode;
|
||||||
import com.jme3.math.*;
|
import com.jme3.math.*;
|
||||||
import com.jme3.renderer.Caps;
|
import com.jme3.renderer.Caps;
|
||||||
import com.jme3.renderer.GL1Renderer;
|
|
||||||
import com.jme3.renderer.RenderManager;
|
import com.jme3.renderer.RenderManager;
|
||||||
import com.jme3.renderer.Renderer;
|
import com.jme3.renderer.Renderer;
|
||||||
import com.jme3.renderer.RendererException;
|
import com.jme3.renderer.RendererException;
|
||||||
@ -52,7 +51,6 @@ import com.jme3.scene.Mesh;
|
|||||||
import com.jme3.scene.instancing.InstancedGeometry;
|
import com.jme3.scene.instancing.InstancedGeometry;
|
||||||
import com.jme3.shader.Shader;
|
import com.jme3.shader.Shader;
|
||||||
import com.jme3.shader.Uniform;
|
import com.jme3.shader.Uniform;
|
||||||
import com.jme3.shader.UniformBindingManager;
|
|
||||||
import com.jme3.shader.VarType;
|
import com.jme3.shader.VarType;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.image.ColorSpace;
|
import com.jme3.texture.image.ColorSpace;
|
||||||
@ -697,12 +695,15 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
setParam(name, VarType.Vector4, value);
|
setParam(name, VarType.Vector4, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ColorRGBA getAmbientColor(LightList lightList) {
|
private ColorRGBA getAmbientColor(LightList lightList, boolean removeLights) {
|
||||||
ambientLightColor.set(0, 0, 0, 1);
|
ambientLightColor.set(0, 0, 0, 1);
|
||||||
for (int j = 0; j < lightList.size(); j++) {
|
for (int j = 0; j < lightList.size(); j++) {
|
||||||
Light l = lightList.get(j);
|
Light l = lightList.get(j);
|
||||||
if (l instanceof AmbientLight) {
|
if (l instanceof AmbientLight) {
|
||||||
ambientLightColor.addLocal(l.getColor());
|
ambientLightColor.addLocal(l.getColor());
|
||||||
|
if(removeLights){
|
||||||
|
lightList.remove(l);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ambientLightColor.a = 1.0f;
|
ambientLightColor.a = 1.0f;
|
||||||
@ -741,47 +742,73 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
* g_LightPosition.w is the inverse radius (1/r) of the light (for
|
* g_LightPosition.w is the inverse radius (1/r) of the light (for
|
||||||
* attenuation) <br/> </p>
|
* attenuation) <br/> </p>
|
||||||
*/
|
*/
|
||||||
protected void updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights) {
|
protected int updateLightListUniforms(Shader shader, Geometry g, LightList lightList, int numLights, RenderManager rm, int startIndex) {
|
||||||
if (numLights == 0) { // this shader does not do lighting, ignore.
|
if (numLights == 0) { // this shader does not do lighting, ignore.
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uniform lightColor = shader.getUniform("g_LightColor");
|
Uniform lightData = shader.getUniform("g_LightData");
|
||||||
Uniform lightPos = shader.getUniform("g_LightPosition");
|
lightData.setVector4Length(numLights * 3);//8 lights * max 3
|
||||||
Uniform lightDir = shader.getUniform("g_LightDirection");
|
|
||||||
lightColor.setVector4Length(numLights);
|
|
||||||
lightPos.setVector4Length(numLights);
|
|
||||||
lightDir.setVector4Length(numLights);
|
|
||||||
|
|
||||||
Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
|
Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
|
||||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
|
|
||||||
|
|
||||||
int lightIndex = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < numLights; i++) {
|
if (startIndex != 0) {
|
||||||
if (lightList.size() <= i) {
|
// apply additive blending for 2nd and future passes
|
||||||
lightColor.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
rm.getRenderer().applyRenderState(additiveLight);
|
||||||
lightPos.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
|
||||||
} else {
|
}else{
|
||||||
Light l = lightList.get(i);
|
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList,true));
|
||||||
|
}
|
||||||
|
|
||||||
|
int lightDataIndex = 0;
|
||||||
|
TempVars vars = TempVars.get();
|
||||||
|
Vector4f tmpVec = vars.vect4f1;
|
||||||
|
int curIndex;
|
||||||
|
int endIndex = numLights + startIndex;
|
||||||
|
for (curIndex = startIndex; curIndex < endIndex && curIndex < lightList.size(); curIndex++) {
|
||||||
|
|
||||||
|
|
||||||
|
Light l = lightList.get(curIndex);
|
||||||
|
if(l.getType() == Light.Type.Ambient){
|
||||||
|
endIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ColorRGBA color = l.getColor();
|
ColorRGBA color = l.getColor();
|
||||||
lightColor.setVector4InArray(color.getRed(),
|
//Color
|
||||||
|
lightData.setVector4InArray(color.getRed(),
|
||||||
color.getGreen(),
|
color.getGreen(),
|
||||||
color.getBlue(),
|
color.getBlue(),
|
||||||
l.getType().getId(),
|
l.getType().getId(),
|
||||||
i);
|
lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
|
|
||||||
switch (l.getType()) {
|
switch (l.getType()) {
|
||||||
case Directional:
|
case Directional:
|
||||||
DirectionalLight dl = (DirectionalLight) l;
|
DirectionalLight dl = (DirectionalLight) l;
|
||||||
Vector3f dir = dl.getDirection();
|
Vector3f dir = dl.getDirection();
|
||||||
lightPos.setVector4InArray(dir.getX(), dir.getY(), dir.getZ(), -1, lightIndex);
|
//Data directly sent in view space to avoid a matrix mult for each pixel
|
||||||
|
tmpVec.set(dir.getX(), dir.getY(), dir.getZ(), 0.0f);
|
||||||
|
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||||
|
// tmpVec.divideLocal(tmpVec.w);
|
||||||
|
// tmpVec.normalizeLocal();
|
||||||
|
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), -1, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
|
//PADDING
|
||||||
|
lightData.setVector4InArray(0,0,0,0, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
break;
|
break;
|
||||||
case Point:
|
case Point:
|
||||||
PointLight pl = (PointLight) l;
|
PointLight pl = (PointLight) l;
|
||||||
Vector3f pos = pl.getPosition();
|
Vector3f pos = pl.getPosition();
|
||||||
float invRadius = pl.getInvRadius();
|
float invRadius = pl.getInvRadius();
|
||||||
lightPos.setVector4InArray(pos.getX(), pos.getY(), pos.getZ(), invRadius, lightIndex);
|
tmpVec.set(pos.getX(), pos.getY(), pos.getZ(), 1.0f);
|
||||||
|
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||||
|
//tmpVec.divideLocal(tmpVec.w);
|
||||||
|
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRadius, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
|
//PADDING
|
||||||
|
lightData.setVector4InArray(0,0,0,0, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
break;
|
break;
|
||||||
case Spot:
|
case Spot:
|
||||||
SpotLight sl = (SpotLight) l;
|
SpotLight sl = (SpotLight) l;
|
||||||
@ -789,27 +816,32 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
Vector3f dir2 = sl.getDirection();
|
Vector3f dir2 = sl.getDirection();
|
||||||
float invRange = sl.getInvSpotRange();
|
float invRange = sl.getInvSpotRange();
|
||||||
float spotAngleCos = sl.getPackedAngleCos();
|
float spotAngleCos = sl.getPackedAngleCos();
|
||||||
|
tmpVec.set(pos2.getX(), pos2.getY(), pos2.getZ(), 1.0f);
|
||||||
|
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||||
|
// tmpVec.divideLocal(tmpVec.w);
|
||||||
|
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), invRange, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
|
|
||||||
lightPos.setVector4InArray(pos2.getX(), pos2.getY(), pos2.getZ(), invRange, lightIndex);
|
//We transform the spot direction in view space here to save 5 varying later in the lighting shader
|
||||||
lightDir.setVector4InArray(dir2.getX(), dir2.getY(), dir2.getZ(), spotAngleCos, lightIndex);
|
//one vec4 less and a vec4 that becomes a vec3
|
||||||
|
//the downside is that spotAngleCos decoding happens now in the frag shader.
|
||||||
|
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0.0f);
|
||||||
|
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||||
|
tmpVec.normalizeLocal();
|
||||||
|
lightData.setVector4InArray(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
break;
|
break;
|
||||||
case Ambient:
|
|
||||||
// skip this light. Does not increase lightIndex
|
|
||||||
continue;
|
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
|
throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
lightIndex++;
|
|
||||||
}
|
}
|
||||||
|
vars.release();
|
||||||
while (lightIndex < numLights) {
|
//Padding of unsued buffer space
|
||||||
lightColor.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
while(lightDataIndex < numLights * 3) {
|
||||||
lightPos.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
|
lightData.setVector4InArray(0f, 0f, 0f, 0f, lightDataIndex);
|
||||||
|
lightDataIndex++;
|
||||||
lightIndex++;
|
|
||||||
}
|
}
|
||||||
|
return curIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderMultipassLighting(Shader shader, Geometry g, LightList lightList, RenderManager rm) {
|
protected void renderMultipassLighting(Shader shader, Geometry g, LightList lightList, RenderManager rm) {
|
||||||
@ -830,7 +862,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
|
|
||||||
if (isFirstLight) {
|
if (isFirstLight) {
|
||||||
// set ambient color for first light only
|
// set ambient color for first light only
|
||||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
|
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList, false));
|
||||||
isFirstLight = false;
|
isFirstLight = false;
|
||||||
isSecondLight = true;
|
isSecondLight = true;
|
||||||
} else if (isSecondLight) {
|
} else if (isSecondLight) {
|
||||||
@ -885,9 +917,9 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange);
|
tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange);
|
||||||
lightPos.setValue(VarType.Vector4, tmpLightPosition);
|
lightPos.setValue(VarType.Vector4, tmpLightPosition);
|
||||||
|
|
||||||
//We transform the spot directoin in view space here to save 5 varying later in the lighting shader
|
//We transform the spot direction in view space here to save 5 varying later in the lighting shader
|
||||||
//one vec4 less and a vec4 that becomes a vec3
|
//one vec4 less and a vec4 that becomes a vec3
|
||||||
//the downside is that spotAngleCos decoding happen now in the frag shader.
|
//the downside is that spotAngleCos decoding happens now in the frag shader.
|
||||||
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0);
|
tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0);
|
||||||
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
|
||||||
tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos);
|
tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos);
|
||||||
@ -906,7 +938,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
if (isFirstLight && lightList.size() > 0) {
|
if (isFirstLight && lightList.size() > 0) {
|
||||||
// There are only ambient lights in the scene. Render
|
// There are only ambient lights in the scene. Render
|
||||||
// a dummy "normal light" so we can see the ambient
|
// a dummy "normal light" so we can see the ambient
|
||||||
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
|
ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList, false));
|
||||||
lightColor.setValue(VarType.Vector4, ColorRGBA.BlackNoAlpha);
|
lightColor.setValue(VarType.Vector4, ColorRGBA.BlackNoAlpha);
|
||||||
lightPos.setValue(VarType.Vector4, nullDirLight);
|
lightPos.setValue(VarType.Vector4, nullDirLight);
|
||||||
r.setShader(shader);
|
r.setShader(shader);
|
||||||
@ -957,7 +989,10 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
// use the first one that supports all the caps
|
// use the first one that supports all the caps
|
||||||
tech = new Technique(this, techDef);
|
tech = new Technique(this, techDef);
|
||||||
techniques.put(name, tech);
|
techniques.put(name, tech);
|
||||||
break;
|
if(tech.getDef().getLightMode() == renderManager.getPreferredLightMode() ||
|
||||||
|
tech.getDef().getLightMode() == LightMode.Disable){
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastTech = techDef;
|
lastTech = techDef;
|
||||||
}
|
}
|
||||||
@ -990,7 +1025,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
technique = tech;
|
technique = tech;
|
||||||
tech.makeCurrent(def.getAssetManager(), true, rendererCaps);
|
tech.makeCurrent(def.getAssetManager(), true, rendererCaps, renderManager);
|
||||||
|
|
||||||
// shader was changed
|
// shader was changed
|
||||||
sortingId = -1;
|
sortingId = -1;
|
||||||
@ -1000,7 +1035,7 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
if (technique == null) {
|
if (technique == null) {
|
||||||
selectTechnique("Default", rm);
|
selectTechnique("Default", rm);
|
||||||
} else {
|
} else {
|
||||||
technique.makeCurrent(def.getAssetManager(), false, rm.getRenderer().getCaps());
|
technique.makeCurrent(def.getAssetManager(), false, rm.getRenderer().getCaps(), rm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,8 +1197,14 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
|
|||||||
r.setLighting(null);
|
r.setLighting(null);
|
||||||
break;
|
break;
|
||||||
case SinglePass:
|
case SinglePass:
|
||||||
updateLightListUniforms(shader, geom, lights, 4);
|
int nbRenderedLights = 0;
|
||||||
break;
|
resetUniformsNotSetByCurrent(shader);
|
||||||
|
while(nbRenderedLights < lights.size()){
|
||||||
|
nbRenderedLights = updateLightListUniforms(shader, geom, lights, rm.getSinglePassLightBatchSize(), rm, nbRenderedLights);
|
||||||
|
r.setShader(shader);
|
||||||
|
renderMeshFromGeometry(r, geom);
|
||||||
|
}
|
||||||
|
return;
|
||||||
case FixedPipeline:
|
case FixedPipeline:
|
||||||
r.setLighting(lights);
|
r.setLighting(lights);
|
||||||
break;
|
break;
|
||||||
|
@ -33,8 +33,8 @@ package com.jme3.material;
|
|||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.renderer.Caps;
|
import com.jme3.renderer.Caps;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
import com.jme3.shader.*;
|
import com.jme3.shader.*;
|
||||||
import com.jme3.util.ListMap;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -172,7 +172,7 @@ public class Technique /* implements Savable */ {
|
|||||||
*
|
*
|
||||||
* @param assetManager The asset manager to use for loading shaders.
|
* @param assetManager The asset manager to use for loading shaders.
|
||||||
*/
|
*/
|
||||||
public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched, EnumSet<Caps> rendererCaps) {
|
public void makeCurrent(AssetManager assetManager, boolean techniqueSwitched, EnumSet<Caps> rendererCaps, RenderManager rm) {
|
||||||
if (!def.isUsingShaders()) {
|
if (!def.isUsingShaders()) {
|
||||||
// No shaders are used, no processing is neccessary.
|
// No shaders are used, no processing is neccessary.
|
||||||
return;
|
return;
|
||||||
@ -182,6 +182,13 @@ public class Technique /* implements Savable */ {
|
|||||||
if (defines.update(owner.getParamsMap(), def)) {
|
if (defines.update(owner.getParamsMap(), def)) {
|
||||||
needReload = true;
|
needReload = true;
|
||||||
}
|
}
|
||||||
|
if(getDef().getLightMode()== TechniqueDef.LightMode.SinglePass){
|
||||||
|
defines.set("SINGLE_PASS_LIGHTING", VarType.Boolean, true);
|
||||||
|
defines.set("NB_LIGHTS", VarType.Int, rm.getSinglePassLightBatchSize()*3 );
|
||||||
|
}else{
|
||||||
|
defines.set("SINGLE_PASS_LIGHTING", VarType.Boolean, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needReload) {
|
if (needReload) {
|
||||||
|
@ -236,7 +236,22 @@ public enum Caps {
|
|||||||
/**
|
/**
|
||||||
* Supports sRGB framebuffers and sRGB texture format
|
* Supports sRGB framebuffers and sRGB texture format
|
||||||
*/
|
*/
|
||||||
Srgb;
|
Srgb,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supports blitting framebuffers.
|
||||||
|
*/
|
||||||
|
FrameBufferBlit,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supports {@link Format#DXT1} and sister formats.
|
||||||
|
*/
|
||||||
|
TextureCompressionS3TC,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supports anisotropic texture filtering.
|
||||||
|
*/
|
||||||
|
TextureFilterAnisotropic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if given the renderer capabilities, the texture
|
* Returns true if given the renderer capabilities, the texture
|
||||||
|
@ -35,6 +35,7 @@ import com.jme3.material.RenderState;
|
|||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.scene.VertexBuffer;
|
||||||
|
import com.jme3.shader.Shader;
|
||||||
import com.jme3.texture.FrameBuffer;
|
import com.jme3.texture.FrameBuffer;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
|
|
||||||
@ -139,11 +140,21 @@ public class RenderContext {
|
|||||||
*/
|
*/
|
||||||
public int boundShaderProgram;
|
public int boundShaderProgram;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Renderer#setShader(com.jme3.shader.Shader)
|
||||||
|
*/
|
||||||
|
public Shader boundShader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
|
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
|
||||||
*/
|
*/
|
||||||
public int boundFBO = 0;
|
public int boundFBO = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Renderer#setFrameBuffer(com.jme3.texture.FrameBuffer)
|
||||||
|
*/
|
||||||
|
public FrameBuffer boundFB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently bound Renderbuffer
|
* Currently bound Renderbuffer
|
||||||
*
|
*
|
||||||
@ -279,6 +290,10 @@ public class RenderContext {
|
|||||||
*/
|
*/
|
||||||
public RenderState.TestFunction alphaFunc = RenderState.TestFunction.Greater;
|
public RenderState.TestFunction alphaFunc = RenderState.TestFunction.Greater;
|
||||||
|
|
||||||
|
|
||||||
|
public int initialDrawBuf;
|
||||||
|
public int initialReadBuf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the RenderContext to default GL state
|
* Reset the RenderContext to default GL state
|
||||||
*/
|
*/
|
||||||
@ -298,7 +313,9 @@ public class RenderContext {
|
|||||||
blendMode = RenderState.BlendMode.Off;
|
blendMode = RenderState.BlendMode.Off;
|
||||||
wireframe = false;
|
wireframe = false;
|
||||||
boundShaderProgram = 0;
|
boundShaderProgram = 0;
|
||||||
|
boundShader = null;
|
||||||
boundFBO = 0;
|
boundFBO = 0;
|
||||||
|
boundFB = null;
|
||||||
boundRB = 0;
|
boundRB = 0;
|
||||||
boundDrawBuf = -1;
|
boundDrawBuf = -1;
|
||||||
boundReadBuf = -1;
|
boundReadBuf = -1;
|
||||||
|
@ -38,6 +38,7 @@ import com.jme3.material.Material;
|
|||||||
import com.jme3.material.MaterialDef;
|
import com.jme3.material.MaterialDef;
|
||||||
import com.jme3.material.RenderState;
|
import com.jme3.material.RenderState;
|
||||||
import com.jme3.material.Technique;
|
import com.jme3.material.Technique;
|
||||||
|
import com.jme3.material.TechniqueDef;
|
||||||
import com.jme3.math.*;
|
import com.jme3.math.*;
|
||||||
import com.jme3.post.SceneProcessor;
|
import com.jme3.post.SceneProcessor;
|
||||||
import com.jme3.profile.AppProfiler;
|
import com.jme3.profile.AppProfiler;
|
||||||
@ -89,6 +90,8 @@ public class RenderManager {
|
|||||||
private boolean handleTranlucentBucket = true;
|
private boolean handleTranlucentBucket = true;
|
||||||
private AppProfiler prof;
|
private AppProfiler prof;
|
||||||
private LightFilter lightFilter = new DefaultLightFilter();
|
private LightFilter lightFilter = new DefaultLightFilter();
|
||||||
|
private TechniqueDef.LightMode preferredLightMode = TechniqueDef.LightMode.MultiPass;
|
||||||
|
private int singlePassLightBatchSize = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a high-level rendering interface over the
|
* Create a high-level rendering interface over the
|
||||||
@ -780,6 +783,33 @@ public class RenderManager {
|
|||||||
vp.getQueue().clear();
|
vp.getQueue().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the light filter to use when rendering Lighted Geometries
|
||||||
|
*
|
||||||
|
* @see LightFilter
|
||||||
|
* @param lightFilter The light filter tose. Set it to null if you want all lights to be rendered
|
||||||
|
*/
|
||||||
|
public void setLightFilter(LightFilter lightFilter) {
|
||||||
|
this.lightFilter = lightFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreferredLightMode(TechniqueDef.LightMode preferredLightMode) {
|
||||||
|
this.preferredLightMode = preferredLightMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TechniqueDef.LightMode getPreferredLightMode() {
|
||||||
|
return preferredLightMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSinglePassLightBatchSize() {
|
||||||
|
return singlePassLightBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSinglePassLightBatchSize(int singlePassLightBatchSize) {
|
||||||
|
this.singlePassLightBatchSize = singlePassLightBatchSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the given viewport queues.
|
* Render the given viewport queues.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#import "Common/ShaderLib/Parallax.glsllib"
|
#import "Common/ShaderLib/Parallax.glsllib"
|
||||||
#import "Common/ShaderLib/Optics.glsllib"
|
#import "Common/ShaderLib/Optics.glsllib"
|
||||||
#define ATTENUATION
|
#ifndef VERTEX_LIGHTING
|
||||||
//#define HQ_ATTENUATION
|
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
#endif
|
||||||
|
|
||||||
varying vec2 texCoord;
|
varying vec2 texCoord;
|
||||||
#ifdef SEPARATE_TEXCOORD
|
#ifdef SEPARATE_TEXCOORD
|
||||||
@ -58,82 +60,14 @@ varying vec3 SpecularSum;
|
|||||||
uniform float m_AlphaDiscardThreshold;
|
uniform float m_AlphaDiscardThreshold;
|
||||||
|
|
||||||
#ifndef VERTEX_LIGHTING
|
#ifndef VERTEX_LIGHTING
|
||||||
uniform float m_Shininess;
|
uniform float m_Shininess;
|
||||||
|
#ifdef USE_REFLECTION
|
||||||
|
uniform float m_ReflectionPower;
|
||||||
|
uniform float m_ReflectionIntensity;
|
||||||
|
varying vec4 refVec;
|
||||||
|
|
||||||
#ifdef HQ_ATTENUATION
|
uniform ENVMAP m_EnvMap;
|
||||||
uniform vec4 g_LightPosition;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_REFLECTION
|
|
||||||
uniform float m_ReflectionPower;
|
|
||||||
uniform float m_ReflectionIntensity;
|
|
||||||
varying vec4 refVec;
|
|
||||||
|
|
||||||
uniform ENVMAP m_EnvMap;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float tangDot(in vec3 v1, in vec3 v2){
|
|
||||||
float d = dot(v1,v2);
|
|
||||||
#ifdef V_TANGENT
|
|
||||||
d = 1.0 - d*d;
|
|
||||||
return step(0.0, d) * sqrt(d);
|
|
||||||
#else
|
|
||||||
return d;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
|
|
||||||
#ifdef MINNAERT
|
|
||||||
float NdotL = max(0.0, dot(norm, lightdir));
|
|
||||||
float NdotV = max(0.0, dot(norm, viewdir));
|
|
||||||
return NdotL * pow(max(NdotL * NdotV, 0.1), -1.0) * 0.5;
|
|
||||||
#else
|
|
||||||
return max(0.0, dot(norm, lightdir));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
|
||||||
// NOTE: check for shiny <= 1 removed since shininess is now
|
|
||||||
// 1.0 by default (uses matdefs default vals)
|
|
||||||
#ifdef LOW_QUALITY
|
|
||||||
// Blinn-Phong
|
|
||||||
// Note: preferably, H should be computed in the vertex shader
|
|
||||||
vec3 H = (viewdir + lightdir) * vec3(0.5);
|
|
||||||
return pow(max(tangDot(H, norm), 0.0), shiny);
|
|
||||||
#elif defined(WARDISO)
|
|
||||||
// Isotropic Ward
|
|
||||||
vec3 halfVec = normalize(viewdir + lightdir);
|
|
||||||
float NdotH = max(0.001, tangDot(norm, halfVec));
|
|
||||||
float NdotV = max(0.001, tangDot(norm, viewdir));
|
|
||||||
float NdotL = max(0.001, tangDot(norm, lightdir));
|
|
||||||
float a = tan(acos(NdotH));
|
|
||||||
float p = max(shiny/128.0, 0.001);
|
|
||||||
return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
|
|
||||||
#else
|
|
||||||
// Standard Phong
|
|
||||||
vec3 R = reflect(-lightdir, norm);
|
|
||||||
return pow(max(tangDot(R, viewdir), 0.0), shiny);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 computeLighting(in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
|
|
||||||
float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
|
|
||||||
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
|
|
||||||
|
|
||||||
#ifdef HQ_ATTENUATION
|
|
||||||
float att = clamp(1.0 - g_LightPosition.w * length(lightVec), 0.0, 1.0);
|
|
||||||
#else
|
|
||||||
float att = vLightDir.w;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_Shininess <= 1.0) {
|
|
||||||
specularFactor = 0.0; // should be one instruction on most cards ..
|
|
||||||
}
|
|
||||||
|
|
||||||
specularFactor *= diffuseFactor;
|
|
||||||
|
|
||||||
return vec2(diffuseFactor, specularFactor) * vec2(att);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
@ -172,39 +106,12 @@ void main(){
|
|||||||
#ifdef ALPHAMAP
|
#ifdef ALPHAMAP
|
||||||
alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;
|
alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;
|
||||||
#endif
|
#endif
|
||||||
if(alpha < m_AlphaDiscardThreshold){
|
#ifdef DISCARD_ALPHA
|
||||||
discard;
|
if(alpha < m_AlphaDiscardThreshold){
|
||||||
}
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef VERTEX_LIGHTING
|
|
||||||
float spotFallOff = 1.0;
|
|
||||||
|
|
||||||
#if __VERSION__ >= 110
|
|
||||||
// allow use of control flow
|
|
||||||
if(g_LightDirection.w != 0.0){
|
|
||||||
#endif
|
|
||||||
|
|
||||||
vec3 L = normalize(lightVec.xyz);
|
|
||||||
vec3 spotdir = normalize(g_LightDirection.xyz);
|
|
||||||
float curAngleCos = dot(-L, spotdir);
|
|
||||||
float innerAngleCos = floor(g_LightDirection.w) * 0.001;
|
|
||||||
float outerAngleCos = fract(g_LightDirection.w);
|
|
||||||
float innerMinusOuter = innerAngleCos - outerAngleCos;
|
|
||||||
spotFallOff = (curAngleCos - outerAngleCos) / innerMinusOuter;
|
|
||||||
|
|
||||||
#if __VERSION__ >= 110
|
|
||||||
if(spotFallOff <= 0.0){
|
|
||||||
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
|
|
||||||
gl_FragColor.a = alpha;
|
|
||||||
return;
|
|
||||||
}else{
|
|
||||||
spotFallOff = clamp(spotFallOff, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
spotFallOff = clamp(spotFallOff, step(g_LightDirection.w, 0.001), 1.0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ***********************
|
// ***********************
|
||||||
// Read from textures
|
// Read from textures
|
||||||
@ -257,8 +164,23 @@ void main(){
|
|||||||
vec4 lightDir = vLightDir;
|
vec4 lightDir = vLightDir;
|
||||||
lightDir.xyz = normalize(lightDir.xyz);
|
lightDir.xyz = normalize(lightDir.xyz);
|
||||||
vec3 viewDir = normalize(vViewDir);
|
vec3 viewDir = normalize(vViewDir);
|
||||||
|
float spotFallOff = 1.0;
|
||||||
|
|
||||||
vec2 light = computeLighting(normal, viewDir, lightDir.xyz) * spotFallOff;
|
#if __VERSION__ >= 110
|
||||||
|
// allow use of control flow
|
||||||
|
if(g_LightDirection.w != 0.0){
|
||||||
|
#endif
|
||||||
|
spotFallOff = computeSpotFalloff(g_LightDirection, lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
if(spotFallOff <= 0.0){
|
||||||
|
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
|
||||||
|
gl_FragColor.a = alpha;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess) ;
|
||||||
#ifdef COLORRAMP
|
#ifdef COLORRAMP
|
||||||
diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
|
diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
|
||||||
specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
|
specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
|
||||||
|
@ -6,34 +6,12 @@ MaterialDef Phong Lighting {
|
|||||||
// For better performance
|
// For better performance
|
||||||
Boolean VertexLighting
|
Boolean VertexLighting
|
||||||
|
|
||||||
// Use more efficent algorithms to improve performance
|
|
||||||
Boolean LowQuality
|
|
||||||
|
|
||||||
// Improve quality at the cost of performance
|
|
||||||
Boolean HighQuality
|
|
||||||
|
|
||||||
// Output alpha from the diffuse map
|
|
||||||
Boolean UseAlpha
|
|
||||||
|
|
||||||
// Alpha threshold for fragment discarding
|
// Alpha threshold for fragment discarding
|
||||||
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
Float AlphaDiscardThreshold (AlphaTestFallOff)
|
||||||
|
|
||||||
// Normal map is in BC5/ATI2n/LATC/3Dc compression format
|
|
||||||
Boolean LATC
|
|
||||||
|
|
||||||
// Use the provided ambient, diffuse, and specular colors
|
// Use the provided ambient, diffuse, and specular colors
|
||||||
Boolean UseMaterialColors
|
Boolean UseMaterialColors
|
||||||
|
|
||||||
// Activate shading along the tangent, instead of the normal
|
|
||||||
// Requires tangent data to be available on the model.
|
|
||||||
Boolean VTangent
|
|
||||||
|
|
||||||
// Use minnaert diffuse instead of lambert
|
|
||||||
Boolean Minnaert
|
|
||||||
|
|
||||||
// Use ward specular instead of phong
|
|
||||||
Boolean WardIso
|
|
||||||
|
|
||||||
// Use vertex color as an additional diffuse color.
|
// Use vertex color as an additional diffuse color.
|
||||||
Boolean UseVertexColor
|
Boolean UseVertexColor
|
||||||
|
|
||||||
@ -133,9 +111,48 @@ MaterialDef Phong Lighting {
|
|||||||
Int NumberOfBones
|
Int NumberOfBones
|
||||||
Matrix4Array BoneMatrices
|
Matrix4Array BoneMatrices
|
||||||
|
|
||||||
|
//For instancing
|
||||||
Boolean UseInstancing
|
Boolean UseInstancing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
LightMode SinglePass
|
||||||
|
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Light/SPLighting.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Light/SPLighting.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
NormalMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
ViewMatrix
|
||||||
|
CameraPosition
|
||||||
|
WorldMatrix
|
||||||
|
ViewProjectionMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
VERTEX_COLOR : UseVertexColor
|
||||||
|
VERTEX_LIGHTING : VertexLighting
|
||||||
|
MATERIAL_COLORS : UseMaterialColors
|
||||||
|
DIFFUSEMAP : DiffuseMap
|
||||||
|
NORMALMAP : NormalMap
|
||||||
|
SPECULARMAP : SpecularMap
|
||||||
|
PARALLAXMAP : ParallaxMap
|
||||||
|
NORMALMAP_PARALLAX : PackedNormalParallax
|
||||||
|
STEEP_PARALLAX : SteepParallax
|
||||||
|
ALPHAMAP : AlphaMap
|
||||||
|
COLORRAMP : ColorRamp
|
||||||
|
LIGHTMAP : LightMap
|
||||||
|
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
|
USE_REFLECTION : EnvMap
|
||||||
|
SPHERE_MAP : SphereMap
|
||||||
|
NUM_BONES : NumberOfBones
|
||||||
|
INSTANCING : UseInstancing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
|
|
||||||
LightMode MultiPass
|
LightMode MultiPass
|
||||||
@ -154,17 +171,9 @@ MaterialDef Phong Lighting {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Defines {
|
Defines {
|
||||||
LATC : LATC
|
|
||||||
VERTEX_COLOR : UseVertexColor
|
VERTEX_COLOR : UseVertexColor
|
||||||
VERTEX_LIGHTING : VertexLighting
|
VERTEX_LIGHTING : VertexLighting
|
||||||
ATTENUATION : Attenuation
|
|
||||||
MATERIAL_COLORS : UseMaterialColors
|
MATERIAL_COLORS : UseMaterialColors
|
||||||
V_TANGENT : VTangent
|
|
||||||
MINNAERT : Minnaert
|
|
||||||
WARDISO : WardIso
|
|
||||||
LOW_QUALITY : LowQuality
|
|
||||||
HQ_ATTENUATION : HighQuality
|
|
||||||
|
|
||||||
DIFFUSEMAP : DiffuseMap
|
DIFFUSEMAP : DiffuseMap
|
||||||
NORMALMAP : NormalMap
|
NORMALMAP : NormalMap
|
||||||
SPECULARMAP : SpecularMap
|
SPECULARMAP : SpecularMap
|
||||||
@ -175,16 +184,16 @@ MaterialDef Phong Lighting {
|
|||||||
COLORRAMP : ColorRamp
|
COLORRAMP : ColorRamp
|
||||||
LIGHTMAP : LightMap
|
LIGHTMAP : LightMap
|
||||||
SEPARATE_TEXCOORD : SeparateTexCoord
|
SEPARATE_TEXCOORD : SeparateTexCoord
|
||||||
|
DISCARD_ALPHA : AlphaDiscardThreshold
|
||||||
USE_REFLECTION : EnvMap
|
USE_REFLECTION : EnvMap
|
||||||
SPHERE_MAP : SphereMap
|
SPHERE_MAP : SphereMap
|
||||||
|
|
||||||
NUM_BONES : NumberOfBones
|
NUM_BONES : NumberOfBones
|
||||||
|
|
||||||
INSTANCING : UseInstancing
|
INSTANCING : UseInstancing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Technique PreShadow {
|
Technique PreShadow {
|
||||||
|
|
||||||
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#import "Common/ShaderLib/Instancing.glsllib"
|
#import "Common/ShaderLib/Instancing.glsllib"
|
||||||
#define ATTENUATION
|
|
||||||
//#define HQ_ATTENUATION
|
|
||||||
|
|
||||||
#import "Common/ShaderLib/Skinning.glsllib"
|
#import "Common/ShaderLib/Skinning.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
#ifdef VERTEX_LIGHTING
|
||||||
|
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uniform vec4 m_Ambient;
|
uniform vec4 m_Ambient;
|
||||||
uniform vec4 m_Diffuse;
|
uniform vec4 m_Diffuse;
|
||||||
@ -28,7 +30,6 @@ attribute vec2 inTexCoord;
|
|||||||
attribute vec3 inNormal;
|
attribute vec3 inNormal;
|
||||||
|
|
||||||
varying vec3 lightVec;
|
varying vec3 lightVec;
|
||||||
//varying vec4 spotVec;
|
|
||||||
|
|
||||||
#ifdef VERTEX_COLOR
|
#ifdef VERTEX_COLOR
|
||||||
attribute vec4 inColor;
|
attribute vec4 inColor;
|
||||||
@ -40,7 +41,6 @@ varying vec3 lightVec;
|
|||||||
#ifndef NORMALMAP
|
#ifndef NORMALMAP
|
||||||
varying vec3 vNormal;
|
varying vec3 vNormal;
|
||||||
#endif
|
#endif
|
||||||
//varying vec3 vPosition;
|
|
||||||
varying vec3 vViewDir;
|
varying vec3 vViewDir;
|
||||||
varying vec4 vLightDir;
|
varying vec4 vLightDir;
|
||||||
#else
|
#else
|
||||||
@ -77,57 +77,6 @@ varying vec3 lightVec;
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// JME3 lights in world space
|
|
||||||
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
|
|
||||||
float posLight = step(0.5, color.w);
|
|
||||||
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
|
|
||||||
lightVec = tempVec;
|
|
||||||
#ifdef ATTENUATION
|
|
||||||
float dist = length(tempVec);
|
|
||||||
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
|
|
||||||
lightDir.xyz = tempVec / vec3(dist);
|
|
||||||
#else
|
|
||||||
lightDir = vec4(normalize(tempVec), 1.0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VERTEX_LIGHTING
|
|
||||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
|
|
||||||
return max(0.0, dot(norm, lightdir));
|
|
||||||
}
|
|
||||||
|
|
||||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
|
||||||
if (shiny <= 1.0){
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
#ifndef LOW_QUALITY
|
|
||||||
vec3 H = (viewdir + lightdir) * vec3(0.5);
|
|
||||||
return pow(max(dot(H, norm), 0.0), shiny);
|
|
||||||
#else
|
|
||||||
return 0.0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec4 wvLightPos){
|
|
||||||
vec4 lightDir;
|
|
||||||
lightComputeDir(wvPos, g_LightColor, wvLightPos, lightDir);
|
|
||||||
float spotFallOff = 1.0;
|
|
||||||
if(g_LightDirection.w != 0.0){
|
|
||||||
vec3 L=normalize(lightVec.xyz);
|
|
||||||
vec3 spotdir = normalize(g_LightDirection.xyz);
|
|
||||||
float curAngleCos = dot(-L, spotdir);
|
|
||||||
float innerAngleCos = floor(g_LightDirection.w) * 0.001;
|
|
||||||
float outerAngleCos = fract(g_LightDirection.w);
|
|
||||||
float innerMinusOuter = innerAngleCos - outerAngleCos;
|
|
||||||
spotFallOff = clamp((curAngleCos - outerAngleCos) / innerMinusOuter, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
float diffuseFactor = lightComputeDiffuse(wvNorm, lightDir.xyz);
|
|
||||||
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, lightDir.xyz, m_Shininess);
|
|
||||||
//specularFactor *= step(0.01, diffuseFactor);
|
|
||||||
return vec2(diffuseFactor, specularFactor) * vec2(lightDir.w)*spotFallOff;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec4 modelSpacePos = vec4(inPosition, 1.0);
|
vec4 modelSpacePos = vec4(inPosition, 1.0);
|
||||||
vec3 modelSpaceNorm = inNormal;
|
vec3 modelSpaceNorm = inNormal;
|
||||||
@ -154,11 +103,6 @@ void main(){
|
|||||||
vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm));//normalize(g_NormalMatrix * modelSpaceNorm);
|
vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm));//normalize(g_NormalMatrix * modelSpaceNorm);
|
||||||
vec3 viewDir = normalize(-wvPosition);
|
vec3 viewDir = normalize(-wvPosition);
|
||||||
|
|
||||||
//vec4 lightColor = g_LightColor[gl_InstanceID];
|
|
||||||
//vec4 lightPos = g_LightPosition[gl_InstanceID];
|
|
||||||
//vec4 wvLightPos = (g_ViewMatrix * vec4(lightPos.xyz, lightColor.w));
|
|
||||||
//wvLightPos.w = lightPos.w;
|
|
||||||
|
|
||||||
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz,clamp(g_LightColor.w,0.0,1.0)));
|
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition.xyz,clamp(g_LightColor.w,0.0,1.0)));
|
||||||
wvLightPos.w = g_LightPosition.w;
|
wvLightPos.w = g_LightPosition.w;
|
||||||
vec4 lightColor = g_LightColor;
|
vec4 lightColor = g_LightColor;
|
||||||
@ -166,41 +110,24 @@ void main(){
|
|||||||
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
vec3 wvTangent = normalize(TransformNormal(modelSpaceTan));
|
vec3 wvTangent = normalize(TransformNormal(modelSpaceTan));
|
||||||
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
||||||
|
|
||||||
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
|
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
|
||||||
|
|
||||||
//vPosition = wvPosition * tbnMat;
|
|
||||||
//vViewDir = viewDir * tbnMat;
|
|
||||||
vViewDir = -wvPosition * tbnMat;
|
vViewDir = -wvPosition * tbnMat;
|
||||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||||
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
||||||
#elif !defined(VERTEX_LIGHTING)
|
#elif !defined(VERTEX_LIGHTING)
|
||||||
vNormal = wvNormal;
|
vNormal = wvNormal;
|
||||||
|
|
||||||
//vPosition = wvPosition;
|
|
||||||
vViewDir = viewDir;
|
vViewDir = viewDir;
|
||||||
|
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
|
||||||
|
|
||||||
#ifdef V_TANGENT
|
|
||||||
vNormal = normalize(TransformNormal(inTangent.xyz));
|
|
||||||
vNormal = -cross(cross(vLightDir.xyz, vNormal), vNormal);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//computing spot direction in view space and unpacking spotlight cos
|
|
||||||
// spotVec = (g_ViewMatrix * vec4(g_LightDirection.xyz, 0.0) );
|
|
||||||
// spotVec.w = floor(g_LightDirection.w) * 0.001;
|
|
||||||
// lightVec.w = fract(g_LightDirection.w);
|
|
||||||
|
|
||||||
lightColor.w = 1.0;
|
|
||||||
#ifdef MATERIAL_COLORS
|
#ifdef MATERIAL_COLORS
|
||||||
AmbientSum = (m_Ambient * g_AmbientLightColor).rgb;
|
AmbientSum = (m_Ambient * g_AmbientLightColor).rgb;
|
||||||
DiffuseSum = m_Diffuse * lightColor;
|
DiffuseSum = m_Diffuse * vec4(lightColor.rgb, 1.0);
|
||||||
SpecularSum = (m_Specular * lightColor).rgb;
|
SpecularSum = (m_Specular * lightColor).rgb;
|
||||||
#else
|
#else
|
||||||
AmbientSum = vec3(0.2, 0.2, 0.2) * g_AmbientLightColor.rgb; // Default: ambient color is dark gray
|
AmbientSum = g_AmbientLightColor.rgb; // Default: ambient color is dark gray
|
||||||
DiffuseSum = lightColor;
|
DiffuseSum = vec4(lightColor.rgb, 1.0);
|
||||||
SpecularSum = vec3(0.0);
|
SpecularSum = vec3(0.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -210,7 +137,19 @@ void main(){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VERTEX_LIGHTING
|
#ifdef VERTEX_LIGHTING
|
||||||
vertexLightValues = computeLighting(wvPosition, wvNormal, viewDir, wvLightPos);
|
float spotFallOff = 1.0;
|
||||||
|
vec4 vLightDir;
|
||||||
|
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
// allow use of control flow
|
||||||
|
if(lightColor.w > 1.0){
|
||||||
|
#endif
|
||||||
|
spotFallOff = computeSpotFalloff(g_LightDirection, lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vertexLightValues = computeLighting(wvNormal, viewDir, vLightDir.xyz, vLightDir.w * spotFallOff, m_Shininess);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_REFLECTION
|
#ifdef USE_REFLECTION
|
||||||
|
@ -0,0 +1,218 @@
|
|||||||
|
#import "Common/ShaderLib/Parallax.glsllib"
|
||||||
|
#import "Common/ShaderLib/Optics.glsllib"
|
||||||
|
#ifndef VERTEX_LIGHTING
|
||||||
|
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec2 texCoord;
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
varying vec2 texCoord2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec3 AmbientSum;
|
||||||
|
varying vec4 DiffuseSum;
|
||||||
|
varying vec3 SpecularSum;
|
||||||
|
|
||||||
|
#ifndef VERTEX_LIGHTING
|
||||||
|
uniform mat4 g_ViewMatrix;
|
||||||
|
uniform vec4 g_LightData[NB_LIGHTS];
|
||||||
|
varying vec3 vPos;
|
||||||
|
#else
|
||||||
|
varying vec3 specularAccum;
|
||||||
|
varying vec4 diffuseAccum;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP
|
||||||
|
uniform sampler2D m_DiffuseMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPECULARMAP
|
||||||
|
uniform sampler2D m_SpecularMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PARALLAXMAP
|
||||||
|
uniform sampler2D m_ParallaxMap;
|
||||||
|
#endif
|
||||||
|
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
|
||||||
|
uniform float m_ParallaxHeight;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIGHTMAP
|
||||||
|
uniform sampler2D m_LightMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
uniform sampler2D m_NormalMap;
|
||||||
|
varying vec3 vTangent;
|
||||||
|
varying vec3 vBinormal;
|
||||||
|
#endif
|
||||||
|
varying vec3 vNormal;
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP
|
||||||
|
uniform sampler2D m_AlphaMap;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLORRAMP
|
||||||
|
uniform sampler2D m_ColorRamp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform float m_AlphaDiscardThreshold;
|
||||||
|
|
||||||
|
#ifndef VERTEX_LIGHTING
|
||||||
|
uniform float m_Shininess;
|
||||||
|
|
||||||
|
#ifdef USE_REFLECTION
|
||||||
|
uniform float m_ReflectionPower;
|
||||||
|
uniform float m_ReflectionIntensity;
|
||||||
|
varying vec4 refVec;
|
||||||
|
|
||||||
|
uniform ENVMAP m_EnvMap;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec2 newTexCoord;
|
||||||
|
|
||||||
|
#if (defined(PARALLAXMAP) || (defined(NORMALMAP_PARALLAX) && defined(NORMALMAP))) && !defined(VERTEX_LIGHTING)
|
||||||
|
|
||||||
|
#ifdef STEEP_PARALLAX
|
||||||
|
#ifdef NORMALMAP_PARALLAX
|
||||||
|
//parallax map is stored in the alpha channel of the normal map
|
||||||
|
newTexCoord = steepParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#else
|
||||||
|
//parallax map is a texture
|
||||||
|
newTexCoord = steepParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef NORMALMAP_PARALLAX
|
||||||
|
//parallax map is stored in the alpha channel of the normal map
|
||||||
|
newTexCoord = classicParallaxOffset(m_NormalMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#else
|
||||||
|
//parallax map is a texture
|
||||||
|
newTexCoord = classicParallaxOffset(m_ParallaxMap, vViewDir, texCoord, m_ParallaxHeight);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
newTexCoord = texCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP
|
||||||
|
vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord);
|
||||||
|
#else
|
||||||
|
vec4 diffuseColor = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float alpha = DiffuseSum.a * diffuseColor.a;
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP
|
||||||
|
alpha = alpha * texture2D(m_AlphaMap, newTexCoord).r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DISCARD_ALPHA
|
||||||
|
if(alpha < m_AlphaDiscardThreshold){
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ***********************
|
||||||
|
// Read from textures
|
||||||
|
// ***********************
|
||||||
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
|
vec4 normalHeight = texture2D(m_NormalMap, newTexCoord);
|
||||||
|
//Note the -2.0 and -1.0. We invert the green channel of the normal map,
|
||||||
|
//as it's complient with normal maps generated with blender.
|
||||||
|
//see http://hub.jmonkeyengine.org/forum/topic/parallax-mapping-fundamental-bug/#post-256898
|
||||||
|
//for more explanation.
|
||||||
|
vec3 normal = normalize((normalHeight.xyz * vec3(2.0,-2.0,2.0) - vec3(1.0,-1.0,1.0)));
|
||||||
|
#elif !defined(VERTEX_LIGHTING)
|
||||||
|
vec3 normal = normalize(vNormal);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SPECULARMAP
|
||||||
|
vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
|
||||||
|
#else
|
||||||
|
vec4 specularColor = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIGHTMAP
|
||||||
|
vec3 lightMapColor;
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
lightMapColor = texture2D(m_LightMap, texCoord2).rgb;
|
||||||
|
#else
|
||||||
|
lightMapColor = texture2D(m_LightMap, texCoord).rgb;
|
||||||
|
#endif
|
||||||
|
specularColor.rgb *= lightMapColor;
|
||||||
|
diffuseColor.rgb *= lightMapColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VERTEX_LIGHTING
|
||||||
|
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb
|
||||||
|
+diffuseAccum.rgb *diffuseColor.rgb
|
||||||
|
+specularAccum.rgb * specularColor.rgb;
|
||||||
|
gl_FragColor.a=1.0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
gl_FragColor.rgb = AmbientSum * diffuseColor.rgb;
|
||||||
|
|
||||||
|
#ifdef USE_REFLECTION
|
||||||
|
vec4 refColor = Optics_GetEnvColor(m_EnvMap, refVec.xyz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
mat3 tbnMat = mat3(normalize(vTangent.xyz) , normalize(vBinormal.xyz) , normalize(vNormal.xyz));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for( int i = 0;i < NB_LIGHTS; i+=3){
|
||||||
|
vec4 lightColor = g_LightData[i];
|
||||||
|
vec4 lightData1 = g_LightData[i+1];
|
||||||
|
vec4 lightDir;
|
||||||
|
vec3 lightVec;
|
||||||
|
lightComputeDir(vPos, lightColor.w, lightData1, lightDir,lightVec);
|
||||||
|
|
||||||
|
float spotFallOff = 1.0;
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
// allow use of control flow
|
||||||
|
if(lightColor.w > 1.0){
|
||||||
|
#endif
|
||||||
|
spotFallOff = computeSpotFalloff(g_LightData[i+2], lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
//Normal map -> lighting is computed in tangent space
|
||||||
|
lightDir.xyz = normalize(lightDir.xyz * tbnMat);
|
||||||
|
vec3 viewDir = normalize(-vPos.xyz * tbnMat);
|
||||||
|
#else
|
||||||
|
//no Normal map -> lighting is computed in view space
|
||||||
|
lightDir.xyz = normalize(lightDir.xyz);
|
||||||
|
vec3 viewDir = normalize(-vPos.xyz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff , m_Shininess);
|
||||||
|
|
||||||
|
#ifdef COLORRAMP
|
||||||
|
diffuseColor.rgb *= texture2D(m_ColorRamp, vec2(light.x, 0.0)).rgb;
|
||||||
|
specularColor.rgb *= texture2D(m_ColorRamp, vec2(light.y, 0.0)).rgb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Workaround, since it is not possible to modify varying variables
|
||||||
|
vec4 SpecularSum2 = vec4(SpecularSum, 1.0);
|
||||||
|
#ifdef USE_REFLECTION
|
||||||
|
// Interpolate light specularity toward reflection color
|
||||||
|
// Multiply result by specular map
|
||||||
|
specularColor = mix(SpecularSum2 * light.y, refColor, refVec.w) * specularColor;
|
||||||
|
|
||||||
|
SpecularSum2 = vec4(1.0);
|
||||||
|
light.y = 1.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_FragColor.rgb += DiffuseSum.rgb * lightColor.rgb * diffuseColor.rgb * vec3(light.x) +
|
||||||
|
SpecularSum2.rgb * specularColor.rgb * vec3(light.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
gl_FragColor.a = alpha;
|
||||||
|
}
|
@ -0,0 +1,172 @@
|
|||||||
|
#import "Common/ShaderLib/Instancing.glsllib"
|
||||||
|
#import "Common/ShaderLib/Skinning.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
#ifdef VERTEX_LIGHTING
|
||||||
|
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
uniform vec4 m_Ambient;
|
||||||
|
uniform vec4 m_Diffuse;
|
||||||
|
uniform vec4 m_Specular;
|
||||||
|
uniform float m_Shininess;
|
||||||
|
|
||||||
|
#if defined(VERTEX_LIGHTING)
|
||||||
|
uniform vec4 g_LightData[NB_LIGHTS];
|
||||||
|
#endif
|
||||||
|
uniform vec4 g_AmbientLightColor;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
varying vec2 texCoord2;
|
||||||
|
attribute vec2 inTexCoord2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
varying vec3 AmbientSum;
|
||||||
|
varying vec4 DiffuseSum;
|
||||||
|
varying vec3 SpecularSum;
|
||||||
|
|
||||||
|
attribute vec3 inPosition;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
attribute vec3 inNormal;
|
||||||
|
|
||||||
|
#ifdef VERTEX_COLOR
|
||||||
|
attribute vec4 inColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef VERTEX_LIGHTING
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vPos;
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
attribute vec4 inTangent;
|
||||||
|
varying vec3 vTangent;
|
||||||
|
varying vec3 vBinormal;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
varying vec3 specularAccum;
|
||||||
|
varying vec4 diffuseAccum;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_REFLECTION
|
||||||
|
uniform vec3 g_CameraPosition;
|
||||||
|
uniform vec3 m_FresnelParams;
|
||||||
|
varying vec4 refVec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input:
|
||||||
|
* attribute inPosition
|
||||||
|
* attribute inNormal
|
||||||
|
* uniform g_WorldMatrix
|
||||||
|
* uniform g_CameraPosition
|
||||||
|
*
|
||||||
|
* Output:
|
||||||
|
* varying refVec
|
||||||
|
*/
|
||||||
|
void computeRef(in vec4 modelSpacePos){
|
||||||
|
// vec3 worldPos = (g_WorldMatrix * modelSpacePos).xyz;
|
||||||
|
vec3 worldPos = TransformWorld(modelSpacePos).xyz;
|
||||||
|
|
||||||
|
vec3 I = normalize( g_CameraPosition - worldPos ).xyz;
|
||||||
|
// vec3 N = normalize( (g_WorldMatrix * vec4(inNormal, 0.0)).xyz );
|
||||||
|
vec3 N = normalize( TransformWorld(vec4(inNormal, 0.0)).xyz );
|
||||||
|
|
||||||
|
refVec.xyz = reflect(I, N);
|
||||||
|
refVec.w = m_FresnelParams.x + m_FresnelParams.y * pow(1.0 + dot(I, N), m_FresnelParams.z);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 modelSpacePos = vec4(inPosition, 1.0);
|
||||||
|
vec3 modelSpaceNorm = inNormal;
|
||||||
|
|
||||||
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
|
vec3 modelSpaceTan = inTangent.xyz;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NUM_BONES
|
||||||
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
|
Skinning_Compute(modelSpacePos, modelSpaceNorm, modelSpaceTan);
|
||||||
|
#else
|
||||||
|
Skinning_Compute(modelSpacePos, modelSpaceNorm);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gl_Position = TransformWorldViewProjection(modelSpacePos);
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
#ifdef SEPARATE_TEXCOORD
|
||||||
|
texCoord2 = inTexCoord2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 wvPosition = TransformWorldView(modelSpacePos).xyz;
|
||||||
|
vec3 wvNormal = normalize(TransformNormal(modelSpaceNorm));
|
||||||
|
vec3 viewDir = normalize(-wvPosition);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(NORMALMAP) && !defined(VERTEX_LIGHTING)
|
||||||
|
vTangent = TransformNormal(modelSpaceTan);
|
||||||
|
vBinormal = cross(wvNormal, vTangent)* inTangent.w;
|
||||||
|
vNormal = wvNormal;
|
||||||
|
vPos = wvPosition;
|
||||||
|
#elif !defined(VERTEX_LIGHTING)
|
||||||
|
vNormal = wvNormal;
|
||||||
|
vPos = wvPosition;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MATERIAL_COLORS
|
||||||
|
AmbientSum = m_Ambient.rgb * g_AmbientLightColor.rgb;
|
||||||
|
SpecularSum = m_Specular.rgb;
|
||||||
|
DiffuseSum = m_Diffuse;
|
||||||
|
#else
|
||||||
|
AmbientSum = g_AmbientLightColor.rgb;
|
||||||
|
SpecularSum = vec3(0.0);
|
||||||
|
DiffuseSum = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
#ifdef VERTEX_COLOR
|
||||||
|
AmbientSum *= inColor.rgb;
|
||||||
|
DiffuseSum *= inColor;
|
||||||
|
#endif
|
||||||
|
#ifdef VERTEX_LIGHTING
|
||||||
|
int i = 0;
|
||||||
|
diffuseAccum = vec4(0.0);
|
||||||
|
specularAccum = vec3(0.0);
|
||||||
|
vec4 diffuseColor;
|
||||||
|
vec3 specularColor;
|
||||||
|
for (int i =0;i < NB_LIGHTS; i+=3){
|
||||||
|
vec4 lightColor = g_LightData[i];
|
||||||
|
vec4 lightData1 = g_LightData[i+1];
|
||||||
|
DiffuseSum = vec4(1.0);
|
||||||
|
#ifdef MATERIAL_COLORS
|
||||||
|
diffuseColor = m_Diffuse * vec4(lightColor.rgb, 1.0);
|
||||||
|
specularColor = m_Specular.rgb * lightColor.rgb;
|
||||||
|
#else
|
||||||
|
diffuseColor = vec4(lightColor.rgb, 1.0);
|
||||||
|
specularColor = vec3(0.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 lightDir;
|
||||||
|
vec3 lightVec;
|
||||||
|
lightComputeDir(wvPosition, lightColor.w, lightData1, lightDir, lightVec);
|
||||||
|
// lightDir = normalize(lightDir);
|
||||||
|
// lightVec = normalize(lightVec);
|
||||||
|
|
||||||
|
float spotFallOff = 1.0;
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
// allow use of control flow
|
||||||
|
if(lightColor.w > 1.0){
|
||||||
|
#endif
|
||||||
|
vec4 lightDirection = g_LightData[i+2];
|
||||||
|
spotFallOff = computeSpotFalloff(lightDirection, lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
vec2 v = computeLighting(wvNormal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess);
|
||||||
|
diffuseAccum +=v.x * diffuseColor;
|
||||||
|
specularAccum += v.y * specularColor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_REFLECTION
|
||||||
|
computeRef(modelSpacePos);
|
||||||
|
#endif
|
||||||
|
}
|
@ -1,48 +1,30 @@
|
|||||||
#ifndef NUM_LIGHTS
|
/*Common function for light calculations*/
|
||||||
#define NUM_LIGHTS 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform mat4 g_ViewMatrix;
|
|
||||||
uniform vec4 g_LightPosition[NUM_LIGHTS];
|
|
||||||
uniform vec4 g_g_LightColor[NUM_LIGHTS];
|
|
||||||
uniform float m_Shininess;
|
|
||||||
|
|
||||||
float Lighting_Diffuse(vec3 norm, vec3 lightdir){
|
/*
|
||||||
return max(0.0, dot(norm, lightdir));
|
* Computes light direction
|
||||||
}
|
* lightType should be 0.0,1.0,2.0, repectively for Directional, point and spot lights.
|
||||||
|
* Outputs the light direction and the light half vector.
|
||||||
float Lighting_Specular(vec3 norm, vec3 viewdir, vec3 lightdir, float shiny){
|
*/
|
||||||
vec3 refdir = reflect(-lightdir, norm);
|
void lightComputeDir(in vec3 worldPos, in float ligthType, in vec4 position, out vec4 lightDir, out vec3 lightVec){
|
||||||
return pow(max(dot(refdir, viewdir), 0.0), shiny);
|
float posLight = step(0.5, ligthType);
|
||||||
}
|
|
||||||
|
|
||||||
void Lighting_Direction(vec3 worldPos, vec4 color, vec4 position, out vec4 lightDir){
|
|
||||||
float posLight = step(0.5, color.w);
|
|
||||||
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
|
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
|
||||||
|
lightVec = tempVec;
|
||||||
float dist = length(tempVec);
|
float dist = length(tempVec);
|
||||||
|
|
||||||
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
|
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
|
||||||
lightDir.xyz = tempVec / dist;
|
lightDir.xyz = tempVec / vec3(dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lighting_ComputePS(vec3 tanNormal, mat3 tbnMat,
|
/*
|
||||||
int lightCount, out vec3 outDiffuse, out vec3 outSpecular){
|
* Computes the spot falloff for a spotlight
|
||||||
// find tangent view dir & vert pos
|
*/
|
||||||
vec3 tanViewDir = viewDir * tbnMat;
|
float computeSpotFalloff(in vec4 lightDirection, in vec3 lightVector){
|
||||||
|
vec3 L=normalize(lightVector);
|
||||||
for (int i = 0; i < lightCount; i++){
|
vec3 spotdir = normalize(lightDirection.xyz);
|
||||||
// find light dir in tangent space, works for point & directional lights
|
float curAngleCos = dot(-L, spotdir);
|
||||||
vec4 wvLightPos = (g_ViewMatrix * vec4(g_LightPosition[i].xyz, g_LightColor[i].w));
|
float innerAngleCos = floor(lightDirection.w) * 0.001;
|
||||||
wvLightPos.w = g_LightPosition[i].w;
|
float outerAngleCos = fract(lightDirection.w);
|
||||||
|
float innerMinusOuter = innerAngleCos - outerAngleCos;
|
||||||
vec4 tanLightDir;
|
return clamp((curAngleCos - outerAngleCos) / innerMinusOuter, step(lightDirection.w, 0.001), 1.0);
|
||||||
Lighting_Direction(wvPosition, g_LightColor[i], wvLightPos, tanLightDir);
|
|
||||||
tanLightDir.xyz = tanLightDir.xyz * tbnMat;
|
|
||||||
|
|
||||||
vec3 lightScale = g_LightColor[i].rgb * tanLightDir.w;
|
|
||||||
float specular = Lighting_Specular(tanNormal, tanViewDir, tanLightDir.xyz, m_Shininess);
|
|
||||||
float diffuse = Lighting_Diffuse(tanNormal, tanLightDir.xyz);
|
|
||||||
outSpecular += specular * lightScale * step(0.01, diffuse) * g_LightColor[i].rgb;
|
|
||||||
outDiffuse += diffuse * lightScale * g_LightColor[i].rgb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
/*Standard Phong ligting*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes diffuse factor
|
||||||
|
*/
|
||||||
|
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir){
|
||||||
|
return max(0.0, dot(norm, lightdir));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes specular factor
|
||||||
|
*/
|
||||||
|
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
||||||
|
vec3 R = reflect(-lightdir, norm);
|
||||||
|
return pow(max(dot(R, viewdir), 0.0), shiny);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes diffuse and specular factors and pack them in a vec2 (x=diffuse, y=specular)
|
||||||
|
*/
|
||||||
|
vec2 computeLighting(in vec3 norm, in vec3 viewDir, in vec3 lightDir, in float attenuation, in float shininess){
|
||||||
|
float diffuseFactor = lightComputeDiffuse(norm, lightDir);
|
||||||
|
float specularFactor = lightComputeSpecular(norm, viewDir, lightDir, shininess);
|
||||||
|
if (shininess <= 1.0) {
|
||||||
|
specularFactor = 0.0; // should be one instruction on most cards ..
|
||||||
|
}
|
||||||
|
specularFactor *= diffuseFactor;
|
||||||
|
return vec2(diffuseFactor, specularFactor) * vec2(attenuation);
|
||||||
|
}
|
@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package jme3test.light;
|
||||||
|
|
||||||
|
import com.jme3.app.BasicProfilerState;
|
||||||
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.font.BitmapText;
|
||||||
|
import com.jme3.input.KeyInput;
|
||||||
|
import com.jme3.input.controls.ActionListener;
|
||||||
|
import com.jme3.input.controls.KeyTrigger;
|
||||||
|
import com.jme3.light.AmbientLight;
|
||||||
|
import com.jme3.light.DirectionalLight;
|
||||||
|
import com.jme3.light.Light;
|
||||||
|
import com.jme3.light.LightList;
|
||||||
|
import com.jme3.light.PointLight;
|
||||||
|
import com.jme3.light.SpotLight;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.material.TechniqueDef;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
|
import com.jme3.math.Quaternion;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.LightNode;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
import com.jme3.scene.shape.Box;
|
||||||
|
|
||||||
|
public class TestManyLightsSingle extends SimpleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TestManyLightsSingle app = new TestManyLightsSingle();
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
TechniqueDef.LightMode lm = TechniqueDef.LightMode.MultiPass;
|
||||||
|
int lightNum = 6 ;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleInitApp() {
|
||||||
|
renderManager.setPreferredLightMode(lm);
|
||||||
|
renderManager.setSinglePassLightBatchSize(lightNum);
|
||||||
|
|
||||||
|
|
||||||
|
flyCam.setMoveSpeed(10);
|
||||||
|
|
||||||
|
Node scene = (Node) assetManager.loadModel("Scenes/ManyLights/Main.scene");
|
||||||
|
rootNode.attachChild(scene);
|
||||||
|
Node n = (Node) rootNode.getChild(0);
|
||||||
|
LightList lightList = n.getWorldLightList();
|
||||||
|
Geometry g = (Geometry) n.getChild("Grid-geom-1");
|
||||||
|
|
||||||
|
g.getMaterial().setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
|
||||||
|
|
||||||
|
/* A colored lit cube. Needs light source! */
|
||||||
|
Box boxMesh = new Box(1f, 1f, 1f);
|
||||||
|
Geometry boxGeo = new Geometry("Colored Box", boxMesh);
|
||||||
|
Material boxMat = g.getMaterial().clone();
|
||||||
|
boxMat.setBoolean("UseMaterialColors", true);
|
||||||
|
boxMat.setColor("Ambient", new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
|
||||||
|
boxMat.setColor("Diffuse", ColorRGBA.Blue);
|
||||||
|
boxGeo.setMaterial(boxMat);
|
||||||
|
|
||||||
|
int nb = 0;
|
||||||
|
for (Light light : lightList) {
|
||||||
|
nb++;
|
||||||
|
PointLight p = (PointLight) light;
|
||||||
|
if (nb >60) {
|
||||||
|
n.removeLight(light);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
LightNode ln = new LightNode("l", light);
|
||||||
|
n.attachChild(ln);
|
||||||
|
ln.setLocalTranslation(p.getPosition());
|
||||||
|
int rand = FastMath.nextRandomInt(0, 3);
|
||||||
|
switch (rand) {
|
||||||
|
case 0:
|
||||||
|
light.setColor(ColorRGBA.Red);
|
||||||
|
// ln.addControl(new MoveControl(5f));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
light.setColor(ColorRGBA.Yellow);
|
||||||
|
// ln.addControl(new MoveControl(5f));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
light.setColor(ColorRGBA.Green);
|
||||||
|
//ln.addControl(new MoveControl(-5f));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
light.setColor(ColorRGBA.Orange);
|
||||||
|
//ln.addControl(new MoveControl(-5f));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Geometry b = boxGeo.clone();
|
||||||
|
n.attachChild(b);
|
||||||
|
b.setLocalTranslation(p.getPosition().x, 2, p.getPosition().z);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cam.setLocation(new Vector3f(3.1893547f, 17.977385f, 30.8378f));
|
||||||
|
// cam.setRotation(new Quaternion(0.14317635f, 0.82302624f, -0.23777823f, 0.49557027f));
|
||||||
|
|
||||||
|
cam.setLocation(new Vector3f(-1.8901939f, 29.34097f, 73.07533f));
|
||||||
|
cam.setRotation(new Quaternion(0.0021000702f, 0.971012f, -0.23886925f, 0.008527749f));
|
||||||
|
|
||||||
|
|
||||||
|
BasicProfilerState profiler = new BasicProfilerState(true);
|
||||||
|
profiler.setGraphScale(1000f);
|
||||||
|
|
||||||
|
// getStateManager().attach(profiler);
|
||||||
|
// guiNode.setCullHint(CullHint.Always);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
flyCam.setDragToRotate(true);
|
||||||
|
flyCam.setMoveSpeed(50);
|
||||||
|
|
||||||
|
|
||||||
|
inputManager.addListener(new ActionListener() {
|
||||||
|
public void onAction(String name, boolean isPressed, float tpf) {
|
||||||
|
if (name.equals("toggle") && isPressed) {
|
||||||
|
if (lm == TechniqueDef.LightMode.SinglePass) {
|
||||||
|
lm = TechniqueDef.LightMode.MultiPass;
|
||||||
|
} else {
|
||||||
|
lm = TechniqueDef.LightMode.SinglePass;
|
||||||
|
}
|
||||||
|
renderManager.setPreferredLightMode(lm);
|
||||||
|
}
|
||||||
|
if (name.equals("lightsUp") && isPressed) {
|
||||||
|
lightNum++;
|
||||||
|
renderManager.setSinglePassLightBatchSize(lightNum);
|
||||||
|
helloText.setText("nb lights per batch : " + lightNum);
|
||||||
|
}
|
||||||
|
if (name.equals("lightsDown") && isPressed) {
|
||||||
|
lightNum--;
|
||||||
|
renderManager.setSinglePassLightBatchSize(lightNum);
|
||||||
|
helloText.setText("nb lights per batch : " + lightNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "toggle", "lightsUp", "lightsDown");
|
||||||
|
|
||||||
|
inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
|
||||||
|
inputManager.addMapping("lightsUp", new KeyTrigger(KeyInput.KEY_UP));
|
||||||
|
inputManager.addMapping("lightsDown", new KeyTrigger(KeyInput.KEY_DOWN));
|
||||||
|
|
||||||
|
|
||||||
|
SpotLight spot = new SpotLight();
|
||||||
|
spot.setDirection(new Vector3f(-1f, -1f, -1f).normalizeLocal());
|
||||||
|
spot.setColor(ColorRGBA.Blue.mult(5));
|
||||||
|
spot.setSpotOuterAngle(FastMath.DEG_TO_RAD * 20);
|
||||||
|
spot.setSpotInnerAngle(FastMath.DEG_TO_RAD * 5);
|
||||||
|
spot.setPosition(new Vector3f(10, 10, 20));
|
||||||
|
rootNode.addLight(spot);
|
||||||
|
|
||||||
|
DirectionalLight dl = new DirectionalLight();
|
||||||
|
dl.setDirection(new Vector3f(-1, -1, 1));
|
||||||
|
rootNode.addLight(dl);
|
||||||
|
|
||||||
|
AmbientLight al = new AmbientLight();
|
||||||
|
al.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
|
||||||
|
rootNode.addLight(al);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write text on the screen (HUD)
|
||||||
|
*/
|
||||||
|
guiNode.detachAllChildren();
|
||||||
|
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
|
||||||
|
helloText = new BitmapText(guiFont, false);
|
||||||
|
helloText.setSize(guiFont.getCharSet().getRenderedSize());
|
||||||
|
helloText.setText("nb lights per batch : " + lightNum);
|
||||||
|
helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
|
||||||
|
guiNode.attachChild(helloText);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
BitmapText helloText;
|
||||||
|
long time;
|
||||||
|
long nbFrames;
|
||||||
|
long startTime = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleUpdate(float tpf) {
|
||||||
|
// if (nbFrames == 4000) {
|
||||||
|
// startTime = System.nanoTime();
|
||||||
|
// }
|
||||||
|
// if (nbFrames > 4000) {
|
||||||
|
// time = System.nanoTime();
|
||||||
|
// float average = ((float) time - (float) startTime) / ((float) nbFrames - 4000f);
|
||||||
|
// helloText.setText("Average = " + average);
|
||||||
|
// }
|
||||||
|
// nbFrames++;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveControl extends AbstractControl {
|
||||||
|
|
||||||
|
float direction;
|
||||||
|
Vector3f origPos = new Vector3f();
|
||||||
|
|
||||||
|
public MoveControl(float direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSpatial(Spatial spatial) {
|
||||||
|
super.setSpatial(spatial); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
origPos.set(spatial.getLocalTranslation());
|
||||||
|
}
|
||||||
|
float time = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
time += tpf;
|
||||||
|
spatial.setLocalTranslation(origPos.x + FastMath.cos(time) * direction, origPos.y, origPos.z + FastMath.sin(time) * direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -802,7 +802,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
TextureUtil.uploadTexture(img, target, i, 0, tdc);
|
TextureUtil.uploadTexture(img, target, i, 0, tdc);
|
||||||
}
|
}
|
||||||
} else {*/
|
} else {*/
|
||||||
TextureUtil.uploadTexture(ctxCaps, img, target, 0, 0, false);
|
TextureUtil.uploadTexture(caps, img, target, 0, 0, false);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
img.clearUpdateNeeded();
|
img.clearUpdateNeeded();
|
||||||
@ -853,7 +853,7 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
|
|
||||||
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
setTexture(0, tex);
|
setTexture(0, tex);
|
||||||
TextureUtil.uploadSubTexture(ctxCaps, pixels, convertTextureType(tex.getType()), 0, x, y, false);
|
TextureUtil.uploadSubTexture(caps, pixels, convertTextureType(tex.getType()), 0, x, y, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearTextureUnits() {
|
private void clearTextureUnits() {
|
||||||
|
@ -57,7 +57,9 @@ import com.jme3.util.BufferUtils;
|
|||||||
import com.jme3.util.ListMap;
|
import com.jme3.util.ListMap;
|
||||||
import com.jme3.util.NativeObjectManager;
|
import com.jme3.util.NativeObjectManager;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -70,7 +72,6 @@ import static org.lwjgl.opengl.ARBInstancedArrays.*;
|
|||||||
import static org.lwjgl.opengl.ARBMultisample.*;
|
import static org.lwjgl.opengl.ARBMultisample.*;
|
||||||
import static org.lwjgl.opengl.ARBTextureMultisample.*;
|
import static org.lwjgl.opengl.ARBTextureMultisample.*;
|
||||||
import static org.lwjgl.opengl.ARBVertexArrayObject.*;
|
import static org.lwjgl.opengl.ARBVertexArrayObject.*;
|
||||||
import org.lwjgl.opengl.ContextCapabilities;
|
|
||||||
import static org.lwjgl.opengl.EXTFramebufferBlit.*;
|
import static org.lwjgl.opengl.EXTFramebufferBlit.*;
|
||||||
import static org.lwjgl.opengl.EXTFramebufferMultisample.*;
|
import static org.lwjgl.opengl.EXTFramebufferMultisample.*;
|
||||||
import static org.lwjgl.opengl.EXTFramebufferObject.*;
|
import static org.lwjgl.opengl.EXTFramebufferObject.*;
|
||||||
@ -84,7 +85,7 @@ import static org.lwjgl.opengl.GL13.*;
|
|||||||
import static org.lwjgl.opengl.GL14.*;
|
import static org.lwjgl.opengl.GL14.*;
|
||||||
import static org.lwjgl.opengl.GL15.*;
|
import static org.lwjgl.opengl.GL15.*;
|
||||||
import static org.lwjgl.opengl.GL20.*;
|
import static org.lwjgl.opengl.GL20.*;
|
||||||
import org.lwjgl.opengl.GLContext;
|
import org.lwjgl.opengl.GL30;
|
||||||
//import static org.lwjgl.opengl.GL21.*;
|
//import static org.lwjgl.opengl.GL21.*;
|
||||||
//import static org.lwjgl.opengl.GL30.*;
|
//import static org.lwjgl.opengl.GL30.*;
|
||||||
|
|
||||||
@ -101,10 +102,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
private final RenderContext context = new RenderContext();
|
private final RenderContext context = new RenderContext();
|
||||||
private final NativeObjectManager objManager = new NativeObjectManager();
|
private final NativeObjectManager objManager = new NativeObjectManager();
|
||||||
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
private final EnumSet<Caps> caps = EnumSet.noneOf(Caps.class);
|
||||||
// current state
|
|
||||||
private Shader boundShader;
|
|
||||||
private int initialDrawBuf, initialReadBuf;
|
|
||||||
private int glslVer;
|
|
||||||
private int vertexTextureUnits;
|
private int vertexTextureUnits;
|
||||||
private int fragTextureUnits;
|
private int fragTextureUnits;
|
||||||
private int vertexUniforms;
|
private int vertexUniforms;
|
||||||
@ -120,13 +118,12 @@ public class LwjglRenderer implements Renderer {
|
|||||||
private int maxTriCount;
|
private int maxTriCount;
|
||||||
private int maxColorTexSamples;
|
private int maxColorTexSamples;
|
||||||
private int maxDepthTexSamples;
|
private int maxDepthTexSamples;
|
||||||
private FrameBuffer lastFb = null;
|
|
||||||
private FrameBuffer mainFbOverride = null;
|
private FrameBuffer mainFbOverride = null;
|
||||||
private final Statistics statistics = new Statistics();
|
private final Statistics statistics = new Statistics();
|
||||||
private int vpX, vpY, vpW, vpH;
|
private int vpX, vpY, vpW, vpH;
|
||||||
private int clipX, clipY, clipW, clipH;
|
private int clipX, clipY, clipW, clipH;
|
||||||
private boolean linearizeSrgbImages;
|
private boolean linearizeSrgbImages;
|
||||||
private ContextCapabilities ctxCaps;
|
private HashSet<String> extensions;
|
||||||
|
|
||||||
public LwjglRenderer() {
|
public LwjglRenderer() {
|
||||||
}
|
}
|
||||||
@ -153,18 +150,67 @@ public class LwjglRenderer implements Renderer {
|
|||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("fallthrough")
|
private static HashSet<String> loadExtensions(String extensions) {
|
||||||
public void initialize() {
|
HashSet<String> extensionSet = new HashSet<String>(64);
|
||||||
ctxCaps = GLContext.getCapabilities();
|
for (String extension : extensions.split(" ")) {
|
||||||
if (ctxCaps.OpenGL20) {
|
extensionSet.add(extension);
|
||||||
|
}
|
||||||
|
return extensionSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int extractVersion(String prefixStr, String versionStr) {
|
||||||
|
if (versionStr != null) {
|
||||||
|
int spaceIdx = versionStr.indexOf(" ", prefixStr.length());
|
||||||
|
if (spaceIdx >= 1) {
|
||||||
|
versionStr = versionStr.substring(prefixStr.length(), spaceIdx).trim();
|
||||||
|
} else {
|
||||||
|
versionStr = versionStr.substring(prefixStr.length()).trim();
|
||||||
|
}
|
||||||
|
// Some device have ":" at the end of the version.
|
||||||
|
versionStr = versionStr.replaceAll("\\:", "");
|
||||||
|
|
||||||
|
// Pivot on first point.
|
||||||
|
int firstPoint = versionStr.indexOf(".");
|
||||||
|
|
||||||
|
// Remove everything after second point.
|
||||||
|
int secondPoint = versionStr.indexOf(".", firstPoint + 1);
|
||||||
|
|
||||||
|
if (secondPoint != -1) {
|
||||||
|
versionStr = versionStr.substring(0, secondPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
String majorVerStr = versionStr.substring(0, firstPoint);
|
||||||
|
String minorVerStr = versionStr.substring(firstPoint + 1);
|
||||||
|
|
||||||
|
if (minorVerStr.endsWith("0") && minorVerStr.length() > 1) {
|
||||||
|
minorVerStr = minorVerStr.substring(0, minorVerStr.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int majorVer = Integer.parseInt(majorVerStr);
|
||||||
|
int minorVer = Integer.parseInt(minorVerStr);
|
||||||
|
|
||||||
|
return majorVer * 100 + minorVer * 10;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasExtension(String extensionName) {
|
||||||
|
return extensions.contains(extensionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCapabilities() {
|
||||||
|
int oglVer = extractVersion("", glGetString(GL_VERSION));
|
||||||
|
|
||||||
|
if (oglVer >= 200) {
|
||||||
caps.add(Caps.OpenGL20);
|
caps.add(Caps.OpenGL20);
|
||||||
if (ctxCaps.OpenGL21) {
|
if (oglVer >= 210) {
|
||||||
caps.add(Caps.OpenGL21);
|
caps.add(Caps.OpenGL21);
|
||||||
if (ctxCaps.OpenGL30) {
|
if (oglVer >= 300) {
|
||||||
caps.add(Caps.OpenGL30);
|
caps.add(Caps.OpenGL30);
|
||||||
if (ctxCaps.OpenGL31) {
|
if (oglVer >= 310) {
|
||||||
caps.add(Caps.OpenGL31);
|
caps.add(Caps.OpenGL31);
|
||||||
if (ctxCaps.OpenGL32) {
|
if (oglVer >= 320) {
|
||||||
caps.add(Caps.OpenGL32);
|
caps.add(Caps.OpenGL32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,49 +218,15 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//workaround, always assume we support GLSL100
|
int glslVer = extractVersion("", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
//some cards just don't report this correctly
|
|
||||||
caps.add(Caps.GLSL100);
|
|
||||||
|
|
||||||
String versionStr = null;
|
|
||||||
if (ctxCaps.OpenGL20) {
|
|
||||||
versionStr = glGetString(GL_SHADING_LANGUAGE_VERSION);
|
|
||||||
}
|
|
||||||
if (versionStr == null || versionStr.equals("")) {
|
|
||||||
glslVer = -1;
|
|
||||||
throw new UnsupportedOperationException("GLSL and OpenGL2 is "
|
|
||||||
+ "required for the LWJGL "
|
|
||||||
+ "renderer!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix issue in TestRenderToMemory when GL_FRONT is the main
|
|
||||||
// buffer being used.
|
|
||||||
initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
|
|
||||||
initialReadBuf = glGetInteger(GL_READ_BUFFER);
|
|
||||||
|
|
||||||
// XXX: This has to be GL_BACK for canvas on Mac
|
|
||||||
// Since initialDrawBuf is GL_FRONT for pbuffer, gotta
|
|
||||||
// change this value later on ...
|
|
||||||
// initialDrawBuf = GL_BACK;
|
|
||||||
// initialReadBuf = GL_BACK;
|
|
||||||
|
|
||||||
int spaceIdx = versionStr.indexOf(" ");
|
|
||||||
if (spaceIdx >= 1) {
|
|
||||||
versionStr = versionStr.substring(0, spaceIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
float version = Float.parseFloat(versionStr);
|
|
||||||
glslVer = (int) (version * 100);
|
|
||||||
|
|
||||||
switch (glslVer) {
|
switch (glslVer) {
|
||||||
default:
|
default:
|
||||||
if (glslVer < 400) {
|
if (glslVer < 400) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// so that future OpenGL revisions wont break jme3
|
||||||
// so that future OpenGL revisions wont break jme3
|
// fall through intentional
|
||||||
|
|
||||||
// fall through intentional
|
|
||||||
case 400:
|
case 400:
|
||||||
case 330:
|
case 330:
|
||||||
case 150:
|
case 150:
|
||||||
@ -232,10 +244,27 @@ public class LwjglRenderer implements Renderer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!caps.contains(Caps.GLSL100)) {
|
// Workaround, always assume we support GLSL100.
|
||||||
logger.log(Level.WARNING, "Force-adding GLSL100 support, since OpenGL2 is supported.");
|
// Some cards just don't report this correctly.
|
||||||
caps.add(Caps.GLSL100);
|
caps.add(Caps.GLSL100);
|
||||||
}
|
|
||||||
|
extensions = loadExtensions(glGetString(GL_EXTENSIONS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("fallthrough")
|
||||||
|
public void initialize() {
|
||||||
|
loadCapabilities();
|
||||||
|
|
||||||
|
// Fix issue in TestRenderToMemory when GL_FRONT is the main
|
||||||
|
// buffer being used.
|
||||||
|
context.initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
|
||||||
|
context.initialReadBuf = glGetInteger(GL_READ_BUFFER);
|
||||||
|
|
||||||
|
// XXX: This has to be GL_BACK for canvas on Mac
|
||||||
|
// Since initialDrawBuf is GL_FRONT for pbuffer, gotta
|
||||||
|
// change this value later on ...
|
||||||
|
// initialDrawBuf = GL_BACK;
|
||||||
|
// initialReadBuf = GL_BACK;
|
||||||
|
|
||||||
glGetInteger(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16);
|
glGetInteger(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, intBuf16);
|
||||||
vertexTextureUnits = intBuf16.get(0);
|
vertexTextureUnits = intBuf16.get(0);
|
||||||
@ -280,44 +309,41 @@ public class LwjglRenderer implements Renderer {
|
|||||||
maxCubeTexSize = intBuf16.get(0);
|
maxCubeTexSize = intBuf16.get(0);
|
||||||
logger.log(Level.FINER, "Maximum CubeMap Resolution: {0}", maxCubeTexSize);
|
logger.log(Level.FINER, "Maximum CubeMap Resolution: {0}", maxCubeTexSize);
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_color_buffer_float) {
|
// ctxCaps = GLContext.getCapabilities();
|
||||||
|
|
||||||
|
if (hasExtension("GL_ARB_color_buffer_float") &&
|
||||||
|
hasExtension("GL_ARB_half_float_pixel")) {
|
||||||
// XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
|
// XXX: Require both 16 and 32 bit float support for FloatColorBuffer.
|
||||||
if (ctxCaps.GL_ARB_half_float_pixel) {
|
caps.add(Caps.FloatColorBuffer);
|
||||||
caps.add(Caps.FloatColorBuffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_depth_buffer_float) {
|
if (hasExtension("GL_ARB_depth_buffer_float")) {
|
||||||
caps.add(Caps.FloatDepthBuffer);
|
caps.add(Caps.FloatDepthBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.OpenGL30) {
|
if (caps.contains(Caps.OpenGL30)) {
|
||||||
caps.add(Caps.PackedDepthStencilBuffer);
|
caps.add(Caps.PackedDepthStencilBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_draw_instanced && ctxCaps.GL_ARB_instanced_arrays) {
|
if (hasExtension("GL_ARB_draw_instanced") &&
|
||||||
|
hasExtension("GL_ARB_instanced_arrays")) {
|
||||||
caps.add(Caps.MeshInstancing);
|
caps.add(Caps.MeshInstancing);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_fragment_program) {
|
if (hasExtension("GL_ARB_texture_buffer_object")) {
|
||||||
caps.add(Caps.ARBprogram);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_buffer_object) {
|
|
||||||
caps.add(Caps.TextureBuffer);
|
caps.add(Caps.TextureBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_float) {
|
if (hasExtension("GL_ARB_texture_float") &&
|
||||||
if (ctxCaps.GL_ARB_half_float_pixel) {
|
hasExtension("GL_ARB_half_float_pixel")) {
|
||||||
caps.add(Caps.FloatTexture);
|
caps.add(Caps.FloatTexture);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_vertex_array_object) {
|
if (hasExtension("GL_ARB_vertex_array_object") || caps.contains(Caps.OpenGL30)) {
|
||||||
caps.add(Caps.VertexBufferArray);
|
caps.add(Caps.VertexBufferArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_non_power_of_two) {
|
if (hasExtension("GL_ARB_texture_non_power_of_two") || caps.contains(Caps.OpenGL30)) {
|
||||||
caps.add(Caps.NonPowerOfTwoTextures);
|
caps.add(Caps.NonPowerOfTwoTextures);
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.WARNING, "Your graphics card does not "
|
logger.log(Level.WARNING, "Your graphics card does not "
|
||||||
@ -325,30 +351,34 @@ public class LwjglRenderer implements Renderer {
|
|||||||
+ "Some features might not work.");
|
+ "Some features might not work.");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean latc = ctxCaps.GL_EXT_texture_compression_latc;
|
if (hasExtension("GL_EXT_texture_compression_latc")) {
|
||||||
if (latc) {
|
|
||||||
caps.add(Caps.TextureCompressionLATC);
|
caps.add(Caps.TextureCompressionLATC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_packed_float || ctxCaps.OpenGL30) {
|
if (hasExtension("GL_EXT_packed_float") || caps.contains(Caps.OpenGL30)) {
|
||||||
// This format is part of the OGL3 specification
|
// This format is part of the OGL3 specification
|
||||||
caps.add(Caps.PackedFloatColorBuffer);
|
caps.add(Caps.PackedFloatColorBuffer);
|
||||||
if (ctxCaps.GL_ARB_half_float_pixel) {
|
|
||||||
|
if (hasExtension("GL_ARB_half_float_pixel")) {
|
||||||
// because textures are usually uploaded as RGB16F
|
// because textures are usually uploaded as RGB16F
|
||||||
// need half-float pixel
|
// need half-float pixel
|
||||||
caps.add(Caps.PackedFloatTexture);
|
caps.add(Caps.PackedFloatTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_texture_array || ctxCaps.OpenGL30) {
|
if (hasExtension("GL_EXT_texture_array") || caps.contains(Caps.OpenGL30)) {
|
||||||
caps.add(Caps.TextureArray);
|
caps.add(Caps.TextureArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_texture_shared_exponent || ctxCaps.OpenGL30) {
|
if (hasExtension("GL_EXT_texture_shared_exponent") || caps.contains(Caps.OpenGL30)) {
|
||||||
caps.add(Caps.SharedExponentTexture);
|
caps.add(Caps.SharedExponentTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_framebuffer_object) {
|
if (hasExtension("GL_EXT_texture_filter_anisotropic")) {
|
||||||
|
caps.add(Caps.TextureFilterAnisotropic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasExtension("GL_EXT_framebuffer_object")) {
|
||||||
caps.add(Caps.FrameBuffer);
|
caps.add(Caps.FrameBuffer);
|
||||||
|
|
||||||
glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16);
|
glGetInteger(GL_MAX_RENDERBUFFER_SIZE_EXT, intBuf16);
|
||||||
@ -359,7 +389,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
maxFBOAttachs = intBuf16.get(0);
|
maxFBOAttachs = intBuf16.get(0);
|
||||||
logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs);
|
logger.log(Level.FINER, "FBO Max renderbuffers: {0}", maxFBOAttachs);
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_framebuffer_multisample) {
|
if (hasExtension("GL_EXT_framebuffer_multisample")) {
|
||||||
caps.add(Caps.FrameBufferMultisample);
|
caps.add(Caps.FrameBufferMultisample);
|
||||||
|
|
||||||
glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16);
|
glGetInteger(GL_MAX_SAMPLES_EXT, intBuf16);
|
||||||
@ -367,7 +397,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples);
|
logger.log(Level.FINER, "FBO Max Samples: {0}", maxFBOSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_texture_multisample) {
|
if (hasExtension("GL_ARB_texture_multisample")) {
|
||||||
caps.add(Caps.TextureMultisample);
|
caps.add(Caps.TextureMultisample);
|
||||||
|
|
||||||
glGetInteger(GL_MAX_COLOR_TEXTURE_SAMPLES, intBuf16);
|
glGetInteger(GL_MAX_COLOR_TEXTURE_SAMPLES, intBuf16);
|
||||||
@ -387,7 +417,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_ARB_multisample) {
|
if (hasExtension("GL_ARB_multisample")) {
|
||||||
glGetInteger(GL_SAMPLE_BUFFERS_ARB, intBuf16);
|
glGetInteger(GL_SAMPLE_BUFFERS_ARB, intBuf16);
|
||||||
boolean available = intBuf16.get(0) != 0;
|
boolean available = intBuf16.get(0) != 0;
|
||||||
glGetInteger(GL_SAMPLES_ARB, intBuf16);
|
glGetInteger(GL_SAMPLES_ARB, intBuf16);
|
||||||
@ -401,7 +431,8 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Supports sRGB pipeline.
|
// Supports sRGB pipeline.
|
||||||
if ( (ctxCaps.GL_ARB_framebuffer_sRGB && ctxCaps.GL_EXT_texture_sRGB ) || ctxCaps.OpenGL30 ) {
|
if ( (hasExtension("GL_ARB_framebuffer_sRGB") && hasExtension("GL_EXT_texture_sRGB"))
|
||||||
|
|| caps.contains(Caps.OpenGL30) ) {
|
||||||
caps.add(Caps.Srgb);
|
caps.add(Caps.Srgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,11 +441,8 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
public void invalidateState() {
|
public void invalidateState() {
|
||||||
context.reset();
|
context.reset();
|
||||||
boundShader = null;
|
context.initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
|
||||||
lastFb = null;
|
context.initialReadBuf = glGetInteger(GL_READ_BUFFER);
|
||||||
|
|
||||||
initialDrawBuf = glGetInteger(GL_DRAW_BUFFER);
|
|
||||||
initialReadBuf = glGetInteger(GL_READ_BUFFER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetGLObjects() {
|
public void resetGLObjects() {
|
||||||
@ -479,7 +507,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setAlphaToCoverage(boolean value) {
|
public void setAlphaToCoverage(boolean value) {
|
||||||
if (ctxCaps.GL_ARB_multisample) {
|
if (caps.contains(Caps.Multisample)) {
|
||||||
if (value) {
|
if (value) {
|
||||||
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
|
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
|
||||||
} else {
|
} else {
|
||||||
@ -822,7 +850,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
if (context.boundShaderProgram != shaderId) {
|
if (context.boundShaderProgram != shaderId) {
|
||||||
glUseProgram(shaderId);
|
glUseProgram(shaderId);
|
||||||
statistics.onShaderUse(shader, true);
|
statistics.onShaderUse(shader, true);
|
||||||
boundShader = shader;
|
context.boundShader = shader;
|
||||||
context.boundShaderProgram = shaderId;
|
context.boundShaderProgram = shaderId;
|
||||||
} else {
|
} else {
|
||||||
statistics.onShaderUse(shader, false);
|
statistics.onShaderUse(shader, false);
|
||||||
@ -1081,12 +1109,12 @@ public class LwjglRenderer implements Renderer {
|
|||||||
glAttachShader(id, source.getId());
|
glAttachShader(id, source.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.GL_EXT_gpu_shader4) {
|
if (caps.contains(Caps.OpenGL30)) {
|
||||||
// Check if GLSL version is 1.5 for shader
|
// Check if GLSL version is 1.5 for shader
|
||||||
glBindFragDataLocationEXT(id, 0, "outFragColor");
|
GL30.glBindFragDataLocation(id, 0, "outFragColor");
|
||||||
// For MRT
|
// For MRT
|
||||||
for (int i = 0; i < maxMRTFBOAttachs; i++) {
|
for (int i = 0; i < maxMRTFBOAttachs; i++) {
|
||||||
glBindFragDataLocationEXT(id, i, "outFragData[" + i + "]");
|
GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1191,7 +1219,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
public void copyFrameBuffer(FrameBuffer src, FrameBuffer dst, boolean copyDepth) {
|
||||||
if (ctxCaps.GL_EXT_framebuffer_blit) {
|
if (caps.contains(Caps.FrameBufferBlit)) {
|
||||||
int srcX0 = 0;
|
int srcX0 = 0;
|
||||||
int srcY0 = 0;
|
int srcY0 = 0;
|
||||||
int srcX1;
|
int srcX1;
|
||||||
@ -1292,11 +1320,11 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
int attachment = convertAttachmentSlot(rb.getSlot());
|
int attachment = convertAttachmentSlot(rb.getSlot());
|
||||||
|
|
||||||
int type = glGetFramebufferAttachmentParameterEXT(GL_DRAW_FRAMEBUFFER_EXT,
|
int type = glGetFramebufferAttachmentParameteriEXT(GL_DRAW_FRAMEBUFFER_EXT,
|
||||||
attachment,
|
attachment,
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT);
|
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT);
|
||||||
|
|
||||||
int rbName = glGetFramebufferAttachmentParameterEXT(GL_DRAW_FRAMEBUFFER_EXT,
|
int rbName = glGetFramebufferAttachmentParameteriEXT(GL_DRAW_FRAMEBUFFER_EXT,
|
||||||
attachment,
|
attachment,
|
||||||
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT);
|
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT);
|
||||||
|
|
||||||
@ -1397,9 +1425,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
+ ":" + fb.getHeight() + " is not supported.");
|
+ ":" + fb.getHeight() + " is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(ctxCaps, rb.getFormat(), fb.isSrgb());
|
TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(caps, rb.getFormat(), fb.isSrgb());
|
||||||
|
|
||||||
if (fb.getSamples() > 1 && ctxCaps.GL_EXT_framebuffer_multisample) {
|
if (fb.getSamples() > 1 && caps.contains(Caps.FrameBufferMultisample)) {
|
||||||
int samples = fb.getSamples();
|
int samples = fb.getSamples();
|
||||||
if (maxFBOSamples < samples) {
|
if (maxFBOSamples < samples) {
|
||||||
samples = maxFBOSamples;
|
samples = maxFBOSamples;
|
||||||
@ -1503,7 +1531,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
if (fb.getSamples() <= 1) {
|
if (fb.getSamples() <= 1) {
|
||||||
throw new IllegalArgumentException("Framebuffer must be multisampled");
|
throw new IllegalArgumentException("Framebuffer must be multisampled");
|
||||||
}
|
}
|
||||||
if (!ctxCaps.GL_ARB_texture_multisample) {
|
if (!caps.contains(Caps.TextureMultisample)) {
|
||||||
throw new RendererException("Multisampled textures are not supported");
|
throw new RendererException("Multisampled textures are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1525,7 +1553,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFrameBuffer(FrameBuffer fb) {
|
public void setFrameBuffer(FrameBuffer fb) {
|
||||||
if (!ctxCaps.GL_EXT_framebuffer_object) {
|
if (!caps.contains(Caps.FrameBuffer)) {
|
||||||
throw new RendererException("Framebuffer objects are not supported" +
|
throw new RendererException("Framebuffer objects are not supported" +
|
||||||
" by the video hardware");
|
" by the video hardware");
|
||||||
}
|
}
|
||||||
@ -1534,16 +1562,16 @@ public class LwjglRenderer implements Renderer {
|
|||||||
fb = mainFbOverride;
|
fb = mainFbOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastFb == fb) {
|
if (context.boundFB == fb) {
|
||||||
if (fb == null || !fb.isUpdateNeeded()) {
|
if (fb == null || !fb.isUpdateNeeded()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate mipmaps for last FB if needed
|
// generate mipmaps for last FB if needed
|
||||||
if (lastFb != null) {
|
if (context.boundFB != null) {
|
||||||
for (int i = 0; i < lastFb.getNumColorBuffers(); i++) {
|
for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) {
|
||||||
RenderBuffer rb = lastFb.getColorBuffer(i);
|
RenderBuffer rb = context.boundFB.getColorBuffer(i);
|
||||||
Texture tex = rb.getTexture();
|
Texture tex = rb.getTexture();
|
||||||
if (tex != null
|
if (tex != null
|
||||||
&& tex.getMinFilter().usesMipMapLevels()) {
|
&& tex.getMinFilter().usesMipMapLevels()) {
|
||||||
@ -1567,15 +1595,15 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
// select back buffer
|
// select back buffer
|
||||||
if (context.boundDrawBuf != -1) {
|
if (context.boundDrawBuf != -1) {
|
||||||
glDrawBuffer(initialDrawBuf);
|
glDrawBuffer(context.initialDrawBuf);
|
||||||
context.boundDrawBuf = -1;
|
context.boundDrawBuf = -1;
|
||||||
}
|
}
|
||||||
if (context.boundReadBuf != -1) {
|
if (context.boundReadBuf != -1) {
|
||||||
glReadBuffer(initialReadBuf);
|
glReadBuffer(context.initialReadBuf);
|
||||||
context.boundReadBuf = -1;
|
context.boundReadBuf = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastFb = null;
|
context.boundFB = null;
|
||||||
} else {
|
} else {
|
||||||
if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) {
|
if (fb.getNumColorBuffers() == 0 && fb.getDepthBuffer() == null) {
|
||||||
throw new IllegalArgumentException("The framebuffer: " + fb
|
throw new IllegalArgumentException("The framebuffer: " + fb
|
||||||
@ -1644,7 +1672,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
assert fb.getId() >= 0;
|
assert fb.getId() >= 0;
|
||||||
assert context.boundFBO == fb.getId();
|
assert context.boundFBO == fb.getId();
|
||||||
|
|
||||||
lastFb = fb;
|
context.boundFB = fb;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
checkFrameBufferError();
|
checkFrameBufferError();
|
||||||
@ -1707,7 +1735,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|* Textures *|
|
|* Textures *|
|
||||||
\*********************************************************************/
|
\*********************************************************************/
|
||||||
private int convertTextureType(Texture.Type type, int samples, int face) {
|
private int convertTextureType(Texture.Type type, int samples, int face) {
|
||||||
if (samples > 1 && !ctxCaps.GL_ARB_texture_multisample) {
|
if (samples > 1 && !caps.contains(Caps.TextureMultisample)) {
|
||||||
throw new RendererException("Multisample textures are not supported" +
|
throw new RendererException("Multisample textures are not supported" +
|
||||||
" by the video hardware.");
|
" by the video hardware.");
|
||||||
}
|
}
|
||||||
@ -1751,22 +1779,37 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int convertMinFilter(Texture.MinFilter filter) {
|
private int convertMinFilter(Texture.MinFilter filter, boolean haveMips) {
|
||||||
switch (filter) {
|
if (haveMips){
|
||||||
case Trilinear:
|
switch (filter) {
|
||||||
return GL_LINEAR_MIPMAP_LINEAR;
|
case Trilinear:
|
||||||
case BilinearNearestMipMap:
|
return GL_LINEAR_MIPMAP_LINEAR;
|
||||||
return GL_LINEAR_MIPMAP_NEAREST;
|
case BilinearNearestMipMap:
|
||||||
case NearestLinearMipMap:
|
return GL_LINEAR_MIPMAP_NEAREST;
|
||||||
return GL_NEAREST_MIPMAP_LINEAR;
|
case NearestLinearMipMap:
|
||||||
case NearestNearestMipMap:
|
return GL_NEAREST_MIPMAP_LINEAR;
|
||||||
return GL_NEAREST_MIPMAP_NEAREST;
|
case NearestNearestMipMap:
|
||||||
case BilinearNoMipMaps:
|
return GL_NEAREST_MIPMAP_NEAREST;
|
||||||
return GL_LINEAR;
|
case BilinearNoMipMaps:
|
||||||
case NearestNoMipMaps:
|
return GL_LINEAR;
|
||||||
return GL_NEAREST;
|
case NearestNoMipMaps:
|
||||||
default:
|
return GL_NEAREST;
|
||||||
throw new UnsupportedOperationException("Unknown min filter: " + filter);
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown min filter: " + filter);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (filter) {
|
||||||
|
case Trilinear:
|
||||||
|
case BilinearNearestMipMap:
|
||||||
|
case BilinearNoMipMaps:
|
||||||
|
return GL_LINEAR;
|
||||||
|
case NearestLinearMipMap:
|
||||||
|
case NearestNearestMipMap:
|
||||||
|
case NearestNoMipMaps:
|
||||||
|
return GL_NEAREST;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown min filter: " + filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1792,14 +1835,20 @@ public class LwjglRenderer implements Renderer {
|
|||||||
Image image = tex.getImage();
|
Image image = tex.getImage();
|
||||||
int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1, -1);
|
int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1, -1);
|
||||||
|
|
||||||
|
boolean haveMips = true;
|
||||||
|
|
||||||
|
if (image != null) {
|
||||||
|
haveMips = image.isGeneratedMipmapsRequired() || image.hasMipmaps();
|
||||||
|
}
|
||||||
|
|
||||||
// filter things
|
// filter things
|
||||||
int minFilter = convertMinFilter(tex.getMinFilter());
|
int minFilter = convertMinFilter(tex.getMinFilter(), haveMips);
|
||||||
int magFilter = convertMagFilter(tex.getMagFilter());
|
int magFilter = convertMagFilter(tex.getMagFilter());
|
||||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter);
|
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter);
|
||||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);
|
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilter);
|
||||||
|
|
||||||
if (tex.getAnisotropicFilter() > 1) {
|
if (tex.getAnisotropicFilter() > 1) {
|
||||||
if (ctxCaps.GL_EXT_texture_filter_anisotropic) {
|
if (caps.contains(Caps.TextureFilterAnisotropic)) {
|
||||||
glTexParameterf(target,
|
glTexParameterf(target,
|
||||||
GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||||
tex.getAnisotropicFilter());
|
tex.getAnisotropicFilter());
|
||||||
@ -1881,7 +1930,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
// Image does not have mipmaps, but they are required.
|
// Image does not have mipmaps, but they are required.
|
||||||
// Generate from base level.
|
// Generate from base level.
|
||||||
|
|
||||||
if (!ctxCaps.OpenGL30) {
|
if (!caps.contains(Caps.OpenGL30)) {
|
||||||
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
|
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||||
img.setMipmapsGenerated(true);
|
img.setMipmapsGenerated(true);
|
||||||
} else {
|
} else {
|
||||||
@ -1908,7 +1957,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT.
|
// Yes, some OpenGL2 cards (GeForce 5) still dont support NPOT.
|
||||||
if (!ctxCaps.GL_ARB_texture_non_power_of_two && img.isNPOT()) {
|
if (!caps.contains(Caps.NonPowerOfTwoTextures) && img.isNPOT()) {
|
||||||
if (img.getData(0) == null) {
|
if (img.getData(0) == null) {
|
||||||
throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
|
throw new RendererException("non-power-of-2 framebuffer textures are not supported by the video hardware");
|
||||||
} else {
|
} else {
|
||||||
@ -1917,7 +1966,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if graphics card doesn't support multisample textures
|
// Check if graphics card doesn't support multisample textures
|
||||||
if (!ctxCaps.GL_ARB_texture_multisample) {
|
if (!caps.contains(Caps.TextureMultisample)) {
|
||||||
if (img.getMultiSamples() > 1) {
|
if (img.getMultiSamples() > 1) {
|
||||||
throw new RendererException("Multisample textures not supported by graphics hardware");
|
throw new RendererException("Multisample textures not supported by graphics hardware");
|
||||||
}
|
}
|
||||||
@ -1928,6 +1977,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
if (img.getWidth() > maxCubeTexSize || img.getHeight() > maxCubeTexSize) {
|
if (img.getWidth() > maxCubeTexSize || img.getHeight() > maxCubeTexSize) {
|
||||||
throw new RendererException("Cannot upload cubemap " + img + ". The maximum supported cubemap resolution is " + maxCubeTexSize);
|
throw new RendererException("Cannot upload cubemap " + img + ". The maximum supported cubemap resolution is " + maxCubeTexSize);
|
||||||
}
|
}
|
||||||
|
if (img.getWidth() != img.getHeight()) {
|
||||||
|
throw new RendererException("Cubemaps must have square dimensions");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (img.getWidth() > maxTexSize || img.getHeight() > maxTexSize) {
|
if (img.getWidth() > maxTexSize || img.getHeight() > maxTexSize) {
|
||||||
throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize);
|
throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + maxTexSize);
|
||||||
@ -1942,7 +1994,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
TextureUtil.uploadTexture(ctxCaps, img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages);
|
TextureUtil.uploadTexture(caps, img, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, 0, linearizeSrgbImages);
|
||||||
}
|
}
|
||||||
} else if (target == GL_TEXTURE_2D_ARRAY_EXT) {
|
} else if (target == GL_TEXTURE_2D_ARRAY_EXT) {
|
||||||
if (!caps.contains(Caps.TextureArray)) {
|
if (!caps.contains(Caps.TextureArray)) {
|
||||||
@ -1952,22 +2004,22 @@ public class LwjglRenderer implements Renderer {
|
|||||||
List<ByteBuffer> data = img.getData();
|
List<ByteBuffer> data = img.getData();
|
||||||
|
|
||||||
// -1 index specifies prepare data for 2D Array
|
// -1 index specifies prepare data for 2D Array
|
||||||
TextureUtil.uploadTexture(ctxCaps, img, target, -1, 0, linearizeSrgbImages);
|
TextureUtil.uploadTexture(caps, img, target, -1, 0, linearizeSrgbImages);
|
||||||
|
|
||||||
for (int i = 0; i < data.size(); i++) {
|
for (int i = 0; i < data.size(); i++) {
|
||||||
// upload each slice of 2D array in turn
|
// upload each slice of 2D array in turn
|
||||||
// this time with the appropriate index
|
// this time with the appropriate index
|
||||||
TextureUtil.uploadTexture(ctxCaps, img, target, i, 0, linearizeSrgbImages);
|
TextureUtil.uploadTexture(caps, img, target, i, 0, linearizeSrgbImages);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TextureUtil.uploadTexture(ctxCaps, img, target, 0, 0, linearizeSrgbImages);
|
TextureUtil.uploadTexture(caps, img, target, 0, 0, linearizeSrgbImages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (img.getMultiSamples() != imageSamples) {
|
if (img.getMultiSamples() != imageSamples) {
|
||||||
img.setMultiSamples(imageSamples);
|
img.setMultiSamples(imageSamples);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxCaps.OpenGL30) {
|
if (caps.contains(Caps.OpenGL30)) {
|
||||||
if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData() != null) {
|
if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData() != null) {
|
||||||
// XXX: Required for ATI
|
// XXX: Required for ATI
|
||||||
glEnable(target);
|
glEnable(target);
|
||||||
@ -2018,7 +2070,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
public void modifyTexture(Texture tex, Image pixels, int x, int y) {
|
||||||
setTexture(0, tex);
|
setTexture(0, tex);
|
||||||
TextureUtil.uploadSubTexture(ctxCaps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages);
|
TextureUtil.uploadSubTexture(caps, pixels, convertTextureType(tex.getType(), pixels.getMultiSamples(), -1), 0, x, y, linearizeSrgbImages);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearTextureUnits() {
|
public void clearTextureUnits() {
|
||||||
@ -2213,8 +2265,9 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int programId = context.boundShaderProgram;
|
int programId = context.boundShaderProgram;
|
||||||
|
|
||||||
if (programId > 0) {
|
if (programId > 0) {
|
||||||
Attribute attrib = boundShader.getAttribute(vb.getBufferType());
|
Attribute attrib = context.boundShader.getAttribute(vb.getBufferType());
|
||||||
int loc = attrib.getLocation();
|
int loc = attrib.getLocation();
|
||||||
if (loc == -1) {
|
if (loc == -1) {
|
||||||
return; // not defined
|
return; // not defined
|
||||||
@ -2236,8 +2289,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vb.isInstanced()) {
|
if (vb.isInstanced()) {
|
||||||
if (!ctxCaps.GL_ARB_instanced_arrays
|
if (!caps.contains(Caps.MeshInstancing)) {
|
||||||
|| !ctxCaps.GL_ARB_draw_instanced) {
|
|
||||||
throw new RendererException("Instancing is required, "
|
throw new RendererException("Instancing is required, "
|
||||||
+ "but not supported by the "
|
+ "but not supported by the "
|
||||||
+ "graphics hardware");
|
+ "graphics hardware");
|
||||||
|
@ -32,11 +32,13 @@
|
|||||||
|
|
||||||
package com.jme3.renderer.lwjgl;
|
package com.jme3.renderer.lwjgl;
|
||||||
|
|
||||||
|
import com.jme3.renderer.Caps;
|
||||||
import com.jme3.renderer.RendererException;
|
import com.jme3.renderer.RendererException;
|
||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Image.Format;
|
import com.jme3.texture.Image.Format;
|
||||||
import com.jme3.texture.image.ColorSpace;
|
import com.jme3.texture.image.ColorSpace;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import static org.lwjgl.opengl.ARBDepthBufferFloat.*;
|
import static org.lwjgl.opengl.ARBDepthBufferFloat.*;
|
||||||
@ -55,7 +57,6 @@ import static org.lwjgl.opengl.GL11.*;
|
|||||||
import static org.lwjgl.opengl.GL12.*;
|
import static org.lwjgl.opengl.GL12.*;
|
||||||
import static org.lwjgl.opengl.GL13.*;
|
import static org.lwjgl.opengl.GL13.*;
|
||||||
import static org.lwjgl.opengl.GL14.*;
|
import static org.lwjgl.opengl.GL14.*;
|
||||||
import static org.lwjgl.opengl.GL20.*;
|
|
||||||
|
|
||||||
class TextureUtil {
|
class TextureUtil {
|
||||||
|
|
||||||
@ -157,18 +158,18 @@ class TextureUtil {
|
|||||||
private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
|
private static final GLImageFormat sRGB_DXT3 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
|
||||||
private static final GLImageFormat sRGB_DXT5 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
|
private static final GLImageFormat sRGB_DXT5 = new GLImageFormat(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, true);
|
||||||
|
|
||||||
public static GLImageFormat getImageFormat(ContextCapabilities caps, Format fmt, boolean isSrgb){
|
public static GLImageFormat getImageFormat(EnumSet<Caps> caps, Format fmt, boolean isSrgb){
|
||||||
switch (fmt){
|
switch (fmt){
|
||||||
case DXT1:
|
case DXT1:
|
||||||
case DXT1A:
|
case DXT1A:
|
||||||
case DXT3:
|
case DXT3:
|
||||||
case DXT5:
|
case DXT5:
|
||||||
if (!caps.GL_EXT_texture_compression_s3tc) {
|
if (!caps.contains(Caps.TextureCompressionS3TC)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Depth24Stencil8:
|
case Depth24Stencil8:
|
||||||
if (!caps.OpenGL30 && !caps.GL_EXT_packed_depth_stencil){
|
if (!caps.contains(Caps.PackedDepthStencilBuffer)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -179,30 +180,30 @@ class TextureUtil {
|
|||||||
case RGB32F:
|
case RGB32F:
|
||||||
case RGBA16F:
|
case RGBA16F:
|
||||||
case RGBA32F:
|
case RGBA32F:
|
||||||
if (!caps.OpenGL30 && !caps.GL_ARB_texture_float){
|
if (!caps.contains(Caps.FloatTexture)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Depth32F:
|
case Depth32F:
|
||||||
if (!caps.OpenGL30 && !caps.GL_NV_depth_buffer_float){
|
if (!caps.contains(Caps.FloatDepthBuffer)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LATC:
|
case LATC:
|
||||||
case LTC:
|
case LTC:
|
||||||
if (!caps.GL_EXT_texture_compression_latc){
|
if (!caps.contains(Caps.TextureCompressionLATC)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RGB9E5:
|
case RGB9E5:
|
||||||
case RGB16F_to_RGB9E5:
|
case RGB16F_to_RGB9E5:
|
||||||
if (!caps.OpenGL30 && !caps.GL_EXT_texture_shared_exponent){
|
if (!caps.contains(Caps.SharedExponentTexture)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RGB111110F:
|
case RGB111110F:
|
||||||
case RGB16F_to_RGB111110F:
|
case RGB16F_to_RGB111110F:
|
||||||
if (!caps.OpenGL30 && !caps.GL_EXT_packed_float){
|
if (!caps.contains(Caps.PackedFloatTexture)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -214,7 +215,7 @@ class TextureUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GLImageFormat getImageFormatWithError(ContextCapabilities caps, Format fmt, boolean isSrgb) {
|
public static GLImageFormat getImageFormatWithError(EnumSet<Caps> caps, Format fmt, boolean isSrgb) {
|
||||||
GLImageFormat glFmt = getImageFormat(caps, fmt, isSrgb);
|
GLImageFormat glFmt = getImageFormat(caps, fmt, isSrgb);
|
||||||
if (glFmt == null) {
|
if (glFmt == null) {
|
||||||
throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware.");
|
throw new RendererException("Image format '" + fmt + "' is unsupported by the video hardware.");
|
||||||
@ -254,7 +255,7 @@ class TextureUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadTexture(ContextCapabilities caps,
|
public static void uploadTexture(EnumSet<Caps> caps,
|
||||||
Image image,
|
Image image,
|
||||||
int target,
|
int target,
|
||||||
int index,
|
int index,
|
||||||
@ -412,7 +413,7 @@ class TextureUtil {
|
|||||||
* @param y the y position where to put the image in the texture
|
* @param y the y position where to put the image in the texture
|
||||||
*/
|
*/
|
||||||
public static void uploadSubTexture(
|
public static void uploadSubTexture(
|
||||||
ContextCapabilities caps,
|
EnumSet<Caps> caps,
|
||||||
Image image,
|
Image image,
|
||||||
int target,
|
int target,
|
||||||
int index,
|
int index,
|
||||||
|
@ -0,0 +1,615 @@
|
|||||||
|
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
|
||||||
|
uniform float m_Shininess;
|
||||||
|
|
||||||
|
varying vec4 AmbientSum;
|
||||||
|
varying vec4 DiffuseSum;
|
||||||
|
varying vec4 SpecularSum;
|
||||||
|
|
||||||
|
uniform mat4 g_ViewMatrix;
|
||||||
|
uniform vec4 g_LightData[NB_LIGHTS];
|
||||||
|
varying vec3 vTangent;
|
||||||
|
varying vec3 vBinormal;
|
||||||
|
varying vec3 vPos;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP
|
||||||
|
uniform sampler2D m_DiffuseMap;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_1
|
||||||
|
uniform sampler2D m_DiffuseMap_1;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_2
|
||||||
|
uniform sampler2D m_DiffuseMap_2;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_3
|
||||||
|
uniform sampler2D m_DiffuseMap_3;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_4
|
||||||
|
uniform sampler2D m_DiffuseMap_4;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_5
|
||||||
|
uniform sampler2D m_DiffuseMap_5;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_6
|
||||||
|
uniform sampler2D m_DiffuseMap_6;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_7
|
||||||
|
uniform sampler2D m_DiffuseMap_7;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_8
|
||||||
|
uniform sampler2D m_DiffuseMap_8;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_9
|
||||||
|
uniform sampler2D m_DiffuseMap_9;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_10
|
||||||
|
uniform sampler2D m_DiffuseMap_10;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_11
|
||||||
|
uniform sampler2D m_DiffuseMap_11;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP_0_SCALE
|
||||||
|
uniform float m_DiffuseMap_0_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_1_SCALE
|
||||||
|
uniform float m_DiffuseMap_1_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_2_SCALE
|
||||||
|
uniform float m_DiffuseMap_2_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_3_SCALE
|
||||||
|
uniform float m_DiffuseMap_3_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_4_SCALE
|
||||||
|
uniform float m_DiffuseMap_4_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_5_SCALE
|
||||||
|
uniform float m_DiffuseMap_5_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_6_SCALE
|
||||||
|
uniform float m_DiffuseMap_6_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_7_SCALE
|
||||||
|
uniform float m_DiffuseMap_7_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_8_SCALE
|
||||||
|
uniform float m_DiffuseMap_8_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_9_SCALE
|
||||||
|
uniform float m_DiffuseMap_9_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_10_SCALE
|
||||||
|
uniform float m_DiffuseMap_10_scale;
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_11_SCALE
|
||||||
|
uniform float m_DiffuseMap_11_scale;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP
|
||||||
|
uniform sampler2D m_AlphaMap;
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
uniform sampler2D m_AlphaMap_1;
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
uniform sampler2D m_AlphaMap_2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
uniform sampler2D m_NormalMap;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_1
|
||||||
|
uniform sampler2D m_NormalMap_1;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_2
|
||||||
|
uniform sampler2D m_NormalMap_2;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_3
|
||||||
|
uniform sampler2D m_NormalMap_3;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_4
|
||||||
|
uniform sampler2D m_NormalMap_4;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_5
|
||||||
|
uniform sampler2D m_NormalMap_5;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_6
|
||||||
|
uniform sampler2D m_NormalMap_6;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_7
|
||||||
|
uniform sampler2D m_NormalMap_7;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_8
|
||||||
|
uniform sampler2D m_NormalMap_8;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_9
|
||||||
|
uniform sampler2D m_NormalMap_9;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_10
|
||||||
|
uniform sampler2D m_NormalMap_10;
|
||||||
|
#endif
|
||||||
|
#ifdef NORMALMAP_11
|
||||||
|
uniform sampler2D m_NormalMap_11;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TRI_PLANAR_MAPPING
|
||||||
|
varying vec4 wVertex;
|
||||||
|
varying vec3 wNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP
|
||||||
|
|
||||||
|
vec4 calculateDiffuseBlend(in vec2 texCoord) {
|
||||||
|
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord * m_DiffuseMap_0_scale);
|
||||||
|
diffuseColor *= alphaBlend.r;
|
||||||
|
#ifdef DIFFUSEMAP_1
|
||||||
|
vec4 diffuseColor1 = texture2D(m_DiffuseMap_1, texCoord * m_DiffuseMap_1_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor1, alphaBlend.g );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_2
|
||||||
|
vec4 diffuseColor2 = texture2D(m_DiffuseMap_2, texCoord * m_DiffuseMap_2_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor2, alphaBlend.b );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_3
|
||||||
|
vec4 diffuseColor3 = texture2D(m_DiffuseMap_3, texCoord * m_DiffuseMap_3_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor3, alphaBlend.a );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
#ifdef DIFFUSEMAP_4
|
||||||
|
vec4 diffuseColor4 = texture2D(m_DiffuseMap_4, texCoord * m_DiffuseMap_4_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor4, alphaBlend1.r );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_5
|
||||||
|
vec4 diffuseColor5 = texture2D(m_DiffuseMap_5, texCoord * m_DiffuseMap_5_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor5, alphaBlend1.g );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_6
|
||||||
|
vec4 diffuseColor6 = texture2D(m_DiffuseMap_6, texCoord * m_DiffuseMap_6_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor6, alphaBlend1.b );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_7
|
||||||
|
vec4 diffuseColor7 = texture2D(m_DiffuseMap_7, texCoord * m_DiffuseMap_7_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor7, alphaBlend1.a );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
#ifdef DIFFUSEMAP_8
|
||||||
|
vec4 diffuseColor8 = texture2D(m_DiffuseMap_8, texCoord * m_DiffuseMap_8_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor8, alphaBlend2.r );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_9
|
||||||
|
vec4 diffuseColor9 = texture2D(m_DiffuseMap_9, texCoord * m_DiffuseMap_9_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor9, alphaBlend2.g );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_10
|
||||||
|
vec4 diffuseColor10 = texture2D(m_DiffuseMap_10, texCoord * m_DiffuseMap_10_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor10, alphaBlend2.b );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_11
|
||||||
|
vec4 diffuseColor11 = texture2D(m_DiffuseMap_11, texCoord * m_DiffuseMap_11_scale);
|
||||||
|
diffuseColor = mix( diffuseColor, diffuseColor11, alphaBlend2.a );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return diffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 calculateNormal(in vec2 texCoord) {
|
||||||
|
vec3 normal = vec3(0,0,1);
|
||||||
|
vec3 n = vec3(0,0,0);
|
||||||
|
|
||||||
|
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
n = texture2D(m_NormalMap, texCoord * m_DiffuseMap_0_scale).xyz;
|
||||||
|
normal += n * alphaBlend.r;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_1
|
||||||
|
n = texture2D(m_NormalMap_1, texCoord * m_DiffuseMap_1_scale).xyz;
|
||||||
|
normal += n * alphaBlend.g;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.g;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_2
|
||||||
|
n = texture2D(m_NormalMap_2, texCoord * m_DiffuseMap_2_scale).xyz;
|
||||||
|
normal += n * alphaBlend.b;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_3
|
||||||
|
n = texture2D(m_NormalMap_3, texCoord * m_DiffuseMap_3_scale).xyz;
|
||||||
|
normal += n * alphaBlend.a;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
#ifdef NORMALMAP_4
|
||||||
|
n = texture2D(m_NormalMap_4, texCoord * m_DiffuseMap_4_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_5
|
||||||
|
n = texture2D(m_NormalMap_5, texCoord * m_DiffuseMap_5_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.g;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_6
|
||||||
|
n = texture2D(m_NormalMap_6, texCoord * m_DiffuseMap_6_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_7
|
||||||
|
n = texture2D(m_NormalMap_7, texCoord * m_DiffuseMap_7_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.a;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
#ifdef NORMALMAP_8
|
||||||
|
n = texture2D(m_NormalMap_8, texCoord * m_DiffuseMap_8_scale).xyz;
|
||||||
|
normal += n * alphaBlend2.r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_9
|
||||||
|
n = texture2D(m_NormalMap_9, texCoord * m_DiffuseMap_9_scale);
|
||||||
|
normal += n * alphaBlend2.g;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_10
|
||||||
|
n = texture2D(m_NormalMap_10, texCoord * m_DiffuseMap_10_scale);
|
||||||
|
normal += n * alphaBlend2.b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_11
|
||||||
|
n = texture2D(m_NormalMap_11, texCoord * m_DiffuseMap_11_scale);
|
||||||
|
normal += n * alphaBlend2.a;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
normal = (normal.xyz * vec3(2.0) - vec3(1.0));
|
||||||
|
return normalize(normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TRI_PLANAR_MAPPING
|
||||||
|
|
||||||
|
vec4 getTriPlanarBlend(in vec4 coords, in vec3 blending, in sampler2D map, in float scale) {
|
||||||
|
vec4 col1 = texture2D( map, coords.yz * scale);
|
||||||
|
vec4 col2 = texture2D( map, coords.xz * scale);
|
||||||
|
vec4 col3 = texture2D( map, coords.xy * scale);
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex = col1 * blending.x + col2 * blending.y + col3 * blending.z;
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 calculateTriPlanarDiffuseBlend(in vec3 wNorm, in vec4 wVert, in vec2 texCoord) {
|
||||||
|
// tri-planar texture bending factor for this fragment's normal
|
||||||
|
vec3 blending = abs( wNorm );
|
||||||
|
blending = (blending -0.2) * 0.7;
|
||||||
|
blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 (very important!)
|
||||||
|
float b = (blending.x + blending.y + blending.z);
|
||||||
|
blending /= vec3(b, b, b);
|
||||||
|
|
||||||
|
// texture coords
|
||||||
|
vec4 coords = wVert;
|
||||||
|
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex0 = getTriPlanarBlend(coords, blending, m_DiffuseMap, m_DiffuseMap_0_scale);
|
||||||
|
|
||||||
|
#ifdef DIFFUSEMAP_1
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex1 = getTriPlanarBlend(coords, blending, m_DiffuseMap_1, m_DiffuseMap_1_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_2
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex2 = getTriPlanarBlend(coords, blending, m_DiffuseMap_2, m_DiffuseMap_2_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_3
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex3 = getTriPlanarBlend(coords, blending, m_DiffuseMap_3, m_DiffuseMap_3_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_4
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex4 = getTriPlanarBlend(coords, blending, m_DiffuseMap_4, m_DiffuseMap_4_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_5
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex5 = getTriPlanarBlend(coords, blending, m_DiffuseMap_5, m_DiffuseMap_5_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_6
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex6 = getTriPlanarBlend(coords, blending, m_DiffuseMap_6, m_DiffuseMap_6_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_7
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex7 = getTriPlanarBlend(coords, blending, m_DiffuseMap_7, m_DiffuseMap_7_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_8
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex8 = getTriPlanarBlend(coords, blending, m_DiffuseMap_8, m_DiffuseMap_8_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_9
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex9 = getTriPlanarBlend(coords, blending, m_DiffuseMap_9, m_DiffuseMap_9_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_10
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex10 = getTriPlanarBlend(coords, blending, m_DiffuseMap_10, m_DiffuseMap_10_scale);
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_11
|
||||||
|
// blend the results of the 3 planar projections.
|
||||||
|
vec4 tex11 = getTriPlanarBlend(coords, blending, m_DiffuseMap_11, m_DiffuseMap_11_scale);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec4 diffuseColor = tex0 * alphaBlend.r;
|
||||||
|
#ifdef DIFFUSEMAP_1
|
||||||
|
diffuseColor = mix( diffuseColor, tex1, alphaBlend.g );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_2
|
||||||
|
diffuseColor = mix( diffuseColor, tex2, alphaBlend.b );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_3
|
||||||
|
diffuseColor = mix( diffuseColor, tex3, alphaBlend.a );
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
#ifdef DIFFUSEMAP_4
|
||||||
|
diffuseColor = mix( diffuseColor, tex4, alphaBlend1.r );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_5
|
||||||
|
diffuseColor = mix( diffuseColor, tex5, alphaBlend1.g );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_6
|
||||||
|
diffuseColor = mix( diffuseColor, tex6, alphaBlend1.b );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_7
|
||||||
|
diffuseColor = mix( diffuseColor, tex7, alphaBlend1.a );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
#ifdef DIFFUSEMAP_8
|
||||||
|
diffuseColor = mix( diffuseColor, tex8, alphaBlend2.r );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_9
|
||||||
|
diffuseColor = mix( diffuseColor, tex9, alphaBlend2.g );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_10
|
||||||
|
diffuseColor = mix( diffuseColor, tex10, alphaBlend2.b );
|
||||||
|
#endif
|
||||||
|
#ifdef DIFFUSEMAP_11
|
||||||
|
diffuseColor = mix( diffuseColor, tex11, alphaBlend2.a );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return diffuseColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 calculateNormalTriPlanar(in vec3 wNorm, in vec4 wVert,in vec2 texCoord) {
|
||||||
|
// tri-planar texture bending factor for this fragment's world-space normal
|
||||||
|
vec3 blending = abs( wNorm );
|
||||||
|
blending = (blending -0.2) * 0.7;
|
||||||
|
blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 (very important!)
|
||||||
|
float b = (blending.x + blending.y + blending.z);
|
||||||
|
blending /= vec3(b, b, b);
|
||||||
|
|
||||||
|
// texture coords
|
||||||
|
vec4 coords = wVert;
|
||||||
|
vec4 alphaBlend = texture2D( m_AlphaMap, texCoord.xy );
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
vec4 alphaBlend1 = texture2D( m_AlphaMap_1, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
vec4 alphaBlend2 = texture2D( m_AlphaMap_2, texCoord.xy );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 normal = vec3(0,0,1);
|
||||||
|
vec3 n = vec3(0,0,0);
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap, m_DiffuseMap_0_scale).xyz;
|
||||||
|
normal += n * alphaBlend.r;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_1
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_1, m_DiffuseMap_1_scale).xyz;
|
||||||
|
normal += n * alphaBlend.g;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.g;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_2
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_2, m_DiffuseMap_2_scale).xyz;
|
||||||
|
normal += n * alphaBlend.b;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_3
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_3, m_DiffuseMap_3_scale).xyz;
|
||||||
|
normal += n * alphaBlend.a;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.a;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_1
|
||||||
|
#ifdef NORMALMAP_4
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_4, m_DiffuseMap_4_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.r;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_5
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_5, m_DiffuseMap_5_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.g;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.g;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_6
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_6, m_DiffuseMap_6_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.b;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_7
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_7, m_DiffuseMap_7_scale).xyz;
|
||||||
|
normal += n * alphaBlend1.a;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.a;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ALPHAMAP_2
|
||||||
|
#ifdef NORMALMAP_8
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_8, m_DiffuseMap_8_scale).xyz;
|
||||||
|
normal += n * alphaBlend2.r;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_9
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_9, m_DiffuseMap_9_scale).xyz;
|
||||||
|
normal += n * alphaBlend2.g;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.g;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_10
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_10, m_DiffuseMap_10_scale).xyz;
|
||||||
|
normal += n * alphaBlend2.b;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.b;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP_11
|
||||||
|
n = getTriPlanarBlend(coords, blending, m_NormalMap_11, m_DiffuseMap_11_scale).xyz;
|
||||||
|
normal += n * alphaBlend2.a;
|
||||||
|
#else
|
||||||
|
normal += vec3(0.5,0.5,1) * alphaBlend.a;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
normal = (normal.xyz * vec3(2.0) - vec3(1.0));
|
||||||
|
return normalize(normal);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
// diffuse calculations
|
||||||
|
//----------------------
|
||||||
|
#ifdef DIFFUSEMAP
|
||||||
|
#ifdef ALPHAMAP
|
||||||
|
#ifdef TRI_PLANAR_MAPPING
|
||||||
|
vec4 diffuseColor = calculateTriPlanarDiffuseBlend(wNormal, wVertex, texCoord);
|
||||||
|
#else
|
||||||
|
vec4 diffuseColor = calculateDiffuseBlend(texCoord);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
vec4 diffuseColor = texture2D(m_DiffuseMap, texCoord);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
vec4 diffuseColor = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------
|
||||||
|
// normal calculations
|
||||||
|
//---------------------
|
||||||
|
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
|
||||||
|
#ifdef TRI_PLANAR_MAPPING
|
||||||
|
vec3 normal = calculateNormalTriPlanar(wNormal, wVertex, texCoord);
|
||||||
|
#else
|
||||||
|
vec3 normal = calculateNormal(texCoord);
|
||||||
|
#endif
|
||||||
|
mat3 tbnMat = mat3(normalize(vTangent.xyz) , normalize(vBinormal.xyz) , normalize(vNormal.xyz));
|
||||||
|
#else
|
||||||
|
vec3 normal = vNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------
|
||||||
|
// lighting calculations
|
||||||
|
//-----------------------
|
||||||
|
gl_FragColor = AmbientSum * diffuseColor;
|
||||||
|
for( int i = 0;i < NB_LIGHTS; i+=3){
|
||||||
|
vec4 lightColor = g_LightData[i];
|
||||||
|
vec4 lightData1 = g_LightData[i+1];
|
||||||
|
vec4 lightDir;
|
||||||
|
vec3 lightVec;
|
||||||
|
lightComputeDir(vPos, lightColor.w, lightData1, lightDir, lightVec);
|
||||||
|
|
||||||
|
float spotFallOff = 1.0;
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
// allow use of control flow
|
||||||
|
if(lightColor.w > 1.0){
|
||||||
|
#endif
|
||||||
|
spotFallOff = computeSpotFalloff(g_LightData[i+2], lightVec);
|
||||||
|
#if __VERSION__ >= 110
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NORMALMAP
|
||||||
|
//Normal map -> lighting is computed in tangent space
|
||||||
|
lightDir.xyz = normalize(lightDir.xyz * tbnMat);
|
||||||
|
vec3 viewDir = normalize(-vPos.xyz * tbnMat);
|
||||||
|
#else
|
||||||
|
//no Normal map -> lighting is computed in view space
|
||||||
|
lightDir.xyz = normalize(lightDir.xyz);
|
||||||
|
vec3 viewDir = normalize(-vPos.xyz);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec2 light = computeLighting(normal, viewDir, lightDir.xyz, lightDir.w * spotFallOff, m_Shininess);
|
||||||
|
gl_FragColor.rgb += DiffuseSum.rgb * lightColor.rgb * diffuseColor.rgb * vec3(light.x) +
|
||||||
|
SpecularSum.rgb * vec3(light.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
|
uniform mat4 g_WorldViewMatrix;
|
||||||
|
uniform mat3 g_NormalMatrix;
|
||||||
|
uniform mat4 g_ViewMatrix;
|
||||||
|
|
||||||
|
uniform vec4 g_AmbientLightColor;
|
||||||
|
|
||||||
|
attribute vec3 inPosition;
|
||||||
|
attribute vec3 inNormal;
|
||||||
|
attribute vec2 inTexCoord;
|
||||||
|
attribute vec4 inTangent;
|
||||||
|
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
varying vec3 vPos;
|
||||||
|
varying vec3 vTangent;
|
||||||
|
varying vec3 vBinormal;
|
||||||
|
|
||||||
|
varying vec4 AmbientSum;
|
||||||
|
varying vec4 DiffuseSum;
|
||||||
|
varying vec4 SpecularSum;
|
||||||
|
|
||||||
|
#ifdef TRI_PLANAR_MAPPING
|
||||||
|
varying vec4 wVertex;
|
||||||
|
varying vec3 wNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
vec4 pos = vec4(inPosition, 1.0);
|
||||||
|
gl_Position = g_WorldViewProjectionMatrix * pos;
|
||||||
|
#ifdef TERRAIN_GRID
|
||||||
|
texCoord = inTexCoord * 2.0;
|
||||||
|
#else
|
||||||
|
texCoord = inTexCoord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 wvPosition = (g_WorldViewMatrix * pos).xyz;
|
||||||
|
vec3 wvNormal = normalize(g_NormalMatrix * inNormal);
|
||||||
|
|
||||||
|
//--------------------------
|
||||||
|
// specific to normal maps:
|
||||||
|
//--------------------------
|
||||||
|
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
|
||||||
|
vTangent = g_NormalMatrix * inTangent.xyz;
|
||||||
|
vBinormal = cross(wvNormal, vTangent)* inTangent.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
// general to all lighting
|
||||||
|
//-------------------------
|
||||||
|
vNormal = wvNormal;
|
||||||
|
vPos = wvPosition;
|
||||||
|
|
||||||
|
AmbientSum = g_AmbientLightColor;
|
||||||
|
DiffuseSum = vec4(1.0);
|
||||||
|
SpecularSum = vec4(0.0);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TRI_PLANAR_MAPPING
|
||||||
|
wVertex = vec4(inPosition,0.0);
|
||||||
|
wNormal = inNormal;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
#import "Common/ShaderLib/PhongLighting.glsllib"
|
||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
|
||||||
uniform float m_Shininess;
|
uniform float m_Shininess;
|
||||||
uniform vec4 g_LightDirection;
|
uniform vec4 g_LightDirection;
|
||||||
@ -145,54 +147,6 @@ varying vec3 lightVec;
|
|||||||
varying vec3 wNormal;
|
varying vec3 wNormal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float tangDot(in vec3 v1, in vec3 v2){
|
|
||||||
float d = dot(v1,v2);
|
|
||||||
#ifdef V_TANGENT
|
|
||||||
d = 1.0 - d*d;
|
|
||||||
return step(0.0, d) * sqrt(d);
|
|
||||||
#else
|
|
||||||
return d;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float lightComputeDiffuse(in vec3 norm, in vec3 lightdir, in vec3 viewdir){
|
|
||||||
return max(0.0, dot(norm, lightdir));
|
|
||||||
}
|
|
||||||
|
|
||||||
float lightComputeSpecular(in vec3 norm, in vec3 viewdir, in vec3 lightdir, in float shiny){
|
|
||||||
#ifdef WARDISO
|
|
||||||
// Isotropic Ward
|
|
||||||
vec3 halfVec = normalize(viewdir + lightdir);
|
|
||||||
float NdotH = max(0.001, tangDot(norm, halfVec));
|
|
||||||
float NdotV = max(0.001, tangDot(norm, viewdir));
|
|
||||||
float NdotL = max(0.001, tangDot(norm, lightdir));
|
|
||||||
float a = tan(acos(NdotH));
|
|
||||||
float p = max(shiny/128.0, 0.001);
|
|
||||||
return NdotL * (1.0 / (4.0*3.14159265*p*p)) * (exp(-(a*a)/(p*p)) / (sqrt(NdotV * NdotL)));
|
|
||||||
#else
|
|
||||||
// Standard Phong
|
|
||||||
vec3 R = reflect(-lightdir, norm);
|
|
||||||
return pow(max(tangDot(R, viewdir), 0.0), shiny);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 computeLighting(in vec3 wvPos, in vec3 wvNorm, in vec3 wvViewDir, in vec3 wvLightDir){
|
|
||||||
float diffuseFactor = lightComputeDiffuse(wvNorm, wvLightDir, wvViewDir);
|
|
||||||
float specularFactor = lightComputeSpecular(wvNorm, wvViewDir, wvLightDir, m_Shininess);
|
|
||||||
|
|
||||||
if (m_Shininess <= 1.0) {
|
|
||||||
specularFactor = 0.0; // should be one instruction on most cards ..
|
|
||||||
}
|
|
||||||
|
|
||||||
float att = vLightDir.w;
|
|
||||||
|
|
||||||
return vec2(diffuseFactor, specularFactor) * vec2(att);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ALPHAMAP
|
#ifdef ALPHAMAP
|
||||||
|
|
||||||
vec4 calculateDiffuseBlend(in vec2 texCoord) {
|
vec4 calculateDiffuseBlend(in vec2 texCoord) {
|
||||||
@ -648,7 +602,7 @@ void main(){
|
|||||||
vec4 lightDir = vLightDir;
|
vec4 lightDir = vLightDir;
|
||||||
lightDir.xyz = normalize(lightDir.xyz);
|
lightDir.xyz = normalize(lightDir.xyz);
|
||||||
|
|
||||||
vec2 light = computeLighting(vPosition, normal, vViewDir.xyz, lightDir.xyz)*spotFallOff;
|
vec2 light = computeLighting(normal, vViewDir.xyz, lightDir.xyz,lightDir.w*spotFallOff,m_Shininess);
|
||||||
|
|
||||||
vec4 specularColor = vec4(1.0);
|
vec4 specularColor = vec4(1.0);
|
||||||
|
|
||||||
|
@ -163,6 +163,70 @@ MaterialDef Terrain Lighting {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Technique {
|
||||||
|
|
||||||
|
LightMode SinglePass
|
||||||
|
|
||||||
|
VertexShader GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.vert
|
||||||
|
FragmentShader GLSL100: Common/MatDefs/Terrain/SPTerrainLighting.frag
|
||||||
|
|
||||||
|
WorldParameters {
|
||||||
|
WorldViewProjectionMatrix
|
||||||
|
NormalMatrix
|
||||||
|
WorldViewMatrix
|
||||||
|
ViewMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
Defines {
|
||||||
|
TRI_PLANAR_MAPPING : useTriPlanarMapping
|
||||||
|
TERRAIN_GRID : isTerrainGrid
|
||||||
|
WARDISO : WardIso
|
||||||
|
|
||||||
|
DIFFUSEMAP : DiffuseMap
|
||||||
|
DIFFUSEMAP_1 : DiffuseMap_1
|
||||||
|
DIFFUSEMAP_2 : DiffuseMap_2
|
||||||
|
DIFFUSEMAP_3 : DiffuseMap_3
|
||||||
|
DIFFUSEMAP_4 : DiffuseMap_4
|
||||||
|
DIFFUSEMAP_5 : DiffuseMap_5
|
||||||
|
DIFFUSEMAP_6 : DiffuseMap_6
|
||||||
|
DIFFUSEMAP_7 : DiffuseMap_7
|
||||||
|
DIFFUSEMAP_8 : DiffuseMap_8
|
||||||
|
DIFFUSEMAP_9 : DiffuseMap_9
|
||||||
|
DIFFUSEMAP_10 : DiffuseMap_10
|
||||||
|
DIFFUSEMAP_11 : DiffuseMap_11
|
||||||
|
NORMALMAP : NormalMap
|
||||||
|
NORMALMAP_1 : NormalMap_1
|
||||||
|
NORMALMAP_2 : NormalMap_2
|
||||||
|
NORMALMAP_3 : NormalMap_3
|
||||||
|
NORMALMAP_4 : NormalMap_4
|
||||||
|
NORMALMAP_5 : NormalMap_5
|
||||||
|
NORMALMAP_6 : NormalMap_6
|
||||||
|
NORMALMAP_7 : NormalMap_7
|
||||||
|
NORMALMAP_8 : NormalMap_8
|
||||||
|
NORMALMAP_9 : NormalMap_9
|
||||||
|
NORMALMAP_10 : NormalMap_10
|
||||||
|
NORMALMAP_11 : NormalMap_11
|
||||||
|
SPECULARMAP : SpecularMap
|
||||||
|
ALPHAMAP : AlphaMap
|
||||||
|
ALPHAMAP_1 : AlphaMap_1
|
||||||
|
ALPHAMAP_2 : AlphaMap_2
|
||||||
|
DIFFUSEMAP_0_SCALE : DiffuseMap_0_scale
|
||||||
|
DIFFUSEMAP_1_SCALE : DiffuseMap_1_scale
|
||||||
|
DIFFUSEMAP_2_SCALE : DiffuseMap_2_scale
|
||||||
|
DIFFUSEMAP_3_SCALE : DiffuseMap_3_scale
|
||||||
|
DIFFUSEMAP_4_SCALE : DiffuseMap_4_scale
|
||||||
|
DIFFUSEMAP_5_SCALE : DiffuseMap_5_scale
|
||||||
|
DIFFUSEMAP_6_SCALE : DiffuseMap_6_scale
|
||||||
|
DIFFUSEMAP_7_SCALE : DiffuseMap_7_scale
|
||||||
|
DIFFUSEMAP_8_SCALE : DiffuseMap_8_scale
|
||||||
|
DIFFUSEMAP_9_SCALE : DiffuseMap_9_scale
|
||||||
|
DIFFUSEMAP_10_SCALE : DiffuseMap_10_scale
|
||||||
|
DIFFUSEMAP_11_SCALE : DiffuseMap_11_scale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Technique PreShadow {
|
Technique PreShadow {
|
||||||
|
|
||||||
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#import "Common/ShaderLib/Lighting.glsllib"
|
||||||
|
|
||||||
uniform mat4 g_WorldViewProjectionMatrix;
|
uniform mat4 g_WorldViewProjectionMatrix;
|
||||||
uniform mat4 g_WorldViewMatrix;
|
uniform mat4 g_WorldViewMatrix;
|
||||||
uniform mat3 g_NormalMatrix;
|
uniform mat3 g_NormalMatrix;
|
||||||
@ -34,16 +36,6 @@ varying vec4 SpecularSum;
|
|||||||
varying vec3 wNormal;
|
varying vec3 wNormal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// JME3 lights in world space
|
|
||||||
void lightComputeDir(in vec3 worldPos, in vec4 color, in vec4 position, out vec4 lightDir){
|
|
||||||
float posLight = step(0.5, color.w);
|
|
||||||
vec3 tempVec = position.xyz * sign(posLight - 0.5) - (worldPos * posLight);
|
|
||||||
lightVec.xyz = tempVec;
|
|
||||||
float dist = length(tempVec);
|
|
||||||
lightDir.w = clamp(1.0 - position.w * dist * posLight, 0.0, 1.0);
|
|
||||||
lightDir.xyz = tempVec / vec3(dist);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
vec4 pos = vec4(inPosition, 1.0);
|
vec4 pos = vec4(inPosition, 1.0);
|
||||||
@ -66,35 +58,30 @@ void main(){
|
|||||||
// specific to normal maps:
|
// specific to normal maps:
|
||||||
//--------------------------
|
//--------------------------
|
||||||
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
|
#if defined(NORMALMAP) || defined(NORMALMAP_1) || defined(NORMALMAP_2) || defined(NORMALMAP_3) || defined(NORMALMAP_4) || defined(NORMALMAP_5) || defined(NORMALMAP_6) || defined(NORMALMAP_7) || defined(NORMALMAP_8) || defined(NORMALMAP_9) || defined(NORMALMAP_10) || defined(NORMALMAP_11)
|
||||||
vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
|
vec3 wvTangent = normalize(g_NormalMatrix * inTangent.xyz);
|
||||||
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
vec3 wvBinormal = cross(wvNormal, wvTangent);
|
||||||
|
|
||||||
mat3 tbnMat = mat3(wvTangent, wvBinormal * -inTangent.w,wvNormal);
|
mat3 tbnMat = mat3(wvTangent, wvBinormal * inTangent.w,wvNormal);
|
||||||
|
|
||||||
vPosition = wvPosition * tbnMat;
|
vPosition = wvPosition * tbnMat;
|
||||||
vViewDir = viewDir * tbnMat;
|
vViewDir = viewDir * tbnMat;
|
||||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
|
||||||
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||||
|
vLightDir.xyz = (vLightDir.xyz * tbnMat).xyz;
|
||||||
#else
|
#else
|
||||||
|
//-------------------------
|
||||||
|
// general to all lighting
|
||||||
|
//-------------------------
|
||||||
|
vNormal = wvNormal;
|
||||||
|
|
||||||
//-------------------------
|
vPosition = wvPosition;
|
||||||
// general to all lighting
|
vViewDir = viewDir;
|
||||||
//-------------------------
|
|
||||||
vNormal = wvNormal;
|
|
||||||
|
|
||||||
vPosition = wvPosition;
|
lightComputeDir(wvPosition, lightColor.w, wvLightPos, vLightDir, lightVec);
|
||||||
vViewDir = viewDir;
|
|
||||||
|
|
||||||
lightComputeDir(wvPosition, lightColor, wvLightPos, vLightDir);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//computing spot direction in view space and unpacking spotlight cos
|
AmbientSum = g_AmbientLightColor; // Default: ambient color is dark gray
|
||||||
// spotVec=(g_ViewMatrix *vec4(g_LightDirection.xyz,0.0) );
|
|
||||||
// spotVec.w=floor(g_LightDirection.w)*0.001;
|
|
||||||
// lightVec.w = fract(g_LightDirection.w);
|
|
||||||
|
|
||||||
AmbientSum = vec4(0.2, 0.2, 0.2, 1.0) * g_AmbientLightColor; // Default: ambient color is dark gray
|
|
||||||
DiffuseSum = lightColor;
|
DiffuseSum = lightColor;
|
||||||
SpecularSum = lightColor;
|
SpecularSum = lightColor;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user