mirror of
https://github.com/DrBeef/JKXR.git
synced 2024-11-24 21:11:03 +00:00
Restored original vanilla renderer and renamed current to rd-gles
This commit is contained in:
parent
cd9026c927
commit
399e803068
73 changed files with 64120 additions and 5333 deletions
|
@ -23,7 +23,7 @@ LOCAL_STATIC_LIBRARIES := sigc libzip libpng libminizip
|
|||
LOCAL_SHARED_LIBRARIES := vrapi gl4es
|
||||
|
||||
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-vanilla $(JK3_CODE_PATH)/rd-common
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
|
|
@ -23,7 +23,7 @@ LOCAL_STATIC_LIBRARIES := sigc libzip libpng libminizip
|
|||
LOCAL_SHARED_LIBRARIES := vrapi gl4es
|
||||
|
||||
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-vanilla $(JK3_CODE_PATH)/rd-common
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(TOP_DIR)/JKVR $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(SUPPORT_LIBS)/minizip/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
|
|
@ -18,7 +18,7 @@ LOCAL_LDLIBS += -llog -lz
|
|||
#LOCAL_STATIC_LIBRARIES := s-setup lz
|
||||
LOCAL_SHARED_LIBRARIES :=
|
||||
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(TOP_DIR)/SupportLibs/openal/include $(JK3_CODE_PATH)/rd-vanilla $(JK3_CODE_PATH)/rd-common
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK3_CODE_PATH)/game $(TOP_DIR)/SupportLibs/openal/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
|
||||
|
||||
JK3_SRC = \
|
||||
code/game/AI_Animal.cpp \
|
||||
|
|
|
@ -18,7 +18,7 @@ LOCAL_LDLIBS += -llog -lz
|
|||
#LOCAL_STATIC_LIBRARIES := s-setup lz
|
||||
LOCAL_SHARED_LIBRARIES :=
|
||||
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK2_CODE_PATH)/game $(TOP_DIR)/SupportLibs/openal/include $(JK3_CODE_PATH)/rd-vanilla $(JK3_CODE_PATH)/rd-common
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(TOP_DIR) $(GL4ES_PATH) $(GL4ES_PATH)/include $(JK2_CODE_PATH)/game $(TOP_DIR)/SupportLibs/openal/include $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
|
||||
|
||||
JK2_SRC = \
|
||||
codeJK2/game/AI_Atst.cpp \
|
||||
|
|
|
@ -18,45 +18,45 @@ LOCAL_LDLIBS += -lGLESv3 -landroid -lEGL -ldl -llog
|
|||
LOCAL_STATIC_LIBRARIES := libpng libjpeg
|
||||
LOCAL_SHARED_LIBRARIES := gl4es
|
||||
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(SUPPORT_LIBS)/libpng $(TOP_DIR) $(JK3_CODE_PATH)/rd-vanilla $(JK3_CODE_PATH)/rd-common
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(SUPPORT_LIBS)/libpng $(TOP_DIR) $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
|
||||
|
||||
|
||||
JK3_SRC = \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_API.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_bolts.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_bones.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_misc.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_surfaces.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_API.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_bolts.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_bones.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_misc.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_surfaces.cpp \
|
||||
${JK3_CODE_PATH}/qcommon/matcomp.cpp \
|
||||
${JK3_CODE_PATH}/qcommon/q_shared.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_arb.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_backend.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_bsp.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_cmds.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_curve.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_draw.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_ghoul2.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_image.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_init.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_light.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_main.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_marks.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_mesh.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_model.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_quicksprite.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_scene.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shade.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shade_calc.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shader.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shadows.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_skin.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_sky.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_stl.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_subs.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_surface.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_surfacesprites.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_world.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_WorldEffects.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_arb.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_backend.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_bsp.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_cmds.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_curve.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_draw.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_ghoul2.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_image.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_init.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_light.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_main.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_marks.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_mesh.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_model.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_quicksprite.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_scene.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shade.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shade_calc.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shader.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shadows.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_skin.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_sky.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_stl.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_subs.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_surface.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_surfacesprites.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_world.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_WorldEffects.cpp \
|
||||
${JK3_CODE_PATH}/rd-common/tr_font.cpp \
|
||||
${JK3_CODE_PATH}/rd-common/tr_image_load.cpp \
|
||||
${JK3_CODE_PATH}/rd-common/tr_image_jpg.cpp \
|
||||
|
|
|
@ -18,45 +18,45 @@ LOCAL_LDLIBS += -lGLESv3 -landroid -lEGL -ldl -llog
|
|||
LOCAL_STATIC_LIBRARIES := libpng libjpeg
|
||||
LOCAL_SHARED_LIBRARIES := gl4es
|
||||
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(SUPPORT_LIBS)/libpng $(TOP_DIR) $(JK3_CODE_PATH)/rd-vanilla $(JK3_CODE_PATH)/rd-common
|
||||
LOCAL_C_INCLUDES := $(JK3_BASE_C_INCLUDES) $(SUPPORT_LIBS)/libpng $(TOP_DIR) $(JK3_CODE_PATH)/rd-gles $(JK3_CODE_PATH)/rd-common
|
||||
|
||||
|
||||
JK3_SRC = \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_API.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_bolts.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_bones.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_misc.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/G2_surfaces.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_API.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_bolts.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_bones.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_misc.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/G2_surfaces.cpp \
|
||||
${JK3_CODE_PATH}/qcommon/matcomp.cpp \
|
||||
${JK3_CODE_PATH}/qcommon/q_shared.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_arb.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_backend.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_bsp.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_cmds.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_curve.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_draw.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_ghoul2.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_image.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_init.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_light.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_main.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_marks.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_mesh.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_model.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_quicksprite.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_scene.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shade.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shade_calc.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shader.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_shadows.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_skin.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_sky.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_stl.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_subs.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_surface.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_surfacesprites.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_world.cpp \
|
||||
${JK3_CODE_PATH}/rd-vanilla/tr_WorldEffects.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_arb.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_backend.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_bsp.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_cmds.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_curve.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_draw.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_ghoul2.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_image.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_init.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_light.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_main.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_marks.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_mesh.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_model.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_quicksprite.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_scene.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shade.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shade_calc.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shader.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_shadows.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_skin.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_sky.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_stl.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_subs.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_surface.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_surfacesprites.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_world.cpp \
|
||||
${JK3_CODE_PATH}/rd-gles/tr_WorldEffects.cpp \
|
||||
${JK3_CODE_PATH}/rd-common/tr_font.cpp \
|
||||
${JK3_CODE_PATH}/rd-common/tr_image_load.cpp \
|
||||
${JK3_CODE_PATH}/rd-common/tr_image_jpg.cpp \
|
||||
|
|
|
@ -24,7 +24,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
#if !defined(G2_H_INC)
|
||||
#define G2_H_INC
|
||||
|
||||
#include "rd-vanilla/tr_local.h"
|
||||
#include "tr_local.h"
|
||||
|
||||
class CMiniHeap;
|
||||
|
||||
|
|
203
Projects/Android/jni/OpenJK/code/rd-gles/CMakeLists.txt
Normal file
203
Projects/Android/jni/OpenJK/code/rd-gles/CMakeLists.txt
Normal file
|
@ -0,0 +1,203 @@
|
|||
#============================================================================
|
||||
# Copyright (C) 2013 - 2018, OpenJK contributors
|
||||
#
|
||||
# This file is part of the OpenJK source code.
|
||||
#
|
||||
# OpenJK is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#============================================================================
|
||||
|
||||
# Make sure the user is not executing this script directly
|
||||
if(NOT InOpenJK)
|
||||
message(FATAL_ERROR "Use the top-level cmake script!")
|
||||
endif(NOT InOpenJK)
|
||||
|
||||
if(BuildSPRdVanilla OR BuildJK2SPRdVanilla)
|
||||
|
||||
set(SPRDVanillaRendererIncludeDirectories ${SPDir})
|
||||
set(SPRDVanillaRendererIncludeDirectories
|
||||
${SharedDir}
|
||||
${SPRDVanillaRendererIncludeDirectories}
|
||||
"${SPDir}/rd-vanilla"
|
||||
"${GSLIncludeDirectory}"
|
||||
)
|
||||
|
||||
# Modular Renderer crap (let's hope this works..)
|
||||
|
||||
# Defines
|
||||
set(SPRDVanillaDefines ${SharedDefines} "RENDERER" "_JK2EXE")
|
||||
|
||||
# Files
|
||||
|
||||
# GHOUL 2
|
||||
set(SPRDVanillaG2Files
|
||||
"${SPDir}/ghoul2/G2.h"
|
||||
"${SPDir}/ghoul2/ghoul2_gore.h"
|
||||
"${SPDir}/rd-vanilla/G2_API.cpp"
|
||||
"${SPDir}/rd-vanilla/G2_bolts.cpp"
|
||||
"${SPDir}/rd-vanilla/G2_bones.cpp"
|
||||
"${SPDir}/rd-vanilla/G2_misc.cpp"
|
||||
"${SPDir}/rd-vanilla/G2_surfaces.cpp"
|
||||
)
|
||||
source_group("ghoul2" FILES ${SPRDVanillaG2Files})
|
||||
set(SPRDVanillaFiles ${SPRDVanillaFiles} ${SPRDVanillaG2Files})
|
||||
|
||||
# Transparently use either bundled or system jpeg.
|
||||
list(APPEND SPRDVanillaRendererIncludeDirectories ${JPEG_INCLUDE_DIR})
|
||||
list(APPEND SPRDVanillaRendererLibraries ${JPEG_LIBRARIES})
|
||||
|
||||
# Transparently use either bundled or system libpng. Order is important --
|
||||
# libpng used zlib, so it must come before it on the linker command line.
|
||||
list(APPEND SPRDVanillaRendererIncludeDirectories ${PNG_INCLUDE_DIRS})
|
||||
list(APPEND SPRDVanillaRendererLibraries ${PNG_LIBRARIES})
|
||||
|
||||
# Transparently use either bundled or system zlib.
|
||||
list(APPEND SPRDVanillaRendererIncludeDirectories ${ZLIB_INCLUDE_DIR})
|
||||
list(APPEND SPRDVanillaRendererLibraries ${ZLIB_LIBRARIES})
|
||||
|
||||
# Transparently use our bundled minizip.
|
||||
list(APPEND SPRDVanillaRendererIncludeDirectories ${MINIZIP_INCLUDE_DIRS})
|
||||
list(APPEND SPRDVanillaRendererLibraries ${MINIZIP_LIBRARIES})
|
||||
|
||||
# Transparantly make use of all renderer directories
|
||||
list(APPEND SPRDVanillaRendererIncludeDirectories "${SPDir}/rd-common")
|
||||
list(APPEND SPRDVanillaRendererIncludeDirectories "${SPDir}/rd-vanilla")
|
||||
|
||||
# Misc files
|
||||
set(SPRDVanillaCommonFiles
|
||||
"${SPDir}/qcommon/matcomp.cpp"
|
||||
"${SPDir}/qcommon/q_shared.cpp"
|
||||
"${SPDir}/qcommon/q_shared.h"
|
||||
"${SPDir}/qcommon/ojk_i_saved_game.h"
|
||||
"${SPDir}/qcommon/ojk_saved_game_class_archivers.h"
|
||||
"${SPDir}/qcommon/ojk_saved_game_helper.h"
|
||||
"${SPDir}/qcommon/ojk_saved_game_helper_fwd.h"
|
||||
"${SPDir}/qcommon/ojk_scope_guard.h"
|
||||
${SharedCommonFiles}
|
||||
)
|
||||
source_group("common" FILES ${SPRDVanillaCommonFiles})
|
||||
set(SPRDVanillaFiles ${SPRDVanillaFiles} ${SPRDVanillaCommonFiles})
|
||||
|
||||
# Misc files
|
||||
set(SPRDVanillaCommonSafeFiles
|
||||
${SharedCommonSafeFiles}
|
||||
)
|
||||
source_group("common/safe" FILES ${SPRDVanillaCommonSafeFiles})
|
||||
set(SPRDVanillaFiles ${SPRDVanillaFiles} ${SPRDVanillaCommonSafeFiles})
|
||||
|
||||
# main files
|
||||
set(SPRDVanillaMainFiles
|
||||
"${SPDir}/rd-vanilla/glext.h"
|
||||
"${SPDir}/rd-vanilla/qgl.h"
|
||||
"${SPDir}/rd-vanilla/tr_arb.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_backend.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_bsp.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_cmds.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_curve.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_draw.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_ghoul2.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_image.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_init.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_light.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_local.h"
|
||||
"${SPDir}/rd-vanilla/tr_main.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_marks.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_mesh.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_model.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_quicksprite.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_quicksprite.h"
|
||||
"${SPDir}/rd-vanilla/tr_scene.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_shade.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_shade_calc.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_shader.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_shadows.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_skin.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_sky.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_stl.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_stl.h"
|
||||
"${SPDir}/rd-vanilla/tr_subs.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_surface.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_surfacesprites.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_world.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_WorldEffects.cpp"
|
||||
"${SPDir}/rd-vanilla/tr_WorldEffects.h"
|
||||
)
|
||||
source_group("renderer" FILES ${SPRDVanillaMainFiles})
|
||||
set(SPRDVanillaFiles ${SPRDVanillaFiles} ${SPRDVanillaMainFiles})
|
||||
|
||||
set(SPRDVanillaRdCommonFiles
|
||||
"${SPDir}/rd-common/mdx_format.h"
|
||||
"${SPDir}/rd-common/tr_common.h"
|
||||
"${SPDir}/rd-common/tr_font.cpp"
|
||||
"${SPDir}/rd-common/tr_font.h"
|
||||
"${SPDir}/rd-common/tr_image_load.cpp"
|
||||
"${SPDir}/rd-common/tr_image_jpg.cpp"
|
||||
"${SPDir}/rd-common/tr_image_tga.cpp"
|
||||
"${SPDir}/rd-common/tr_image_png.cpp"
|
||||
"${SPDir}/rd-common/tr_noise.cpp"
|
||||
"${SPDir}/rd-common/tr_public.h"
|
||||
"${SPDir}/rd-common/tr_types.h")
|
||||
source_group("rd-common" FILES ${SPRDVanillaRdCommonFiles})
|
||||
set(SPRDVanillaFiles ${SPRDVanillaFiles} ${SPRDVanillaRdCommonFiles})
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
set(SPRDVanillaRendererIncludeDirectories ${SPRDVanillaRendererIncludeDirectories} ${OPENGL_INCLUDE_DIR})
|
||||
set(SPRDVanillaRendererLibraries ${SPRDVanillaRendererLibraries} ${OPENGL_LIBRARIES})
|
||||
|
||||
set(SPRDVanillaRendererIncludeDirectories ${SPRDVanillaRendererIncludeDirectories} ${OpenJKLibDir})
|
||||
|
||||
function(add_sp_renderer_project ProjectName Label EngineName InstallDir Component)
|
||||
add_library(${ProjectName} SHARED ${SPRDVanillaFiles})
|
||||
if(NOT MSVC)
|
||||
# remove "lib" prefix for .so/.dylib files
|
||||
set_target_properties(${ProjectName} PROPERTIES PREFIX "")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
install(TARGETS ${ProjectName}
|
||||
RUNTIME
|
||||
DESTINATION ${InstallDir}
|
||||
COMPONENT ${Component})
|
||||
else(WIN32)
|
||||
if(MakeApplicationBundles AND (BuildSPEngine OR BuildJK2SPEngine))
|
||||
install(TARGETS ${ProjectName}
|
||||
LIBRARY
|
||||
DESTINATION "${InstallDir}/${EngineName}.app/Contents/MacOS/"
|
||||
COMPONENT ${Component})
|
||||
else()
|
||||
install(TARGETS ${ProjectName}
|
||||
LIBRARY
|
||||
DESTINATION ${InstallDir}
|
||||
COMPONENT ${Component})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_target_properties(${ProjectName} PROPERTIES COMPILE_DEFINITIONS "${SPRDVanillaDefines}")
|
||||
|
||||
# Hide symbols not explicitly marked public.
|
||||
set_property(TARGET ${ProjectName} APPEND PROPERTY COMPILE_OPTIONS ${OPENJK_VISIBILITY_FLAGS})
|
||||
|
||||
set_target_properties(${ProjectName} PROPERTIES INCLUDE_DIRECTORIES "${SPRDVanillaRendererIncludeDirectories}")
|
||||
set_target_properties(${ProjectName} PROPERTIES PROJECT_LABEL ${Label})
|
||||
|
||||
target_link_libraries(${ProjectName} ${SPRDVanillaRendererLibraries})
|
||||
endfunction(add_sp_renderer_project)
|
||||
|
||||
if(BuildSPRdVanilla)
|
||||
add_sp_renderer_project(${SPRDVanillaRenderer} "SP Vanilla Renderer" ${SPEngine} ${JKAInstallDir} ${JKASPClientComponent})
|
||||
endif(BuildSPRdVanilla)
|
||||
if(BuildJK2SPRdVanilla)
|
||||
set(SPRDVanillaDefines ${SPRDVanillaDefines} "JK2_MODE")
|
||||
add_sp_renderer_project(${JK2SPVanillaRenderer} "JK2 SP Vanilla Renderer" ${JK2SPEngine} ${JK2InstallDir} ${JK2SPClientComponent})
|
||||
endif(BuildJK2SPRdVanilla)
|
||||
|
||||
endif(BuildSPRdVanilla OR BuildJK2SPRdVanilla)
|
2345
Projects/Android/jni/OpenJK/code/rd-gles/G2_API.cpp
Normal file
2345
Projects/Android/jni/OpenJK/code/rd-gles/G2_API.cpp
Normal file
File diff suppressed because it is too large
Load diff
265
Projects/Android/jni/OpenJK/code/rd-gles/G2_bolts.cpp
Normal file
265
Projects/Android/jni/OpenJK/code/rd-gles/G2_bolts.cpp
Normal file
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#ifndef __Q_SHARED_H
|
||||
#include "../qcommon/q_shared.h"
|
||||
#endif
|
||||
|
||||
#if !defined(TR_LOCAL_H)
|
||||
#include "tr_local.h"
|
||||
#endif
|
||||
|
||||
#if !defined(G2_H_INC)
|
||||
#include "../ghoul2/G2.h"
|
||||
#endif
|
||||
|
||||
#define G2_MODEL_OK(g) ((g)&&(g)->mValid&&(g)->aHeader&&(g)->currentModel&&(g)->animModel)
|
||||
|
||||
//=====================================================================================================================
|
||||
// Bolt List handling routines - so entities can attach themselves to any part of the model in question
|
||||
|
||||
// Given a bone number, see if that bone is already in our bone list
|
||||
int G2_Find_Bolt_Bone_Num(boltInfo_v &bltlist, const int boneNum)
|
||||
{
|
||||
// look through entire list
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
if (bltlist[i].boneNumber == boneNum)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Given a bone number, see if that surface is already in our surfacelist list
|
||||
int G2_Find_Bolt_Surface_Num(boltInfo_v &bltlist, const int surfaceNum, const int flags)
|
||||
{
|
||||
// look through entire list
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
if ((bltlist[i].surfaceNumber == surfaceNum) && ((bltlist[i].surfaceType & flags) == flags))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find it
|
||||
return -1;
|
||||
}
|
||||
|
||||
//=========================================================================================
|
||||
//// Public Bolt Routines
|
||||
int G2_Add_Bolt_Surf_Num(CGhoul2Info *ghlInfo, boltInfo_v &bltlist, surfaceInfo_v &slist, const int surfNum)
|
||||
{
|
||||
assert(ghlInfo&&ghlInfo->mValid);
|
||||
boltInfo_t tempBolt;
|
||||
|
||||
assert(surfNum>=0&&surfNum<(int)slist.size());
|
||||
// ensure surface num is valid
|
||||
if (surfNum >= (int)slist.size())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// look through entire list - see if it's already there first
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// already there??
|
||||
if (bltlist[i].surfaceNumber == surfNum)
|
||||
{
|
||||
// increment the usage count
|
||||
bltlist[i].boltUsed++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// we have a surface
|
||||
// look through entire list - see if it's already there first
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this surface entry has info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1 && bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
// if we found an entry that had a -1 for the bone / surface number, then we hit a surface / bone slot that was empty
|
||||
bltlist[i].surfaceNumber = surfNum;
|
||||
bltlist[i].surfaceType = G2SURFACEFLAG_GENERATED;
|
||||
bltlist[i].boltUsed = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find an existing surface of that name, or an empty slot. Lets add an entry
|
||||
tempBolt.surfaceNumber = surfNum;
|
||||
tempBolt.surfaceType = G2SURFACEFLAG_GENERATED;
|
||||
tempBolt.boneNumber = -1;
|
||||
tempBolt.boltUsed = 1;
|
||||
bltlist.push_back(tempBolt);
|
||||
return bltlist.size()-1;
|
||||
|
||||
}
|
||||
|
||||
void G2_Bolt_Not_Found(const char *boneName,const char *modName);
|
||||
int G2_Add_Bolt(CGhoul2Info *ghlInfo, boltInfo_v &bltlist, surfaceInfo_v &slist, const char *boneName)
|
||||
{
|
||||
assert(ghlInfo&&ghlInfo->mValid);
|
||||
int surfNum = -1;
|
||||
mdxaSkel_t *skel;
|
||||
mdxaSkelOffsets_t *offsets;
|
||||
boltInfo_t tempBolt;
|
||||
uint32_t flags;
|
||||
|
||||
assert(G2_MODEL_OK(ghlInfo));
|
||||
|
||||
// first up, we'll search for that which this bolt names in all the surfaces
|
||||
surfNum = G2_IsSurfaceLegal(ghlInfo->currentModel, boneName, &flags);
|
||||
|
||||
// did we find it as a surface?
|
||||
if (surfNum != -1)
|
||||
{
|
||||
// look through entire list - see if it's already there first
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// already there??
|
||||
if (bltlist[i].surfaceNumber == surfNum)
|
||||
{
|
||||
// increment the usage count
|
||||
bltlist[i].boltUsed++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// look through entire list - see if we can re-use one
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this surface entry has info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1 && bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
// if we found an entry that had a -1 for the bone / surface number, then we hit a surface / bone slot that was empty
|
||||
bltlist[i].surfaceNumber = surfNum;
|
||||
bltlist[i].boltUsed = 1;
|
||||
bltlist[i].surfaceType = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find an existing surface of that name, or an empty slot. Lets add an entry
|
||||
tempBolt.surfaceNumber = surfNum;
|
||||
tempBolt.boneNumber = -1;
|
||||
tempBolt.boltUsed = 1;
|
||||
tempBolt.surfaceType = 0;
|
||||
bltlist.push_back(tempBolt);
|
||||
return bltlist.size()-1;
|
||||
}
|
||||
|
||||
// no, check to see if it's a bone then
|
||||
|
||||
offsets = (mdxaSkelOffsets_t *)((byte *)ghlInfo->aHeader + sizeof(mdxaHeader_t));
|
||||
|
||||
int x;
|
||||
// walk the entire list of bones in the gla file for this model and see if any match the name of the bone we want to find
|
||||
for (x=0; x< ghlInfo->aHeader->numBones; x++)
|
||||
{
|
||||
skel = (mdxaSkel_t *)((byte *)ghlInfo->aHeader + sizeof(mdxaHeader_t) + offsets->offsets[x]);
|
||||
// if name is the same, we found it
|
||||
if (!Q_stricmp(skel->name, boneName))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check to see we did actually make a match with a bone in the model
|
||||
if (x == ghlInfo->aHeader->numBones)
|
||||
{
|
||||
// didn't find it? Error
|
||||
//assert(0&&x == mod_a->mdxa->numBones);
|
||||
#if _DEBUG
|
||||
G2_Bolt_Not_Found(boneName,ghlInfo->mFileName);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
// look through entire list - see if it's already there first
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// already there??
|
||||
if (bltlist[i].boneNumber == x)
|
||||
{
|
||||
// increment the usage count
|
||||
bltlist[i].boltUsed++;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// look through entire list - see if we can re-use it
|
||||
for(size_t i=0; i<bltlist.size(); i++)
|
||||
{
|
||||
// if this bone entry has info in it, bounce over it
|
||||
if (bltlist[i].boneNumber == -1 && bltlist[i].surfaceNumber == -1)
|
||||
{
|
||||
// if we found an entry that had a -1 for the bonenumber, then we hit a bone slot that was empty
|
||||
bltlist[i].boneNumber = x;
|
||||
bltlist[i].boltUsed = 1;
|
||||
bltlist[i].surfaceType = 0;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// ok, we didn't find an existing bone of that name, or an empty slot. Lets add an entry
|
||||
tempBolt.boneNumber = x;
|
||||
tempBolt.surfaceNumber = -1;
|
||||
tempBolt.boltUsed = 1;
|
||||
tempBolt.surfaceType = 0;
|
||||
bltlist.push_back(tempBolt);
|
||||
return bltlist.size()-1;
|
||||
|
||||
}
|
||||
|
||||
// Given a model handle, and a bone name, we want to remove this bone from the bone override list
|
||||
qboolean G2_Remove_Bolt (boltInfo_v &bltlist, int index)
|
||||
{
|
||||
assert(index>=0&&index<(int)bltlist.size());
|
||||
// did we find it?
|
||||
if (index != -1)
|
||||
{
|
||||
bltlist[index].boltUsed--;
|
||||
if (!bltlist[index].boltUsed)
|
||||
{
|
||||
// set this bone to not used
|
||||
bltlist[index].boneNumber = -1;
|
||||
bltlist[index].surfaceNumber = -1;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// set the bolt list to all unused so the bone transformation routine ignores it.
|
||||
void G2_Init_Bolt_List(boltInfo_v &bltlist)
|
||||
{
|
||||
bltlist.clear();
|
||||
}
|
||||
|
4784
Projects/Android/jni/OpenJK/code/rd-gles/G2_bones.cpp
Normal file
4784
Projects/Android/jni/OpenJK/code/rd-gles/G2_bones.cpp
Normal file
File diff suppressed because it is too large
Load diff
1981
Projects/Android/jni/OpenJK/code/rd-gles/G2_misc.cpp
Normal file
1981
Projects/Android/jni/OpenJK/code/rd-gles/G2_misc.cpp
Normal file
File diff suppressed because it is too large
Load diff
443
Projects/Android/jni/OpenJK/code/rd-gles/G2_surfaces.cpp
Normal file
443
Projects/Android/jni/OpenJK/code/rd-gles/G2_surfaces.cpp
Normal file
|
@ -0,0 +1,443 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#ifndef __Q_SHARED_H
|
||||
#include "../qcommon/q_shared.h"
|
||||
#endif
|
||||
|
||||
#if !defined(TR_LOCAL_H)
|
||||
#include "tr_local.h"
|
||||
#endif
|
||||
|
||||
#if !defined(G2_H_INC)
|
||||
#include "../ghoul2/G2.h"
|
||||
#endif
|
||||
|
||||
#define G2_MODEL_OK(g) ((g)&&(g)->mValid&&(g)->aHeader&&(g)->currentModel&&(g)->animModel)
|
||||
|
||||
class CQuickOverride
|
||||
{
|
||||
int mOverride[512];
|
||||
int mAt[512];
|
||||
int mCurrentTouch;
|
||||
public:
|
||||
CQuickOverride()
|
||||
{
|
||||
mCurrentTouch=1;
|
||||
int i;
|
||||
for (i=0;i<512;i++)
|
||||
{
|
||||
mOverride[i]=0;
|
||||
}
|
||||
}
|
||||
void Invalidate()
|
||||
{
|
||||
mCurrentTouch++;
|
||||
}
|
||||
void Set(int index,int pos)
|
||||
{
|
||||
if (index==10000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(index>=0&&index<512);
|
||||
mOverride[index]=mCurrentTouch;
|
||||
mAt[index]=pos;
|
||||
}
|
||||
int Test(int index)
|
||||
{
|
||||
assert(index>=0&&index<512);
|
||||
if (mOverride[index]!=mCurrentTouch)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mAt[index];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static CQuickOverride QuickOverride;
|
||||
|
||||
|
||||
// find a particular surface in the surface override list
|
||||
const surfaceInfo_t *G2_FindOverrideSurface(int surfaceNum,const surfaceInfo_v &surfaceList)
|
||||
{
|
||||
|
||||
if (surfaceNum<0)
|
||||
{
|
||||
// starting a new lookup
|
||||
QuickOverride.Invalidate();
|
||||
for(size_t i=0; i<surfaceList.size(); i++)
|
||||
{
|
||||
if (surfaceList[i].surface>=0)
|
||||
{
|
||||
QuickOverride.Set(surfaceList[i].surface,i);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
int idx=QuickOverride.Test(surfaceNum);
|
||||
if (idx<0)
|
||||
{
|
||||
if (surfaceNum==10000)
|
||||
{
|
||||
for(size_t i=0; i<surfaceList.size(); i++)
|
||||
{
|
||||
if (surfaceList[i].surface == surfaceNum)
|
||||
{
|
||||
return &surfaceList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#if _DEBUG
|
||||
// look through entire list
|
||||
size_t i;
|
||||
for(i=0; i<surfaceList.size(); i++)
|
||||
{
|
||||
if (surfaceList[i].surface == surfaceNum)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// didn't find it.
|
||||
assert(i==surfaceList.size()); // our quickoverride is not working right
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
assert(idx>=0&&idx<(int)surfaceList.size());
|
||||
assert(surfaceList[idx].surface == surfaceNum);
|
||||
return &surfaceList[idx];
|
||||
}
|
||||
|
||||
|
||||
// given a surface name, lets see if it's legal in the model
|
||||
int G2_IsSurfaceLegal(const model_s *mod_m, const char *surfaceName, uint32_t *flags)
|
||||
{
|
||||
assert(mod_m);
|
||||
assert(mod_m->mdxm);
|
||||
// damn include file dependancies
|
||||
mdxmSurfHierarchy_t *surf;
|
||||
surf = (mdxmSurfHierarchy_t *) ( (byte *)mod_m->mdxm + mod_m->mdxm->ofsSurfHierarchy );
|
||||
|
||||
for ( int i = 0 ; i < mod_m->mdxm->numSurfaces ; i++)
|
||||
{
|
||||
if (!Q_stricmp(surfaceName, surf->name))
|
||||
{
|
||||
*flags = surf->flags;
|
||||
return i;
|
||||
}
|
||||
// find the next surface
|
||||
surf = (mdxmSurfHierarchy_t *)( (byte *)surf + (intptr_t)( &((mdxmSurfHierarchy_t *)0)->childIndexes[ surf->numChildren ] ));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************
|
||||
* G2_FindSurface
|
||||
* find a surface in a ghoul2 surface override list based on it's name
|
||||
*
|
||||
* Input
|
||||
* filename of model, surface list of model instance, name of surface, int to be filled in
|
||||
* with the index of this surface (defaults to NULL)
|
||||
*
|
||||
* Output
|
||||
* pointer to surface if successful, false otherwise
|
||||
*
|
||||
************************************************************************************************/
|
||||
const mdxmSurface_t *G2_FindSurface(CGhoul2Info *ghlInfo, surfaceInfo_v &slist, const char *surfaceName,
|
||||
int *surfIndex/*NULL*/)
|
||||
{
|
||||
int i = 0;
|
||||
// find the model we want
|
||||
assert(G2_MODEL_OK(ghlInfo));
|
||||
|
||||
const mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)ghlInfo->currentModel->mdxm + sizeof(mdxmHeader_t));
|
||||
|
||||
// first find if we already have this surface in the list
|
||||
for (i = slist.size() - 1; i >= 0; i--)
|
||||
{
|
||||
if ((slist[i].surface != 10000) && (slist[i].surface != -1))
|
||||
{
|
||||
const mdxmSurface_t *surf = (mdxmSurface_t *)G2_FindSurface(ghlInfo->currentModel, slist[i].surface, 0);
|
||||
// back track and get the surfinfo struct for this surface
|
||||
const mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surf->thisSurfaceIndex]);
|
||||
|
||||
// are these the droids we're looking for?
|
||||
if (!Q_stricmp (surfInfo->name, surfaceName))
|
||||
{
|
||||
// yup
|
||||
if (surfIndex)
|
||||
{
|
||||
*surfIndex = i;
|
||||
}
|
||||
return surf;
|
||||
}
|
||||
}
|
||||
}
|
||||
// didn't find it
|
||||
if (surfIndex)
|
||||
{
|
||||
*surfIndex = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set a named surface offFlags - if it doesn't find a surface with this name in the list then it will add one.
|
||||
qboolean G2_SetSurfaceOnOff (CGhoul2Info *ghlInfo, const char *surfaceName, const int offFlags)
|
||||
{
|
||||
int surfIndex = -1;
|
||||
surfaceInfo_t temp_slist_entry;
|
||||
|
||||
// find the model we want
|
||||
// first find if we already have this surface in the list
|
||||
const mdxmSurface_t *surf = G2_FindSurface(ghlInfo, ghlInfo->mSlist, surfaceName, &surfIndex);
|
||||
if (surf)
|
||||
{
|
||||
// set descendants value
|
||||
|
||||
// slist[surfIndex].offFlags = offFlags;
|
||||
// seems to me that we shouldn't overwrite the other flags.
|
||||
// the only bit we really care about in the incoming flags is the off bit
|
||||
ghlInfo->mSlist[surfIndex].offFlags &= ~(G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
ghlInfo->mSlist[surfIndex].offFlags |= offFlags & (G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
return qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ok, not in the list already - in that case, lets verify this surface exists in the model mesh
|
||||
uint32_t flags;
|
||||
int surfaceNum = G2_IsSurfaceLegal(ghlInfo->currentModel, surfaceName, &flags);
|
||||
if (surfaceNum != -1)
|
||||
{
|
||||
uint32_t newflags = flags;
|
||||
// the only bit we really care about in the incoming flags is the off bit
|
||||
newflags &= ~(G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
newflags |= offFlags & (G2SURFACEFLAG_OFF | G2SURFACEFLAG_NODESCENDANTS);
|
||||
|
||||
if (newflags != flags)
|
||||
{ // insert here then because it changed, no need to add an override otherwise
|
||||
temp_slist_entry.offFlags = newflags;
|
||||
temp_slist_entry.surface = surfaceNum;
|
||||
|
||||
ghlInfo->mSlist.push_back(temp_slist_entry);
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void G2_FindRecursiveSurface(const model_t *currentModel, int surfaceNum, surfaceInfo_v &rootList, int *activeSurfaces)
|
||||
{
|
||||
assert(currentModel);
|
||||
assert(currentModel->mdxm);
|
||||
int i;
|
||||
const mdxmSurface_t *surface = (mdxmSurface_t *)G2_FindSurface(currentModel, surfaceNum, 0);
|
||||
const mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)currentModel->mdxm + sizeof(mdxmHeader_t));
|
||||
const mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surface->thisSurfaceIndex]);
|
||||
|
||||
// see if we have an override surface in the surface list
|
||||
const surfaceInfo_t *surfOverride = G2_FindOverrideSurface(surfaceNum, rootList);
|
||||
|
||||
// really, we should use the default flags for this surface unless it's been overriden
|
||||
int offFlags = surfInfo->flags;
|
||||
|
||||
// set the off flags if we have some
|
||||
if (surfOverride)
|
||||
{
|
||||
offFlags = surfOverride->offFlags;
|
||||
}
|
||||
|
||||
// if this surface is not off, indicate as such in the active surface list
|
||||
if (!(offFlags & G2SURFACEFLAG_OFF))
|
||||
{
|
||||
activeSurfaces[surfaceNum] = 1;
|
||||
}
|
||||
else
|
||||
// if we are turning off all descendants, then stop this recursion now
|
||||
if (offFlags & G2SURFACEFLAG_NODESCENDANTS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// now recursively call for the children
|
||||
for (i=0; i< surfInfo->numChildren; i++)
|
||||
{
|
||||
surfaceNum = surfInfo->childIndexes[i];
|
||||
G2_FindRecursiveSurface(currentModel, surfaceNum, rootList, activeSurfaces);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
qboolean G2_SetRootSurface( CGhoul2Info_v &ghoul2, const int modelIndex, const char *surfaceName)
|
||||
{
|
||||
int surf;
|
||||
uint32_t flags;
|
||||
assert(modelIndex>=0&&modelIndex<ghoul2.size());
|
||||
assert(ghoul2[modelIndex].currentModel);
|
||||
assert(ghoul2[modelIndex].currentModel->mdxm);
|
||||
// first find if we already have this surface in the list
|
||||
surf = G2_IsSurfaceLegal(ghoul2[modelIndex].currentModel, surfaceName, &flags);
|
||||
if (surf != -1)
|
||||
{
|
||||
ghoul2[modelIndex].mSurfaceRoot = surf;
|
||||
return qtrue;
|
||||
}
|
||||
assert(0);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
extern int G2_DecideTraceLod(CGhoul2Info &ghoul2, int useLod);
|
||||
int G2_AddSurface(CGhoul2Info *ghoul2, int surfaceNumber, int polyNumber, float BarycentricI, float BarycentricJ, int lod )
|
||||
{
|
||||
lod = G2_DecideTraceLod(*ghoul2, lod);
|
||||
|
||||
// first up, see if we have a free one already set up - look only from the end of the constant surfaces onwards
|
||||
size_t i;
|
||||
for (i=0; i<ghoul2->mSlist.size(); i++)
|
||||
{
|
||||
// is the surface count -1? That would indicate it's free
|
||||
if (ghoul2->mSlist[i].surface == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i==ghoul2->mSlist.size())
|
||||
{
|
||||
ghoul2->mSlist.push_back(surfaceInfo_t());
|
||||
}
|
||||
ghoul2->mSlist[i].offFlags = G2SURFACEFLAG_GENERATED;
|
||||
ghoul2->mSlist[i].surface = 10000; // no model will ever have 10000 surfaces
|
||||
ghoul2->mSlist[i].genBarycentricI = BarycentricI;
|
||||
ghoul2->mSlist[i].genBarycentricJ = BarycentricJ;
|
||||
ghoul2->mSlist[i].genPolySurfaceIndex = ((polyNumber & 0xffff) << 16) | (surfaceNumber & 0xffff);
|
||||
ghoul2->mSlist[i].genLod = lod;
|
||||
return i;
|
||||
}
|
||||
|
||||
qboolean G2_RemoveSurface(surfaceInfo_v &slist, const int index)
|
||||
{
|
||||
if (index != -1)
|
||||
{
|
||||
slist[index].surface = -1;
|
||||
return qtrue;
|
||||
}
|
||||
assert(0);
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
int G2_GetParentSurface(CGhoul2Info *ghlInfo, const int index)
|
||||
{
|
||||
assert(ghlInfo->currentModel);
|
||||
assert(ghlInfo->currentModel->mdxm);
|
||||
const mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)ghlInfo->currentModel->mdxm + sizeof(mdxmHeader_t));
|
||||
|
||||
// walk each surface and see if this index is listed in it's children
|
||||
const mdxmSurface_t *surf = (mdxmSurface_t *)G2_FindSurface(ghlInfo->currentModel, index, 0);
|
||||
const mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surf->thisSurfaceIndex]);
|
||||
|
||||
return surfInfo->parentIndex;
|
||||
|
||||
}
|
||||
|
||||
int G2_GetSurfaceIndex(CGhoul2Info *ghlInfo, const char *surfaceName)
|
||||
{
|
||||
uint32_t flags;
|
||||
assert(ghlInfo->currentModel);
|
||||
return G2_IsSurfaceLegal(ghlInfo->currentModel, surfaceName, &flags);
|
||||
}
|
||||
|
||||
int G2_IsSurfaceRendered(CGhoul2Info *ghlInfo, const char *surfaceName, surfaceInfo_v &slist)
|
||||
{
|
||||
uint32_t flags = 0u;//, surfFlags = 0;
|
||||
int surfIndex = 0;
|
||||
assert(ghlInfo->currentModel);
|
||||
assert(ghlInfo->currentModel->mdxm);
|
||||
if (!ghlInfo->currentModel->mdxm)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now travel up the skeleton to see if any of it's ancestors have a 'no descendants' turned on
|
||||
|
||||
// find the original surface in the surface list
|
||||
int surfNum = G2_IsSurfaceLegal(ghlInfo->currentModel, surfaceName, &flags);
|
||||
if ( surfNum != -1 )
|
||||
{//must be legal
|
||||
const mdxmHierarchyOffsets_t *surfIndexes = (mdxmHierarchyOffsets_t *)((byte *)ghlInfo->currentModel->mdxm + sizeof(mdxmHeader_t));
|
||||
const mdxmSurfHierarchy_t *surfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surfNum]);
|
||||
surfNum = surfInfo->parentIndex;
|
||||
// walk the surface hierarchy up until we hit the root
|
||||
while (surfNum != -1)
|
||||
{
|
||||
const mdxmSurface_t *parentSurf;
|
||||
uint32_t parentFlags = 0u;
|
||||
const mdxmSurfHierarchy_t *parentSurfInfo;
|
||||
|
||||
parentSurfInfo = (mdxmSurfHierarchy_t *)((byte *)surfIndexes + surfIndexes->offsets[surfNum]);
|
||||
|
||||
// find the original surface in the surface list
|
||||
//G2 was bug, above comment was accurate, but we don't want the original flags, we want the parent flags
|
||||
G2_IsSurfaceLegal(ghlInfo->currentModel, parentSurfInfo->name, &parentFlags);
|
||||
|
||||
// now see if we already have overriden this surface in the slist
|
||||
parentSurf = G2_FindSurface(ghlInfo, slist, parentSurfInfo->name, &surfIndex);
|
||||
if (parentSurf)
|
||||
{
|
||||
// set descendants value
|
||||
parentFlags = slist[surfIndex].offFlags;
|
||||
}
|
||||
// now we have the parent flags, lets see if any have the 'no descendants' flag set
|
||||
if (parentFlags & G2SURFACEFLAG_NODESCENDANTS)
|
||||
{
|
||||
flags |= G2SURFACEFLAG_OFF;
|
||||
break;
|
||||
}
|
||||
// set up scan of next parent
|
||||
surfNum = parentSurfInfo->parentIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ( flags == 0 )
|
||||
{//it's not being overridden by a parent
|
||||
// now see if we already have overriden this surface in the slist
|
||||
const mdxmSurface_t *surf = G2_FindSurface(ghlInfo, slist, surfaceName, &surfIndex);
|
||||
if (surf)
|
||||
{
|
||||
// set descendants value
|
||||
flags = slist[surfIndex].offFlags;
|
||||
}
|
||||
// ok, at this point in flags we have what this surface is set to, and the index of the surface itself
|
||||
}
|
||||
return flags;
|
||||
|
||||
}
|
3034
Projects/Android/jni/OpenJK/code/rd-gles/glext.h
Normal file
3034
Projects/Android/jni/OpenJK/code/rd-gles/glext.h
Normal file
File diff suppressed because it is too large
Load diff
794
Projects/Android/jni/OpenJK/code/rd-gles/qgl.h
Normal file
794
Projects/Android/jni/OpenJK/code/rd-gles/qgl.h
Normal file
|
@ -0,0 +1,794 @@
|
|||
/*
|
||||
** QGL.H
|
||||
*/
|
||||
|
||||
#ifndef __QGL_H__
|
||||
#define __QGL_H__
|
||||
|
||||
#if defined( __LINT__ )
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
#elif defined( _WIN32 )
|
||||
|
||||
#pragma warning (disable: 4201)
|
||||
#pragma warning (disable: 4214)
|
||||
#pragma warning (disable: 4514)
|
||||
#pragma warning (disable: 4032)
|
||||
#pragma warning (disable: 4201)
|
||||
#pragma warning (disable: 4214)
|
||||
#include <windows.h>
|
||||
#include <gl/gl.h>
|
||||
|
||||
#elif defined( __APPLE__ ) && defined( __MACH__ )
|
||||
|
||||
#include <MesaGL/gl.h>
|
||||
|
||||
#elif defined( __linux__ )
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
#include <GLES/gl.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
//#include <GL/glxew.h>
|
||||
//#include <GL/fxmesa.h> //LAvaPort
|
||||
#else
|
||||
|
||||
#include <gl.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef WINAPI
|
||||
#define WINAPI
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
#define GLdouble GLfloat
|
||||
extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
||||
extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
|
||||
extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
||||
|
||||
extern void ( APIENTRY * qglPointParameterfEXT)( GLenum, GLfloat);
|
||||
extern void ( APIENTRY * qglPointParameterfvEXT)( GLenum, GLfloat const *);
|
||||
|
||||
extern void (* qglLockArraysEXT) (GLint first, GLsizei count);
|
||||
extern void (* qglUnlockArraysEXT) (void);
|
||||
|
||||
extern void myglClear(GLbitfield mask);
|
||||
extern void myglTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void myglDrawBuffer(GLenum mode);
|
||||
extern void myglViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
extern void myglScissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
|
||||
#else
|
||||
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
** multitexture extension definitions
|
||||
*/
|
||||
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
|
||||
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
|
||||
#define GL_MAX_ACTIVE_TEXTURES_ARB 0x84E2
|
||||
|
||||
#define GL_TEXTURE0_ARB 0x84C0
|
||||
#define GL_TEXTURE1_ARB 0x84C1
|
||||
#define GL_TEXTURE2_ARB 0x84C2
|
||||
#define GL_TEXTURE3_ARB 0x84C3
|
||||
|
||||
#define GL_TEXTURE_RECTANGLE_EXT 0x84F5
|
||||
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
|
||||
typedef void (APIENTRY * PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
|
||||
typedef void (APIENTRY * PFNGLACTIVETEXTUREARBPROC) (GLenum target);
|
||||
typedef void (APIENTRY * PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum target);
|
||||
|
||||
|
||||
// Steps to adding a new extension:
|
||||
// - Add the typedef and function pointer externs here.
|
||||
// - Define the function pointer in tr_init.cpp and possibly add a cvar to track your ext status.
|
||||
// - Load the extension in win_glimp.cpp.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Register Combiner extension definitions. - AReis
|
||||
/***********************************************************************************************************/
|
||||
// NOTE: These are obviously not all the regcom flags. I'm only including the ones I use (to reduce code clutter), so
|
||||
// if you need any of the other flags, just add them.
|
||||
#define GL_REGISTER_COMBINERS_NV 0x8522
|
||||
#define GL_COMBINER0_NV 0x8550
|
||||
#define GL_COMBINER1_NV 0x8551
|
||||
#define GL_COMBINER2_NV 0x8552
|
||||
#define GL_COMBINER3_NV 0x8553
|
||||
#define GL_COMBINER4_NV 0x8554
|
||||
#define GL_COMBINER5_NV 0x8555
|
||||
#define GL_COMBINER6_NV 0x8556
|
||||
#define GL_COMBINER7_NV 0x8557
|
||||
#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
|
||||
#define GL_VARIABLE_A_NV 0x8523
|
||||
#define GL_VARIABLE_B_NV 0x8524
|
||||
#define GL_VARIABLE_C_NV 0x8525
|
||||
#define GL_VARIABLE_D_NV 0x8526
|
||||
#define GL_VARIABLE_E_NV 0x8527
|
||||
#define GL_VARIABLE_F_NV 0x8528
|
||||
#define GL_VARIABLE_G_NV 0x8529
|
||||
#define GL_DISCARD_NV 0x8530
|
||||
#define GL_CONSTANT_COLOR0_NV 0x852A
|
||||
#define GL_CONSTANT_COLOR1_NV 0x852B
|
||||
#define GL_SPARE0_NV 0x852E
|
||||
#define GL_SPARE1_NV 0x852F
|
||||
#define GL_UNSIGNED_IDENTITY_NV 0x8536
|
||||
#define GL_UNSIGNED_INVERT_NV 0x8537
|
||||
#endif //HAVE_GLES
|
||||
|
||||
typedef void (APIENTRY *PFNGLCOMBINERPARAMETERFVNV) (GLenum pname,const GLfloat *params);
|
||||
typedef void (APIENTRY *PFNGLCOMBINERPARAMETERIVNV) (GLenum pname,const GLint *params);
|
||||
typedef void (APIENTRY *PFNGLCOMBINERPARAMETERFNV) (GLenum pname,GLfloat param);
|
||||
typedef void (APIENTRY *PFNGLCOMBINERPARAMETERINV) (GLenum pname,GLint param);
|
||||
typedef void (APIENTRY *PFNGLCOMBINERINPUTNV) (GLenum stage,GLenum portion,GLenum variable,GLenum input,GLenum mapping,
|
||||
GLenum componentUsage);
|
||||
typedef void (APIENTRY *PFNGLCOMBINEROUTPUTNV) (GLenum stage,GLenum portion,GLenum abOutput,GLenum cdOutput,GLenum sumOutput,
|
||||
GLenum scale, GLenum bias,GLboolean abDotProduct,GLboolean cdDotProduct,
|
||||
GLboolean muxSum);
|
||||
typedef void (APIENTRY *PFNGLFINALCOMBINERINPUTNV) (GLenum variable,GLenum input,GLenum mapping,GLenum componentUsage);
|
||||
|
||||
typedef void (APIENTRY *PFNGLGETCOMBINERINPUTPARAMETERFVNV) (GLenum stage,GLenum portion,GLenum variable,GLenum pname,GLfloat *params);
|
||||
typedef void (APIENTRY *PFNGLGETCOMBINERINPUTPARAMETERIVNV) (GLenum stage,GLenum portion,GLenum variable,GLenum pname,GLint *params);
|
||||
typedef void (APIENTRY *PFNGLGETCOMBINEROUTPUTPARAMETERFVNV) (GLenum stage,GLenum portion,GLenum pname,GLfloat *params);
|
||||
typedef void (APIENTRY *PFNGLGETCOMBINEROUTPUTPARAMETERIVNV) (GLenum stage,GLenum portion,GLenum pname,GLint *params);
|
||||
typedef void (APIENTRY *PFNGLGETFINALCOMBINERINPUTPARAMETERFVNV) (GLenum variable,GLenum pname,GLfloat *params);
|
||||
typedef void (APIENTRY *PFNGLGETFINALCOMBINERINPUTPARAMETERIVNV) (GLenum variable,GLenum pname,GLfloat *params);
|
||||
/***********************************************************************************************************/
|
||||
|
||||
// Declare Register Combiners function pointers.
|
||||
extern PFNGLCOMBINERPARAMETERFVNV qglCombinerParameterfvNV;
|
||||
extern PFNGLCOMBINERPARAMETERIVNV qglCombinerParameterivNV;
|
||||
extern PFNGLCOMBINERPARAMETERFNV qglCombinerParameterfNV;
|
||||
extern PFNGLCOMBINERPARAMETERINV qglCombinerParameteriNV;
|
||||
extern PFNGLCOMBINERINPUTNV qglCombinerInputNV;
|
||||
extern PFNGLCOMBINEROUTPUTNV qglCombinerOutputNV;
|
||||
extern PFNGLFINALCOMBINERINPUTNV qglFinalCombinerInputNV;
|
||||
extern PFNGLGETCOMBINERINPUTPARAMETERFVNV qglGetCombinerInputParameterfvNV;
|
||||
extern PFNGLGETCOMBINERINPUTPARAMETERIVNV qglGetCombinerInputParameterivNV;
|
||||
extern PFNGLGETCOMBINEROUTPUTPARAMETERFVNV qglGetCombinerOutputParameterfvNV;
|
||||
extern PFNGLGETCOMBINEROUTPUTPARAMETERIVNV qglGetCombinerOutputParameterivNV;
|
||||
extern PFNGLGETFINALCOMBINERINPUTPARAMETERFVNV qglGetFinalCombinerInputParameterfvNV;
|
||||
extern PFNGLGETFINALCOMBINERINPUTPARAMETERIVNV qglGetFinalCombinerInputParameterivNV;
|
||||
#ifndef HAVE_GLES
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Pixel Format extension definitions. - AReis
|
||||
/***********************************************************************************************************/
|
||||
#ifdef _WINDOWS
|
||||
#define WGL_COLOR_BITS_ARB 0x2014
|
||||
#define WGL_ALPHA_BITS_ARB 0x201B
|
||||
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
|
||||
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
||||
/***********************************************************************************************************/
|
||||
|
||||
// Declare Pixel Format function pointers.
|
||||
extern PFNWGLGETPIXELFORMATATTRIBIVARBPROC qwglGetPixelFormatAttribivARB;
|
||||
extern PFNWGLGETPIXELFORMATATTRIBFVARBPROC qwglGetPixelFormatAttribfvARB;
|
||||
extern PFNWGLCHOOSEPIXELFORMATARBPROC qwglChoosePixelFormatARB;
|
||||
|
||||
#endif
|
||||
#ifdef LINUX
|
||||
|
||||
typedef GLXFBConfig* ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
|
||||
typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
|
||||
typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
|
||||
typedef XVisualInfo* ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
|
||||
|
||||
|
||||
extern PFNGLXCHOOSEFBCONFIGPROC qglXChooseFBConfig;
|
||||
extern PFNGLXCREATENEWCONTEXTPROC qglXCreateNewContext;
|
||||
extern PFNGLXGETFBCONFIGATTRIBPROC qglXGetFBConfigAttrib;
|
||||
extern PFNGLXGETVISUALFROMFBCONFIGPROC qglXGetVisualFromFBConfig;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Pixel Buffer extension definitions. - AReis
|
||||
/***********************************************************************************************************/
|
||||
|
||||
#ifdef _WINDOWS
|
||||
DECLARE_HANDLE(HPBUFFERARB);
|
||||
|
||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
|
||||
#define WGL_PBUFFER_WIDTH_ARB 0x2034
|
||||
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
|
||||
#define WGL_RED_BITS_ARB 0x2015
|
||||
#define WGL_GREEN_BITS_ARB 0x2017
|
||||
#define WGL_BLUE_BITS_ARB 0x2019
|
||||
|
||||
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
|
||||
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
|
||||
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
|
||||
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
|
||||
/***********************************************************************************************************/
|
||||
|
||||
// Declare Pixel Buffer function pointers.
|
||||
extern PFNWGLCREATEPBUFFERARBPROC qwglCreatePbufferARB;
|
||||
extern PFNWGLGETPBUFFERDCARBPROC qwglGetPbufferDCARB;
|
||||
extern PFNWGLRELEASEPBUFFERDCARBPROC qwglReleasePbufferDCARB;
|
||||
extern PFNWGLDESTROYPBUFFERARBPROC qwglDestroyPbufferARB;
|
||||
extern PFNWGLQUERYPBUFFERARBPROC qwglQueryPbufferARB;
|
||||
#endif
|
||||
#ifdef _LINUX
|
||||
|
||||
typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
|
||||
typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
|
||||
|
||||
|
||||
extern PFNGLXCREATEPBUFFERPROC qglXCreatePbufferARB;
|
||||
extern PFNGLXDESTROYPBUFFERPROC qglXDestroyPbufferARB;
|
||||
|
||||
#endif
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Render-Texture extension definitions. - AReis
|
||||
/***********************************************************************************************************/
|
||||
#ifdef _WINDOWS
|
||||
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
|
||||
#define WGL_TEXTURE_FORMAT_ARB 0x2072
|
||||
#define WGL_TEXTURE_TARGET_ARB 0x2073
|
||||
#define WGL_TEXTURE_RGB_ARB 0x2075
|
||||
#define WGL_TEXTURE_RGBA_ARB 0x2076
|
||||
#define WGL_TEXTURE_2D_ARB 0x207A
|
||||
#define WGL_FRONT_LEFT_ARB 0x2083
|
||||
|
||||
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int * piAttribList);
|
||||
/***********************************************************************************************************/
|
||||
|
||||
// Declare Render-Texture function pointers.
|
||||
extern PFNWGLBINDTEXIMAGEARBPROC qwglBindTexImageARB;
|
||||
extern PFNWGLRELEASETEXIMAGEARBPROC qwglReleaseTexImageARB;
|
||||
extern PFNWGLSETPBUFFERATTRIBARBPROC qwglSetPbufferAttribARB;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Vertex and Fragment Program extension definitions. - AReis
|
||||
/***********************************************************************************************************/
|
||||
#ifndef GL_ARB_fragment_program
|
||||
#define GL_FRAGMENT_PROGRAM_ARB 0x8804
|
||||
#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
|
||||
#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
|
||||
#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
|
||||
#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
|
||||
#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
|
||||
#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
|
||||
#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
|
||||
#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
|
||||
#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
|
||||
#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
|
||||
#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
|
||||
#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
|
||||
#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
|
||||
#endif
|
||||
|
||||
// NOTE: These are obviously not all the vertex program flags (have you seen how many there actually are!). I'm
|
||||
// only including the ones I use (to reduce code clutter), so if you need any of the other flags, just add them.
|
||||
#define GL_VERTEX_PROGRAM_ARB 0x8620
|
||||
#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
|
||||
#endif //HAVE_GLES
|
||||
|
||||
typedef void (APIENTRY * PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
|
||||
typedef void (APIENTRY * PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
|
||||
typedef void (APIENTRY * PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
|
||||
typedef void (APIENTRY * PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
typedef void (APIENTRY * PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
|
||||
typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
|
||||
typedef void (APIENTRY * PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
|
||||
typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
|
||||
typedef void (APIENTRY * PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
|
||||
typedef void (APIENTRY * PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
|
||||
typedef void (APIENTRY * PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
|
||||
typedef GLboolean (APIENTRY * PFNGLISPROGRAMARBPROC) (GLuint program);
|
||||
/***********************************************************************************************************/
|
||||
|
||||
// Declare Vertex and Fragment Program function pointers.
|
||||
extern PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
|
||||
extern PFNGLBINDPROGRAMARBPROC qglBindProgramARB;
|
||||
extern PFNGLDELETEPROGRAMSARBPROC qglDeleteProgramsARB;
|
||||
extern PFNGLGENPROGRAMSARBPROC qglGenProgramsARB;
|
||||
extern PFNGLPROGRAMENVPARAMETER4DARBPROC qglProgramEnvParameter4dARB;
|
||||
extern PFNGLPROGRAMENVPARAMETER4DVARBPROC qglProgramEnvParameter4dvARB;
|
||||
extern PFNGLPROGRAMENVPARAMETER4FARBPROC qglProgramEnvParameter4fARB;
|
||||
extern PFNGLPROGRAMENVPARAMETER4FVARBPROC qglProgramEnvParameter4fvARB;
|
||||
extern PFNGLPROGRAMLOCALPARAMETER4DARBPROC qglProgramLocalParameter4dARB;
|
||||
extern PFNGLPROGRAMLOCALPARAMETER4DVARBPROC qglProgramLocalParameter4dvARB;
|
||||
extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC qglProgramLocalParameter4fARB;
|
||||
extern PFNGLPROGRAMLOCALPARAMETER4FVARBPROC qglProgramLocalParameter4fvARB;
|
||||
extern PFNGLGETPROGRAMENVPARAMETERDVARBPROC qglGetProgramEnvParameterdvARB;
|
||||
extern PFNGLGETPROGRAMENVPARAMETERFVARBPROC qglGetProgramEnvParameterfvARB;
|
||||
extern PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC qglGetProgramLocalParameterdvARB;
|
||||
extern PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC qglGetProgramLocalParameterfvARB;
|
||||
extern PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB;
|
||||
extern PFNGLGETPROGRAMSTRINGARBPROC qglGetProgramStringARB;
|
||||
extern PFNGLISPROGRAMARBPROC qglIsProgramARB;
|
||||
|
||||
extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
/*
|
||||
** extension constants
|
||||
*/
|
||||
|
||||
|
||||
// S3TC compression constants
|
||||
#define GL_RGB_S3TC 0x83A0
|
||||
#define GL_RGB4_S3TC 0x83A1
|
||||
|
||||
|
||||
// extensions will be function pointers on all platforms
|
||||
|
||||
extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
||||
extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
||||
|
||||
extern void ( APIENTRY * qglLockArraysEXT) (GLint, GLint);
|
||||
extern void ( APIENTRY * qglUnlockArraysEXT) (void);
|
||||
|
||||
extern void ( APIENTRY * qglPointParameterfEXT)( GLenum, GLfloat);
|
||||
extern void ( APIENTRY * qglPointParameterfvEXT)( GLenum, GLfloat *);
|
||||
|
||||
#endif //HAVE_GLES
|
||||
// Added 10/23/02 by Aurelio Reis.
|
||||
extern void ( APIENTRY * qglPointParameteriNV)( GLenum, GLint);
|
||||
extern void ( APIENTRY * qglPointParameterivNV)( GLenum, const GLint *);
|
||||
|
||||
//===========================================================================
|
||||
|
||||
// non-windows systems will just redefine qgl* to gl*
|
||||
#if (!defined( _WIN32 ) && !defined( __linux__ )) || defined(HAVE_GLES)
|
||||
|
||||
#include "qgl_linked.h"
|
||||
|
||||
#else
|
||||
|
||||
// windows systems use a function pointer for each call so we can load minidrivers
|
||||
|
||||
extern void ( APIENTRY * qglAccum )(GLenum op, GLfloat value);
|
||||
extern void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref);
|
||||
extern GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences);
|
||||
extern void ( APIENTRY * qglArrayElement )(GLint i);
|
||||
extern void ( APIENTRY * qglBegin )(GLenum mode);
|
||||
extern void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture);
|
||||
extern void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
|
||||
extern void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor);
|
||||
extern void ( APIENTRY * qglCallList )(GLuint list);
|
||||
extern void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists);
|
||||
extern void ( APIENTRY * qglClear )(GLbitfield mask);
|
||||
extern void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
extern void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
||||
extern void ( APIENTRY * qglClearDepth )(GLclampd depth);
|
||||
extern void ( APIENTRY * qglClearIndex )(GLfloat c);
|
||||
extern void ( APIENTRY * qglClearStencil )(GLint s);
|
||||
extern void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation);
|
||||
extern void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue);
|
||||
extern void ( APIENTRY * qglColor3bv )(const GLbyte *v);
|
||||
extern void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue);
|
||||
extern void ( APIENTRY * qglColor3dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue);
|
||||
extern void ( APIENTRY * qglColor3fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue);
|
||||
extern void ( APIENTRY * qglColor3iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue);
|
||||
extern void ( APIENTRY * qglColor3sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue);
|
||||
extern void ( APIENTRY * qglColor3ubv )(const GLubyte *v);
|
||||
extern void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue);
|
||||
extern void ( APIENTRY * qglColor3uiv )(const GLuint *v);
|
||||
extern void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue);
|
||||
extern void ( APIENTRY * qglColor3usv )(const GLushort *v);
|
||||
extern void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
|
||||
extern void ( APIENTRY * qglColor4bv )(const GLbyte *v);
|
||||
extern void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
|
||||
extern void ( APIENTRY * qglColor4dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
extern void ( APIENTRY * qglColor4fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha);
|
||||
extern void ( APIENTRY * qglColor4iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha);
|
||||
extern void ( APIENTRY * qglColor4sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
|
||||
extern void ( APIENTRY * qglColor4ubv )(const GLubyte *v);
|
||||
extern void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha);
|
||||
extern void ( APIENTRY * qglColor4uiv )(const GLuint *v);
|
||||
extern void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha);
|
||||
extern void ( APIENTRY * qglColor4usv )(const GLushort *v);
|
||||
extern void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
extern void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode);
|
||||
extern void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
|
||||
extern void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
|
||||
extern void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
extern void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
|
||||
extern void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
extern void ( APIENTRY * qglCullFace )(GLenum mode);
|
||||
extern void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range);
|
||||
extern void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures);
|
||||
extern void ( APIENTRY * qglDepthFunc )(GLenum func);
|
||||
extern void ( APIENTRY * qglDepthMask )(GLboolean flag);
|
||||
extern void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar);
|
||||
extern void ( APIENTRY * qglDisable )(GLenum cap);
|
||||
extern void ( APIENTRY * qglDisableClientState )(GLenum array);
|
||||
extern void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count);
|
||||
extern void ( APIENTRY * qglDrawBuffer )(GLenum mode);
|
||||
extern void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
extern void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglEdgeFlag )(GLboolean flag);
|
||||
extern void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer);
|
||||
extern void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag);
|
||||
extern void ( APIENTRY * qglEnable )(GLenum cap);
|
||||
extern void ( APIENTRY * qglEnableClientState )(GLenum array);
|
||||
extern void ( APIENTRY * qglEnd )(void);
|
||||
extern void ( APIENTRY * qglEndList )(void);
|
||||
extern void ( APIENTRY * qglEvalCoord1d )(GLdouble u);
|
||||
extern void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u);
|
||||
extern void ( APIENTRY * qglEvalCoord1f )(GLfloat u);
|
||||
extern void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u);
|
||||
extern void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v);
|
||||
extern void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u);
|
||||
extern void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v);
|
||||
extern void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u);
|
||||
extern void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2);
|
||||
extern void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
|
||||
extern void ( APIENTRY * qglEvalPoint1 )(GLint i);
|
||||
extern void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j);
|
||||
extern void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer);
|
||||
extern void ( APIENTRY * qglFinish )(void);
|
||||
extern void ( APIENTRY * qglFlush )(void);
|
||||
extern void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglFogi )(GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglFrontFace )(GLenum mode);
|
||||
extern void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
extern GLuint ( APIENTRY * qglGenLists )(GLsizei range);
|
||||
extern void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures);
|
||||
extern void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params);
|
||||
extern void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation);
|
||||
extern void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params);
|
||||
extern GLenum ( APIENTRY * qglGetError )(void);
|
||||
extern void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v);
|
||||
extern void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v);
|
||||
extern void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v);
|
||||
extern void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values);
|
||||
extern void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values);
|
||||
extern void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values);
|
||||
extern void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params);
|
||||
extern void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask);
|
||||
extern const GLubyte * ( APIENTRY * qglGetString )(GLenum name);
|
||||
extern void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params);
|
||||
extern void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params);
|
||||
extern void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params);
|
||||
extern void ( APIENTRY * qglHint )(GLenum target, GLenum mode);
|
||||
extern void ( APIENTRY * qglIndexMask )(GLuint mask);
|
||||
extern void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void ( APIENTRY * qglIndexd )(GLdouble c);
|
||||
extern void ( APIENTRY * qglIndexdv )(const GLdouble *c);
|
||||
extern void ( APIENTRY * qglIndexf )(GLfloat c);
|
||||
extern void ( APIENTRY * qglIndexfv )(const GLfloat *c);
|
||||
extern void ( APIENTRY * qglIndexi )(GLint c);
|
||||
extern void ( APIENTRY * qglIndexiv )(const GLint *c);
|
||||
extern void ( APIENTRY * qglIndexs )(GLshort c);
|
||||
extern void ( APIENTRY * qglIndexsv )(const GLshort *c);
|
||||
extern void ( APIENTRY * qglIndexub )(GLubyte c);
|
||||
extern void ( APIENTRY * qglIndexubv )(const GLubyte *c);
|
||||
extern void ( APIENTRY * qglInitNames )(void);
|
||||
extern void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer);
|
||||
extern GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap);
|
||||
extern GLboolean ( APIENTRY * qglIsList )(GLuint l);
|
||||
extern GLboolean ( APIENTRY * qglIsTexture )(GLuint texture);
|
||||
extern void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern);
|
||||
extern void ( APIENTRY * qglLineWidth )(GLfloat width);
|
||||
extern void ( APIENTRY * qglListBase )(GLuint base);
|
||||
extern void ( APIENTRY * qglLoadIdentity )(void);
|
||||
extern void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m);
|
||||
extern void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m);
|
||||
extern void ( APIENTRY * qglLoadName )(GLuint name);
|
||||
extern void ( APIENTRY * qglLogicOp )(GLenum opcode);
|
||||
extern void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
|
||||
extern void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
|
||||
extern void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
|
||||
extern void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
|
||||
extern void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2);
|
||||
extern void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2);
|
||||
extern void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
|
||||
extern void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
|
||||
extern void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglMatrixMode )(GLenum mode);
|
||||
extern void ( APIENTRY * qglMultMatrixd )(const GLdouble *m);
|
||||
extern void ( APIENTRY * qglMultMatrixf )(const GLfloat *m);
|
||||
extern void ( APIENTRY * qglNewList )(GLuint list, GLenum mode);
|
||||
extern void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz);
|
||||
extern void ( APIENTRY * qglNormal3bv )(const GLbyte *v);
|
||||
extern void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz);
|
||||
extern void ( APIENTRY * qglNormal3dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz);
|
||||
extern void ( APIENTRY * qglNormal3fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz);
|
||||
extern void ( APIENTRY * qglNormal3iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz);
|
||||
extern void ( APIENTRY * qglNormal3sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
extern void ( APIENTRY * qglPassThrough )(GLfloat token);
|
||||
extern void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values);
|
||||
extern void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values);
|
||||
extern void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values);
|
||||
extern void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor);
|
||||
extern void ( APIENTRY * qglPointSize )(GLfloat size);
|
||||
extern void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode);
|
||||
extern void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units);
|
||||
extern void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask);
|
||||
extern void ( APIENTRY * qglPopAttrib )(void);
|
||||
extern void ( APIENTRY * qglPopClientAttrib )(void);
|
||||
extern void ( APIENTRY * qglPopMatrix )(void);
|
||||
extern void ( APIENTRY * qglPopName )(void);
|
||||
extern void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities);
|
||||
extern void ( APIENTRY * qglPushAttrib )(GLbitfield mask);
|
||||
extern void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask);
|
||||
extern void ( APIENTRY * qglPushMatrix )(void);
|
||||
extern void ( APIENTRY * qglPushName )(GLuint name);
|
||||
extern void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y);
|
||||
extern void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y);
|
||||
extern void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y);
|
||||
extern void ( APIENTRY * qglRasterPos2iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y);
|
||||
extern void ( APIENTRY * qglRasterPos2sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z);
|
||||
extern void ( APIENTRY * qglRasterPos3iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z);
|
||||
extern void ( APIENTRY * qglRasterPos3sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
extern void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
extern void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w);
|
||||
extern void ( APIENTRY * qglRasterPos4iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w);
|
||||
extern void ( APIENTRY * qglRasterPos4sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglReadBuffer )(GLenum mode);
|
||||
extern void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
|
||||
extern void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2);
|
||||
extern void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
|
||||
extern void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2);
|
||||
extern void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2);
|
||||
extern void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2);
|
||||
extern void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
|
||||
extern void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2);
|
||||
extern GLint ( APIENTRY * qglRenderMode )(GLenum mode);
|
||||
extern void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
extern void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer);
|
||||
extern void ( APIENTRY * qglShadeModel )(GLenum mode);
|
||||
extern void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask);
|
||||
extern void ( APIENTRY * qglStencilMask )(GLuint mask);
|
||||
extern void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass);
|
||||
extern void ( APIENTRY * qglTexCoord1d )(GLdouble s);
|
||||
extern void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglTexCoord1f )(GLfloat s);
|
||||
extern void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglTexCoord1i )(GLint s);
|
||||
extern void ( APIENTRY * qglTexCoord1iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglTexCoord1s )(GLshort s);
|
||||
extern void ( APIENTRY * qglTexCoord1sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t);
|
||||
extern void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t);
|
||||
extern void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t);
|
||||
extern void ( APIENTRY * qglTexCoord2iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t);
|
||||
extern void ( APIENTRY * qglTexCoord2sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r);
|
||||
extern void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r);
|
||||
extern void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r);
|
||||
extern void ( APIENTRY * qglTexCoord3iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r);
|
||||
extern void ( APIENTRY * qglTexCoord3sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
|
||||
extern void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
||||
extern void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q);
|
||||
extern void ( APIENTRY * qglTexCoord4iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q);
|
||||
extern void ( APIENTRY * qglTexCoord4sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param);
|
||||
extern void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params);
|
||||
extern void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param);
|
||||
extern void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
|
||||
extern void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param);
|
||||
extern void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params);
|
||||
extern void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
extern void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y);
|
||||
extern void ( APIENTRY * qglVertex2dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y);
|
||||
extern void ( APIENTRY * qglVertex2fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglVertex2i )(GLint x, GLint y);
|
||||
extern void ( APIENTRY * qglVertex2iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y);
|
||||
extern void ( APIENTRY * qglVertex2sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z);
|
||||
extern void ( APIENTRY * qglVertex3dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z);
|
||||
extern void ( APIENTRY * qglVertex3fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z);
|
||||
extern void ( APIENTRY * qglVertex3iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z);
|
||||
extern void ( APIENTRY * qglVertex3sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
||||
extern void ( APIENTRY * qglVertex4dv )(const GLdouble *v);
|
||||
extern void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
extern void ( APIENTRY * qglVertex4fv )(const GLfloat *v);
|
||||
extern void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w);
|
||||
extern void ( APIENTRY * qglVertex4iv )(const GLint *v);
|
||||
extern void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w);
|
||||
extern void ( APIENTRY * qglVertex4sv )(const GLshort *v);
|
||||
extern void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
#if defined( _WIN32 )
|
||||
|
||||
extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT);
|
||||
extern HGLRC ( WINAPI * qwglCreateContext)(HDC);
|
||||
extern HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int);
|
||||
extern BOOL ( WINAPI * qwglDeleteContext)(HGLRC);
|
||||
extern HGLRC ( WINAPI * qwglGetCurrentContext)(VOID);
|
||||
extern HDC ( WINAPI * qwglGetCurrentDC)(VOID);
|
||||
extern PROC ( WINAPI * qwglGetProcAddress)(LPCSTR);
|
||||
extern BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC);
|
||||
extern BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC);
|
||||
extern BOOL ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD);
|
||||
|
||||
extern BOOL ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT,
|
||||
FLOAT, int, LPGLYPHMETRICSFLOAT);
|
||||
|
||||
extern BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT,
|
||||
LPLAYERPLANEDESCRIPTOR);
|
||||
extern int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int,
|
||||
CONST COLORREF *);
|
||||
extern int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int,
|
||||
COLORREF *);
|
||||
extern BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL);
|
||||
extern BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT);
|
||||
|
||||
extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval );
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#if defined( __linux__ )
|
||||
|
||||
//FX Mesa Functions
|
||||
//extern fxMesaContext (*qfxMesaCreateContext)(GLuint win, GrScreenResolution_t, GrScreenRefresh_t, const GLint attribList[]);
|
||||
//extern fxMesaContext (*qfxMesaCreateBestContext)(GLuint win, GLint width, GLint height, const GLint attribList[]);
|
||||
//extern void (*qfxMesaDestroyContext)(fxMesaContext ctx);
|
||||
//extern void (*qfxMesaMakeCurrent)(fxMesaContext ctx);
|
||||
//extern fxMesaContext (*qfxMesaGetCurrentContext)(void);
|
||||
//extern void (*qfxMesaSwapBuffers)(void);
|
||||
|
||||
//GLX Functions
|
||||
extern XVisualInfo * (*qglXChooseVisual)( Display *dpy, int screen, int *attribList );
|
||||
extern GLXContext (*qglXCreateContext)( Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct );
|
||||
extern void (*qglXDestroyContext)( Display *dpy, GLXContext ctx );
|
||||
extern Bool (*qglXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx);
|
||||
extern void (*qglXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, GLuint mask );
|
||||
extern void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
|
||||
extern Bool (*qglXSwapIntervalEXT) (int interval);
|
||||
|
||||
#endif //HAVE_GLES
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
#endif // _WIN32 && __linux__
|
2366
Projects/Android/jni/OpenJK/code/rd-gles/tr_WorldEffects.cpp
Normal file
2366
Projects/Android/jni/OpenJK/code/rd-gles/tr_WorldEffects.cpp
Normal file
File diff suppressed because it is too large
Load diff
65
Projects/Android/jni/OpenJK/code/rd-gles/tr_WorldEffects.h
Normal file
65
Projects/Android/jni/OpenJK/code/rd-gles/tr_WorldEffects.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// RAVEN SOFTWARE - STAR WARS: JK II
|
||||
// (c) 2002 Activision
|
||||
//
|
||||
// World Effects
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
#if !defined __TR_WORLDEFFECTS_H
|
||||
#define __TR_WORLDEFFECTS_H
|
||||
|
||||
#include "../qcommon/q_shared.h" // For Vec3_t
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Supported Commands
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
void R_AddWeatherZone(vec3_t mins, vec3_t maxs);
|
||||
|
||||
void R_InitWorldEffects(void);
|
||||
void R_ShutdownWorldEffects(void);
|
||||
void RB_RenderWorldEffects(void);
|
||||
|
||||
void R_WorldEffectCommand(const char *command);
|
||||
void R_WorldEffect_f(void);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Exported Functionality
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool R_GetWindVector(vec3_t windVector, vec3_t atpoint);
|
||||
bool R_GetWindSpeed(float &windSpeed, vec3_t atpoint);
|
||||
bool R_GetWindGusting(vec3_t atpoint);
|
||||
bool R_IsOutside(vec3_t pos);
|
||||
float R_IsOutsideCausingPain(vec3_t pos);
|
||||
float R_GetChanceOfSaberFizz();
|
||||
bool R_IsShaking(vec3_t pos);
|
||||
bool R_SetTempGlobalFogColor(vec3_t color);
|
||||
|
||||
bool R_IsRaining();
|
||||
bool R_IsPuffing();
|
||||
|
||||
|
||||
#endif // __TR_WORLDEFFECTS_H
|
194
Projects/Android/jni/OpenJK/code/rd-gles/tr_arb.cpp
Normal file
194
Projects/Android/jni/OpenJK/code/rd-gles/tr_arb.cpp
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_glow.c -- this file deals with the arb shaders for dynamic glow
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Vertex and Pixel Shader definitions. - AReis
|
||||
/***********************************************************************************************************/
|
||||
// This vertex shader basically passes through most values and calculates no lighting. The only
|
||||
// unusual thing it does is add the inputed texel offsets to all four texture units (this allows
|
||||
// nearest neighbor pixel peeking).
|
||||
const unsigned char g_strGlowVShaderARB[] =
|
||||
{
|
||||
"!!ARBvp1.0\
|
||||
\
|
||||
# Input.\n\
|
||||
ATTRIB iPos = vertex.position;\
|
||||
ATTRIB iColor = vertex.color;\
|
||||
ATTRIB iTex0 = vertex.texcoord[0];\
|
||||
ATTRIB iTex1 = vertex.texcoord[1];\
|
||||
ATTRIB iTex2 = vertex.texcoord[2];\
|
||||
ATTRIB iTex3 = vertex.texcoord[3];\
|
||||
\
|
||||
# Output.\n\
|
||||
OUTPUT oPos = result.position;\
|
||||
OUTPUT oColor = result.color;\
|
||||
OUTPUT oTex0 = result.texcoord[0];\
|
||||
OUTPUT oTex1 = result.texcoord[1];\
|
||||
OUTPUT oTex2 = result.texcoord[2];\
|
||||
OUTPUT oTex3 = result.texcoord[3];\
|
||||
\
|
||||
# Constants.\n\
|
||||
PARAM ModelViewProj[4]= { state.matrix.mvp };\
|
||||
PARAM TexelOffset0 = program.env[0];\
|
||||
PARAM TexelOffset1 = program.env[1];\
|
||||
PARAM TexelOffset2 = program.env[2];\
|
||||
PARAM TexelOffset3 = program.env[3];\
|
||||
\
|
||||
# Main.\n\
|
||||
DP4 oPos.x, ModelViewProj[0], iPos;\
|
||||
DP4 oPos.y, ModelViewProj[1], iPos;\
|
||||
DP4 oPos.z, ModelViewProj[2], iPos;\
|
||||
DP4 oPos.w, ModelViewProj[3], iPos;\
|
||||
MOV oColor, iColor;\
|
||||
# Notice the optimization of using one texture coord instead of all four.\n\
|
||||
ADD oTex0, iTex0, TexelOffset0;\
|
||||
ADD oTex1, iTex0, TexelOffset1;\
|
||||
ADD oTex2, iTex0, TexelOffset2;\
|
||||
ADD oTex3, iTex0, TexelOffset3;\
|
||||
\
|
||||
END"
|
||||
};
|
||||
|
||||
// This Pixel Shader loads four texture units and adds them all together (with a modifier
|
||||
// multiplied to each in the process). The final output is r0 = t0 + t1 + t2 + t3.
|
||||
const unsigned char g_strGlowPShaderARB[] =
|
||||
{
|
||||
"!!ARBfp1.0\
|
||||
\
|
||||
# Input.\n\
|
||||
ATTRIB iColor = fragment.color.primary;\
|
||||
\
|
||||
# Output.\n\
|
||||
OUTPUT oColor = result.color;\
|
||||
\
|
||||
# Constants.\n\
|
||||
PARAM Weight = program.env[0];\
|
||||
TEMP t0;\
|
||||
TEMP t1;\
|
||||
TEMP t2;\
|
||||
TEMP t3;\
|
||||
TEMP r0;\
|
||||
\
|
||||
# Main.\n\
|
||||
TEX t0, fragment.texcoord[0], texture[0], RECT;\
|
||||
TEX t1, fragment.texcoord[1], texture[1], RECT;\
|
||||
TEX t2, fragment.texcoord[2], texture[2], RECT;\
|
||||
TEX t3, fragment.texcoord[3], texture[3], RECT;\
|
||||
\
|
||||
MUL r0, t0, Weight;\
|
||||
MAD r0, t1, Weight, r0;\
|
||||
MAD r0, t2, Weight, r0;\
|
||||
MAD r0, t3, Weight, r0;\
|
||||
\
|
||||
MOV oColor, r0;\
|
||||
\
|
||||
END"
|
||||
};
|
||||
/***********************************************************************************************************/
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
|
||||
#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
|
||||
|
||||
void ARB_InitGlowShaders(void) {
|
||||
// Allocate and Load the global 'Glow' Vertex Program. - AReis
|
||||
if ( qglGenProgramsARB )
|
||||
{
|
||||
qglGenProgramsARB( 1, &tr.glowVShader );
|
||||
qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, tr.glowVShader );
|
||||
qglProgramStringARB( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, ( GLsizei ) strlen( ( char * ) g_strGlowVShaderARB ), g_strGlowVShaderARB );
|
||||
|
||||
// const GLubyte *strErr = qglGetString( GL_PROGRAM_ERROR_STRING_ARB );
|
||||
int iErrPos = 0;
|
||||
qglGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &iErrPos );
|
||||
assert( iErrPos == -1 );
|
||||
}
|
||||
|
||||
// NOTE: I make an assumption here. If you have (current) nvidia hardware, you obviously support register combiners instead of fragment
|
||||
// programs, so use those. The problem with this is that nv30 WILL support fragment shaders, breaking this logic. The good thing is that
|
||||
// if you always ask for regcoms before fragment shaders, you'll always just use regcoms (problem solved... for now). - AReis
|
||||
|
||||
// Load Pixel Shaders (either regcoms or fragprogs).
|
||||
if ( qglCombinerParameteriNV )
|
||||
{
|
||||
// The purpose of this regcom is to blend all the pixels together from the 4 texture units, but with their
|
||||
// texture coordinates offset by 1 (or more) texels, effectively letting us blend adjoining pixels. The weight is
|
||||
// used to either strengthen or weaken the pixel intensity. The more it diffuses (the higher the radius of the glow),
|
||||
// the higher the intensity should be for a noticable effect.
|
||||
// Regcom result is: ( tex1 * fBlurWeight ) + ( tex2 * fBlurWeight ) + ( tex2 * fBlurWeight ) + ( tex2 * fBlurWeight )
|
||||
|
||||
// VV guys, this is the pixel shader you would use instead :-)
|
||||
/*
|
||||
// c0 is the blur weight.
|
||||
ps 1.1
|
||||
tex t0
|
||||
tex t1
|
||||
tex t2
|
||||
tex t3
|
||||
|
||||
mul r0, c0, t0;
|
||||
madd r0, c0, t1, r0;
|
||||
madd r0, c0, t2, r0;
|
||||
madd r0, c0, t3, r0;
|
||||
*/
|
||||
tr.glowPShader = qglGenLists( 1 );
|
||||
qglNewList( tr.glowPShader, GL_COMPILE );
|
||||
qglCombinerParameteriNV( GL_NUM_GENERAL_COMBINERS_NV, 2 );
|
||||
|
||||
// spare0 = fBlend * tex0 + fBlend * tex1.
|
||||
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerInputNV( GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerOutputNV( GL_COMBINER0_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE0_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
|
||||
|
||||
// spare1 = fBlend * tex2 + fBlend * tex3.
|
||||
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_TEXTURE2_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_C_NV, GL_TEXTURE3_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerInputNV( GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_D_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglCombinerOutputNV( GL_COMBINER1_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SPARE1_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE );
|
||||
|
||||
// ( A * B ) + ( ( 1 - A ) * C ) + D = ( spare0 * 1 ) + ( ( 1 - spare0 ) * 0 ) + spare1 == spare0 + spare1.
|
||||
qglFinalCombinerInputNV( GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglFinalCombinerInputNV( GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB );
|
||||
qglFinalCombinerInputNV( GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglFinalCombinerInputNV( GL_VARIABLE_D_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB );
|
||||
qglEndList();
|
||||
}
|
||||
else if ( qglGenProgramsARB )
|
||||
{
|
||||
qglGenProgramsARB( 1, &tr.glowPShader );
|
||||
qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, tr.glowPShader );
|
||||
qglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, ( GLsizei ) strlen( ( char * ) g_strGlowPShaderARB ), g_strGlowPShaderARB );
|
||||
|
||||
// const GLubyte *strErr = qglGetString( GL_PROGRAM_ERROR_STRING_ARB );
|
||||
int iErrPos = 0;
|
||||
qglGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &iErrPos );
|
||||
assert( iErrPos == -1 );
|
||||
}
|
||||
}
|
||||
#endif
|
2065
Projects/Android/jni/OpenJK/code/rd-gles/tr_backend.cpp
Normal file
2065
Projects/Android/jni/OpenJK/code/rd-gles/tr_backend.cpp
Normal file
File diff suppressed because it is too large
Load diff
1469
Projects/Android/jni/OpenJK/code/rd-gles/tr_bsp.cpp
Normal file
1469
Projects/Android/jni/OpenJK/code/rd-gles/tr_bsp.cpp
Normal file
File diff suppressed because it is too large
Load diff
531
Projects/Android/jni/OpenJK/code/rd-gles/tr_cmds.cpp
Normal file
531
Projects/Android/jni/OpenJK/code/rd-gles/tr_cmds.cpp
Normal file
|
@ -0,0 +1,531 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_PerformanceCounters
|
||||
=====================
|
||||
*/
|
||||
void R_PerformanceCounters( void ) {
|
||||
if ( !r_speeds->integer ) {
|
||||
// clear the counters even if we aren't printing
|
||||
memset( &tr.pc, 0, sizeof( tr.pc ) );
|
||||
memset( &backEnd.pc, 0, sizeof( backEnd.pc ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if (r_speeds->integer == 1) {
|
||||
const float texSize = R_SumOfUsedImages( qfalse )/(8*1048576.0f)*(r_texturebits->integer?r_texturebits->integer:glConfig.colorBits);
|
||||
ri.Printf (PRINT_ALL, "%i/%i shdrs/srfs %i leafs %i vrts %i/%i tris %.2fMB tex %.2f dc\n",
|
||||
backEnd.pc.c_shaders, backEnd.pc.c_surfaces, tr.pc.c_leafs, backEnd.pc.c_vertexes,
|
||||
backEnd.pc.c_indexes/3, backEnd.pc.c_totalIndexes/3,
|
||||
texSize, backEnd.pc.c_overDraw / (float)(glConfig.vidWidth * glConfig.vidHeight) );
|
||||
} else if (r_speeds->integer == 2) {
|
||||
ri.Printf (PRINT_ALL, "(patch) %i sin %i sclip %i sout %i bin %i bclip %i bout\n",
|
||||
tr.pc.c_sphere_cull_patch_in, tr.pc.c_sphere_cull_patch_clip, tr.pc.c_sphere_cull_patch_out,
|
||||
tr.pc.c_box_cull_patch_in, tr.pc.c_box_cull_patch_clip, tr.pc.c_box_cull_patch_out );
|
||||
ri.Printf (PRINT_ALL, "(md3) %i sin %i sclip %i sout %i bin %i bclip %i bout\n",
|
||||
tr.pc.c_sphere_cull_md3_in, tr.pc.c_sphere_cull_md3_clip, tr.pc.c_sphere_cull_md3_out,
|
||||
tr.pc.c_box_cull_md3_in, tr.pc.c_box_cull_md3_clip, tr.pc.c_box_cull_md3_out );
|
||||
} else if (r_speeds->integer == 3) {
|
||||
ri.Printf (PRINT_ALL, "viewcluster: %i\n", tr.viewCluster );
|
||||
} else if (r_speeds->integer == 4) {
|
||||
if ( backEnd.pc.c_dlightVertexes ) {
|
||||
ri.Printf (PRINT_ALL, "dlight srf:%i culled:%i verts:%i tris:%i\n",
|
||||
tr.pc.c_dlightSurfaces, tr.pc.c_dlightSurfacesCulled,
|
||||
backEnd.pc.c_dlightVertexes, backEnd.pc.c_dlightIndexes / 3 );
|
||||
}
|
||||
}
|
||||
else if (r_speeds->integer == 5 )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "zFar: %.0f\n", tr.viewParms.zFar );
|
||||
}
|
||||
else if (r_speeds->integer == 6 )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "flare adds:%i tests:%i renders:%i\n",
|
||||
backEnd.pc.c_flareAdds, backEnd.pc.c_flareTests, backEnd.pc.c_flareRenders );
|
||||
}
|
||||
else if (r_speeds->integer == 7) {
|
||||
const float texSize = R_SumOfUsedImages(qtrue) / (1048576.0f);
|
||||
const float backBuff= glConfig.vidWidth * glConfig.vidHeight * glConfig.colorBits / (8.0f * 1024*1024);
|
||||
const float depthBuff= glConfig.vidWidth * glConfig.vidHeight * glConfig.depthBits / (8.0f * 1024*1024);
|
||||
const float stencilBuff= glConfig.vidWidth * glConfig.vidHeight * glConfig.stencilBits / (8.0f * 1024*1024);
|
||||
ri.Printf (PRINT_ALL, "Tex MB %.2f + buffers %.2f MB = Total %.2fMB\n",
|
||||
texSize, backBuff*2+depthBuff+stencilBuff, texSize+backBuff*2+depthBuff+stencilBuff);
|
||||
}
|
||||
|
||||
memset( &tr.pc, 0, sizeof( tr.pc ) );
|
||||
memset( &backEnd.pc, 0, sizeof( backEnd.pc ) );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
R_IssueRenderCommands
|
||||
====================
|
||||
*/
|
||||
void R_IssueRenderCommands( qboolean runPerformanceCounters ) {
|
||||
renderCommandList_t *cmdList;
|
||||
|
||||
cmdList = &backEndData->commands;
|
||||
|
||||
// add an end-of-list command
|
||||
byteAlias_t *ba = (byteAlias_t *)&cmdList->cmds[cmdList->used];
|
||||
ba->ui = RC_END_OF_LIST;
|
||||
|
||||
// clear it out, in case this is a sync and not a buffer flip
|
||||
cmdList->used = 0;
|
||||
|
||||
// at this point, the back end thread is idle, so it is ok
|
||||
// to look at it's performance counters
|
||||
if ( runPerformanceCounters ) {
|
||||
R_PerformanceCounters();
|
||||
}
|
||||
|
||||
// actually start the commands going
|
||||
if ( !r_skipBackEnd->integer ) {
|
||||
// let it start on the new batch
|
||||
RB_ExecuteRenderCommands( cmdList->cmds );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
R_IssuePendingRenderCommands
|
||||
|
||||
Issue any pending commands and wait for them to complete.
|
||||
====================
|
||||
*/
|
||||
void R_IssuePendingRenderCommands( void ) {
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
R_IssueRenderCommands( qfalse );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
R_GetCommandBufferReserved
|
||||
|
||||
make sure there is enough command space
|
||||
============
|
||||
*/
|
||||
static void *R_GetCommandBufferReserved( int bytes, int reservedBytes ) {
|
||||
renderCommandList_t *cmdList;
|
||||
|
||||
cmdList = &backEndData->commands;
|
||||
bytes = PAD(bytes, sizeof(void *));
|
||||
|
||||
// always leave room for the end of list command
|
||||
if ( cmdList->used + bytes + sizeof( int ) + reservedBytes > MAX_RENDER_COMMANDS ) {
|
||||
if ( bytes > MAX_RENDER_COMMANDS - (int)sizeof( int ) ) {
|
||||
ri.Error( ERR_FATAL, "R_GetCommandBuffer: bad size %i", bytes );
|
||||
}
|
||||
// if we run out of room, just start dropping commands
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cmdList->used += bytes;
|
||||
|
||||
return cmdList->cmds + cmdList->used - bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
R_GetCommandBuffer
|
||||
|
||||
make sure there is enough command space
|
||||
============
|
||||
*/
|
||||
static void *R_GetCommandBuffer( int bytes ) {
|
||||
return R_GetCommandBufferReserved( bytes, PAD( sizeof( swapBuffersCommand_t ), sizeof(void *) ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
R_AddDrawSurfCmd
|
||||
|
||||
=============
|
||||
*/
|
||||
void R_AddDrawSurfCmd( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
||||
drawSurfsCommand_t *cmd;
|
||||
|
||||
cmd = (drawSurfsCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_DRAW_SURFS;
|
||||
|
||||
cmd->drawSurfs = drawSurfs;
|
||||
cmd->numDrawSurfs = numDrawSurfs;
|
||||
|
||||
cmd->refdef = tr.refdef;
|
||||
cmd->viewParms = tr.viewParms;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_SetColor
|
||||
|
||||
Passing NULL will set the color to white
|
||||
=============
|
||||
*/
|
||||
void RE_SetColor( const float *rgba ) {
|
||||
setColorCommand_t *cmd;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
cmd = (setColorCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_SET_COLOR;
|
||||
if ( !rgba ) {
|
||||
rgba = colorWhite;
|
||||
}
|
||||
cmd->color[0] = rgba[0];
|
||||
cmd->color[1] = rgba[1];
|
||||
cmd->color[2] = rgba[2];
|
||||
cmd->color[3] = rgba[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_StretchPic
|
||||
=============
|
||||
*/
|
||||
void RE_StretchPic ( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2, qhandle_t hShader ) {
|
||||
stretchPicCommand_t *cmd;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
cmd = (stretchPicCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_STRETCH_PIC;
|
||||
cmd->shader = R_GetShaderByHandle( hShader );
|
||||
cmd->x = x;
|
||||
cmd->y = y;
|
||||
cmd->w = w;
|
||||
cmd->h = h;
|
||||
cmd->s1 = s1;
|
||||
cmd->t1 = t1;
|
||||
cmd->s2 = s2;
|
||||
cmd->t2 = t2;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_RotatePic
|
||||
=============
|
||||
*/
|
||||
void RE_RotatePic ( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2,float a, qhandle_t hShader ) {
|
||||
rotatePicCommand_t *cmd;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
cmd = (rotatePicCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_ROTATE_PIC;
|
||||
cmd->shader = R_GetShaderByHandle( hShader );
|
||||
cmd->x = x;
|
||||
cmd->y = y;
|
||||
cmd->w = w;
|
||||
cmd->h = h;
|
||||
cmd->s1 = s1;
|
||||
cmd->t1 = t1;
|
||||
cmd->s2 = s2;
|
||||
cmd->t2 = t2;
|
||||
cmd->a = a;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_RotatePic2
|
||||
=============
|
||||
*/
|
||||
void RE_RotatePic2 ( float x, float y, float w, float h,
|
||||
float s1, float t1, float s2, float t2,float a, qhandle_t hShader ) {
|
||||
rotatePicCommand_t *cmd;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (rotatePicCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_ROTATE_PIC2;
|
||||
cmd->shader = R_GetShaderByHandle( hShader );
|
||||
cmd->x = x;
|
||||
cmd->y = y;
|
||||
cmd->w = w;
|
||||
cmd->h = h;
|
||||
cmd->s1 = s1;
|
||||
cmd->t1 = t1;
|
||||
cmd->s2 = s2;
|
||||
cmd->t2 = t2;
|
||||
cmd->a = a;
|
||||
}
|
||||
|
||||
void RE_LAGoggles( void )
|
||||
{
|
||||
tr.refdef.rdflags |= (RDF_doLAGoggles|RDF_doFullbright);
|
||||
tr.refdef.doLAGoggles = qtrue;
|
||||
|
||||
jk_fog_t *fog = &tr.world->fogs[tr.world->numfogs];
|
||||
|
||||
fog->parms.color[0] = 0.75f;
|
||||
fog->parms.color[1] = 0.42f + Q_flrand(0.0f, 1.0f) * 0.025f;
|
||||
fog->parms.color[2] = 0.07f;
|
||||
fog->parms.depthForOpaque = 10000;
|
||||
fog->colorInt = ColorBytes4(fog->parms.color[0], fog->parms.color[1], fog->parms.color[2], 1.0f);
|
||||
fog->tcScale = 2.0f / ( fog->parms.depthForOpaque * (1.0f + cos( tr.refdef.floatTime) * 0.1f));
|
||||
}
|
||||
|
||||
void RE_RenderWorldEffects(void)
|
||||
{
|
||||
setModeCommand_t *cmd;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (setModeCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_WORLD_EFFECTS;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_Scissor
|
||||
=============
|
||||
*/
|
||||
void RE_Scissor ( float x, float y, float w, float h)
|
||||
{
|
||||
scissorCommand_t *cmd;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (scissorCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_SCISSOR;
|
||||
cmd->x = x;
|
||||
cmd->y = y;
|
||||
cmd->w = w;
|
||||
cmd->h = h;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
RE_BeginFrame
|
||||
|
||||
If running in stereo, RE_BeginFrame will be called twice
|
||||
for each RE_EndFrame
|
||||
====================
|
||||
*/
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame ) {
|
||||
drawBufferCommand_t *cmd = NULL;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
glState.finishCalled = qfalse;
|
||||
|
||||
tr.frameCount++;
|
||||
tr.frameSceneNum = 0;
|
||||
|
||||
//
|
||||
// do overdraw measurement
|
||||
//
|
||||
#ifndef HAVE_GLES
|
||||
if ( r_measureOverdraw->integer )
|
||||
{
|
||||
if ( glConfig.stencilBits < 4 )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits );
|
||||
ri.Cvar_Set( "r_measureOverdraw", "0" );
|
||||
r_measureOverdraw->modified = qfalse;
|
||||
}
|
||||
else if ( r_shadows->integer == 2 )
|
||||
{
|
||||
ri.Printf( PRINT_ALL, "Warning: stencil shadows and overdraw measurement are mutually exclusive\n" );
|
||||
ri.Cvar_Set( "r_measureOverdraw", "0" );
|
||||
r_measureOverdraw->modified = qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_IssuePendingRenderCommands();
|
||||
qglEnable( GL_STENCIL_TEST );
|
||||
qglStencilMask( ~0U );
|
||||
qglClearStencil( 0U );
|
||||
qglStencilFunc( GL_ALWAYS, 0U, ~0U );
|
||||
qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
|
||||
}
|
||||
r_measureOverdraw->modified = qfalse;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is only reached if it was on and is now off
|
||||
if ( r_measureOverdraw->modified ) {
|
||||
R_IssuePendingRenderCommands();
|
||||
qglDisable( GL_STENCIL_TEST );
|
||||
r_measureOverdraw->modified = qfalse;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// texturemode stuff
|
||||
//
|
||||
if ( r_textureMode->modified || r_ext_texture_filter_anisotropic->modified) {
|
||||
R_IssuePendingRenderCommands();
|
||||
GL_TextureMode( r_textureMode->string );
|
||||
r_textureMode->modified = qfalse;
|
||||
r_ext_texture_filter_anisotropic->modified = qfalse;
|
||||
}
|
||||
|
||||
//
|
||||
// gamma stuff
|
||||
//
|
||||
if ( r_gamma->modified ) {
|
||||
r_gamma->modified = qfalse;
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
R_SetColorMappings();
|
||||
}
|
||||
|
||||
// check for errors
|
||||
if ( !r_ignoreGLErrors->integer ) {
|
||||
int err;
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
if ( ( err = qglGetError() ) != GL_NO_ERROR ) {
|
||||
Com_Error( ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!\n", err );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// draw buffer stuff
|
||||
//
|
||||
cmd = (drawBufferCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_DRAW_BUFFER;
|
||||
|
||||
{
|
||||
if ( stereoFrame == STEREO_LEFT ) {
|
||||
cmd->buffer = (int)0;
|
||||
} else if ( stereoFrame == STEREO_RIGHT ) {
|
||||
cmd->buffer = (int)1;
|
||||
} else {
|
||||
ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_EndFrame
|
||||
|
||||
Returns the number of msec spent in the back end
|
||||
=============
|
||||
*/
|
||||
void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) {
|
||||
swapBuffersCommand_t *cmd;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (swapBuffersCommand_t*)R_GetCommandBuffer(sizeof(*cmd));
|
||||
if (!cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd->commandId = RC_FLUSH;
|
||||
|
||||
R_IssueRenderCommands( qfalse );
|
||||
|
||||
// use the other buffers next frame, because another CPU
|
||||
// may still be rendering into the current ones
|
||||
R_InitNextFrame();
|
||||
|
||||
if (frontEndMsec) {
|
||||
*frontEndMsec = tr.frontEndMsec;
|
||||
}
|
||||
tr.frontEndMsec = 0;
|
||||
if (backEndMsec) {
|
||||
*backEndMsec = backEnd.pc.msec;
|
||||
}
|
||||
backEnd.pc.msec = 0;
|
||||
|
||||
for(int i=0;i<MAX_LIGHT_STYLES;i++)
|
||||
{
|
||||
styleUpdated[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RE_SubmitStereoFrame( ) {
|
||||
swapBuffersCommand_t *cmd;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (swapBuffersCommand_t*)R_GetCommandBuffer(sizeof(*cmd));
|
||||
if (!cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd->commandId = RC_SWAP_BUFFERS;
|
||||
|
||||
R_IssueRenderCommands( qtrue );
|
||||
}
|
485
Projects/Android/jni/OpenJK/code/rd-gles/tr_curve.cpp
Normal file
485
Projects/Android/jni/OpenJK/code/rd-gles/tr_curve.cpp
Normal file
|
@ -0,0 +1,485 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_common.h"
|
||||
#include "tr_local.h"
|
||||
|
||||
/*
|
||||
|
||||
This file does all of the processing necessary to turn a raw grid of points
|
||||
read from the map file into a srfGridMesh_t ready for rendering.
|
||||
|
||||
The level of detail solution is direction independent, based only on subdivided
|
||||
distance from the true curve.
|
||||
|
||||
Only a single entry point:
|
||||
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
LerpDrawVert
|
||||
============
|
||||
*/
|
||||
static void LerpDrawVert( drawVert_t *a, drawVert_t *b, drawVert_t *out ) {
|
||||
int k;
|
||||
out->xyz[0] = 0.5 * (a->xyz[0] + b->xyz[0]);
|
||||
out->xyz[1] = 0.5 * (a->xyz[1] + b->xyz[1]);
|
||||
out->xyz[2] = 0.5 * (a->xyz[2] + b->xyz[2]);
|
||||
|
||||
out->st[0] = 0.5 * (a->st[0] + b->st[0]);
|
||||
out->st[1] = 0.5 * (a->st[1] + b->st[1]);
|
||||
|
||||
out->normal[0] = 0.5 * (a->normal[0] + b->normal[0]);
|
||||
out->normal[1] = 0.5 * (a->normal[1] + b->normal[1]);
|
||||
out->normal[2] = 0.5 * (a->normal[2] + b->normal[2]);
|
||||
|
||||
for(k=0;k<MAXLIGHTMAPS;k++)
|
||||
{
|
||||
out->lightmap[k][0] = 0.5 * (a->lightmap[k][0] + b->lightmap[k][0]);
|
||||
out->lightmap[k][1] = 0.5 * (a->lightmap[k][1] + b->lightmap[k][1]);
|
||||
|
||||
out->color[k][0] = (a->color[k][0] + b->color[k][0]) >> 1;
|
||||
out->color[k][1] = (a->color[k][1] + b->color[k][1]) >> 1;
|
||||
out->color[k][2] = (a->color[k][2] + b->color[k][2]) >> 1;
|
||||
out->color[k][3] = (a->color[k][3] + b->color[k][3]) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Transpose
|
||||
============
|
||||
*/
|
||||
static void Transpose( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
|
||||
int i, j;
|
||||
drawVert_t temp;
|
||||
|
||||
if ( width > height ) {
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
for ( j = i + 1 ; j < width ; j++ ) {
|
||||
if ( j < height ) {
|
||||
// swap the value
|
||||
temp = ctrl[j][i];
|
||||
ctrl[j][i] = ctrl[i][j];
|
||||
ctrl[i][j] = temp;
|
||||
} else {
|
||||
// just copy
|
||||
ctrl[j][i] = ctrl[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = i + 1 ; j < height ; j++ ) {
|
||||
if ( j < width ) {
|
||||
// swap the value
|
||||
temp = ctrl[i][j];
|
||||
ctrl[i][j] = ctrl[j][i];
|
||||
ctrl[j][i] = temp;
|
||||
} else {
|
||||
// just copy
|
||||
ctrl[i][j] = ctrl[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
MakeMeshNormals
|
||||
|
||||
Handles all the complicated wrapping and degenerate cases
|
||||
=================
|
||||
*/
|
||||
static void MakeMeshNormals( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
|
||||
int i, j, k, dist;
|
||||
vec3_t normal;
|
||||
vec3_t sum;
|
||||
int count;
|
||||
vec3_t base;
|
||||
vec3_t delta;
|
||||
int x, y;
|
||||
drawVert_t *dv;
|
||||
vec3_t around[8], temp;
|
||||
qboolean good[8];
|
||||
qboolean wrapWidth, wrapHeight;
|
||||
float len;
|
||||
static int neighbors[8][2] = {
|
||||
{0,1}, {1,1}, {1,0}, {1,-1}, {0,-1}, {-1,-1}, {-1,0}, {-1,1}
|
||||
};
|
||||
|
||||
wrapWidth = qfalse;
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
VectorSubtract( ctrl[i][0].xyz, ctrl[i][width-1].xyz, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > 1.0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == height ) {
|
||||
wrapWidth = qtrue;
|
||||
}
|
||||
|
||||
wrapHeight = qfalse;
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
VectorSubtract( ctrl[0][i].xyz, ctrl[height-1][i].xyz, delta );
|
||||
len = VectorLength( delta );
|
||||
if ( len > 1.0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( i == width) {
|
||||
wrapHeight = qtrue;
|
||||
}
|
||||
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
count = 0;
|
||||
dv = &ctrl[j][i];
|
||||
VectorCopy( dv->xyz, base );
|
||||
for ( k = 0 ; k < 8 ; k++ ) {
|
||||
VectorClear( around[k] );
|
||||
good[k] = qfalse;
|
||||
|
||||
for ( dist = 1 ; dist <= 3 ; dist++ ) {
|
||||
x = i + neighbors[k][0] * dist;
|
||||
y = j + neighbors[k][1] * dist;
|
||||
if ( wrapWidth ) {
|
||||
if ( x < 0 ) {
|
||||
x = width - 1 + x;
|
||||
} else if ( x >= width ) {
|
||||
x = 1 + x - width;
|
||||
}
|
||||
}
|
||||
if ( wrapHeight ) {
|
||||
if ( y < 0 ) {
|
||||
y = height - 1 + y;
|
||||
} else if ( y >= height ) {
|
||||
y = 1 + y - height;
|
||||
}
|
||||
}
|
||||
|
||||
if ( x < 0 || x >= width || y < 0 || y >= height ) {
|
||||
break; // edge of patch
|
||||
}
|
||||
VectorSubtract( ctrl[y][x].xyz, base, temp );
|
||||
if ( VectorNormalize2( temp, temp ) == 0 ) {
|
||||
continue; // degenerate edge, get more dist
|
||||
} else {
|
||||
good[k] = qtrue;
|
||||
VectorCopy( temp, around[k] );
|
||||
break; // good edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( sum );
|
||||
for ( k = 0 ; k < 8 ; k++ ) {
|
||||
if ( !good[k] || !good[(k+1)&7] ) {
|
||||
continue; // didn't get two points
|
||||
}
|
||||
CrossProduct( around[(k+1)&7], around[k], normal );
|
||||
if ( VectorNormalize2( normal, normal ) == 0 ) {
|
||||
continue;
|
||||
}
|
||||
VectorAdd( normal, sum, sum );
|
||||
count++;
|
||||
}
|
||||
if ( count == 0 ) {
|
||||
//printf("bad normal\n");
|
||||
count = 1;
|
||||
}
|
||||
VectorNormalize2( sum, dv->normal );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
InvertCtrl
|
||||
============
|
||||
*/
|
||||
static void InvertCtrl( int width, int height, drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE] ) {
|
||||
int i, j;
|
||||
drawVert_t temp;
|
||||
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
for ( j = 0 ; j < width/2 ; j++ ) {
|
||||
temp = ctrl[i][j];
|
||||
ctrl[i][j] = ctrl[i][width-1-j];
|
||||
ctrl[i][width-1-j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
InvertErrorTable
|
||||
=================
|
||||
*/
|
||||
static void InvertErrorTable( float errorTable[2][MAX_GRID_SIZE], int width, int height ) {
|
||||
int i;
|
||||
float copy[2][MAX_GRID_SIZE];
|
||||
|
||||
memcpy( copy, errorTable, sizeof( copy ) );
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
errorTable[1][i] = copy[0][i]; //[width-1-i];
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
errorTable[0][i] = copy[1][height-1-i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
PutPointsOnCurve
|
||||
==================
|
||||
*/
|
||||
static void PutPointsOnCurve( drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE],
|
||||
int width, int height ) {
|
||||
int i, j;
|
||||
drawVert_t prev, next;
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 1 ; j < height ; j += 2 ) {
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j+1][i], &prev );
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j-1][i], &next );
|
||||
LerpDrawVert( &prev, &next, &ctrl[j][i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
for ( i = 1 ; i < width ; i += 2 ) {
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j][i+1], &prev );
|
||||
LerpDrawVert( &ctrl[j][i], &ctrl[j][i-1], &next );
|
||||
LerpDrawVert( &prev, &next, &ctrl[j][i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SubdividePatchToGrid
|
||||
|
||||
=================
|
||||
*/
|
||||
srfGridMesh_t *R_SubdividePatchToGrid( int width, int height,
|
||||
drawVert_t points[MAX_PATCH_SIZE*MAX_PATCH_SIZE] ) {
|
||||
int i, j, k, l;
|
||||
drawVert_t prev, next, mid;
|
||||
float len, maxLen;
|
||||
int dir;
|
||||
int t;
|
||||
drawVert_t ctrl[MAX_GRID_SIZE][MAX_GRID_SIZE];
|
||||
float errorTable[2][MAX_GRID_SIZE];
|
||||
srfGridMesh_t *grid;
|
||||
drawVert_t *vert;
|
||||
vec3_t tmpVec;
|
||||
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
ctrl[j][i] = points[j*width+i];
|
||||
}
|
||||
}
|
||||
|
||||
for ( dir = 0 ; dir < 2 ; dir++ ) {
|
||||
|
||||
for ( j = 0 ; j < MAX_GRID_SIZE ; j++ ) {
|
||||
errorTable[dir][j] = 0;
|
||||
}
|
||||
|
||||
// horizontal subdivisions
|
||||
for ( j = 0 ; j + 2 < width ; j += 2 ) {
|
||||
// check subdivided midpoints against control points
|
||||
maxLen = 0;
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
vec3_t midxyz;
|
||||
vec3_t dir;
|
||||
vec3_t projected;
|
||||
float d;
|
||||
|
||||
// calculate the point on the curve
|
||||
for ( l = 0 ; l < 3 ; l++ ) {
|
||||
midxyz[l] = (ctrl[i][j].xyz[l] + ctrl[i][j+1].xyz[l] * 2
|
||||
+ ctrl[i][j+2].xyz[l] ) * 0.25;
|
||||
}
|
||||
|
||||
// see how far off the line it is
|
||||
// using dist-from-line will not account for internal
|
||||
// texture warping, but it gives a lot less polygons than
|
||||
// dist-from-midpoint
|
||||
VectorSubtract( midxyz, ctrl[i][j].xyz, midxyz );
|
||||
VectorSubtract( ctrl[i][j+2].xyz, ctrl[i][j].xyz, dir );
|
||||
VectorNormalize( dir );
|
||||
|
||||
d = DotProduct( midxyz, dir );
|
||||
VectorScale( dir, d, projected );
|
||||
VectorSubtract( midxyz, projected, midxyz);
|
||||
len = VectorLength( midxyz );
|
||||
|
||||
if ( len > maxLen ) {
|
||||
maxLen = len;
|
||||
}
|
||||
}
|
||||
|
||||
// if all the points are on the lines, remove the entire columns
|
||||
if ( maxLen < 0.1 ) {
|
||||
errorTable[dir][j+1] = 999;
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if we want to insert subdivided columns
|
||||
if ( width + 2 > MAX_GRID_SIZE ) {
|
||||
errorTable[dir][j+1] = 1.0/maxLen;
|
||||
continue; // can't subdivide any more
|
||||
}
|
||||
|
||||
if ( maxLen <= r_subdivisions->value ) {
|
||||
errorTable[dir][j+1] = 1.0/maxLen;
|
||||
continue; // didn't need subdivision
|
||||
}
|
||||
|
||||
errorTable[dir][j+2] = 1.0/maxLen;
|
||||
|
||||
// insert two columns and replace the peak
|
||||
width += 2;
|
||||
for ( i = 0 ; i < height ; i++ ) {
|
||||
LerpDrawVert( &ctrl[i][j], &ctrl[i][j+1], &prev );
|
||||
LerpDrawVert( &ctrl[i][j+1], &ctrl[i][j+2], &next );
|
||||
LerpDrawVert( &prev, &next, &mid );
|
||||
|
||||
for ( k = width - 1 ; k > j + 3 ; k-- ) {
|
||||
ctrl[i][k] = ctrl[i][k-2];
|
||||
}
|
||||
ctrl[i][j + 1] = prev;
|
||||
ctrl[i][j + 2] = mid;
|
||||
ctrl[i][j + 3] = next;
|
||||
}
|
||||
|
||||
// back up and recheck this set again, it may need more subdivision
|
||||
j -= 2;
|
||||
|
||||
}
|
||||
|
||||
Transpose( width, height, ctrl );
|
||||
t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
}
|
||||
|
||||
|
||||
// put all the aproximating points on the curve
|
||||
PutPointsOnCurve( ctrl, width, height );
|
||||
|
||||
// cull out any rows or columns that are colinear
|
||||
for ( i = 1 ; i < width-1 ; i++ ) {
|
||||
if ( errorTable[0][i] != 999 ) {
|
||||
continue;
|
||||
}
|
||||
for ( j = i+1 ; j < width ; j++ ) {
|
||||
for ( k = 0 ; k < height ; k++ ) {
|
||||
ctrl[k][j-1] = ctrl[k][j];
|
||||
}
|
||||
errorTable[0][j-1] = errorTable[0][j];
|
||||
}
|
||||
width--;
|
||||
}
|
||||
|
||||
for ( i = 1 ; i < height-1 ; i++ ) {
|
||||
if ( errorTable[1][i] != 999 ) {
|
||||
continue;
|
||||
}
|
||||
for ( j = i+1 ; j < height ; j++ ) {
|
||||
for ( k = 0 ; k < width ; k++ ) {
|
||||
ctrl[j-1][k] = ctrl[j][k];
|
||||
}
|
||||
errorTable[1][j-1] = errorTable[1][j];
|
||||
}
|
||||
height--;
|
||||
}
|
||||
|
||||
#if 1
|
||||
// flip for longest tristrips as an optimization
|
||||
// the results should be visually identical with or
|
||||
// without this step
|
||||
if ( height > width ) {
|
||||
Transpose( width, height, ctrl );
|
||||
InvertErrorTable( errorTable, width, height );
|
||||
t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
InvertCtrl( width, height, ctrl );
|
||||
}
|
||||
#endif
|
||||
|
||||
// calculate normals
|
||||
MakeMeshNormals( width, height, ctrl );
|
||||
|
||||
// copy the results out to a grid
|
||||
grid = (struct srfGridMesh_s *) R_Hunk_Alloc( (width * height - 1) * sizeof( drawVert_t ) + sizeof( *grid ), qtrue );
|
||||
|
||||
grid->widthLodError = (float *) R_Hunk_Alloc( width * 4, qfalse );
|
||||
memcpy( grid->widthLodError, errorTable[0], width * 4 );
|
||||
|
||||
grid->heightLodError = (float *) R_Hunk_Alloc( height * 4, qfalse );
|
||||
memcpy( grid->heightLodError, errorTable[1], height * 4 );
|
||||
|
||||
grid->width = width;
|
||||
grid->height = height;
|
||||
grid->surfaceType = SF_GRID;
|
||||
ClearBounds( grid->meshBounds[0], grid->meshBounds[1] );
|
||||
for ( i = 0 ; i < width ; i++ ) {
|
||||
for ( j = 0 ; j < height ; j++ ) {
|
||||
vert = &grid->verts[j*width+i];
|
||||
*vert = ctrl[j][i];
|
||||
AddPointToBounds( vert->xyz, grid->meshBounds[0], grid->meshBounds[1] );
|
||||
}
|
||||
}
|
||||
|
||||
// compute local origin and bounds
|
||||
VectorAdd( grid->meshBounds[0], grid->meshBounds[1], grid->localOrigin );
|
||||
VectorScale( grid->localOrigin, 0.5f, grid->localOrigin );
|
||||
VectorSubtract( grid->meshBounds[0], grid->localOrigin, tmpVec );
|
||||
grid->meshRadius = VectorLength( tmpVec );
|
||||
|
||||
VectorCopy( grid->localOrigin, grid->lodOrigin );
|
||||
grid->lodRadius = grid->meshRadius;
|
||||
|
||||
return grid;
|
||||
}
|
1071
Projects/Android/jni/OpenJK/code/rd-gles/tr_draw.cpp
Normal file
1071
Projects/Android/jni/OpenJK/code/rd-gles/tr_draw.cpp
Normal file
File diff suppressed because it is too large
Load diff
3949
Projects/Android/jni/OpenJK/code/rd-gles/tr_ghoul2.cpp
Normal file
3949
Projects/Android/jni/OpenJK/code/rd-gles/tr_ghoul2.cpp
Normal file
File diff suppressed because it is too large
Load diff
1738
Projects/Android/jni/OpenJK/code/rd-gles/tr_image.cpp
Normal file
1738
Projects/Android/jni/OpenJK/code/rd-gles/tr_image.cpp
Normal file
File diff suppressed because it is too large
Load diff
2240
Projects/Android/jni/OpenJK/code/rd-gles/tr_init.cpp
Normal file
2240
Projects/Android/jni/OpenJK/code/rd-gles/tr_init.cpp
Normal file
File diff suppressed because it is too large
Load diff
520
Projects/Android/jni/OpenJK/code/rd-gles/tr_light.cpp
Normal file
520
Projects/Android/jni/OpenJK/code/rd-gles/tr_light.cpp
Normal file
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_light.c
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
#define DLIGHT_AT_RADIUS 16
|
||||
// at the edge of a dlight's influence, this amount of light will be added
|
||||
|
||||
#define DLIGHT_MINIMUM_RADIUS 16
|
||||
// never calculate a range less than this to prevent huge light numbers
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_TransformDlights
|
||||
|
||||
Transforms the origins of an array of dlights.
|
||||
Used by both the front end (for DlightBmodel) and
|
||||
the back end (before doing the lighting calculation)
|
||||
===============
|
||||
*/
|
||||
void R_TransformDlights( int count, dlight_t *dl, orientationr_t *ori) {
|
||||
int i;
|
||||
vec3_t temp;
|
||||
|
||||
for ( i = 0 ; i < count ; i++, dl++ ) {
|
||||
VectorSubtract( dl->origin, ori->origin, temp );
|
||||
dl->transformed[0] = DotProduct( temp, ori->axis[0] );
|
||||
dl->transformed[1] = DotProduct( temp, ori->axis[1] );
|
||||
dl->transformed[2] = DotProduct( temp, ori->axis[2] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_DlightBmodel
|
||||
|
||||
Determine which dynamic lights may effect this bmodel
|
||||
=============
|
||||
*/
|
||||
void R_DlightBmodel( bmodel_t *bmodel, qboolean NoLight ) {
|
||||
int i, j;
|
||||
dlight_t *dl;
|
||||
int mask;
|
||||
msurface_t *surf;
|
||||
|
||||
// transform all the lights
|
||||
R_TransformDlights( tr.refdef.num_dlights, tr.refdef.dlights, &tr.ori );
|
||||
|
||||
mask = 0;
|
||||
if (!NoLight)
|
||||
{
|
||||
for ( i=0 ; i<tr.refdef.num_dlights ; i++ ) {
|
||||
dl = &tr.refdef.dlights[i];
|
||||
|
||||
// see if the point is close enough to the bounds to matter
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( dl->transformed[j] - bmodel->bounds[1][j] > dl->radius ) {
|
||||
break;
|
||||
}
|
||||
if ( bmodel->bounds[0][j] - dl->transformed[j] > dl->radius ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j < 3 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we need to check this light
|
||||
mask |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
tr.currentEntity->needDlights = (qboolean)(mask != 0);
|
||||
tr.currentEntity->dlightBits = mask;
|
||||
|
||||
|
||||
// set the dlight bits in all the surfaces
|
||||
for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
|
||||
surf = bmodel->firstSurface + i;
|
||||
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
((srfGridMesh_t *)surf->data)->dlightBits = mask;
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
((srfTriangles_t *)surf->data)->dlightBits = mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
LIGHT SAMPLING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
extern cvar_t *r_ambientScale;
|
||||
extern cvar_t *r_directedScale;
|
||||
extern cvar_t *r_debugLight;
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupEntityLightingGrid
|
||||
|
||||
=================
|
||||
*/
|
||||
static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
|
||||
vec3_t lightOrigin;
|
||||
int pos[3];
|
||||
int i, j;
|
||||
float frac[3];
|
||||
int gridStep[3];
|
||||
vec3_t direction;
|
||||
float totalFactor;
|
||||
unsigned short *startGridPos;
|
||||
|
||||
if (r_fullbright->integer || (tr.refdef.rdflags & RDF_doLAGoggles) )
|
||||
{
|
||||
ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = 255.0;
|
||||
ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = 255.0;
|
||||
VectorCopy( tr.sunDirection, ent->lightDir );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy( ent->e.lightingOrigin, lightOrigin );
|
||||
} else {
|
||||
VectorCopy( ent->e.origin, lightOrigin );
|
||||
}
|
||||
#define ACCURATE_LIGHTGRID_SAMPLING 1
|
||||
#if ACCURATE_LIGHTGRID_SAMPLING
|
||||
vec3_t startLightOrigin;
|
||||
VectorCopy( lightOrigin, startLightOrigin );
|
||||
#endif
|
||||
|
||||
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
float v;
|
||||
|
||||
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
|
||||
pos[i] = floor( v );
|
||||
frac[i] = v - pos[i];
|
||||
if ( pos[i] < 0 ) {
|
||||
pos[i] = 0;
|
||||
} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
|
||||
pos[i] = tr.world->lightGridBounds[i] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear( ent->ambientLight );
|
||||
VectorClear( ent->directedLight );
|
||||
VectorClear( direction );
|
||||
|
||||
// trilerp the light value
|
||||
gridStep[0] = 1;
|
||||
gridStep[1] = tr.world->lightGridBounds[0];
|
||||
gridStep[2] = tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
|
||||
startGridPos = tr.world->lightGridArray + pos[0] * gridStep[0]
|
||||
+ pos[1] * gridStep[1] + pos[2] * gridStep[2];
|
||||
#if ACCURATE_LIGHTGRID_SAMPLING
|
||||
vec3_t startGridOrg;
|
||||
VectorCopy( tr.world->lightGridOrigin, startGridOrg );
|
||||
startGridOrg[0] += pos[0] * tr.world->lightGridSize[0];
|
||||
startGridOrg[1] += pos[1] * tr.world->lightGridSize[1];
|
||||
startGridOrg[2] += pos[2] * tr.world->lightGridSize[2];
|
||||
#endif
|
||||
totalFactor = 0;
|
||||
for ( i = 0 ; i < 8 ; i++ ) {
|
||||
float factor;
|
||||
mgrid_t *data;
|
||||
unsigned short *gridPos;
|
||||
int lat, lng;
|
||||
vec3_t normal;
|
||||
#if ACCURATE_LIGHTGRID_SAMPLING
|
||||
vec3_t gridOrg;
|
||||
VectorCopy( startGridOrg, gridOrg );
|
||||
#endif
|
||||
|
||||
factor = 1.0;
|
||||
gridPos = startGridPos;
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if ( i & (1<<j) ) {
|
||||
factor *= frac[j];
|
||||
gridPos += gridStep[j];
|
||||
#if ACCURATE_LIGHTGRID_SAMPLING
|
||||
gridOrg[j] += tr.world->lightGridSize[j];
|
||||
#endif
|
||||
} else {
|
||||
factor *= (1.0 - frac[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (gridPos >= tr.world->lightGridArray + tr.world->numGridArrayElements)
|
||||
{//we've gone off the array somehow
|
||||
continue;
|
||||
}
|
||||
data = tr.world->lightGridData + *gridPos;
|
||||
|
||||
if ( data->styles[0] == LS_NONE )
|
||||
{
|
||||
continue; // ignore samples in walls
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( !SV_inPVS( startLightOrigin, gridOrg ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
totalFactor += factor;
|
||||
|
||||
for(j=0;j<MAXLIGHTMAPS;j++)
|
||||
{
|
||||
if (data->styles[j] != LS_NONE)
|
||||
{
|
||||
const byte style= data->styles[j];
|
||||
|
||||
ent->ambientLight[0] += factor * data->ambientLight[j][0] * styleColors[style][0] / 255.0f;
|
||||
ent->ambientLight[1] += factor * data->ambientLight[j][1] * styleColors[style][1] / 255.0f;
|
||||
ent->ambientLight[2] += factor * data->ambientLight[j][2] * styleColors[style][2] / 255.0f;
|
||||
|
||||
ent->directedLight[0] += factor * data->directLight[j][0] * styleColors[style][0] / 255.0f;
|
||||
ent->directedLight[1] += factor * data->directLight[j][1] * styleColors[style][1] / 255.0f;
|
||||
ent->directedLight[2] += factor * data->directLight[j][2] * styleColors[style][2] / 255.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lat = data->latLong[1];
|
||||
lng = data->latLong[0];
|
||||
lat *= (FUNCTABLE_SIZE/256);
|
||||
lng *= (FUNCTABLE_SIZE/256);
|
||||
|
||||
// decode X as cos( lat ) * sin( long )
|
||||
// decode Y as sin( lat ) * sin( long )
|
||||
// decode Z as cos( long )
|
||||
|
||||
normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
|
||||
normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
|
||||
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
|
||||
|
||||
VectorMA( direction, factor, normal, direction );
|
||||
|
||||
#if ACCURATE_LIGHTGRID_SAMPLING
|
||||
if ( r_debugLight->integer && ent->e.hModel == -1 )
|
||||
{
|
||||
//draw
|
||||
refEntity_t refEnt;
|
||||
refEnt.hModel = 0;
|
||||
refEnt.ghoul2 = NULL;
|
||||
refEnt.renderfx = 0;
|
||||
VectorCopy( gridOrg, refEnt.origin );
|
||||
vectoangles( normal, refEnt.angles );
|
||||
AnglesToAxis( refEnt.angles, refEnt.axis );
|
||||
refEnt.reType = RT_MODEL;
|
||||
RE_AddRefEntityToScene( &refEnt );
|
||||
|
||||
refEnt.renderfx = RF_DEPTHHACK;
|
||||
refEnt.reType = RT_SPRITE;
|
||||
refEnt.customShader = RE_RegisterShader( "gfx/misc/debugAmbient" );
|
||||
refEnt.shaderRGBA[0] = data->ambientLight[0][0];
|
||||
refEnt.shaderRGBA[1] = data->ambientLight[0][1];
|
||||
refEnt.shaderRGBA[2] = data->ambientLight[0][2];
|
||||
refEnt.shaderRGBA[3] = 255;
|
||||
refEnt.radius = factor*50+2.0f; // maybe always give it a minimum size?
|
||||
refEnt.rotation = 0; // don't let the sprite wobble around
|
||||
RE_AddRefEntityToScene( &refEnt );
|
||||
|
||||
refEnt.reType = RT_LINE;
|
||||
refEnt.customShader = RE_RegisterShader( "gfx/misc/debugArrow" );
|
||||
refEnt.shaderRGBA[0] = data->directLight[0][0];
|
||||
refEnt.shaderRGBA[1] = data->directLight[0][1];
|
||||
refEnt.shaderRGBA[2] = data->directLight[0][2];
|
||||
refEnt.shaderRGBA[3] = 255;
|
||||
VectorCopy( refEnt.origin, refEnt.oldorigin );
|
||||
VectorMA( gridOrg, (factor*-255) - 2.0f, normal, refEnt.origin ); // maybe always give it a minimum length
|
||||
refEnt.radius = 1.5f;
|
||||
RE_AddRefEntityToScene( &refEnt );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( totalFactor > 0 && totalFactor < 0.99 )
|
||||
{
|
||||
totalFactor = 1.0 / totalFactor;
|
||||
VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
|
||||
VectorScale( ent->directedLight, totalFactor, ent->directedLight );
|
||||
}
|
||||
|
||||
VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
|
||||
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
|
||||
|
||||
VectorNormalize2( direction, ent->lightDir );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
LogLight
|
||||
===============
|
||||
*/
|
||||
static void LogLight( trRefEntity_t *ent ) {
|
||||
int max1, max2;
|
||||
|
||||
/*
|
||||
if ( !(ent->e.renderfx & RF_FIRST_PERSON ) ) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
max1 = VectorLength( ent->ambientLight );
|
||||
/*
|
||||
max1 = ent->ambientLight[0];
|
||||
if ( ent->ambientLight[1] > max1 ) {
|
||||
max1 = ent->ambientLight[1];
|
||||
} else if ( ent->ambientLight[2] > max1 ) {
|
||||
max1 = ent->ambientLight[2];
|
||||
}
|
||||
*/
|
||||
|
||||
max2 = VectorLength( ent->directedLight );
|
||||
/*
|
||||
max2 = ent->directedLight[0];
|
||||
if ( ent->directedLight[1] > max2 ) {
|
||||
max2 = ent->directedLight[1];
|
||||
} else if ( ent->directedLight[2] > max2 ) {
|
||||
max2 = ent->directedLight[2];
|
||||
}
|
||||
*/
|
||||
|
||||
ri.Printf( PRINT_ALL, "amb:%i dir:%i direction: (%4.2f, %4.2f, %4.2f)\n", max1, max2, ent->lightDir[0], ent->lightDir[1], ent->lightDir[2] );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupEntityLighting
|
||||
|
||||
Calculates all the lighting values that will be used
|
||||
by the Calc_* functions
|
||||
=================
|
||||
*/
|
||||
void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
|
||||
int i;
|
||||
dlight_t *dl;
|
||||
float power;
|
||||
vec3_t dir;
|
||||
float d;
|
||||
vec3_t lightDir;
|
||||
vec3_t lightOrigin;
|
||||
|
||||
// lighting calculations
|
||||
if ( ent->lightingCalculated ) {
|
||||
return;
|
||||
}
|
||||
ent->lightingCalculated = qtrue;
|
||||
|
||||
//
|
||||
// trace a sample point down to find ambient light
|
||||
//
|
||||
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
|
||||
// seperate lightOrigins are needed so an object that is
|
||||
// sinking into the ground can still be lit, and so
|
||||
// multi-part models can be lit identically
|
||||
VectorCopy( ent->e.lightingOrigin, lightOrigin );
|
||||
} else {
|
||||
VectorCopy( ent->e.origin, lightOrigin );
|
||||
}
|
||||
|
||||
// if NOWORLDMODEL, only use dynamic lights (menu system, etc)
|
||||
if ( !(refdef->rdflags & RDF_NOWORLDMODEL )
|
||||
&& tr.world->lightGridData ) {
|
||||
R_SetupEntityLightingGrid( ent );
|
||||
} else {
|
||||
ent->ambientLight[0] = ent->ambientLight[1] =
|
||||
ent->ambientLight[2] = tr.identityLight * 150;
|
||||
ent->directedLight[0] = ent->directedLight[1] =
|
||||
ent->directedLight[2] = tr.identityLight * 150;
|
||||
VectorCopy( tr.sunDirection, ent->lightDir );
|
||||
}
|
||||
|
||||
// bonus items and view weapons have a fixed minimum add
|
||||
if ( ent->e.renderfx & RF_MORELIGHT ) {
|
||||
ent->ambientLight[0] += tr.identityLight * 96;
|
||||
ent->ambientLight[1] += tr.identityLight * 96;
|
||||
ent->ambientLight[2] += tr.identityLight * 96;
|
||||
}
|
||||
else {
|
||||
// give everything a minimum light add
|
||||
ent->ambientLight[0] += tr.identityLight * 32;
|
||||
ent->ambientLight[1] += tr.identityLight * 32;
|
||||
ent->ambientLight[2] += tr.identityLight * 32;
|
||||
}
|
||||
|
||||
//
|
||||
// modify the light by dynamic lights
|
||||
//
|
||||
d = VectorLength( ent->directedLight );
|
||||
VectorScale( ent->lightDir, d, lightDir );
|
||||
|
||||
for ( i = 0 ; i < refdef->num_dlights ; i++ ) {
|
||||
dl = &refdef->dlights[i];
|
||||
VectorSubtract( dl->origin, lightOrigin, dir );
|
||||
d = VectorNormalize( dir );
|
||||
|
||||
power = DLIGHT_AT_RADIUS * ( dl->radius * dl->radius );
|
||||
if ( d < DLIGHT_MINIMUM_RADIUS ) {
|
||||
d = DLIGHT_MINIMUM_RADIUS;
|
||||
}
|
||||
d = power / ( d * d );
|
||||
|
||||
VectorMA( ent->directedLight, d, dl->color, ent->directedLight );
|
||||
VectorMA( lightDir, d, dir, lightDir );
|
||||
}
|
||||
|
||||
// clamp ambient
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
if ( ent->ambientLight[i] > tr.identityLightByte ) {
|
||||
ent->ambientLight[i] = tr.identityLightByte;
|
||||
}
|
||||
}
|
||||
|
||||
if ( r_debugLight->integer ) {
|
||||
LogLight( ent );
|
||||
}
|
||||
|
||||
// save out the byte packet version
|
||||
((byte *)&ent->ambientLightInt)[0] = Q_ftol( ent->ambientLight[0] );
|
||||
((byte *)&ent->ambientLightInt)[1] = Q_ftol( ent->ambientLight[1] );
|
||||
((byte *)&ent->ambientLightInt)[2] = Q_ftol( ent->ambientLight[2] );
|
||||
((byte *)&ent->ambientLightInt)[3] = 0xff;
|
||||
|
||||
// transform the direction to local space
|
||||
VectorNormalize( lightDir );
|
||||
ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
|
||||
ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
|
||||
ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
|
||||
}
|
||||
|
||||
//pass in origin
|
||||
qboolean RE_GetLighting( const vec3_t origin, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir) {
|
||||
trRefEntity_t tr_ent;
|
||||
|
||||
if ( !tr.world || !tr.world->lightGridData) {
|
||||
ambientLight[0] = ambientLight[1] = ambientLight[2] = 255.0;
|
||||
directedLight[0] = directedLight[1] = directedLight[2] = 255.0;
|
||||
VectorCopy( tr.sunDirection, lightDir );
|
||||
return qfalse;
|
||||
}
|
||||
memset (&tr_ent, 0, sizeof(tr_ent) );
|
||||
|
||||
if ( ambientLight[0] == 666 )
|
||||
{//HAX0R
|
||||
tr_ent.e.hModel = -1;
|
||||
}
|
||||
|
||||
VectorCopy (origin, tr_ent.e.origin);
|
||||
R_SetupEntityLightingGrid( &tr_ent );
|
||||
VectorCopy ( tr_ent.ambientLight, ambientLight);
|
||||
VectorCopy ( tr_ent.directedLight, directedLight);
|
||||
VectorCopy ( tr_ent.lightDir, lightDir);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_LightForPoint
|
||||
=================
|
||||
*/
|
||||
int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir )
|
||||
{
|
||||
trRefEntity_t ent;
|
||||
|
||||
// bk010103 - this segfaults with -nolight maps
|
||||
if ( tr.world->lightGridData == NULL )
|
||||
return qfalse;
|
||||
|
||||
memset(&ent, 0, sizeof(ent));
|
||||
VectorCopy( point, ent.e.origin );
|
||||
R_SetupEntityLightingGrid( &ent );
|
||||
VectorCopy(ent.ambientLight, ambientLight);
|
||||
VectorCopy(ent.directedLight, directedLight);
|
||||
VectorCopy(ent.lightDir, lightDir);
|
||||
|
||||
return qtrue;
|
||||
}
|
1853
Projects/Android/jni/OpenJK/code/rd-gles/tr_local.h
Normal file
1853
Projects/Android/jni/OpenJK/code/rd-gles/tr_local.h
Normal file
File diff suppressed because it is too large
Load diff
1570
Projects/Android/jni/OpenJK/code/rd-gles/tr_main.cpp
Normal file
1570
Projects/Android/jni/OpenJK/code/rd-gles/tr_main.cpp
Normal file
File diff suppressed because it is too large
Load diff
471
Projects/Android/jni/OpenJK/code/rd-gles/tr_marks.cpp
Normal file
471
Projects/Android/jni/OpenJK/code/rd-gles/tr_marks.cpp
Normal file
|
@ -0,0 +1,471 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_marks.c -- polygon projection on the world polygons
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
#define MAX_VERTS_ON_POLY 64
|
||||
|
||||
#define MARKER_OFFSET 0 // 1
|
||||
|
||||
/*
|
||||
=============
|
||||
R_ChopPolyBehindPlane
|
||||
|
||||
Out must have space for two more vertexes than in
|
||||
=============
|
||||
*/
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_BACK 1
|
||||
#define SIDE_ON 2
|
||||
static void R_ChopPolyBehindPlane( int numInPoints, vec3_t inPoints[MAX_VERTS_ON_POLY],
|
||||
int *numOutPoints, vec3_t outPoints[MAX_VERTS_ON_POLY],
|
||||
vec3_t normal, vec_t dist, vec_t epsilon) {
|
||||
float dists[MAX_VERTS_ON_POLY+4] = { 0 };
|
||||
int sides[MAX_VERTS_ON_POLY+4] = { 0 };
|
||||
int counts[3];
|
||||
float dot;
|
||||
int i, j;
|
||||
float *p1, *p2, *clip;
|
||||
float d;
|
||||
|
||||
// don't clip if it might overflow
|
||||
if ( numInPoints >= MAX_VERTS_ON_POLY - 2 ) {
|
||||
*numOutPoints = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
|
||||
// determine sides for each point
|
||||
for ( i = 0 ; i < numInPoints ; i++ ) {
|
||||
dot = DotProduct( inPoints[i], normal );
|
||||
dot -= dist;
|
||||
dists[i] = dot;
|
||||
if ( dot > epsilon ) {
|
||||
sides[i] = SIDE_FRONT;
|
||||
} else if ( dot < -epsilon ) {
|
||||
sides[i] = SIDE_BACK;
|
||||
} else {
|
||||
sides[i] = SIDE_ON;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
|
||||
*numOutPoints = 0;
|
||||
|
||||
if ( !counts[0] ) {
|
||||
return;
|
||||
}
|
||||
if ( !counts[1] ) {
|
||||
*numOutPoints = numInPoints;
|
||||
memcpy( outPoints, inPoints, numInPoints * sizeof(vec3_t) );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < numInPoints ; i++ ) {
|
||||
p1 = inPoints[i];
|
||||
clip = outPoints[ *numOutPoints ];
|
||||
|
||||
if ( sides[i] == SIDE_ON ) {
|
||||
VectorCopy( p1, clip );
|
||||
(*numOutPoints)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( sides[i] == SIDE_FRONT ) {
|
||||
VectorCopy( p1, clip );
|
||||
(*numOutPoints)++;
|
||||
clip = outPoints[ *numOutPoints ];
|
||||
}
|
||||
|
||||
if ( sides[i+1] == SIDE_ON || sides[i+1] == sides[i] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// generate a split point
|
||||
p2 = inPoints[ (i+1) % numInPoints ];
|
||||
|
||||
d = dists[i] - dists[i+1];
|
||||
if ( d == 0 ) {
|
||||
dot = 0;
|
||||
} else {
|
||||
dot = dists[i] / d;
|
||||
}
|
||||
|
||||
// clip xyz
|
||||
|
||||
for (j=0 ; j<3 ; j++) {
|
||||
clip[j] = p1[j] + dot * ( p2[j] - p1[j] );
|
||||
}
|
||||
|
||||
(*numOutPoints)++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_BoxSurfaces_r
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_BoxSurfaces_r(mnode_t *node, vec3_t mins, vec3_t maxs, surfaceType_t **list, int listsize, int *listlength, vec3_t dir) {
|
||||
|
||||
int s, c;
|
||||
msurface_t *surf, **mark;
|
||||
|
||||
// do the tail recursion in a loop
|
||||
while ( node->contents == -1 ) {
|
||||
s = BoxOnPlaneSide( mins, maxs, node->plane );
|
||||
if (s == 1) {
|
||||
node = node->children[0];
|
||||
} else if (s == 2) {
|
||||
node = node->children[1];
|
||||
} else {
|
||||
R_BoxSurfaces_r(node->children[0], mins, maxs, list, listsize, listlength, dir);
|
||||
node = node->children[1];
|
||||
}
|
||||
}
|
||||
|
||||
// add the individual surfaces
|
||||
mark = node->firstmarksurface;
|
||||
c = node->nummarksurfaces;
|
||||
while (c--) {
|
||||
//
|
||||
if (*listlength >= listsize) break;
|
||||
//
|
||||
surf = *mark;
|
||||
|
||||
// check if the surface has NOIMPACT or NOMARKS set
|
||||
if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) )
|
||||
|| ( surf->shader->contentFlags & CONTENTS_FOG ) ) {
|
||||
surf->viewCount = tr.viewCount;
|
||||
}
|
||||
// extra check for surfaces to avoid list overflows
|
||||
else if (*(surf->data) == SF_FACE) {
|
||||
// the face plane should go through the box
|
||||
s = BoxOnPlaneSide( mins, maxs, &(( srfSurfaceFace_t * ) surf->data)->plane );
|
||||
if (s == 1 || s == 2) {
|
||||
surf->viewCount = tr.viewCount;
|
||||
} else if (DotProduct((( srfSurfaceFace_t * ) surf->data)->plane.normal, dir) > -0.5) {
|
||||
// don't add faces that make sharp angles with the projection direction
|
||||
surf->viewCount = tr.viewCount;
|
||||
}
|
||||
}
|
||||
else if (*(surfaceType_t *) (surf->data) != SF_GRID
|
||||
&& *(surfaceType_t *) (surf->data) != SF_TRIANGLES )
|
||||
{
|
||||
surf->viewCount = tr.viewCount;
|
||||
}
|
||||
// check the viewCount because the surface may have
|
||||
// already been added if it spans multiple leafs
|
||||
if (surf->viewCount != tr.viewCount) {
|
||||
surf->viewCount = tr.viewCount;
|
||||
list[*listlength] = (surfaceType_t *) surf->data;
|
||||
(*listlength)++;
|
||||
}
|
||||
mark++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AddMarkFragments
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_AddMarkFragments(int numClipPoints, vec3_t clipPoints[2][MAX_VERTS_ON_POLY],
|
||||
int numPlanes, vec3_t *normals, float *dists,
|
||||
int maxPoints, vec3_t pointBuffer,
|
||||
int maxFragments, markFragment_t *fragmentBuffer,
|
||||
int *returnedPoints, int *returnedFragments,
|
||||
vec3_t mins, vec3_t maxs) {
|
||||
int pingPong, i;
|
||||
markFragment_t *mf;
|
||||
|
||||
// chop the surface by all the bounding planes of the to be projected polygon
|
||||
pingPong = 0;
|
||||
|
||||
for ( i = 0 ; i < numPlanes ; i++ ) {
|
||||
|
||||
R_ChopPolyBehindPlane( numClipPoints, clipPoints[pingPong],
|
||||
&numClipPoints, clipPoints[!pingPong],
|
||||
normals[i], dists[i], 0.5 );
|
||||
pingPong ^= 1;
|
||||
if ( numClipPoints == 0 ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// completely clipped away?
|
||||
if ( numClipPoints == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// add this fragment to the returned list
|
||||
if ( numClipPoints + (*returnedPoints) > maxPoints ) {
|
||||
return; // not enough space for this polygon
|
||||
}
|
||||
/*
|
||||
// all the clip points should be within the bounding box
|
||||
for ( i = 0 ; i < numClipPoints ; i++ ) {
|
||||
int j;
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
if (clipPoints[pingPong][i][j] < mins[j] - 0.5) break;
|
||||
if (clipPoints[pingPong][i][j] > maxs[j] + 0.5) break;
|
||||
}
|
||||
if (j < 3) break;
|
||||
}
|
||||
if (i < numClipPoints) return;
|
||||
*/
|
||||
|
||||
mf = fragmentBuffer + (*returnedFragments);
|
||||
mf->firstPoint = (*returnedPoints);
|
||||
mf->numPoints = numClipPoints;
|
||||
memcpy( pointBuffer + (*returnedPoints) * 3, clipPoints[pingPong], numClipPoints * sizeof(vec3_t) );
|
||||
|
||||
(*returnedPoints) += numClipPoints;
|
||||
(*returnedFragments)++;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_MarkFragments
|
||||
|
||||
=================
|
||||
*/
|
||||
int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ) {
|
||||
int numsurfaces, numPlanes;
|
||||
int i, j, k, m, n;
|
||||
surfaceType_t *surfaces[64];
|
||||
vec3_t mins, maxs;
|
||||
int returnedFragments;
|
||||
int returnedPoints;
|
||||
vec3_t normals[MAX_VERTS_ON_POLY+2];
|
||||
float dists[MAX_VERTS_ON_POLY+2];
|
||||
vec3_t clipPoints[2][MAX_VERTS_ON_POLY];
|
||||
vec3_t normal;
|
||||
vec3_t projectionDir;
|
||||
vec3_t v1, v2;
|
||||
|
||||
//increment view count for double check prevention
|
||||
tr.viewCount++;
|
||||
|
||||
//
|
||||
VectorNormalize2( projection, projectionDir );
|
||||
// find all the brushes that are to be considered
|
||||
ClearBounds( mins, maxs );
|
||||
for ( i = 0 ; i < numPoints ; i++ ) {
|
||||
vec3_t temp;
|
||||
|
||||
AddPointToBounds( points[i], mins, maxs );
|
||||
VectorAdd( points[i], projection, temp );
|
||||
AddPointToBounds( temp, mins, maxs );
|
||||
// make sure we get all the leafs (also the one(s) in front of the hit surface)
|
||||
VectorMA( points[i], -20, projectionDir, temp );
|
||||
AddPointToBounds( temp, mins, maxs );
|
||||
}
|
||||
|
||||
if (numPoints > MAX_VERTS_ON_POLY) numPoints = MAX_VERTS_ON_POLY;
|
||||
// create the bounding planes for the to be projected polygon
|
||||
for ( i = 0 ; i < numPoints ; i++ ) {
|
||||
VectorSubtract(points[(i+1)%numPoints], points[i], v1);
|
||||
VectorAdd(points[i], projection, v2);
|
||||
VectorSubtract(points[i], v2, v2);
|
||||
CrossProduct(v1, v2, normals[i]);
|
||||
VectorNormalizeFast(normals[i]);
|
||||
dists[i] = DotProduct(normals[i], points[i]);
|
||||
}
|
||||
// add near and far clipping planes for projection
|
||||
VectorCopy(projectionDir, normals[numPoints]);
|
||||
dists[numPoints] = DotProduct(normals[numPoints], points[0]) - 32;
|
||||
VectorCopy(projectionDir, normals[numPoints+1]);
|
||||
VectorInverse(normals[numPoints+1]);
|
||||
dists[numPoints+1] = DotProduct(normals[numPoints+1], points[0]) - 20;
|
||||
numPlanes = numPoints + 2;
|
||||
|
||||
numsurfaces = 0;
|
||||
R_BoxSurfaces_r(tr.world->nodes, mins, maxs, surfaces, 64, &numsurfaces, projectionDir);
|
||||
//assert(numsurfaces <= 64);
|
||||
//assert(numsurfaces != 64);
|
||||
|
||||
returnedPoints = 0;
|
||||
returnedFragments = 0;
|
||||
|
||||
for ( i = 0 ; i < numsurfaces ; i++ ) {
|
||||
|
||||
if (*surfaces[i] == SF_GRID) {
|
||||
const srfGridMesh_t * const cv = (srfGridMesh_t *) surfaces[i];
|
||||
for ( m = 0 ; m < cv->height - 1 ; m++ ) {
|
||||
for ( n = 0 ; n < cv->width - 1 ; n++ ) {
|
||||
// We triangulate the grid and chop all triangles within
|
||||
// the bounding planes of the to be projected polygon.
|
||||
// LOD is not taken into account, not such a big deal though.
|
||||
//
|
||||
// It's probably much nicer to chop the grid itself and deal
|
||||
// with this grid as a normal SF_GRID surface so LOD will
|
||||
// be applied. However the LOD of that chopped grid must
|
||||
// be synced with the LOD of the original curve.
|
||||
// One way to do this; the chopped grid shares vertices with
|
||||
// the original curve. When LOD is applied to the original
|
||||
// curve the unused vertices are flagged. Now the chopped curve
|
||||
// should skip the flagged vertices. This still leaves the
|
||||
// problems with the vertices at the chopped grid edges.
|
||||
//
|
||||
// To avoid issues when LOD applied to "hollow curves" (like
|
||||
// the ones around many jump pads) we now just add a 2 unit
|
||||
// offset to the triangle vertices.
|
||||
// The offset is added in the vertex normal vector direction
|
||||
// so all triangles will still fit together.
|
||||
// The 2 unit offset should avoid pretty much all LOD problems.
|
||||
|
||||
const int numClipPoints = 3;
|
||||
|
||||
const drawVert_t * const dv = cv->verts + m * cv->width + n;
|
||||
|
||||
VectorCopy(dv[0].xyz, clipPoints[0][0]);
|
||||
VectorMA(clipPoints[0][0], MARKER_OFFSET, dv[0].normal, clipPoints[0][0]);
|
||||
VectorCopy(dv[cv->width].xyz, clipPoints[0][1]);
|
||||
VectorMA(clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1]);
|
||||
VectorCopy(dv[1].xyz, clipPoints[0][2]);
|
||||
VectorMA(clipPoints[0][2], MARKER_OFFSET, dv[1].normal, clipPoints[0][2]);
|
||||
// check the normal of this triangle
|
||||
VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
|
||||
VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
|
||||
CrossProduct(v1, v2, normal);
|
||||
VectorNormalizeFast(normal);
|
||||
if (DotProduct(normal, projectionDir) < -0.1) {
|
||||
// add the fragments of this triangle
|
||||
R_AddMarkFragments(numClipPoints, clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
|
||||
if ( returnedFragments == maxFragments ) {
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
|
||||
VectorCopy(dv[1].xyz, clipPoints[0][0]);
|
||||
VectorMA(clipPoints[0][0], MARKER_OFFSET, dv[1].normal, clipPoints[0][0]);
|
||||
VectorCopy(dv[cv->width].xyz, clipPoints[0][1]);
|
||||
VectorMA(clipPoints[0][1], MARKER_OFFSET, dv[cv->width].normal, clipPoints[0][1]);
|
||||
VectorCopy(dv[cv->width+1].xyz, clipPoints[0][2]);
|
||||
VectorMA(clipPoints[0][2], MARKER_OFFSET, dv[cv->width+1].normal, clipPoints[0][2]);
|
||||
// check the normal of this triangle
|
||||
VectorSubtract(clipPoints[0][0], clipPoints[0][1], v1);
|
||||
VectorSubtract(clipPoints[0][2], clipPoints[0][1], v2);
|
||||
CrossProduct(v1, v2, normal);
|
||||
VectorNormalizeFast(normal);
|
||||
if (DotProduct(normal, projectionDir) < -0.05) {
|
||||
// add the fragments of this triangle
|
||||
R_AddMarkFragments(numClipPoints, clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
|
||||
if ( returnedFragments == maxFragments ) {
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*surfaces[i] == SF_FACE) {
|
||||
const srfSurfaceFace_t * const surf = ( srfSurfaceFace_t * ) surfaces[i];
|
||||
// check the normal of this face
|
||||
if (DotProduct(surf->plane.normal, projectionDir) > -0.5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int * const indexes = (int *)( (byte *)surf + surf->ofsIndices );
|
||||
|
||||
for ( k = 0 ; k < surf->numIndices ; k += 3 ) {
|
||||
for ( j = 0 ; j < 3 ; j++ ) {
|
||||
const float * const v = surf->points[0] + VERTEXSIZE * indexes[k+j];
|
||||
VectorMA( v, MARKER_OFFSET, surf->plane.normal, clipPoints[0][j] );
|
||||
}
|
||||
// add the fragments of this face
|
||||
R_AddMarkFragments( 3 , clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
if ( returnedFragments == maxFragments ) {
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (*surfaces[i] == SF_TRIANGLES)
|
||||
{
|
||||
const srfTriangles_t * const surf = ( srfTriangles_t * ) surfaces[i];
|
||||
|
||||
for ( k = 0 ; k < surf->numIndexes ; k += 3 )
|
||||
{
|
||||
int i1=surf->indexes[k];
|
||||
int i2=surf->indexes[k+1];
|
||||
int i3=surf->indexes[k+2];
|
||||
VectorSubtract(surf->verts[i1].xyz,surf->verts[i2].xyz, v1);
|
||||
VectorSubtract(surf->verts[i3].xyz,surf->verts[i2].xyz, v2);
|
||||
CrossProduct(v1, v2, normal);
|
||||
VectorNormalizeFast(normal);
|
||||
// check the normal of this triangle
|
||||
if (DotProduct(normal, projectionDir) < -0.1)
|
||||
{
|
||||
VectorMA(surf->verts[i1].xyz, MARKER_OFFSET, normal, clipPoints[0][0]);
|
||||
VectorMA(surf->verts[i2].xyz, MARKER_OFFSET, normal, clipPoints[0][1]);
|
||||
VectorMA(surf->verts[i3].xyz, MARKER_OFFSET, normal, clipPoints[0][2]);
|
||||
|
||||
// add the fragments of this triangle
|
||||
R_AddMarkFragments( 3 , clipPoints,
|
||||
numPlanes, normals, dists,
|
||||
maxPoints, pointBuffer,
|
||||
maxFragments, fragmentBuffer,
|
||||
&returnedPoints, &returnedFragments, mins, maxs);
|
||||
if ( returnedFragments == maxFragments )
|
||||
{
|
||||
return returnedFragments; // not enough space for more fragments
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// ignore all other world surfaces
|
||||
// might be cool to also project polygons on a triangle soup
|
||||
// however this will probably create huge amounts of extra polys
|
||||
// even more than the projection onto curves
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return returnedFragments;
|
||||
}
|
||||
|
437
Projects/Android/jni/OpenJK/code/rd-gles/tr_mesh.cpp
Normal file
437
Projects/Android/jni/OpenJK/code/rd-gles/tr_mesh.cpp
Normal file
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_mesh.c: triangle model functions
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "qcommon/matcomp.h"
|
||||
|
||||
float ProjectRadius( float r, vec3_t location )
|
||||
{
|
||||
float pr;
|
||||
float dist;
|
||||
float c;
|
||||
vec3_t p;
|
||||
float width;
|
||||
float depth;
|
||||
|
||||
c = DotProduct( tr.viewParms.ori.axis[0], tr.viewParms.ori.origin );
|
||||
dist = DotProduct( tr.viewParms.ori.axis[0], location ) - c;
|
||||
|
||||
if ( dist <= 0 )
|
||||
return 0;
|
||||
|
||||
p[0] = 0;
|
||||
p[1] = Q_fabs( r );
|
||||
p[2] = -dist;
|
||||
|
||||
width = p[0] * tr.viewParms.projectionMatrix[1] +
|
||||
p[1] * tr.viewParms.projectionMatrix[5] +
|
||||
p[2] * tr.viewParms.projectionMatrix[9] +
|
||||
tr.viewParms.projectionMatrix[13];
|
||||
|
||||
depth = p[0] * tr.viewParms.projectionMatrix[3] +
|
||||
p[1] * tr.viewParms.projectionMatrix[7] +
|
||||
p[2] * tr.viewParms.projectionMatrix[11] +
|
||||
tr.viewParms.projectionMatrix[15];
|
||||
|
||||
pr = width / depth;
|
||||
|
||||
if ( pr > 1.0f )
|
||||
pr = 1.0f;
|
||||
|
||||
return pr;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_CullModel
|
||||
=============
|
||||
*/
|
||||
static int R_CullModel( md3Header_t *header, trRefEntity_t *ent ) {
|
||||
vec3_t bounds[2];
|
||||
md3Frame_t *oldFrame, *newFrame;
|
||||
int i;
|
||||
|
||||
// compute frame pointers
|
||||
newFrame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + ent->e.frame;
|
||||
oldFrame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + ent->e.oldframe;
|
||||
|
||||
// cull bounding sphere ONLY if this is not an upscaled entity
|
||||
if ( !ent->e.nonNormalizedAxes )
|
||||
{
|
||||
if ( ent->e.frame == ent->e.oldframe )
|
||||
{
|
||||
switch ( R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius ) )
|
||||
{
|
||||
case CULL_OUT:
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
|
||||
case CULL_IN:
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sphereCull, sphereCullB;
|
||||
|
||||
sphereCull = R_CullLocalPointAndRadius( newFrame->localOrigin, newFrame->radius );
|
||||
if ( newFrame == oldFrame ) {
|
||||
sphereCullB = sphereCull;
|
||||
} else {
|
||||
sphereCullB = R_CullLocalPointAndRadius( oldFrame->localOrigin, oldFrame->radius );
|
||||
}
|
||||
|
||||
if ( sphereCull == sphereCullB )
|
||||
{
|
||||
if ( sphereCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
else if ( sphereCull == CULL_IN )
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_sphere_cull_md3_clip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate a bounding box in the current coordinate system
|
||||
for (i = 0 ; i < 3 ; i++) {
|
||||
bounds[0][i] = oldFrame->bounds[0][i] < newFrame->bounds[0][i] ? oldFrame->bounds[0][i] : newFrame->bounds[0][i];
|
||||
bounds[1][i] = oldFrame->bounds[1][i] > newFrame->bounds[1][i] ? oldFrame->bounds[1][i] : newFrame->bounds[1][i];
|
||||
}
|
||||
|
||||
switch ( R_CullLocalBox( bounds ) )
|
||||
{
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
return CULL_IN;
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
return CULL_CLIP;
|
||||
case CULL_OUT:
|
||||
default:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
return CULL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
RE_GetModelBounds
|
||||
|
||||
Returns the bounds of the current model
|
||||
(qhandle_t)hModel and (int)frame need to be set
|
||||
=================
|
||||
*/
|
||||
|
||||
void RE_GetModelBounds(refEntity_t *refEnt, vec3_t bounds1, vec3_t bounds2)
|
||||
{
|
||||
md3Frame_t *frame;
|
||||
md3Header_t *header;
|
||||
model_t *model;
|
||||
|
||||
assert(refEnt);
|
||||
|
||||
model = R_GetModelByHandle( refEnt->hModel );
|
||||
assert(model);
|
||||
header = model->md3[0];
|
||||
assert(header);
|
||||
frame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + refEnt->frame;
|
||||
assert(frame);
|
||||
|
||||
VectorCopy(frame->bounds[0], bounds1);
|
||||
VectorCopy(frame->bounds[1], bounds2);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_ComputeLOD
|
||||
|
||||
=================
|
||||
*/
|
||||
static int R_ComputeLOD( trRefEntity_t *ent ) {
|
||||
float radius;
|
||||
float flod;
|
||||
float projectedRadius;
|
||||
int lod;
|
||||
|
||||
if ( tr.currentModel->numLods < 2 )
|
||||
{ // model has only 1 LOD level, skip computations and bias
|
||||
return(0);
|
||||
}
|
||||
|
||||
// multiple LODs exist, so compute projected bounding sphere
|
||||
// and use that as a criteria for selecting LOD
|
||||
// if ( tr.currentModel->md3[0] )
|
||||
{ //normal md3
|
||||
md3Frame_t *frame;
|
||||
frame = ( md3Frame_t * ) ( ( ( unsigned char * ) tr.currentModel->md3[0] ) + tr.currentModel->md3[0]->ofsFrames );
|
||||
frame += ent->e.frame;
|
||||
radius = RadiusFromBounds( frame->bounds[0], frame->bounds[1] );
|
||||
}
|
||||
|
||||
if ( ( projectedRadius = ProjectRadius( radius, ent->e.origin ) ) != 0 )
|
||||
{
|
||||
flod = 1.0f - projectedRadius * r_lodscale->value;
|
||||
flod *= tr.currentModel->numLods;
|
||||
}
|
||||
else
|
||||
{ // object intersects near view plane, e.g. view weapon
|
||||
flod = 0;
|
||||
}
|
||||
|
||||
lod = Q_ftol( flod );
|
||||
|
||||
if ( lod < 0 ) {
|
||||
lod = 0;
|
||||
} else if ( lod >= tr.currentModel->numLods ) {
|
||||
lod = tr.currentModel->numLods - 1;
|
||||
}
|
||||
|
||||
lod += r_lodbias->integer;
|
||||
if ( lod >= tr.currentModel->numLods )
|
||||
lod = tr.currentModel->numLods - 1;
|
||||
if ( lod < 0 )
|
||||
lod = 0;
|
||||
|
||||
return lod;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_ComputeFogNum
|
||||
|
||||
=================
|
||||
*/
|
||||
static int R_ComputeFogNum( md3Header_t *header, trRefEntity_t *ent ) {
|
||||
int i;
|
||||
jk_fog_t *fog;
|
||||
md3Frame_t *md3Frame;
|
||||
vec3_t localOrigin;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( tr.refdef.doLAGoggles )
|
||||
{
|
||||
return tr.world->numfogs;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: non-normalized axis issues
|
||||
md3Frame = ( md3Frame_t * ) ( ( byte * ) header + header->ofsFrames ) + ent->e.frame;
|
||||
VectorAdd( ent->e.origin, md3Frame->localOrigin, localOrigin );
|
||||
|
||||
int partialFog = 0;
|
||||
for ( i = 1 ; i < tr.world->numfogs ; i++ ) {
|
||||
fog = &tr.world->fogs[i];
|
||||
if ( localOrigin[0] - md3Frame->radius >= fog->bounds[0][0]
|
||||
&& localOrigin[0] + md3Frame->radius <= fog->bounds[1][0]
|
||||
&& localOrigin[1] - md3Frame->radius >= fog->bounds[0][1]
|
||||
&& localOrigin[1] + md3Frame->radius <= fog->bounds[1][1]
|
||||
&& localOrigin[2] - md3Frame->radius >= fog->bounds[0][2]
|
||||
&& localOrigin[2] + md3Frame->radius <= fog->bounds[1][2] )
|
||||
{//totally inside it
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
if ( ( localOrigin[0] - md3Frame->radius >= fog->bounds[0][0] && localOrigin[1] - md3Frame->radius >= fog->bounds[0][1] && localOrigin[2] - md3Frame->radius >= fog->bounds[0][2] &&
|
||||
localOrigin[0] - md3Frame->radius <= fog->bounds[1][0] && localOrigin[1] - md3Frame->radius <= fog->bounds[1][1] && localOrigin[2] - md3Frame->radius <= fog->bounds[1][2]) ||
|
||||
( localOrigin[0] + md3Frame->radius >= fog->bounds[0][0] && localOrigin[1] + md3Frame->radius >= fog->bounds[0][1] && localOrigin[2] + md3Frame->radius >= fog->bounds[0][2] &&
|
||||
localOrigin[0] + md3Frame->radius <= fog->bounds[1][0] && localOrigin[1] + md3Frame->radius <= fog->bounds[1][1] && localOrigin[2] + md3Frame->radius <= fog->bounds[1][2] ) )
|
||||
{//partially inside it
|
||||
if ( tr.refdef.fogIndex == i || R_FogParmsMatch( tr.refdef.fogIndex, i ) )
|
||||
{//take new one only if it's the same one that the viewpoint is in
|
||||
return i;
|
||||
break;
|
||||
}
|
||||
else if ( !partialFog )
|
||||
{//first partialFog
|
||||
partialFog = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if all else fails, return the first partialFog
|
||||
return partialFog;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AddMD3Surfaces
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_AddMD3Surfaces( trRefEntity_t *ent ) {
|
||||
int i;
|
||||
md3Header_t *header = 0;
|
||||
md3Surface_t *surface = 0;
|
||||
md3Shader_t *md3Shader = 0;
|
||||
jk_shader_t *shader = 0;
|
||||
jk_shader_t *main_shader = 0;
|
||||
int cull;
|
||||
int lod;
|
||||
int fogNum;
|
||||
qboolean personalModel;
|
||||
|
||||
// don't add third_person objects if not in a portal
|
||||
personalModel = (qboolean)((ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal);
|
||||
|
||||
if ( ent->e.renderfx & RF_CAP_FRAMES) {
|
||||
if (ent->e.frame > tr.currentModel->md3[0]->numFrames-1)
|
||||
ent->e.frame = tr.currentModel->md3[0]->numFrames-1;
|
||||
if (ent->e.oldframe > tr.currentModel->md3[0]->numFrames-1)
|
||||
ent->e.oldframe = tr.currentModel->md3[0]->numFrames-1;
|
||||
}
|
||||
else if ( ent->e.renderfx & RF_WRAP_FRAMES ) {
|
||||
ent->e.frame %= tr.currentModel->md3[0]->numFrames;
|
||||
ent->e.oldframe %= tr.currentModel->md3[0]->numFrames;
|
||||
}
|
||||
|
||||
//
|
||||
// Validate the frames so there is no chance of a crash.
|
||||
// This will write directly into the entity structure, so
|
||||
// when the surfaces are rendered, they don't need to be
|
||||
// range checked again.
|
||||
//
|
||||
if ( (ent->e.frame >= tr.currentModel->md3[0]->numFrames)
|
||||
|| (ent->e.frame < 0)
|
||||
|| (ent->e.oldframe >= tr.currentModel->md3[0]->numFrames)
|
||||
|| (ent->e.oldframe < 0) )
|
||||
{
|
||||
ri.Printf (PRINT_ALL, "R_AddMD3Surfaces: no such frame %d to %d for '%s'\n",
|
||||
ent->e.oldframe, ent->e.frame,
|
||||
tr.currentModel->name );
|
||||
ent->e.frame = 0;
|
||||
ent->e.oldframe = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// compute LOD
|
||||
//
|
||||
lod = R_ComputeLOD( ent );
|
||||
|
||||
header = tr.currentModel->md3[lod];
|
||||
|
||||
//
|
||||
// cull the entire model if merged bounding box of both frames
|
||||
// is outside the view frustum.
|
||||
//
|
||||
cull = R_CullModel ( header, ent );
|
||||
if ( cull == CULL_OUT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// set up lighting now that we know we aren't culled
|
||||
//
|
||||
if ( !personalModel || r_shadows->integer > 1 ) {
|
||||
R_SetupEntityLighting( &tr.refdef, ent );
|
||||
}
|
||||
|
||||
//
|
||||
// see if we are in a fog volume
|
||||
//
|
||||
fogNum = R_ComputeFogNum( header, ent );
|
||||
|
||||
//
|
||||
// draw all surfaces
|
||||
//
|
||||
main_shader = R_GetShaderByHandle( ent->e.customShader );
|
||||
|
||||
surface = (md3Surface_t *)( (byte *)header + header->ofsSurfaces );
|
||||
for ( i = 0 ; i < header->numSurfaces ; i++ ) {
|
||||
|
||||
if ( ent->e.customShader ) {// a little more efficient
|
||||
shader = main_shader;
|
||||
} else if ( ent->e.customSkin > 0 && ent->e.customSkin < tr.numSkins ) {
|
||||
skin_t *skin;
|
||||
int j;
|
||||
|
||||
skin = R_GetSkinByHandle( ent->e.customSkin );
|
||||
|
||||
// match the surface name to something in the skin file
|
||||
shader = tr.defaultShader;
|
||||
for ( j = 0 ; j < skin->numSurfaces ; j++ ) {
|
||||
// the names have both been lowercased
|
||||
if ( !strcmp( skin->surfaces[j]->name, surface->name ) ) {
|
||||
shader = skin->surfaces[j]->shader;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ( surface->numShaders <= 0 ) {
|
||||
shader = tr.defaultShader;
|
||||
} else {
|
||||
md3Shader = (md3Shader_t *) ( (byte *)surface + surface->ofsShaders );
|
||||
md3Shader += ent->e.skinNum % surface->numShaders;
|
||||
shader = tr.shaders[ md3Shader->shaderIndex ];
|
||||
}
|
||||
|
||||
|
||||
// we will add shadows even if the main object isn't visible in the view
|
||||
|
||||
// stencil shadows can't do personal models unless I polyhedron clip
|
||||
if ( !personalModel
|
||||
&& r_shadows->integer == 2
|
||||
&& fogNum == 0
|
||||
&& (ent->e.renderfx & RF_SHADOW_PLANE )
|
||||
&& !(ent->e.renderfx & ( RF_NOSHADOW | RF_DEPTHHACK ) )
|
||||
&& shader->sort == SS_OPAQUE ) {
|
||||
R_AddDrawSurf( (surfaceType_t *)surface, tr.shadowShader, 0, qfalse );
|
||||
}
|
||||
|
||||
// projection shadows work fine with personal models
|
||||
if ( r_shadows->integer == 3
|
||||
&& fogNum == 0
|
||||
&& (ent->e.renderfx & RF_SHADOW_PLANE )
|
||||
&& shader->sort == SS_OPAQUE ) {
|
||||
R_AddDrawSurf( (surfaceType_t *)surface, tr.projectionShadowShader, 0, qfalse );
|
||||
}
|
||||
|
||||
// don't add third_person objects if not viewing through a portal
|
||||
if ( !personalModel ) {
|
||||
R_AddDrawSurf( (surfaceType_t *)surface, shader, fogNum, qfalse );
|
||||
}
|
||||
|
||||
surface = (md3Surface_t *)( (byte *)surface + surface->ofsEnd );
|
||||
}
|
||||
|
||||
}
|
||||
|
1196
Projects/Android/jni/OpenJK/code/rd-gles/tr_model.cpp
Normal file
1196
Projects/Android/jni/OpenJK/code/rd-gles/tr_model.cpp
Normal file
File diff suppressed because it is too large
Load diff
305
Projects/Android/jni/OpenJK/code/rd-gles/tr_quicksprite.cpp
Normal file
305
Projects/Android/jni/OpenJK/code/rd-gles/tr_quicksprite.cpp
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_QuickSprite.cpp: implementation of the CQuickSpriteSystem class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
#include "../server/exe_headers.h"
|
||||
#include "tr_quicksprite.h"
|
||||
|
||||
extern void R_BindAnimatedImage( const textureBundle_t *bundle );
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Singleton System
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
CQuickSpriteSystem SQuickSprite;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CQuickSpriteSystem::CQuickSpriteSystem() :
|
||||
mTexBundle(NULL),
|
||||
mGLStateBits(0),
|
||||
mFogIndex(-1),
|
||||
mUseFog(qfalse),
|
||||
mNextVert(0)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset( mVerts, 0, sizeof( mVerts ) );
|
||||
memset( mFogTextureCoords, 0, sizeof( mFogTextureCoords ) );
|
||||
memset( mColors, 0, sizeof( mColors ) );
|
||||
|
||||
for (i = 0; i < SHADER_MAX_VERTEXES; i += 4)
|
||||
{
|
||||
// Bottom right
|
||||
mTextureCoords[i + 0][0] = 1.0;
|
||||
mTextureCoords[i + 0][1] = 1.0;
|
||||
// Top right
|
||||
mTextureCoords[i + 1][0] = 1.0;
|
||||
mTextureCoords[i + 1][1] = 0.0;
|
||||
// Top left
|
||||
mTextureCoords[i + 2][0] = 0.0;
|
||||
mTextureCoords[i + 2][1] = 0.0;
|
||||
// Bottom left
|
||||
mTextureCoords[i + 3][0] = 0.0;
|
||||
mTextureCoords[i + 3][1] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
CQuickSpriteSystem::~CQuickSpriteSystem(void)
|
||||
{
|
||||
}
|
||||
|
||||
void CQuickSpriteSystem::Flush(void)
|
||||
{
|
||||
if (mNextVert==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if (mUseFog && r_drawfog->integer == 2 &&
|
||||
mFogIndex == tr.world->globalFog)
|
||||
{ //enable hardware fog when we draw this thing if applicable -rww
|
||||
jk_fog_t *fog = tr.world->fogs + mFogIndex;
|
||||
|
||||
qglFogf(GL_FOG_MODE, GL_EXP2);
|
||||
qglFogf(GL_FOG_DENSITY, logtestExp2 / fog->parms.depthForOpaque);
|
||||
qglFogfv(GL_FOG_COLOR, fog->parms.color);
|
||||
qglEnable(GL_FOG);
|
||||
}
|
||||
*/
|
||||
//this should not be needed, since I just wait to disable fog for the surface til after surface sprites are done
|
||||
|
||||
//
|
||||
// render the main pass
|
||||
//
|
||||
R_BindAnimatedImage( mTexBundle );
|
||||
GL_State(mGLStateBits);
|
||||
|
||||
//
|
||||
// set arrays and lock
|
||||
//
|
||||
#ifdef HAVE_GLES
|
||||
unsigned short indexes[(mNextVert/2)*3];
|
||||
int idx;
|
||||
// split TRIANGLE_FAN in 2 TRIANGLES
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
|
||||
qglEnableClientState( GL_COLOR_ARRAY);
|
||||
/*for (int i=0; i<mNextVert; i+=4) {
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, mTextureCoords+i);
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors+i );
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts+i);
|
||||
qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}*/
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords );
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors );
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts);
|
||||
idx = 0;
|
||||
for (int i=0; i<mNextVert; i+=4) {
|
||||
// Triangle 1
|
||||
indexes[idx+0]=i;
|
||||
indexes[idx+1]=i+1;
|
||||
indexes[idx+2]=i+2;
|
||||
idx+=3;
|
||||
// Triangle 2
|
||||
indexes[idx+0]=i;
|
||||
indexes[idx+1]=i+2;
|
||||
indexes[idx+2]=i+3;
|
||||
idx+=3;
|
||||
}
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
|
||||
#else
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords );
|
||||
|
||||
qglEnableClientState( GL_COLOR_ARRAY);
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors );
|
||||
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts);
|
||||
|
||||
if ( qglLockArraysEXT )
|
||||
{
|
||||
qglLockArraysEXT(0, mNextVert);
|
||||
GLimp_LogComment( "glLockArraysEXT\n" );
|
||||
}
|
||||
|
||||
qglDrawArrays(GL_QUADS, 0, mNextVert);
|
||||
#endif
|
||||
|
||||
backEnd.pc.c_vertexes += mNextVert;
|
||||
backEnd.pc.c_indexes += mNextVert;
|
||||
backEnd.pc.c_totalIndexes += mNextVert;
|
||||
|
||||
#ifdef JK2_MODE
|
||||
if (mUseFog)
|
||||
#else
|
||||
//only for software fog pass (global soft/volumetric) -rww
|
||||
if (mUseFog && (r_drawfog->integer != 2 || mFogIndex != tr.world->globalFog))
|
||||
#endif
|
||||
{
|
||||
jk_fog_t *fog = tr.world->fogs + mFogIndex;
|
||||
|
||||
//
|
||||
// render the fog pass
|
||||
//
|
||||
GL_Bind( tr.fogImage );
|
||||
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
|
||||
|
||||
//
|
||||
// set arrays and lock
|
||||
//
|
||||
#ifdef HAVE_GLES
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglColor4ubv((GLubyte *)&fog->colorInt);
|
||||
/*for (int i=0; i<mNextVert; i+=4) {
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, mFogTextureCoords+i);
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts+i);
|
||||
qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}*/
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, mFogTextureCoords);
|
||||
// qglEnableClientState( GL_TEXTURE_COORD_ARRAY); // Done above
|
||||
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglColor4ubv((GLubyte *)&fog->colorInt);
|
||||
|
||||
// qglVertexPointer (3, GL_FLOAT, 16, mVerts); // Done above
|
||||
|
||||
qglDrawArrays(GL_QUADS, 0, mNextVert);
|
||||
#endif
|
||||
|
||||
// Second pass from fog
|
||||
backEnd.pc.c_totalIndexes += mNextVert;
|
||||
}
|
||||
|
||||
//
|
||||
// unlock arrays
|
||||
//
|
||||
if (qglUnlockArraysEXT)
|
||||
{
|
||||
qglUnlockArraysEXT();
|
||||
GLimp_LogComment( "glUnlockArraysEXT\n" );
|
||||
}
|
||||
|
||||
mNextVert=0;
|
||||
}
|
||||
|
||||
|
||||
void CQuickSpriteSystem::StartGroup(textureBundle_t *bundle, uint32_t glbits, int fogIndex )
|
||||
{
|
||||
mNextVert = 0;
|
||||
|
||||
mTexBundle = bundle;
|
||||
mGLStateBits = glbits;
|
||||
if (fogIndex != -1)
|
||||
{
|
||||
mUseFog = qtrue;
|
||||
mFogIndex = fogIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
mUseFog = qfalse;
|
||||
}
|
||||
|
||||
int cullingOn;
|
||||
qglGetIntegerv(GL_CULL_FACE,&cullingOn);
|
||||
|
||||
if(cullingOn)
|
||||
{
|
||||
mTurnCullBackOn=qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTurnCullBackOn=qfalse;
|
||||
}
|
||||
qglDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
|
||||
void CQuickSpriteSystem::EndGroup(void)
|
||||
{
|
||||
Flush();
|
||||
|
||||
qglColor4ub(255,255,255,255);
|
||||
if(mTurnCullBackOn)
|
||||
{
|
||||
qglEnable(GL_CULL_FACE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CQuickSpriteSystem::Add(float *pointdata, color4ub_t color, vec2_t fog)
|
||||
{
|
||||
float *curcoord;
|
||||
float *curfogtexcoord;
|
||||
uint32_t *curcolor;
|
||||
|
||||
if (mNextVert>SHADER_MAX_VERTEXES-4)
|
||||
{
|
||||
Flush();
|
||||
}
|
||||
|
||||
curcoord = mVerts[mNextVert];
|
||||
// This is 16*sizeof(float) because, pointdata comes from a float[16]
|
||||
memcpy(curcoord, pointdata, 16*sizeof(float));
|
||||
|
||||
// Set up color
|
||||
curcolor = &mColors[mNextVert];
|
||||
*curcolor++ = *(uint32_t *)color;
|
||||
*curcolor++ = *(uint32_t *)color;
|
||||
*curcolor++ = *(uint32_t *)color;
|
||||
*curcolor++ = *(uint32_t *)color;
|
||||
|
||||
if (fog)
|
||||
{
|
||||
curfogtexcoord = &mFogTextureCoords[mNextVert][0];
|
||||
*curfogtexcoord++ = fog[0];
|
||||
*curfogtexcoord++ = fog[1];
|
||||
|
||||
*curfogtexcoord++ = fog[0];
|
||||
*curfogtexcoord++ = fog[1];
|
||||
|
||||
*curfogtexcoord++ = fog[0];
|
||||
*curfogtexcoord++ = fog[1];
|
||||
|
||||
*curfogtexcoord++ = fog[0];
|
||||
*curfogtexcoord++ = fog[1];
|
||||
|
||||
mUseFog=qtrue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mUseFog=qfalse;
|
||||
}
|
||||
|
||||
mNextVert+=4;
|
||||
}
|
58
Projects/Android/jni/OpenJK/code/rd-gles/tr_quicksprite.h
Normal file
58
Projects/Android/jni/OpenJK/code/rd-gles/tr_quicksprite.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
// tr_QuickSprite.h: interface for the CQuickSprite class.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
class CQuickSpriteSystem
|
||||
{
|
||||
private:
|
||||
textureBundle_t *mTexBundle;
|
||||
uint32_t mGLStateBits;
|
||||
int mFogIndex;
|
||||
qboolean mUseFog;
|
||||
vec4_t mVerts[SHADER_MAX_VERTEXES];
|
||||
vec2_t mTextureCoords[SHADER_MAX_VERTEXES]; // Ideally this would be static, cause it never changes
|
||||
vec2_t mFogTextureCoords[SHADER_MAX_VERTEXES];
|
||||
uint32_t mColors[SHADER_MAX_VERTEXES];
|
||||
int mNextVert;
|
||||
qboolean mTurnCullBackOn;
|
||||
|
||||
void Flush(void);
|
||||
|
||||
public:
|
||||
CQuickSpriteSystem(void);
|
||||
~CQuickSpriteSystem(void);
|
||||
|
||||
void StartGroup(textureBundle_t *bundle, uint32_t glbits, int fogIndex = -1);
|
||||
void EndGroup(void);
|
||||
|
||||
void Add(float *pointdata, color4ub_t color, vec2_t fog=NULL);
|
||||
};
|
||||
|
||||
extern CQuickSpriteSystem SQuickSprite;
|
421
Projects/Android/jni/OpenJK/code/rd-gles/tr_scene.cpp
Normal file
421
Projects/Android/jni/OpenJK/code/rd-gles/tr_scene.cpp
Normal file
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
#include <JKVR/VrClientInfo.h>
|
||||
|
||||
int r_firstSceneDrawSurf;
|
||||
|
||||
int r_numdlights;
|
||||
int r_firstSceneDlight;
|
||||
|
||||
int r_numentities;
|
||||
int r_firstSceneEntity;
|
||||
|
||||
int r_numpolys;
|
||||
int r_firstScenePoly;
|
||||
|
||||
int r_numpolyverts;
|
||||
|
||||
int skyboxportal;
|
||||
int drawskyboxportal;
|
||||
int hasskybox; // Used to indicate whether the BSP contains a skybox (if not, then use fog colour if applicable)
|
||||
|
||||
/*
|
||||
====================
|
||||
R_InitNextFrame
|
||||
|
||||
====================
|
||||
*/
|
||||
void R_InitNextFrame( void ) {
|
||||
|
||||
backEndData->commands.used = 0;
|
||||
|
||||
r_firstSceneDrawSurf = 0;
|
||||
|
||||
r_numdlights = 0;
|
||||
r_firstSceneDlight = 0;
|
||||
|
||||
r_numentities = 0;
|
||||
r_firstSceneEntity = 0;
|
||||
|
||||
r_numpolys = 0;
|
||||
r_firstScenePoly = 0;
|
||||
|
||||
r_numpolyverts = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
RE_ClearScene
|
||||
|
||||
====================
|
||||
*/
|
||||
void RE_ClearScene( void ) {
|
||||
r_firstSceneDlight = r_numdlights;
|
||||
r_firstSceneEntity = r_numentities;
|
||||
r_firstScenePoly = r_numpolys;
|
||||
tr.refdef.rdflags &= ~(RDF_doLAGoggles|RDF_doFullbright); //probably not needed since it gets copied over in RE_RenderScene
|
||||
tr.refdef.doLAGoggles = qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
|
||||
DISCRETE POLYS
|
||||
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_AddPolygonSurfaces
|
||||
|
||||
Adds all the scene's polys into this view's drawsurf list
|
||||
=====================
|
||||
*/
|
||||
void R_AddPolygonSurfaces( void ) {
|
||||
int i;
|
||||
jk_shader_t *sh;
|
||||
srfPoly_t *poly;
|
||||
|
||||
tr.currentEntityNum = REFENTITYNUM_WORLD;
|
||||
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_REFENTITYNUM_SHIFT;
|
||||
|
||||
for ( i = 0, poly = tr.refdef.polys; i < tr.refdef.numPolys ; i++, poly++ ) {
|
||||
sh = R_GetShaderByHandle( poly->hShader );
|
||||
R_AddDrawSurf( ( surfaceType_t * )poly, sh, poly->fogIndex, qfalse );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_AddPolyToScene
|
||||
|
||||
=====================
|
||||
*/
|
||||
void RE_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) {
|
||||
srfPoly_t *poly;
|
||||
int i;
|
||||
int fogIndex = 0;
|
||||
jk_fog_t *fog;
|
||||
vec3_t bounds[2];
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !hShader ) {
|
||||
#ifndef FINAL_BUILD
|
||||
Com_DPrintf( S_COLOR_YELLOW"WARNING: RE_AddPolyToScene: NULL poly shader\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if ( r_numpolyverts + numVerts >= MAX_POLYVERTS || r_numpolys >= MAX_POLYS ) {
|
||||
/*
|
||||
NOTE TTimo this was initially a PRINT_WARNING
|
||||
but it happens a lot with high fighting scenes and particles
|
||||
since we don't plan on changing the const and making for room for those effects
|
||||
simply cut this message to developer only
|
||||
*/
|
||||
ri.Printf( PRINT_DEVELOPER, S_COLOR_YELLOW "WARNING: RE_AddPolyToScene: r_max_polys or r_max_polyverts reached\n");
|
||||
return;
|
||||
}
|
||||
|
||||
poly = &backEndData->polys[r_numpolys];
|
||||
poly->surfaceType = SF_POLY;
|
||||
poly->hShader = hShader;
|
||||
poly->numVerts = numVerts;
|
||||
poly->verts = &backEndData->polyVerts[r_numpolyverts];
|
||||
|
||||
memcpy( poly->verts, verts, numVerts * sizeof( *verts ) );
|
||||
r_numpolys++;
|
||||
r_numpolyverts += numVerts;
|
||||
|
||||
// see if it is in a fog volume
|
||||
if ( !tr.world || tr.world->numfogs == 1) {
|
||||
fogIndex = 0;
|
||||
} else {
|
||||
// find which fog volume the poly is in
|
||||
VectorCopy( poly->verts[0].xyz, bounds[0] );
|
||||
VectorCopy( poly->verts[0].xyz, bounds[1] );
|
||||
for ( i = 1 ; i < poly->numVerts ; i++ ) {
|
||||
AddPointToBounds( poly->verts[i].xyz, bounds[0], bounds[1] );
|
||||
}
|
||||
for ( int fI = 1 ; fI < tr.world->numfogs ; fI++ ) {
|
||||
fog = &tr.world->fogs[fI];
|
||||
if ( bounds[0][0] >= fog->bounds[0][0]
|
||||
&& bounds[0][1] >= fog->bounds[0][1]
|
||||
&& bounds[0][2] >= fog->bounds[0][2]
|
||||
&& bounds[1][0] <= fog->bounds[1][0]
|
||||
&& bounds[1][1] <= fog->bounds[1][1]
|
||||
&& bounds[1][2] <= fog->bounds[1][2] )
|
||||
{//completely in this one
|
||||
fogIndex = fI;
|
||||
break;
|
||||
}
|
||||
else if ( ( bounds[0][0] >= fog->bounds[0][0] && bounds[0][1] >= fog->bounds[0][1] && bounds[0][2] >= fog->bounds[0][2] &&
|
||||
bounds[0][0] <= fog->bounds[1][0] && bounds[0][1] <= fog->bounds[1][1] && bounds[0][2] <= fog->bounds[1][2]) ||
|
||||
( bounds[1][0] >= fog->bounds[0][0] && bounds[1][1] >= fog->bounds[0][1] && bounds[1][2] >= fog->bounds[0][2] &&
|
||||
bounds[1][0] <= fog->bounds[1][0] && bounds[1][1] <= fog->bounds[1][1] && bounds[1][2] <= fog->bounds[1][2] ) )
|
||||
{//partially in this one
|
||||
if ( tr.refdef.fogIndex == fI || R_FogParmsMatch( tr.refdef.fogIndex, fI ) )
|
||||
{//take new one only if it's the same one that the viewpoint is in
|
||||
fogIndex = fI;
|
||||
break;
|
||||
}
|
||||
else if ( !fogIndex )
|
||||
{//didn't find one yet, so use this one
|
||||
fogIndex = fI;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->fogIndex = fogIndex;
|
||||
}
|
||||
|
||||
|
||||
//=================================================================================
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_AddRefEntityToScene
|
||||
|
||||
=====================
|
||||
*/
|
||||
void RE_AddRefEntityToScene( const refEntity_t *ent ) {
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
if ( r_numentities >= MAX_REFENTITIES ) {
|
||||
#ifndef FINAL_BUILD
|
||||
ri.Printf( PRINT_WARNING, "WARNING: RE_AddRefEntityToScene: too many entities\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) {
|
||||
Com_Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType );
|
||||
}
|
||||
|
||||
backEndData->entities[r_numentities].e = *ent;
|
||||
backEndData->entities[r_numentities].lightingCalculated = qfalse;
|
||||
|
||||
r_numentities++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_AddLightToScene
|
||||
|
||||
=====================
|
||||
*/
|
||||
void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
|
||||
dlight_t *dl;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
if ( r_numdlights >= MAX_DLIGHTS ) {
|
||||
return;
|
||||
}
|
||||
if ( intensity <= 0 ) {
|
||||
return;
|
||||
}
|
||||
dl = &backEndData->dlights[r_numdlights++];
|
||||
VectorCopy (org, dl->origin);
|
||||
dl->radius = intensity;
|
||||
dl->color[0] = r;
|
||||
dl->color[1] = g;
|
||||
dl->color[2] = b;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
RE_RenderScene
|
||||
|
||||
Draw a 3D view into a part of the window, then return
|
||||
to 2D drawing.
|
||||
|
||||
Rendering a scene may require multiple views to be rendered
|
||||
to handle mirrors,
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
*/
|
||||
extern int recursivePortalCount;
|
||||
void RE_RenderScene( const refdef_t *fd ) {
|
||||
viewParms_t parms;
|
||||
int startTime;
|
||||
static int lastTime = 0;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
GLimp_LogComment( "====== RE_RenderScene =====\n" );
|
||||
|
||||
if ( r_norefresh->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
startTime = ri.Milliseconds();
|
||||
|
||||
if (!tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
|
||||
Com_Error (ERR_DROP, "R_RenderScene: NULL worldmodel");
|
||||
}
|
||||
|
||||
// memcpy( tr.refdef.text, fd->text, sizeof( tr.refdef.text ) );
|
||||
|
||||
tr.refdef.x = fd->x;
|
||||
tr.refdef.y = fd->y;
|
||||
tr.refdef.width = fd->width;
|
||||
tr.refdef.height = fd->height;
|
||||
tr.refdef.fov_x = fd->fov_x;
|
||||
tr.refdef.fov_y = fd->fov_y;
|
||||
|
||||
memset( &parms, 0, sizeof( parms ) );
|
||||
VectorCopy( fd->viewaxis[0], parms.ori.axis[0] );
|
||||
VectorCopy( fd->viewaxis[1], parms.ori.axis[1] );
|
||||
VectorCopy( fd->viewaxis[2], parms.ori.axis[2] );
|
||||
|
||||
VectorCopy( fd->vieworg, tr.refdef.vieworg );
|
||||
VectorCopy( fd->viewaxis[0], tr.refdef.viewaxis[0] );
|
||||
VectorCopy( fd->viewaxis[1], tr.refdef.viewaxis[1] );
|
||||
VectorCopy( fd->viewaxis[2], tr.refdef.viewaxis[2] );
|
||||
|
||||
tr.refdef.time = fd->time;
|
||||
tr.refdef.frametime = fd->time - lastTime;
|
||||
tr.refdef.rdflags = fd->rdflags;
|
||||
// Ignore my last there. This actually breaks the rest of the game as well, causing massive issues.
|
||||
// We need to figure out what's going on in fd->rdflags first :S .. I'm half-tempted to just revert
|
||||
// back to JK2 and use a qbool for it --eez
|
||||
|
||||
if (fd->rdflags & RDF_SKYBOXPORTAL)
|
||||
{
|
||||
skyboxportal = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// cdr - only change last time for the real render, not the portal
|
||||
lastTime = fd->time;
|
||||
}
|
||||
|
||||
if (fd->rdflags & RDF_DRAWSKYBOX)
|
||||
{
|
||||
drawskyboxportal = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
drawskyboxportal = 0;
|
||||
}
|
||||
|
||||
// copy the areamask data over and note if it has changed, which
|
||||
// will force a reset of the visible leafs even if the view hasn't moved
|
||||
tr.refdef.areamaskModified = qfalse;
|
||||
if ( ! (tr.refdef.rdflags & RDF_NOWORLDMODEL) ) {
|
||||
int areaDiff;
|
||||
int i;
|
||||
|
||||
// compare the area bits
|
||||
areaDiff = 0;
|
||||
for (i = 0 ; i < MAX_MAP_AREA_BYTES/4 ; i++) {
|
||||
areaDiff |= ((int *)tr.refdef.areamask)[i] ^ ((int *)fd->areamask)[i];
|
||||
((int *)tr.refdef.areamask)[i] = ((int *)fd->areamask)[i];
|
||||
}
|
||||
|
||||
if ( areaDiff ) {
|
||||
// a door just opened or something
|
||||
tr.refdef.areamaskModified = qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// derived info
|
||||
|
||||
tr.refdef.floatTime = tr.refdef.time * 0.001;
|
||||
|
||||
tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
|
||||
tr.refdef.drawSurfs = backEndData->drawSurfs;
|
||||
|
||||
tr.refdef.num_entities = r_numentities - r_firstSceneEntity;
|
||||
tr.refdef.entities = &backEndData->entities[r_firstSceneEntity];
|
||||
tr.refdef.num_dlights = r_numdlights - r_firstSceneDlight;
|
||||
tr.refdef.dlights = &backEndData->dlights[r_firstSceneDlight];
|
||||
|
||||
tr.refdef.numPolys = r_numpolys - r_firstScenePoly;
|
||||
tr.refdef.polys = &backEndData->polys[r_firstScenePoly];
|
||||
|
||||
// turn off dynamic lighting globally by clearing all the
|
||||
// dlights if it needs to be disabled or if vertex lighting is enabled
|
||||
if ( r_dynamiclight->integer == 0 ||
|
||||
r_vertexLight->integer == 1 ) {
|
||||
tr.refdef.num_dlights = 0;
|
||||
}
|
||||
|
||||
// a single frame may have multiple scenes draw inside it --
|
||||
// a 3D game view, 3D status bar renderings, 3D menus, etc.
|
||||
// They need to be distinguished by the light flare code, because
|
||||
// the visibility state for a given surface may be different in
|
||||
// each scene / view.
|
||||
tr.frameSceneNum++;
|
||||
tr.sceneCount++;
|
||||
|
||||
// setup view parms for the initial view
|
||||
//
|
||||
// set up viewport
|
||||
// The refdef takes 0-at-the-top y coordinates, so
|
||||
// convert to GL's 0-at-the-bottom space
|
||||
//
|
||||
parms.viewportX = tr.refdef.x;
|
||||
parms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.refdef.height );
|
||||
parms.viewportWidth = tr.refdef.width;
|
||||
parms.viewportHeight = tr.refdef.height;
|
||||
parms.isPortal = qfalse;
|
||||
|
||||
parms.fovX = tr.refdef.fov_x;
|
||||
parms.fovY = tr.refdef.fov_y;
|
||||
|
||||
VectorCopy( fd->vieworg, parms.ori.origin );
|
||||
// VectorCopy( fd->viewaxis[0], parms.ori.axis[0] );
|
||||
// VectorCopy( fd->viewaxis[1], parms.ori.axis[1] );
|
||||
// VectorCopy( fd->viewaxis[2], parms.ori.axis[2] );
|
||||
|
||||
VectorCopy( fd->vieworg, parms.pvsOrigin );
|
||||
|
||||
recursivePortalCount = 0;
|
||||
R_RenderView( &parms );
|
||||
|
||||
// the next scene rendered in this frame will tack on after this one
|
||||
r_firstSceneDrawSurf = tr.refdef.numDrawSurfs;
|
||||
r_firstSceneEntity = r_numentities;
|
||||
r_firstSceneDlight = r_numdlights;
|
||||
r_firstScenePoly = r_numpolys;
|
||||
|
||||
tr.frontEndMsec += ri.Milliseconds() - startTime;
|
||||
RE_RenderWorldEffects();
|
||||
}
|
2255
Projects/Android/jni/OpenJK/code/rd-gles/tr_shade.cpp
Normal file
2255
Projects/Android/jni/OpenJK/code/rd-gles/tr_shade.cpp
Normal file
File diff suppressed because it is too large
Load diff
1388
Projects/Android/jni/OpenJK/code/rd-gles/tr_shade_calc.cpp
Normal file
1388
Projects/Android/jni/OpenJK/code/rd-gles/tr_shade_calc.cpp
Normal file
File diff suppressed because it is too large
Load diff
3889
Projects/Android/jni/OpenJK/code/rd-gles/tr_shader.cpp
Normal file
3889
Projects/Android/jni/OpenJK/code/rd-gles/tr_shader.cpp
Normal file
File diff suppressed because it is too large
Load diff
881
Projects/Android/jni/OpenJK/code/rd-gles/tr_shadows.cpp
Normal file
881
Projects/Android/jni/OpenJK/code/rd-gles/tr_shadows.cpp
Normal file
|
@ -0,0 +1,881 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
/*
|
||||
|
||||
for a projection shadow:
|
||||
|
||||
point[x] += light vector * ( z - shadow plane )
|
||||
point[y] +=
|
||||
point[z] = shadow plane
|
||||
|
||||
1 0 light[x] / light[z]
|
||||
|
||||
*/
|
||||
|
||||
#define _STENCIL_REVERSE
|
||||
|
||||
typedef struct {
|
||||
int i2;
|
||||
int facing;
|
||||
} edgeDef_t;
|
||||
|
||||
#define MAX_EDGE_DEFS 32
|
||||
|
||||
static edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS];
|
||||
static int numEdgeDefs[SHADER_MAX_VERTEXES];
|
||||
static int facing[SHADER_MAX_INDEXES/3];
|
||||
static vec3_t shadowXyz[SHADER_MAX_VERTEXES];
|
||||
#ifdef HAVE_GLES
|
||||
static unsigned short indexes[6 * MAX_EDGE_DEFS * SHADER_MAX_VERTEXES + SHADER_MAX_INDEXES * 2];
|
||||
static int idx = 0;
|
||||
#endif
|
||||
|
||||
void R_AddEdgeDef( int i1, int i2, int facing ) {
|
||||
int c;
|
||||
|
||||
c = numEdgeDefs[ i1 ];
|
||||
if ( c == MAX_EDGE_DEFS ) {
|
||||
return; // overflow
|
||||
}
|
||||
edgeDefs[ i1 ][ c ].i2 = i2;
|
||||
edgeDefs[ i1 ][ c ].facing = facing;
|
||||
|
||||
numEdgeDefs[ i1 ]++;
|
||||
}
|
||||
|
||||
void R_RenderShadowEdges( void ) {
|
||||
int i;
|
||||
int c;
|
||||
int j;
|
||||
int i2;
|
||||
#if 0
|
||||
int c_edges, c_rejected;
|
||||
int c2, k;
|
||||
int hit[2];
|
||||
#endif
|
||||
#ifdef _STENCIL_REVERSE
|
||||
int numTris;
|
||||
int o1, o2, o3;
|
||||
#endif
|
||||
|
||||
// an edge is NOT a silhouette edge if its face doesn't face the light,
|
||||
// or if it has a reverse paired edge that also faces the light.
|
||||
// A well behaved polyhedron would have exactly two faces for each edge,
|
||||
// but lots of models have dangling edges or overfanned edges
|
||||
#if 0
|
||||
c_edges = 0;
|
||||
c_rejected = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
idx = 0;
|
||||
#endif
|
||||
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
|
||||
c = numEdgeDefs[ i ];
|
||||
for ( j = 0 ; j < c ; j++ ) {
|
||||
if ( !edgeDefs[ i ][ j ].facing ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//with this system we can still get edges shared by more than 2 tris which
|
||||
//produces artifacts including seeing the shadow through walls. So for now
|
||||
//we are going to render all edges even though it is a tiny bit slower. -rww
|
||||
#if 1
|
||||
i2 = edgeDefs[ i ][ j ].i2;
|
||||
#ifdef HAVE_GLES
|
||||
// A single drawing call is better than many. So I prefer a singe TRIANGLES call than many TRIANGLE_STRIP call
|
||||
// even if it seems less efficiant, it's faster on the PANDORA
|
||||
indexes[idx++] = i;
|
||||
indexes[idx++] = i + tess.numVertexes;
|
||||
indexes[idx++] = i2;
|
||||
indexes[idx++] = i2;
|
||||
indexes[idx++] = i + tess.numVertexes;
|
||||
indexes[idx++] = i2 + tess.numVertexes;
|
||||
#else
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
qglVertex3fv( tess.xyz[ i ] );
|
||||
qglVertex3fv( tess.xyz[ i + tess.numVertexes ] );
|
||||
qglVertex3fv( tess.xyz[ i2 ] );
|
||||
qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] );
|
||||
qglEnd();
|
||||
#endif
|
||||
#else
|
||||
hit[0] = 0;
|
||||
hit[1] = 0;
|
||||
|
||||
i2 = edgeDefs[ i ][ j ].i2;
|
||||
c2 = numEdgeDefs[ i2 ];
|
||||
for ( k = 0 ; k < c2 ; k++ ) {
|
||||
if ( edgeDefs[ i2 ][ k ].i2 == i ) {
|
||||
hit[ edgeDefs[ i2 ][ k ].facing ]++;
|
||||
}
|
||||
}
|
||||
|
||||
// if it doesn't share the edge with another front facing
|
||||
// triangle, it is a sil edge
|
||||
if (hit[1] != 1)
|
||||
{
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
qglVertex3fv( tess.xyz[ i ] );
|
||||
qglVertex3fv( tess.xyz[ i + tess.numVertexes ] );
|
||||
qglVertex3fv( tess.xyz[ i2 ] );
|
||||
qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] );
|
||||
qglEnd();
|
||||
c_edges++;
|
||||
} else {
|
||||
c_rejected++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _STENCIL_REVERSE
|
||||
//Carmack Reverse<tm> method requires that volumes
|
||||
//be capped properly -rww
|
||||
numTris = tess.numIndexes / 3;
|
||||
|
||||
for ( i = 0 ; i < numTris ; i++ )
|
||||
{
|
||||
if ( !facing[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
o1 = tess.indexes[ i*3 + 0 ];
|
||||
o2 = tess.indexes[ i*3 + 1 ];
|
||||
o3 = tess.indexes[ i*3 + 2 ];
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
indexes[idx++]=o1;
|
||||
indexes[idx++]=o2;
|
||||
indexes[idx++]=o3;
|
||||
indexes[idx++]=o3 + tess.numVertexes;
|
||||
indexes[idx++]=o2 + tess.numVertexes;
|
||||
indexes[idx++]=o1 + tess.numVertexes;
|
||||
#else
|
||||
qglBegin(GL_TRIANGLES);
|
||||
qglVertex3fv(tess.xyz[o1]);
|
||||
qglVertex3fv(tess.xyz[o2]);
|
||||
qglVertex3fv(tess.xyz[o3]);
|
||||
qglEnd();
|
||||
qglBegin(GL_TRIANGLES);
|
||||
qglVertex3fv(tess.xyz[o3 + tess.numVertexes]);
|
||||
qglVertex3fv(tess.xyz[o2 + tess.numVertexes]);
|
||||
qglVertex3fv(tess.xyz[o1 + tess.numVertexes]);
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//#define _DEBUG_STENCIL_SHADOWS
|
||||
|
||||
/*
|
||||
=================
|
||||
RB_ShadowTessEnd
|
||||
|
||||
triangleFromEdge[ v1 ][ v2 ]
|
||||
|
||||
|
||||
set triangle from edge( v1, v2, tri )
|
||||
if ( facing[ triangleFromEdge[ v1 ][ v2 ] ] && !facing[ triangleFromEdge[ v2 ][ v1 ] ) {
|
||||
}
|
||||
=================
|
||||
*/
|
||||
void RB_DoShadowTessEnd( vec3_t lightPos );
|
||||
void RB_ShadowTessEnd( void )
|
||||
{
|
||||
#if 0
|
||||
if (backEnd.currentEntity &&
|
||||
(backEnd.currentEntity->directedLight[0] ||
|
||||
backEnd.currentEntity->directedLight[1] ||
|
||||
backEnd.currentEntity->directedLight[2]))
|
||||
{ //an ent that has its light set for it
|
||||
RB_DoShadowTessEnd(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// if (!tess.dlightBits)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
int i = 0;
|
||||
dlight_t *dl;
|
||||
|
||||
R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.ori );
|
||||
/* while (i < tr.refdef.num_dlights)
|
||||
{
|
||||
if (tess.dlightBits & (1 << i))
|
||||
{
|
||||
dl = &tr.refdef.dlights[i];
|
||||
|
||||
RB_DoShadowTessEnd(dl->transformed);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
*/
|
||||
dl = &tr.refdef.dlights[0];
|
||||
|
||||
RB_DoShadowTessEnd(dl->transformed);
|
||||
|
||||
#else //old ents-only way
|
||||
RB_DoShadowTessEnd(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RB_DoShadowTessEnd( vec3_t lightPos )
|
||||
{
|
||||
int i;
|
||||
int numTris;
|
||||
vec3_t lightDir;
|
||||
|
||||
// we can only do this if we have enough space in the vertex buffers
|
||||
if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( glConfig.stencilBits < 4 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if 1 //controlled method - try to keep shadows in range so they don't show through so much -rww
|
||||
vec3_t worldxyz;
|
||||
vec3_t entLight;
|
||||
float groundDist;
|
||||
|
||||
VectorCopy( backEnd.currentEntity->lightDir, entLight );
|
||||
entLight[2] = 0.0f;
|
||||
VectorNormalize(entLight);
|
||||
|
||||
//Oh well, just cast them straight down no matter what onto the ground plane.
|
||||
//This presets no chance of screwups and still looks better than a stupid
|
||||
//shader blob.
|
||||
VectorSet(lightDir, entLight[0]*0.3f, entLight[1]*0.3f, 1.0f);
|
||||
// project vertexes away from light direction
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
|
||||
//add or.origin to vert xyz to end up with world oriented coord, then figure
|
||||
//out the ground pos for the vert to project the shadow volume to
|
||||
VectorAdd(tess.xyz[i], backEnd.ori.origin, worldxyz);
|
||||
groundDist = worldxyz[2] - backEnd.currentEntity->e.shadowPlane;
|
||||
groundDist += 16.0f; //fudge factor
|
||||
VectorMA( tess.xyz[i], -groundDist, lightDir, tess.xyz[i+tess.numVertexes] );
|
||||
}
|
||||
#else
|
||||
if (lightPos)
|
||||
{
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ )
|
||||
{
|
||||
tess.xyz[i+tess.numVertexes][0] = tess.xyz[i][0]+(( tess.xyz[i][0]-lightPos[0] )*128.0f);
|
||||
tess.xyz[i+tess.numVertexes][1] = tess.xyz[i][1]+(( tess.xyz[i][1]-lightPos[1] )*128.0f);
|
||||
tess.xyz[i+tess.numVertexes][2] = tess.xyz[i][2]+(( tess.xyz[i][2]-lightPos[2] )*128.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( backEnd.currentEntity->lightDir, lightDir );
|
||||
|
||||
// project vertexes away from light direction
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
|
||||
VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// decide which triangles face the light
|
||||
memset( numEdgeDefs, 0, 4 * tess.numVertexes );
|
||||
|
||||
numTris = tess.numIndexes / 3;
|
||||
for ( i = 0 ; i < numTris ; i++ ) {
|
||||
int i1, i2, i3;
|
||||
vec3_t d1, d2, normal;
|
||||
float *v1, *v2, *v3;
|
||||
float d;
|
||||
|
||||
i1 = tess.indexes[ i*3 + 0 ];
|
||||
i2 = tess.indexes[ i*3 + 1 ];
|
||||
i3 = tess.indexes[ i*3 + 2 ];
|
||||
|
||||
v1 = tess.xyz[ i1 ];
|
||||
v2 = tess.xyz[ i2 ];
|
||||
v3 = tess.xyz[ i3 ];
|
||||
|
||||
if (!lightPos)
|
||||
{
|
||||
VectorSubtract( v2, v1, d1 );
|
||||
VectorSubtract( v3, v1, d2 );
|
||||
CrossProduct( d1, d2, normal );
|
||||
|
||||
d = DotProduct( normal, lightDir );
|
||||
}
|
||||
else
|
||||
{
|
||||
float planeEq[4];
|
||||
planeEq[0] = v1[1]*(v2[2]-v3[2]) + v2[1]*(v3[2]-v1[2]) + v3[1]*(v1[2]-v2[2]);
|
||||
planeEq[1] = v1[2]*(v2[0]-v3[0]) + v2[2]*(v3[0]-v1[0]) + v3[2]*(v1[0]-v2[0]);
|
||||
planeEq[2] = v1[0]*(v2[1]-v3[1]) + v2[0]*(v3[1]-v1[1]) + v3[0]*(v1[1]-v2[1]);
|
||||
planeEq[3] = -( v1[0]*( v2[1]*v3[2] - v3[1]*v2[2] ) +
|
||||
v2[0]*(v3[1]*v1[2] - v1[1]*v3[2]) +
|
||||
v3[0]*(v1[1]*v2[2] - v2[1]*v1[2]) );
|
||||
|
||||
d = planeEq[0]*lightPos[0]+
|
||||
planeEq[1]*lightPos[1]+
|
||||
planeEq[2]*lightPos[2]+
|
||||
planeEq[3];
|
||||
}
|
||||
|
||||
if ( d > 0 ) {
|
||||
facing[ i ] = 1;
|
||||
} else {
|
||||
facing[ i ] = 0;
|
||||
}
|
||||
|
||||
// create the edges
|
||||
R_AddEdgeDef( i1, i2, facing[ i ] );
|
||||
R_AddEdgeDef( i2, i3, facing[ i ] );
|
||||
R_AddEdgeDef( i3, i1, facing[ i ] );
|
||||
}
|
||||
|
||||
GL_Bind( tr.whiteImage );
|
||||
//qglEnable( GL_CULL_FACE );
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
|
||||
#ifndef _DEBUG_STENCIL_SHADOWS
|
||||
qglColor3f( 0.2f, 0.2f, 0.2f );
|
||||
|
||||
// don't write to the color buffer
|
||||
qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
|
||||
|
||||
qglEnable( GL_STENCIL_TEST );
|
||||
qglStencilFunc( GL_ALWAYS, 1, 255 );
|
||||
#else
|
||||
qglColor3f( 1.0f, 0.0f, 0.0f );
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
//qglDisable(GL_DEPTH_TEST);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglVertexPointer (3, GL_FLOAT, 16, tess.xyz);
|
||||
#endif
|
||||
|
||||
#ifdef _STENCIL_REVERSE
|
||||
qglDepthFunc(GL_LESS);
|
||||
|
||||
//now using the Carmack Reverse<tm> -rww
|
||||
if ( backEnd.viewParms.isMirror ) {
|
||||
//qglCullFace( GL_BACK );
|
||||
GL_Cull(CT_BACK_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
|
||||
|
||||
R_RenderShadowEdges();
|
||||
|
||||
//qglCullFace( GL_FRONT );
|
||||
GL_Cull(CT_FRONT_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
} else {
|
||||
//qglCullFace( GL_FRONT );
|
||||
GL_Cull(CT_FRONT_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
|
||||
|
||||
R_RenderShadowEdges();
|
||||
|
||||
//qglCullFace( GL_BACK );
|
||||
GL_Cull(CT_BACK_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
}
|
||||
|
||||
qglDepthFunc(GL_LEQUAL);
|
||||
#else
|
||||
// mirrors have the culling order reversed
|
||||
if ( backEnd.viewParms.isMirror ) {
|
||||
qglCullFace( GL_FRONT );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
|
||||
|
||||
R_RenderShadowEdges();
|
||||
|
||||
qglCullFace( GL_BACK );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
} else {
|
||||
qglCullFace( GL_BACK );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
|
||||
|
||||
R_RenderShadowEdges();
|
||||
|
||||
qglCullFace( GL_FRONT );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// reenable writing to the color buffer
|
||||
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG_STENCIL_SHADOWS
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
RB_ShadowFinish
|
||||
|
||||
Darken everything that is is a shadow volume.
|
||||
We have to delay this until everything has been shadowed,
|
||||
because otherwise shadows from different body parts would
|
||||
overlap and double darken.
|
||||
=================
|
||||
*/
|
||||
void RB_ShadowFinish( void ) {
|
||||
if ( r_shadows->integer != 2 ) {
|
||||
return;
|
||||
}
|
||||
if ( glConfig.stencilBits < 4 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_STENCIL_SHADOWS
|
||||
return;
|
||||
#endif
|
||||
|
||||
qglEnable( GL_STENCIL_TEST );
|
||||
qglStencilFunc( GL_NOTEQUAL, 0, 255 );
|
||||
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
|
||||
|
||||
bool planeZeroBack = false;
|
||||
if (qglIsEnabled(GL_CLIP_PLANE0))
|
||||
{
|
||||
planeZeroBack = true;
|
||||
qglDisable (GL_CLIP_PLANE0);
|
||||
}
|
||||
GL_Cull(CT_TWO_SIDED);
|
||||
//qglDisable (GL_CULL_FACE);
|
||||
|
||||
GL_Bind( tr.whiteImage );
|
||||
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
|
||||
// qglColor3f( 0.6f, 0.6f, 0.6f );
|
||||
// GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO );
|
||||
|
||||
// qglColor3f( 1, 0, 0 );
|
||||
// GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
|
||||
|
||||
qglColor4f( 0.0f, 0.0f, 0.0f, 0.5f );
|
||||
//GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
|
||||
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
GLfloat vtx[] = {
|
||||
-100, 100, -10,
|
||||
100, 100, -10,
|
||||
100, -100, -10,
|
||||
-100, -100, -10
|
||||
};
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglVertexPointer ( 3, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
#else
|
||||
qglBegin( GL_QUADS );
|
||||
qglVertex3f( -100, 100, -10 );
|
||||
qglVertex3f( 100, 100, -10 );
|
||||
qglVertex3f( 100, -100, -10 );
|
||||
qglVertex3f( -100, -100, -10 );
|
||||
qglEnd ();
|
||||
#endif
|
||||
|
||||
qglColor4f(1,1,1,1);
|
||||
qglDisable( GL_STENCIL_TEST );
|
||||
if (planeZeroBack)
|
||||
{
|
||||
qglEnable (GL_CLIP_PLANE0);
|
||||
}
|
||||
qglPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
RB_ProjectionShadowDeform
|
||||
|
||||
=================
|
||||
*/
|
||||
void RB_ProjectionShadowDeform( void ) {
|
||||
float *xyz;
|
||||
int i;
|
||||
float h;
|
||||
vec3_t ground;
|
||||
vec3_t light;
|
||||
float groundDist;
|
||||
float d;
|
||||
vec3_t lightDir;
|
||||
|
||||
xyz = ( float * ) tess.xyz;
|
||||
|
||||
ground[0] = backEnd.ori.axis[0][2];
|
||||
ground[1] = backEnd.ori.axis[1][2];
|
||||
ground[2] = backEnd.ori.axis[2][2];
|
||||
|
||||
groundDist = backEnd.ori.origin[2] - backEnd.currentEntity->e.shadowPlane;
|
||||
|
||||
VectorCopy( backEnd.currentEntity->lightDir, lightDir );
|
||||
d = DotProduct( lightDir, ground );
|
||||
// don't let the shadows get too long or go negative
|
||||
if ( d < 0.5 ) {
|
||||
VectorMA( lightDir, (0.5 - d), ground, lightDir );
|
||||
d = DotProduct( lightDir, ground );
|
||||
}
|
||||
d = 1.0 / d;
|
||||
|
||||
light[0] = lightDir[0] * d;
|
||||
light[1] = lightDir[1] * d;
|
||||
light[2] = lightDir[2] * d;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++, xyz += 4 ) {
|
||||
h = DotProduct( xyz, ground ) + groundDist;
|
||||
|
||||
xyz[0] -= light[0] * h;
|
||||
xyz[1] -= light[1] * h;
|
||||
xyz[2] -= light[2] * h;
|
||||
}
|
||||
}
|
||||
|
||||
//update tr.screenImage
|
||||
void RB_CaptureScreenImage(void)
|
||||
{
|
||||
int radX = 2048;
|
||||
int radY = 2048;
|
||||
int x = glConfig.vidWidth/2;
|
||||
int y = glConfig.vidHeight/2;
|
||||
int cX, cY;
|
||||
|
||||
GL_Bind( tr.screenImage );
|
||||
//using this method, we could pixel-filter the texture and all sorts of crazy stuff.
|
||||
//but, it is slow as hell.
|
||||
/*
|
||||
static byte *tmp = NULL;
|
||||
if (!tmp)
|
||||
{
|
||||
tmp = (byte *)R_Malloc((sizeof(byte)*4)*(glConfig.vidWidth*glConfig.vidHeight), TAG_ICARUS, qtrue);
|
||||
}
|
||||
qglReadPixels(0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
|
||||
*/
|
||||
|
||||
if (radX > glConfig.maxTextureSize)
|
||||
{
|
||||
radX = glConfig.maxTextureSize;
|
||||
}
|
||||
if (radY > glConfig.maxTextureSize)
|
||||
{
|
||||
radY = glConfig.maxTextureSize;
|
||||
}
|
||||
|
||||
while (glConfig.vidWidth < radX)
|
||||
{
|
||||
radX /= 2;
|
||||
}
|
||||
while (glConfig.vidHeight < radY)
|
||||
{
|
||||
radY /= 2;
|
||||
}
|
||||
|
||||
cX = x-(radX/2);
|
||||
cY = y-(radY/2);
|
||||
|
||||
if (cX+radX > glConfig.vidWidth)
|
||||
{ //would it go off screen?
|
||||
cX = glConfig.vidWidth-radX;
|
||||
}
|
||||
else if (cX < 0)
|
||||
{ //cap it off at 0
|
||||
cX = 0;
|
||||
}
|
||||
|
||||
if (cY+radY > glConfig.vidHeight)
|
||||
{ //would it go off screen?
|
||||
cY = glConfig.vidHeight-radY;
|
||||
}
|
||||
else if (cY < 0)
|
||||
{ //cap it off at 0
|
||||
cY = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cX, cY, radX, radY, 0);
|
||||
#else
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, cX, cY, radX, radY, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//yeah.. not really shadow-related.. but it's stencil-related. -rww
|
||||
float tr_distortionAlpha = 1.0f; //opaque
|
||||
float tr_distortionStretch = 0.0f; //no stretch override
|
||||
qboolean tr_distortionPrePost = qfalse; //capture before postrender phase?
|
||||
qboolean tr_distortionNegate = qfalse; //negative blend mode
|
||||
void RB_DistortionFill(void)
|
||||
{
|
||||
float alpha = tr_distortionAlpha;
|
||||
float spost = 0.0f;
|
||||
float spost2 = 0.0f;
|
||||
|
||||
if ( glConfig.stencilBits < 4 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//ok, cap the stupid thing now I guess
|
||||
if (!tr_distortionPrePost)
|
||||
{
|
||||
RB_CaptureScreenImage();
|
||||
}
|
||||
|
||||
qglEnable(GL_STENCIL_TEST);
|
||||
qglStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
qglDisable (GL_CLIP_PLANE0);
|
||||
GL_Cull( CT_TWO_SIDED );
|
||||
|
||||
//reset the view matrices and go into ortho mode
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity();
|
||||
qglOrtho(0, glConfig.vidWidth, glConfig.vidHeight, 32, -1, 1);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity();
|
||||
|
||||
if (tr_distortionStretch)
|
||||
{ //override
|
||||
spost = tr_distortionStretch;
|
||||
spost2 = tr_distortionStretch;
|
||||
}
|
||||
else
|
||||
{ //do slow stretchy effect
|
||||
spost = sin(tr.refdef.time*0.0005f);
|
||||
if (spost < 0.0f)
|
||||
{
|
||||
spost = -spost;
|
||||
}
|
||||
spost *= 0.2f;
|
||||
|
||||
spost2 = sin(tr.refdef.time*0.0005f);
|
||||
if (spost2 < 0.0f)
|
||||
{
|
||||
spost2 = -spost2;
|
||||
}
|
||||
spost2 *= 0.08f;
|
||||
}
|
||||
|
||||
if (alpha != 1.0f)
|
||||
{ //blend
|
||||
GL_State(GLS_SRCBLEND_SRC_ALPHA|GLS_DSTBLEND_SRC_ALPHA);
|
||||
}
|
||||
else
|
||||
{ //be sure to reset the draw state
|
||||
GL_State(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
GLfloat tex[] = {
|
||||
0+spost2, 1-spost,
|
||||
0+spost2, 0+spost,
|
||||
1-spost2, 0+spost,
|
||||
1-spost2, 1-spost
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
0, 0,
|
||||
0, glConfig.vidHeight,
|
||||
glConfig.vidWidth, glConfig.vidHeight,
|
||||
glConfig.vidWidth, 0
|
||||
};
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
/* if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );*/
|
||||
#else
|
||||
qglBegin(GL_QUADS);
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
qglTexCoord2f(0+spost2, 1-spost);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
qglTexCoord2f(0+spost2, 0+spost);
|
||||
qglVertex2f(0, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 0+spost);
|
||||
qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 1-spost);
|
||||
qglVertex2f(glConfig.vidWidth, 0);
|
||||
qglEnd();
|
||||
#endif
|
||||
|
||||
if (tr_distortionAlpha == 1.0f && tr_distortionStretch == 0.0f)
|
||||
{ //no overrides
|
||||
if (tr_distortionNegate)
|
||||
{ //probably the crazy alternate saber trail
|
||||
alpha = 0.8f;
|
||||
GL_State(GLS_SRCBLEND_ZERO|GLS_DSTBLEND_ONE_MINUS_SRC_COLOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = 0.5f;
|
||||
GL_State(GLS_SRCBLEND_SRC_ALPHA|GLS_DSTBLEND_SRC_ALPHA);
|
||||
}
|
||||
|
||||
spost = sin(tr.refdef.time*0.0008f);
|
||||
if (spost < 0.0f)
|
||||
{
|
||||
spost = -spost;
|
||||
}
|
||||
spost *= 0.08f;
|
||||
|
||||
spost2 = sin(tr.refdef.time*0.0008f);
|
||||
if (spost2 < 0.0f)
|
||||
{
|
||||
spost2 = -spost2;
|
||||
}
|
||||
spost2 *= 0.2f;
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
/* GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );*/
|
||||
GLfloat tex[] = {
|
||||
0+spost2, 1-spost,
|
||||
0+spost2, 0+spost,
|
||||
1-spost2, 0+spost,
|
||||
1-spost2, 1-spost
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
0, 0,
|
||||
0, glConfig.vidHeight,
|
||||
glConfig.vidWidth, glConfig.vidHeight,
|
||||
glConfig.vidWidth, 0
|
||||
};
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
#else
|
||||
qglBegin(GL_QUADS);
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
qglTexCoord2f(0+spost2, 1-spost);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
qglTexCoord2f(0+spost2, 0+spost);
|
||||
qglVertex2f(0, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 0+spost);
|
||||
qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 1-spost);
|
||||
qglVertex2f(glConfig.vidWidth, 0);
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#endif
|
||||
//pop the view matrices back
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
|
||||
qglDisable( GL_STENCIL_TEST );
|
||||
}
|
485
Projects/Android/jni/OpenJK/code/rd-gles/tr_skin.cpp
Normal file
485
Projects/Android/jni/OpenJK/code/rd-gles/tr_skin.cpp
Normal file
|
@ -0,0 +1,485 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "../qcommon/sstring.h"
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
|
||||
SKINS
|
||||
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
==================
|
||||
CommaParse
|
||||
|
||||
This is unfortunate, but the skin files aren't
|
||||
compatible with our normal parsing rules.
|
||||
==================
|
||||
*/
|
||||
static char *CommaParse( char **data_p ) {
|
||||
int c = 0, len;
|
||||
char *data;
|
||||
static char com_token[MAX_TOKEN_CHARS];
|
||||
|
||||
data = *data_p;
|
||||
len = 0;
|
||||
com_token[0] = 0;
|
||||
|
||||
// make sure incoming data is valid
|
||||
if ( !data ) {
|
||||
*data_p = NULL;
|
||||
return com_token;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
// skip whitespace
|
||||
while( (c = *(const unsigned char* /*eurofix*/)data) <= ' ') {
|
||||
if( !c ) {
|
||||
break;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
|
||||
|
||||
c = *data;
|
||||
|
||||
// skip double slash comments
|
||||
if ( c == '/' && data[1] == '/' )
|
||||
{
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
}
|
||||
// skip /* */ comments
|
||||
else if ( c=='/' && data[1] == '*' )
|
||||
{
|
||||
while ( *data && ( *data != '*' || data[1] != '/' ) )
|
||||
{
|
||||
data++;
|
||||
}
|
||||
if ( *data )
|
||||
{
|
||||
data += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( c == 0 ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// handle quoted strings
|
||||
if (c == '\"')
|
||||
{
|
||||
data++;
|
||||
while (1)
|
||||
{
|
||||
c = *data++;
|
||||
if (c=='\"' || !c)
|
||||
{
|
||||
com_token[len] = 0;
|
||||
*data_p = ( char * ) data;
|
||||
return com_token;
|
||||
}
|
||||
if (len < MAX_TOKEN_CHARS - 1)
|
||||
{
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
if (len < MAX_TOKEN_CHARS - 1)
|
||||
{
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
data++;
|
||||
c = *data;
|
||||
} while (c>32 && c != ',' );
|
||||
|
||||
com_token[len] = 0;
|
||||
|
||||
*data_p = ( char * ) data;
|
||||
return com_token;
|
||||
}
|
||||
|
||||
/*
|
||||
class CStringComparator
|
||||
{
|
||||
public:
|
||||
bool operator()(const char *s1, const char *s2) const { return(stricmp(s1, s2) < 0); }
|
||||
};
|
||||
*/
|
||||
typedef std::map<sstring_t,char * /*, CStringComparator*/ > AnimationCFGs_t;
|
||||
AnimationCFGs_t AnimationCFGs;
|
||||
|
||||
// I added this function for development purposes (and it's VM-safe) so we don't have problems
|
||||
// with our use of cached models but uncached animation.cfg files (so frame sequences are out of sync
|
||||
// if someone rebuild the model while you're ingame and you change levels)...
|
||||
//
|
||||
// Usage: call with psDest == NULL for a size enquire (for malloc),
|
||||
// then with NZ ptr for it to copy to your supplied buffer...
|
||||
//
|
||||
int RE_GetAnimationCFG(const char *psCFGFilename, char *psDest, int iDestSize)
|
||||
{
|
||||
char *psText = NULL;
|
||||
|
||||
AnimationCFGs_t::iterator it = AnimationCFGs.find(psCFGFilename);
|
||||
if (it != AnimationCFGs.end())
|
||||
{
|
||||
psText = (*it).second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not found, so load it...
|
||||
//
|
||||
fileHandle_t f;
|
||||
int iLen = ri.FS_FOpenFileRead( psCFGFilename, &f, qfalse );
|
||||
if (iLen <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
psText = (char *) R_Malloc( iLen+1, TAG_ANIMATION_CFG, qfalse );
|
||||
|
||||
ri.FS_Read( psText, iLen, f );
|
||||
psText[iLen] = '\0';
|
||||
ri.FS_FCloseFile( f );
|
||||
|
||||
AnimationCFGs[psCFGFilename] = psText;
|
||||
}
|
||||
|
||||
if (psText) // sanity, but should always be NZ
|
||||
{
|
||||
if (psDest)
|
||||
{
|
||||
Q_strncpyz(psDest,psText,iDestSize);
|
||||
}
|
||||
|
||||
return strlen(psText);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// only called from devmapbsp, devmapall, or ...
|
||||
//
|
||||
void RE_AnimationCFGs_DeleteAll(void)
|
||||
{
|
||||
for (AnimationCFGs_t::iterator it = AnimationCFGs.begin(); it != AnimationCFGs.end(); ++it)
|
||||
{
|
||||
char *psText = (*it).second;
|
||||
R_Free(psText);
|
||||
}
|
||||
|
||||
AnimationCFGs.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_SplitSkins
|
||||
input = skinname, possibly being a macro for three skins
|
||||
return= true if three part skins found
|
||||
output= qualified names to three skins if return is true, undefined if false
|
||||
===============
|
||||
*/
|
||||
bool RE_SplitSkins(const char *INname, char *skinhead, char *skintorso, char *skinlower)
|
||||
{ //INname= "models/players/jedi_tf/|head01_skin1|torso01|lower01";
|
||||
if (strchr(INname, '|'))
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
strcpy(name, INname);
|
||||
char *p = strchr(name, '|');
|
||||
*p=0;
|
||||
p++;
|
||||
//fill in the base path
|
||||
strcpy (skinhead, name);
|
||||
strcpy (skintorso, name);
|
||||
strcpy (skinlower, name);
|
||||
|
||||
//now get the the individual files
|
||||
|
||||
//advance to second
|
||||
char *p2 = strchr(p, '|');
|
||||
if (!p2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*p2=0;
|
||||
p2++;
|
||||
strcat (skinhead, p);
|
||||
strcat (skinhead, ".skin");
|
||||
|
||||
|
||||
//advance to third
|
||||
p = strchr(p2, '|');
|
||||
if (!p)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*p=0;
|
||||
p++;
|
||||
strcat (skintorso,p2);
|
||||
strcat (skintorso, ".skin");
|
||||
|
||||
strcat (skinlower,p);
|
||||
strcat (skinlower, ".skin");
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// given a name, go get the skin we want and return
|
||||
qhandle_t RE_RegisterIndividualSkin( const char *name , qhandle_t hSkin)
|
||||
{
|
||||
skin_t *skin;
|
||||
skinSurface_t *surf;
|
||||
char *text, *text_p;
|
||||
char *token;
|
||||
char surfName[MAX_QPATH];
|
||||
|
||||
// load and parse the skin file
|
||||
ri.FS_ReadFile( name, (void **)&text );
|
||||
if ( !text ) {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: RE_RegisterSkin( '%s' ) failed to load!\n", name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert (tr.skins[hSkin]); //should already be setup, but might be an 3part append
|
||||
|
||||
skin = tr.skins[hSkin];
|
||||
|
||||
text_p = text;
|
||||
while ( text_p && *text_p ) {
|
||||
// get surface name
|
||||
token = CommaParse( &text_p );
|
||||
Q_strncpyz( surfName, token, sizeof( surfName ) );
|
||||
|
||||
if ( !token[0] ) {
|
||||
break;
|
||||
}
|
||||
// lowercase the surface name so skin compares are faster
|
||||
Q_strlwr( surfName );
|
||||
|
||||
if ( *text_p == ',' ) {
|
||||
text_p++;
|
||||
}
|
||||
|
||||
if ( !strncmp( token, "tag_", 4 ) ) { //these aren't in there, but just in case you load an id style one...
|
||||
continue;
|
||||
}
|
||||
|
||||
// parse the shader name
|
||||
token = CommaParse( &text_p );
|
||||
|
||||
#ifndef JK2_MODE
|
||||
if ( !strcmp( &surfName[strlen(surfName)-4], "_off") )
|
||||
{
|
||||
if ( !strcmp( token ,"*off" ) )
|
||||
{
|
||||
continue; //don't need these double offs
|
||||
}
|
||||
surfName[strlen(surfName)-4] = 0; //remove the "_off"
|
||||
}
|
||||
#endif
|
||||
if ( (unsigned)skin->numSurfaces >= ARRAY_LEN( skin->surfaces ) )
|
||||
{
|
||||
assert( ARRAY_LEN( skin->surfaces ) > (unsigned)skin->numSurfaces );
|
||||
ri.Printf( PRINT_WARNING, "WARNING: RE_RegisterSkin( '%s' ) more than %u surfaces!\n", name, (unsigned int)ARRAY_LEN(skin->surfaces) );
|
||||
break;
|
||||
}
|
||||
surf = skin->surfaces[ skin->numSurfaces ] = (skinSurface_t *) R_Hunk_Alloc( sizeof( *skin->surfaces[0] ), qtrue );
|
||||
Q_strncpyz( surf->name, surfName, sizeof( surf->name ) );
|
||||
surf->shader = R_FindShader( token, lightmapsNone, stylesDefault, qtrue );
|
||||
skin->numSurfaces++;
|
||||
}
|
||||
|
||||
ri.FS_FreeFile( text );
|
||||
|
||||
|
||||
// never let a skin have 0 shaders
|
||||
if ( skin->numSurfaces == 0 ) {
|
||||
return 0; // use default skin
|
||||
}
|
||||
|
||||
return hSkin;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_RegisterSkin
|
||||
|
||||
===============
|
||||
*/
|
||||
qhandle_t RE_RegisterSkin( const char *name) {
|
||||
qhandle_t hSkin;
|
||||
skin_t *skin;
|
||||
|
||||
// if (!cls.cgameStarted && !cls.uiStarted)
|
||||
// {
|
||||
//rww - added uiStarted exception because we want ghoul2 models in the menus.
|
||||
// gwg well we need our skins to set surfaces on and off, so we gotta get em
|
||||
//return 1; // cope with Ghoul2's calling-the-renderer-before-its-even-started hackery, must be any NZ amount here to trigger configstring setting
|
||||
// }
|
||||
|
||||
if (!tr.numSkins)
|
||||
{
|
||||
R_InitSkins(); //make sure we have numSkins set to at least one.
|
||||
}
|
||||
|
||||
if ( !name || !name[0] ) {
|
||||
Com_Printf( "Empty name passed to RE_RegisterSkin\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
Com_Printf( "Skin name exceeds MAX_QPATH\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// see if the skin is already loaded
|
||||
for ( hSkin = 1; hSkin < tr.numSkins ; hSkin++ ) {
|
||||
skin = tr.skins[hSkin];
|
||||
if ( !Q_stricmp( skin->name, name ) ) {
|
||||
if( skin->numSurfaces == 0 ) {
|
||||
return 0; // default skin
|
||||
}
|
||||
return hSkin;
|
||||
}
|
||||
}
|
||||
|
||||
if ( tr.numSkins == MAX_SKINS ) {
|
||||
ri.Printf( PRINT_WARNING, "WARNING: RE_RegisterSkin( '%s' ) MAX_SKINS hit\n", name );
|
||||
return 0;
|
||||
}
|
||||
// allocate a new skin
|
||||
tr.numSkins++;
|
||||
skin = (skin_t*) R_Hunk_Alloc( sizeof( skin_t ), qtrue );
|
||||
tr.skins[hSkin] = skin;
|
||||
Q_strncpyz( skin->name, name, sizeof( skin->name ) ); //always make one so it won't search for it again
|
||||
|
||||
// If not a .skin file, load as a single shader - then return
|
||||
if ( strcmp( name + strlen( name ) - 5, ".skin" ) ) {
|
||||
#ifdef JK2_MODE
|
||||
skin->numSurfaces = 1;
|
||||
skin->surfaces[0] = (skinSurface_t *) R_Hunk_Alloc( sizeof(skin->surfaces[0]), qtrue );
|
||||
skin->surfaces[0]->shader = R_FindShader( name, lightmapsNone, stylesDefault, qtrue );
|
||||
return hSkin;
|
||||
#endif
|
||||
/* skin->numSurfaces = 1;
|
||||
skin->surfaces[0] = (skinSurface_t *) R_Hunk_Alloc( sizeof(skin->surfaces[0]), qtrue );
|
||||
skin->surfaces[0]->shader = R_FindShader( name, lightmapsNone, stylesDefault, qtrue );
|
||||
return hSkin;
|
||||
*/
|
||||
}
|
||||
|
||||
char skinhead[MAX_QPATH]={0};
|
||||
char skintorso[MAX_QPATH]={0};
|
||||
char skinlower[MAX_QPATH]={0};
|
||||
if ( RE_SplitSkins(name, (char*)&skinhead, (char*)&skintorso, (char*)&skinlower ) )
|
||||
{//three part
|
||||
hSkin = RE_RegisterIndividualSkin(skinhead, hSkin);
|
||||
if (hSkin && strcmp(skinhead, skintorso))
|
||||
{
|
||||
hSkin = RE_RegisterIndividualSkin(skintorso, hSkin);
|
||||
}
|
||||
|
||||
if (hSkin && strcmp(skinhead, skinlower) && strcmp(skintorso, skinlower))
|
||||
{
|
||||
hSkin = RE_RegisterIndividualSkin(skinlower, hSkin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{//single skin
|
||||
hSkin = RE_RegisterIndividualSkin(name, hSkin);
|
||||
}
|
||||
return(hSkin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
R_InitSkins
|
||||
===============
|
||||
*/
|
||||
void R_InitSkins( void ) {
|
||||
skin_t *skin;
|
||||
|
||||
tr.numSkins = 1;
|
||||
|
||||
// make the default skin have all default shaders
|
||||
skin = tr.skins[0] = (skin_t*) R_Hunk_Alloc( sizeof( skin_t ), qtrue );
|
||||
Q_strncpyz( skin->name, "<default skin>", sizeof( skin->name ) );
|
||||
skin->numSurfaces = 1;
|
||||
skin->surfaces[0] = (skinSurface_t *) R_Hunk_Alloc( sizeof( *skin->surfaces[0] ), qtrue );
|
||||
skin->surfaces[0]->shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_GetSkinByHandle
|
||||
===============
|
||||
*/
|
||||
skin_t *R_GetSkinByHandle( qhandle_t hSkin ) {
|
||||
if ( hSkin < 1 || hSkin >= tr.numSkins ) {
|
||||
return tr.skins[0];
|
||||
}
|
||||
return tr.skins[ hSkin ];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_SkinList_f
|
||||
===============
|
||||
*/
|
||||
void R_SkinList_f (void) {
|
||||
int i, j;
|
||||
skin_t *skin;
|
||||
|
||||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
|
||||
for ( i = 0 ; i < tr.numSkins ; i++ ) {
|
||||
skin = tr.skins[i];
|
||||
ri.Printf( PRINT_ALL, "%3i:%s\n", i, skin->name );
|
||||
for ( j = 0 ; j < skin->numSurfaces ; j++ ) {
|
||||
ri.Printf( PRINT_ALL, " %s = %s\n",
|
||||
skin->surfaces[j]->name, skin->surfaces[j]->shader->name );
|
||||
}
|
||||
}
|
||||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
}
|
892
Projects/Android/jni/OpenJK/code/rd-gles/tr_sky.cpp
Normal file
892
Projects/Android/jni/OpenJK/code/rd-gles/tr_sky.cpp
Normal file
|
@ -0,0 +1,892 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_sky.c
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
#define SKY_SUBDIVISIONS 8
|
||||
#define HALF_SKY_SUBDIVISIONS (SKY_SUBDIVISIONS/2)
|
||||
|
||||
static float s_cloudTexCoords[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1][2];
|
||||
static float s_cloudTexP[6][SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1];
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
POLYGON TO BOX SIDE PROJECTION
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
static vec3_t sky_clip[6] =
|
||||
{
|
||||
{1,1,0},
|
||||
{1,-1,0},
|
||||
{0,-1,1},
|
||||
{0,1,1},
|
||||
{1,0,1},
|
||||
{-1,0,1}
|
||||
};
|
||||
|
||||
static float sky_mins[2][6], sky_maxs[2][6];
|
||||
static float sky_min, sky_max;
|
||||
|
||||
/*
|
||||
================
|
||||
AddSkyPolygon
|
||||
================
|
||||
*/
|
||||
static void AddSkyPolygon (int nump, vec3_t vecs)
|
||||
{
|
||||
int i,j;
|
||||
vec3_t v, av;
|
||||
float s, t, dv;
|
||||
int axis;
|
||||
float *vp;
|
||||
// s = [0]/[2], t = [1]/[2]
|
||||
static int vec_to_st[6][3] =
|
||||
{
|
||||
{-2,3,1},
|
||||
{2,3,-1},
|
||||
|
||||
{1,3,2},
|
||||
{-1,3,-2},
|
||||
|
||||
{-2,-1,3},
|
||||
{-2,1,-3}
|
||||
|
||||
// {-1,2,3},
|
||||
// {1,2,-3}
|
||||
};
|
||||
|
||||
// decide which face it maps to
|
||||
VectorCopy (vec3_origin, v);
|
||||
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
|
||||
{
|
||||
VectorAdd (vp, v, v);
|
||||
}
|
||||
av[0] = fabs(v[0]);
|
||||
av[1] = fabs(v[1]);
|
||||
av[2] = fabs(v[2]);
|
||||
if (av[0] > av[1] && av[0] > av[2])
|
||||
{
|
||||
if (v[0] < 0)
|
||||
axis = 1;
|
||||
else
|
||||
axis = 0;
|
||||
}
|
||||
else if (av[1] > av[2] && av[1] > av[0])
|
||||
{
|
||||
if (v[1] < 0)
|
||||
axis = 3;
|
||||
else
|
||||
axis = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v[2] < 0)
|
||||
axis = 5;
|
||||
else
|
||||
axis = 4;
|
||||
}
|
||||
|
||||
// project new texture coords
|
||||
for (i=0 ; i<nump ; i++, vecs+=3)
|
||||
{
|
||||
j = vec_to_st[axis][2];
|
||||
if (j > 0)
|
||||
dv = vecs[j - 1];
|
||||
else
|
||||
dv = -vecs[-j - 1];
|
||||
if (dv < 0.001)
|
||||
continue; // don't divide by zero
|
||||
j = vec_to_st[axis][0];
|
||||
if (j < 0)
|
||||
s = -vecs[-j -1] / dv;
|
||||
else
|
||||
s = vecs[j-1] / dv;
|
||||
j = vec_to_st[axis][1];
|
||||
if (j < 0)
|
||||
t = -vecs[-j -1] / dv;
|
||||
else
|
||||
t = vecs[j-1] / dv;
|
||||
|
||||
if (s < sky_mins[0][axis])
|
||||
sky_mins[0][axis] = s;
|
||||
if (t < sky_mins[1][axis])
|
||||
sky_mins[1][axis] = t;
|
||||
if (s > sky_maxs[0][axis])
|
||||
sky_maxs[0][axis] = s;
|
||||
if (t > sky_maxs[1][axis])
|
||||
sky_maxs[1][axis] = t;
|
||||
}
|
||||
}
|
||||
|
||||
#define ON_EPSILON 0.1f // point on plane side epsilon
|
||||
#define MAX_CLIP_VERTS 64
|
||||
/*
|
||||
================
|
||||
ClipSkyPolygon
|
||||
================
|
||||
*/
|
||||
static void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
|
||||
{
|
||||
float *norm;
|
||||
float *v;
|
||||
qboolean front, back;
|
||||
float d, e;
|
||||
float dists[MAX_CLIP_VERTS];
|
||||
int sides[MAX_CLIP_VERTS];
|
||||
vec3_t newv[2][MAX_CLIP_VERTS];
|
||||
int newc[2];
|
||||
int i, j;
|
||||
|
||||
if (nump > MAX_CLIP_VERTS-2)
|
||||
Com_Error (ERR_DROP, "ClipSkyPolygon: MAX_CLIP_VERTS");
|
||||
if (stage == 6)
|
||||
{ // fully clipped, so draw it
|
||||
AddSkyPolygon (nump, vecs);
|
||||
return;
|
||||
}
|
||||
|
||||
front = back = qfalse;
|
||||
norm = sky_clip[stage];
|
||||
for (i=0, v = vecs ; i<nump ; i++, v+=3)
|
||||
{
|
||||
d = DotProduct (v, norm);
|
||||
if (d > ON_EPSILON)
|
||||
{
|
||||
front = qtrue;
|
||||
sides[i] = SIDE_FRONT;
|
||||
}
|
||||
else if (d < -ON_EPSILON)
|
||||
{
|
||||
back = qtrue;
|
||||
sides[i] = SIDE_BACK;
|
||||
}
|
||||
else
|
||||
sides[i] = SIDE_ON;
|
||||
dists[i] = d;
|
||||
}
|
||||
|
||||
if (!front || !back)
|
||||
{ // not clipped
|
||||
ClipSkyPolygon (nump, vecs, stage+1);
|
||||
return;
|
||||
}
|
||||
|
||||
// clip it
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
VectorCopy (vecs, (vecs+(i*3)) );
|
||||
newc[0] = newc[1] = 0;
|
||||
|
||||
for (i=0, v = vecs ; i<nump ; i++, v+=3)
|
||||
{
|
||||
switch (sides[i])
|
||||
{
|
||||
case SIDE_FRONT:
|
||||
VectorCopy (v, newv[0][newc[0]]);
|
||||
newc[0]++;
|
||||
break;
|
||||
case SIDE_BACK:
|
||||
VectorCopy (v, newv[1][newc[1]]);
|
||||
newc[1]++;
|
||||
break;
|
||||
case SIDE_ON:
|
||||
VectorCopy (v, newv[0][newc[0]]);
|
||||
newc[0]++;
|
||||
VectorCopy (v, newv[1][newc[1]]);
|
||||
newc[1]++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
||||
continue;
|
||||
|
||||
d = dists[i] / (dists[i] - dists[i+1]);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
e = v[j] + d*(v[j+3] - v[j]);
|
||||
newv[0][newc[0]][j] = e;
|
||||
newv[1][newc[1]][j] = e;
|
||||
}
|
||||
newc[0]++;
|
||||
newc[1]++;
|
||||
}
|
||||
|
||||
// continue
|
||||
ClipSkyPolygon (newc[0], newv[0][0], stage+1);
|
||||
ClipSkyPolygon (newc[1], newv[1][0], stage+1);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
ClearSkyBox
|
||||
==============
|
||||
*/
|
||||
static void ClearSkyBox (void) {
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<6 ; i++) {
|
||||
sky_mins[0][i] = sky_mins[1][i] = MAX_WORLD_COORD; //9999;
|
||||
sky_maxs[0][i] = sky_maxs[1][i] = MIN_WORLD_COORD; //-9999;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
RB_ClipSkyPolygons
|
||||
================
|
||||
*/
|
||||
void RB_ClipSkyPolygons( shaderCommands_t *input )
|
||||
{
|
||||
vec3_t p[5]; // need one extra point for clipping
|
||||
int i, j;
|
||||
|
||||
ClearSkyBox();
|
||||
|
||||
for ( i = 0; i < input->numIndexes; i += 3 )
|
||||
{
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
{
|
||||
VectorSubtract( input->xyz[input->indexes[i+j]],
|
||||
backEnd.viewParms.ori.origin,
|
||||
p[j] );
|
||||
}
|
||||
ClipSkyPolygon( 3, p[0], 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
|
||||
CLOUD VERTEX GENERATION
|
||||
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
** MakeSkyVec
|
||||
**
|
||||
** Parms: s, t range from -1 to 1
|
||||
*/
|
||||
static void MakeSkyVec( float s, float t, int axis, float outSt[2], vec3_t outXYZ )
|
||||
{
|
||||
// 1 = s, 2 = t, 3 = 2048
|
||||
static int st_to_vec[6][3] =
|
||||
{
|
||||
{3,-1,2},
|
||||
{-3,1,2},
|
||||
|
||||
{1,3,2},
|
||||
{-1,-3,2},
|
||||
|
||||
{-2,-1,3}, // 0 degrees yaw, look straight up
|
||||
{2,-1,-3} // look straight down
|
||||
};
|
||||
|
||||
vec3_t b;
|
||||
int j, k;
|
||||
float boxSize;
|
||||
|
||||
boxSize = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
|
||||
b[0] = s*boxSize;
|
||||
b[1] = t*boxSize;
|
||||
b[2] = boxSize;
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
k = st_to_vec[axis][j];
|
||||
if (k < 0)
|
||||
{
|
||||
outXYZ[j] = -b[-k - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
outXYZ[j] = b[k - 1];
|
||||
}
|
||||
}
|
||||
|
||||
// avoid bilerp seam
|
||||
s = (s+1)*0.5;
|
||||
t = (t+1)*0.5;
|
||||
if (s < sky_min)
|
||||
{
|
||||
s = sky_min;
|
||||
}
|
||||
else if (s > sky_max)
|
||||
{
|
||||
s = sky_max;
|
||||
}
|
||||
|
||||
if (t < sky_min)
|
||||
{
|
||||
t = sky_min;
|
||||
}
|
||||
else if (t > sky_max)
|
||||
{
|
||||
t = sky_max;
|
||||
}
|
||||
|
||||
t = 1.0 - t;
|
||||
|
||||
|
||||
if ( outSt )
|
||||
{
|
||||
outSt[0] = s;
|
||||
outSt[1] = t;
|
||||
}
|
||||
}
|
||||
|
||||
static vec3_t s_skyPoints[SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1];
|
||||
static float s_skyTexCoords[SKY_SUBDIVISIONS+1][SKY_SUBDIVISIONS+1][2];
|
||||
|
||||
static void DrawSkySide( struct image_s *image, const int mins[2], const int maxs[2] )
|
||||
{
|
||||
int s, t;
|
||||
|
||||
GL_Bind( image );
|
||||
#ifdef HAVE_GLES
|
||||
GLfloat vtx[3*1024]; // arbitrary sized
|
||||
GLfloat tex[2*1024];
|
||||
int idx;
|
||||
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (glcol)
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#endif
|
||||
|
||||
|
||||
for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t < maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
|
||||
{
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
idx=0;
|
||||
#else
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
#endif
|
||||
|
||||
for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
memcpy(tex+idx*2, s_skyTexCoords[t][s], sizeof(GLfloat)*2);
|
||||
memcpy(vtx+idx*3, s_skyPoints[t][s], sizeof(GLfloat)*3);
|
||||
idx++;
|
||||
memcpy(tex+idx*2, s_skyTexCoords[t+1][s], sizeof(GLfloat)*2);
|
||||
memcpy(vtx+idx*3, s_skyPoints[t+1][s], sizeof(GLfloat)*3);
|
||||
idx++;
|
||||
#else
|
||||
qglTexCoord2fv( s_skyTexCoords[t][s] );
|
||||
qglVertex3fv( s_skyPoints[t][s] );
|
||||
|
||||
qglTexCoord2fv( s_skyTexCoords[t+1][s] );
|
||||
qglVertex3fv( s_skyPoints[t+1][s] );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
|
||||
qglVertexPointer (3, GL_FLOAT, 0, vtx);
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, tex);
|
||||
qglDrawArrays(GL_TRIANGLE_STRIP, 0, idx);
|
||||
#else
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
if (glcol)
|
||||
qglEnableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DrawSkyBox( jk_shader_t *shader )
|
||||
{
|
||||
int i;
|
||||
|
||||
sky_min = 0.0f;
|
||||
sky_max = 1.0f;
|
||||
|
||||
memset( s_skyTexCoords, 0, sizeof( s_skyTexCoords ) );
|
||||
|
||||
for (i=0 ; i<6 ; i++)
|
||||
{
|
||||
int sky_mins_subd[2], sky_maxs_subd[2];
|
||||
int s, t;
|
||||
|
||||
sky_mins[0][i] = floor( sky_mins[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
sky_mins[1][i] = floor( sky_mins[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
sky_maxs[0][i] = ceil( sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
sky_maxs[1][i] = ceil( sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
if ( ( sky_mins[0][i] >= sky_maxs[0][i] ) ||
|
||||
( sky_mins[1][i] >= sky_maxs[1][i] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sky_mins_subd[0] = sky_mins[0][i] * HALF_SKY_SUBDIVISIONS;
|
||||
sky_mins_subd[1] = sky_mins[1][i] * HALF_SKY_SUBDIVISIONS;
|
||||
sky_maxs_subd[0] = sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS;
|
||||
sky_maxs_subd[1] = sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
if ( sky_mins_subd[0] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[0] = -HALF_SKY_SUBDIVISIONS;
|
||||
else if ( sky_mins_subd[0] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[0] = HALF_SKY_SUBDIVISIONS;
|
||||
if ( sky_mins_subd[1] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[1] = -HALF_SKY_SUBDIVISIONS;
|
||||
else if ( sky_mins_subd[1] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[1] = HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
if ( sky_maxs_subd[0] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[0] = -HALF_SKY_SUBDIVISIONS;
|
||||
else if ( sky_maxs_subd[0] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[0] = HALF_SKY_SUBDIVISIONS;
|
||||
if ( sky_maxs_subd[1] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[1] = -HALF_SKY_SUBDIVISIONS;
|
||||
else if ( sky_maxs_subd[1] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[1] = HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
//
|
||||
// iterate through the subdivisions
|
||||
//
|
||||
for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ )
|
||||
{
|
||||
for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ )
|
||||
{
|
||||
MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
|
||||
( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
|
||||
i,
|
||||
s_skyTexCoords[t][s],
|
||||
s_skyPoints[t][s] );
|
||||
}
|
||||
}
|
||||
|
||||
DrawSkySide( shader->sky->outerbox[i],
|
||||
sky_mins_subd,
|
||||
sky_maxs_subd );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean addIndexes )
|
||||
{
|
||||
int s, t;
|
||||
int vertexStart = tess.numVertexes;
|
||||
int tHeight, sWidth;
|
||||
|
||||
tHeight = maxs[1] - mins[1] + 1;
|
||||
sWidth = maxs[0] - mins[0] + 1;
|
||||
|
||||
for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
|
||||
{
|
||||
for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
|
||||
{
|
||||
VectorAdd( s_skyPoints[t][s], backEnd.viewParms.ori.origin, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0][0] = s_skyTexCoords[t][s][0];
|
||||
tess.texCoords[tess.numVertexes][0][1] = s_skyTexCoords[t][s][1];
|
||||
|
||||
tess.numVertexes++;
|
||||
|
||||
if ( tess.numVertexes >= SHADER_MAX_VERTEXES )
|
||||
{
|
||||
Com_Error( ERR_DROP, "SHADER_MAX_VERTEXES hit in FillCloudySkySide()\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only add indexes for one pass, otherwise it would draw multiple times for each pass
|
||||
if ( addIndexes ) {
|
||||
for ( t = 0; t < tHeight-1; t++ )
|
||||
{
|
||||
for ( s = 0; s < sWidth-1; s++ )
|
||||
{
|
||||
tess.indexes[tess.numIndexes] = vertexStart + s + t * ( sWidth );
|
||||
tess.numIndexes++;
|
||||
tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth );
|
||||
tess.numIndexes++;
|
||||
tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth );
|
||||
tess.numIndexes++;
|
||||
|
||||
tess.indexes[tess.numIndexes] = vertexStart + s + ( t + 1 ) * ( sWidth );
|
||||
tess.numIndexes++;
|
||||
tess.indexes[tess.numIndexes] = vertexStart + s + 1 + ( t + 1 ) * ( sWidth );
|
||||
tess.numIndexes++;
|
||||
tess.indexes[tess.numIndexes] = vertexStart + s + 1 + t * ( sWidth );
|
||||
tess.numIndexes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FillCloudBox( const jk_shader_t *shader, int stage )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i =0; i < 6; i++ )
|
||||
{
|
||||
int sky_mins_subd[2], sky_maxs_subd[2];
|
||||
int s, t;
|
||||
float MIN_T;
|
||||
|
||||
if ( 1 ) // FIXME? shader->sky->fullClouds )
|
||||
{
|
||||
MIN_T = -HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
// still don't want to draw the bottom, even if fullClouds
|
||||
if ( i == 5 )
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
MIN_T = -1;
|
||||
break;
|
||||
case 5:
|
||||
// don't draw clouds beneath you
|
||||
continue;
|
||||
case 4: // top
|
||||
default:
|
||||
MIN_T = -HALF_SKY_SUBDIVISIONS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sky_mins[0][i] = floor( sky_mins[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
sky_mins[1][i] = floor( sky_mins[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
sky_maxs[0][i] = ceil( sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
sky_maxs[1][i] = ceil( sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS ) / HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
if ( ( sky_mins[0][i] >= sky_maxs[0][i] ) ||
|
||||
( sky_mins[1][i] >= sky_maxs[1][i] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sky_mins_subd[0] = Q_ftol( sky_mins[0][i] * HALF_SKY_SUBDIVISIONS );
|
||||
sky_mins_subd[1] = Q_ftol( sky_mins[1][i] * HALF_SKY_SUBDIVISIONS );
|
||||
sky_maxs_subd[0] = Q_ftol( sky_maxs[0][i] * HALF_SKY_SUBDIVISIONS );
|
||||
sky_maxs_subd[1] = Q_ftol( sky_maxs[1][i] * HALF_SKY_SUBDIVISIONS );
|
||||
|
||||
if ( sky_mins_subd[0] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[0] = -HALF_SKY_SUBDIVISIONS;
|
||||
else if ( sky_mins_subd[0] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[0] = HALF_SKY_SUBDIVISIONS;
|
||||
if ( sky_mins_subd[1] < MIN_T )
|
||||
sky_mins_subd[1] = MIN_T;
|
||||
else if ( sky_mins_subd[1] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_mins_subd[1] = HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
if ( sky_maxs_subd[0] < -HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[0] = -HALF_SKY_SUBDIVISIONS;
|
||||
else if ( sky_maxs_subd[0] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[0] = HALF_SKY_SUBDIVISIONS;
|
||||
if ( sky_maxs_subd[1] < MIN_T )
|
||||
sky_maxs_subd[1] = MIN_T;
|
||||
else if ( sky_maxs_subd[1] > HALF_SKY_SUBDIVISIONS )
|
||||
sky_maxs_subd[1] = HALF_SKY_SUBDIVISIONS;
|
||||
|
||||
//
|
||||
// iterate through the subdivisions
|
||||
//
|
||||
for ( t = sky_mins_subd[1]+HALF_SKY_SUBDIVISIONS; t <= sky_maxs_subd[1]+HALF_SKY_SUBDIVISIONS; t++ )
|
||||
{
|
||||
for ( s = sky_mins_subd[0]+HALF_SKY_SUBDIVISIONS; s <= sky_maxs_subd[0]+HALF_SKY_SUBDIVISIONS; s++ )
|
||||
{
|
||||
MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
|
||||
( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
|
||||
i,
|
||||
NULL,
|
||||
s_skyPoints[t][s] );
|
||||
|
||||
s_skyTexCoords[t][s][0] = s_cloudTexCoords[i][t][s][0];
|
||||
s_skyTexCoords[t][s][1] = s_cloudTexCoords[i][t][s][1];
|
||||
}
|
||||
}
|
||||
|
||||
// only add indexes for first stage
|
||||
FillCloudySkySide( sky_mins_subd, sky_maxs_subd, (qboolean)( stage == 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** R_BuildCloudData
|
||||
*/
|
||||
void R_BuildCloudData( shaderCommands_t *input )
|
||||
{
|
||||
int i;
|
||||
|
||||
assert( input->shader->sky );
|
||||
|
||||
sky_min = 1.0 / 256.0f; // FIXME: not correct?
|
||||
sky_max = 255.0 / 256.0f;
|
||||
|
||||
// set up for drawing
|
||||
tess.numIndexes = 0;
|
||||
tess.numVertexes = 0;
|
||||
|
||||
if ( input->shader->sky->cloudHeight )
|
||||
{
|
||||
for ( i = 0; i < input->shader->numUnfoggedPasses; i++ )
|
||||
{
|
||||
FillCloudBox( input->shader, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** R_InitSkyTexCoords
|
||||
** Called when a sky shader is parsed
|
||||
*/
|
||||
#define SQR( a ) ((a)*(a))
|
||||
|
||||
void R_InitSkyTexCoords( float heightCloud )
|
||||
{
|
||||
int i, s, t;
|
||||
float radiusWorld = MAX_WORLD_COORD;
|
||||
float p;
|
||||
float sRad, tRad;
|
||||
vec3_t skyVec;
|
||||
vec3_t v;
|
||||
|
||||
// init zfar so MakeSkyVec works even though
|
||||
// a world hasn't been bounded
|
||||
backEnd.viewParms.zFar = 1024;
|
||||
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
for ( t = 0; t <= SKY_SUBDIVISIONS; t++ )
|
||||
{
|
||||
for ( s = 0; s <= SKY_SUBDIVISIONS; s++ )
|
||||
{
|
||||
// compute vector from view origin to sky side integral point
|
||||
MakeSkyVec( ( s - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
|
||||
( t - HALF_SKY_SUBDIVISIONS ) / ( float ) HALF_SKY_SUBDIVISIONS,
|
||||
i,
|
||||
NULL,
|
||||
skyVec );
|
||||
|
||||
// compute parametric value 'p' that intersects with cloud layer
|
||||
p = ( 1.0f / ( 2 * DotProduct( skyVec, skyVec ) ) ) *
|
||||
( -2 * skyVec[2] * radiusWorld +
|
||||
2 * sqrt( SQR( skyVec[2] ) * SQR( radiusWorld ) +
|
||||
2 * SQR( skyVec[0] ) * radiusWorld * heightCloud +
|
||||
SQR( skyVec[0] ) * SQR( heightCloud ) +
|
||||
2 * SQR( skyVec[1] ) * radiusWorld * heightCloud +
|
||||
SQR( skyVec[1] ) * SQR( heightCloud ) +
|
||||
2 * SQR( skyVec[2] ) * radiusWorld * heightCloud +
|
||||
SQR( skyVec[2] ) * SQR( heightCloud ) ) );
|
||||
|
||||
s_cloudTexP[i][t][s] = p;
|
||||
|
||||
// compute intersection point based on p
|
||||
VectorScale( skyVec, p, v );
|
||||
v[2] += radiusWorld;
|
||||
|
||||
// compute vector from world origin to intersection point 'v'
|
||||
VectorNormalize( v );
|
||||
|
||||
sRad = acos( v[0] );
|
||||
tRad = acos( v[1] );
|
||||
|
||||
s_cloudTexCoords[i][t][s][0] = sRad;
|
||||
s_cloudTexCoords[i][t][s][1] = tRad;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================================
|
||||
|
||||
/*
|
||||
** RB_DrawSun
|
||||
*/
|
||||
void RB_DrawSun( void ) {
|
||||
float size;
|
||||
float dist;
|
||||
vec3_t origin, vec1, vec2;
|
||||
vec3_t temp;
|
||||
|
||||
if ( !backEnd.skyRenderedThisView ) {
|
||||
return;
|
||||
}
|
||||
if ( !r_drawSun->integer ) {
|
||||
return;
|
||||
}
|
||||
qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
|
||||
qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]);
|
||||
|
||||
dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
|
||||
size = dist * 0.4;
|
||||
|
||||
VectorScale( tr.sunDirection, dist, origin );
|
||||
PerpendicularVector( vec1, tr.sunDirection );
|
||||
CrossProduct( tr.sunDirection, vec1, vec2 );
|
||||
|
||||
VectorScale( vec1, size, vec1 );
|
||||
VectorScale( vec2, size, vec2 );
|
||||
|
||||
// farthest depth range
|
||||
qglDepthRange( 1.0, 1.0 );
|
||||
|
||||
// FIXME: use quad stamp
|
||||
RB_BeginSurface( tr.sunShader, tess.fogNum );
|
||||
VectorCopy( origin, temp );
|
||||
VectorSubtract( temp, vec1, temp );
|
||||
VectorSubtract( temp, vec2, temp );
|
||||
VectorCopy( temp, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0][0] = 0;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 0;
|
||||
tess.vertexColors[tess.numVertexes][0] = 255;
|
||||
tess.vertexColors[tess.numVertexes][1] = 255;
|
||||
tess.vertexColors[tess.numVertexes][2] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorCopy( origin, temp );
|
||||
VectorAdd( temp, vec1, temp );
|
||||
VectorSubtract( temp, vec2, temp );
|
||||
VectorCopy( temp, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0][0] = 0;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 1;
|
||||
tess.vertexColors[tess.numVertexes][0] = 255;
|
||||
tess.vertexColors[tess.numVertexes][1] = 255;
|
||||
tess.vertexColors[tess.numVertexes][2] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorCopy( origin, temp );
|
||||
VectorAdd( temp, vec1, temp );
|
||||
VectorAdd( temp, vec2, temp );
|
||||
VectorCopy( temp, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0][0] = 1;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 1;
|
||||
tess.vertexColors[tess.numVertexes][0] = 255;
|
||||
tess.vertexColors[tess.numVertexes][1] = 255;
|
||||
tess.vertexColors[tess.numVertexes][2] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
VectorCopy( origin, temp );
|
||||
VectorSubtract( temp, vec1, temp );
|
||||
VectorAdd( temp, vec2, temp );
|
||||
VectorCopy( temp, tess.xyz[tess.numVertexes] );
|
||||
tess.texCoords[tess.numVertexes][0][0] = 1;
|
||||
tess.texCoords[tess.numVertexes][0][1] = 0;
|
||||
tess.vertexColors[tess.numVertexes][0] = 255;
|
||||
tess.vertexColors[tess.numVertexes][1] = 255;
|
||||
tess.vertexColors[tess.numVertexes][2] = 255;
|
||||
tess.numVertexes++;
|
||||
|
||||
tess.indexes[tess.numIndexes++] = 0;
|
||||
tess.indexes[tess.numIndexes++] = 1;
|
||||
tess.indexes[tess.numIndexes++] = 2;
|
||||
tess.indexes[tess.numIndexes++] = 0;
|
||||
tess.indexes[tess.numIndexes++] = 2;
|
||||
tess.indexes[tess.numIndexes++] = 3;
|
||||
|
||||
RB_EndSurface();
|
||||
|
||||
// back to normal depth range
|
||||
qglDepthRange( 0.0, 1.0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
RB_StageIteratorSky
|
||||
|
||||
All of the visible sky triangles are in tess
|
||||
|
||||
Other things could be stuck in here, like birds in the sky, etc
|
||||
================
|
||||
*/
|
||||
void RB_StageIteratorSky( void ) {
|
||||
if ( r_fastsky->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skyboxportal && !(backEnd.refdef.rdflags & RDF_SKYBOXPORTAL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hasskybox = 1;
|
||||
|
||||
// go through all the polygons and project them onto
|
||||
// the sky box to see which blocks on each side need
|
||||
// to be drawn
|
||||
RB_ClipSkyPolygons( &tess );
|
||||
|
||||
// r_showsky will let all the sky blocks be drawn in
|
||||
// front of everything to allow developers to see how
|
||||
// much sky is getting sucked in
|
||||
if ( r_showsky->integer ) {
|
||||
qglDepthRange( 0.0, 0.0 );
|
||||
} else {
|
||||
qglDepthRange( 1.0, 1.0 );
|
||||
}
|
||||
|
||||
// draw the outer skybox
|
||||
if ( tess.shader->sky->outerbox[0] && tess.shader->sky->outerbox[0] != tr.defaultImage ) {
|
||||
qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );
|
||||
|
||||
qglPushMatrix ();
|
||||
GL_State( 0 );
|
||||
qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]);
|
||||
|
||||
DrawSkyBox( tess.shader );
|
||||
|
||||
qglPopMatrix();
|
||||
}
|
||||
|
||||
// generate the vertexes for all the clouds, which will be drawn
|
||||
// by the generic shader routine
|
||||
R_BuildCloudData( &tess );
|
||||
|
||||
RB_StageIteratorGeneric();
|
||||
|
||||
// draw the inner skybox
|
||||
|
||||
|
||||
// back to normal depth range
|
||||
qglDepthRange( 0.0, 1.0 );
|
||||
|
||||
// note that sky was drawn so we will draw a sun later
|
||||
backEnd.skyRenderedThisView = qtrue;
|
||||
}
|
||||
|
78
Projects/Android/jni/OpenJK/code/rd-gles/tr_stl.cpp
Normal file
78
Projects/Android/jni/OpenJK/code/rd-gles/tr_stl.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
// Filename:- tr_stl.cpp
|
||||
//
|
||||
// I mainly made this file because I was getting sick of all the stupid error messages in MS's STL implementation,
|
||||
// and didn't want them showing up in the renderer files they were used in. This way keeps them more or less invisible
|
||||
// because of minimal dependancies
|
||||
//
|
||||
#include "tr_local.h" // this isn't actually needed other than getting rid of warnings via pragmas
|
||||
#include "tr_stl.h"
|
||||
|
||||
#include <map>
|
||||
#include "../qcommon/sstring.h" // #include <string>
|
||||
|
||||
typedef std::map<sstring_t, const char *> ShaderEntryPtrs_t;
|
||||
typedef ShaderEntryPtrs_t::size_type ShaderEntryPtr_size;
|
||||
ShaderEntryPtrs_t ShaderEntryPtrs;
|
||||
|
||||
void ShaderEntryPtrs_Clear(void)
|
||||
{
|
||||
ShaderEntryPtrs.clear();
|
||||
}
|
||||
|
||||
|
||||
int ShaderEntryPtrs_Size(void)
|
||||
{
|
||||
return ShaderEntryPtrs.size();
|
||||
}
|
||||
|
||||
void ShaderEntryPtrs_Insert(const char *token, const char *p)
|
||||
{
|
||||
ShaderEntryPtrs_t::iterator it = ShaderEntryPtrs.find(token);
|
||||
|
||||
if (it == ShaderEntryPtrs.end())
|
||||
{
|
||||
ShaderEntryPtrs[token] = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf( PRINT_DEVELOPER, "Duplicate shader entry %s!\n",token );
|
||||
}
|
||||
}
|
||||
|
||||
// returns NULL if not found...
|
||||
//
|
||||
const char *ShaderEntryPtrs_Lookup(const char *psShaderName)
|
||||
{
|
||||
ShaderEntryPtrs_t::iterator it = ShaderEntryPtrs.find(psShaderName);
|
||||
if (it != ShaderEntryPtrs.end())
|
||||
{
|
||||
const char *p = (*it).second;
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
42
Projects/Android/jni/OpenJK/code/rd-gles/tr_stl.h
Normal file
42
Projects/Android/jni/OpenJK/code/rd-gles/tr_stl.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// Filename: tr_stl.h
|
||||
//
|
||||
// I had to make this new file, because if I put the STL "map" include inside tr_local.h then one of the other header
|
||||
// files got compile errors because of using "map" in the function protos as a GLEnum, this way seemed simpler...
|
||||
|
||||
#pragma once
|
||||
|
||||
// REM this out if you want to compile without using STL (but slower of course)
|
||||
//
|
||||
#define USE_STL_FOR_SHADER_LOOKUPS
|
||||
|
||||
#ifdef USE_STL_FOR_SHADER_LOOKUPS
|
||||
void ShaderEntryPtrs_Clear(void);
|
||||
int ShaderEntryPtrs_Size(void);
|
||||
const char *ShaderEntryPtrs_Lookup(const char *psShaderName);
|
||||
void ShaderEntryPtrs_Insert(const char *token, const char *p);
|
||||
#else
|
||||
|
||||
#define ShaderEntryPtrs_Clear()
|
||||
#endif // #ifdef USE_STL_FOR_SHADER_LOOKUPS
|
99
Projects/Android/jni/OpenJK/code/rd-gles/tr_subs.cpp
Normal file
99
Projects/Android/jni/OpenJK/code/rd-gles/tr_subs.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2005 - 2015, ioquake3 contributors
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
// tr_subs.cpp - common function replacements for modular renderer
|
||||
#include "tr_local.h"
|
||||
|
||||
void QDECL Com_Printf( const char *msg, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, msg);
|
||||
Q_vsnprintf(text, sizeof(text), msg, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
ri.Printf(PRINT_ALL, "%s", text);
|
||||
}
|
||||
|
||||
void QDECL Com_Error( int level, const char *error, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, error);
|
||||
Q_vsnprintf(text, sizeof(text), error, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
ri.Error(level, "%s", text);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Com_DPrintf
|
||||
|
||||
DLL glue
|
||||
================
|
||||
*/
|
||||
void Com_DPrintf(const char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char text[1024];
|
||||
|
||||
va_start(argptr, format);
|
||||
Q_vsnprintf(text, sizeof(text), format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
ri.Printf(PRINT_DEVELOPER, "%s", text);
|
||||
}
|
||||
|
||||
// HUNK
|
||||
|
||||
//int Hunk_MemoryRemaining( void ) {
|
||||
// return ri.Hunk_MemoryRemaining();
|
||||
//}
|
||||
|
||||
// ZONE
|
||||
|
||||
void *R_Malloc( int iSize, memtag_t eTag, qboolean bZeroit ) {
|
||||
return ri.Malloc( iSize, eTag, bZeroit, 4 );
|
||||
}
|
||||
|
||||
void R_Free( void *ptr ) {
|
||||
ri.Z_Free( ptr );
|
||||
}
|
||||
|
||||
int R_MemSize( memtag_t eTag ) {
|
||||
return ri.Z_MemSize( eTag );
|
||||
}
|
||||
|
||||
void R_MorphMallocTag( void *pvBuffer, memtag_t eDesiredTag ) {
|
||||
ri.Z_MorphMallocTag( pvBuffer, eDesiredTag );
|
||||
}
|
||||
|
||||
void *R_Hunk_Alloc( int iSize, qboolean bZeroit ) {
|
||||
return ri.Malloc( iSize, TAG_HUNKALLOC, bZeroit, 4 );
|
||||
}
|
2171
Projects/Android/jni/OpenJK/code/rd-gles/tr_surface.cpp
Normal file
2171
Projects/Android/jni/OpenJK/code/rd-gles/tr_surface.cpp
Normal file
File diff suppressed because it is too large
Load diff
1511
Projects/Android/jni/OpenJK/code/rd-gles/tr_surfacesprites.cpp
Normal file
1511
Projects/Android/jni/OpenJK/code/rd-gles/tr_surfacesprites.cpp
Normal file
File diff suppressed because it is too large
Load diff
811
Projects/Android/jni/OpenJK/code/rd-gles/tr_world.cpp
Normal file
811
Projects/Android/jni/OpenJK/code/rd-gles/tr_world.cpp
Normal file
|
@ -0,0 +1,811 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999 - 2005, Id Software, Inc.
|
||||
Copyright (C) 2000 - 2013, Raven Software, Inc.
|
||||
Copyright (C) 2001 - 2013, Activision, Inc.
|
||||
Copyright (C) 2013 - 2015, OpenJK contributors
|
||||
|
||||
This file is part of the OpenJK source code.
|
||||
|
||||
OpenJK is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CullTriSurf
|
||||
|
||||
Returns true if the grid is completely culled away.
|
||||
Also sets the clipped hint bit in tess
|
||||
=================
|
||||
*/
|
||||
static qboolean R_CullTriSurf( srfTriangles_t *cv ) {
|
||||
int boxCull;
|
||||
|
||||
boxCull = R_CullLocalBox( cv->bounds );
|
||||
|
||||
if ( boxCull == CULL_OUT ) {
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_CullGrid
|
||||
|
||||
Returns true if the grid is completely culled away.
|
||||
Also sets the clipped hint bit in tess
|
||||
=================
|
||||
*/
|
||||
static qboolean R_CullGrid( srfGridMesh_t *cv ) {
|
||||
int boxCull;
|
||||
int sphereCull;
|
||||
|
||||
if ( r_nocurves->integer ) {
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if ( tr.currentEntityNum != REFENTITYNUM_WORLD ) {
|
||||
sphereCull = R_CullLocalPointAndRadius( cv->localOrigin, cv->meshRadius );
|
||||
} else {
|
||||
sphereCull = R_CullPointAndRadius( cv->localOrigin, cv->meshRadius );
|
||||
}
|
||||
boxCull = CULL_OUT;
|
||||
|
||||
// check for trivial reject
|
||||
if ( sphereCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_sphere_cull_patch_out++;
|
||||
return qtrue;
|
||||
}
|
||||
// check bounding box if necessary
|
||||
else if ( sphereCull == CULL_CLIP )
|
||||
{
|
||||
tr.pc.c_sphere_cull_patch_clip++;
|
||||
|
||||
boxCull = R_CullLocalBox( cv->meshBounds );
|
||||
|
||||
if ( boxCull == CULL_OUT )
|
||||
{
|
||||
tr.pc.c_box_cull_patch_out++;
|
||||
return qtrue;
|
||||
}
|
||||
else if ( boxCull == CULL_IN )
|
||||
{
|
||||
tr.pc.c_box_cull_patch_in++;
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_box_cull_patch_clip++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.pc.c_sphere_cull_patch_in++;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_CullSurface
|
||||
|
||||
Tries to back face cull surfaces before they are lighted or
|
||||
added to the sorting list.
|
||||
|
||||
This will also allow mirrors on both sides of a model without recursion.
|
||||
================
|
||||
*/
|
||||
static qboolean R_CullSurface( surfaceType_t *surface, jk_shader_t *shader ) {
|
||||
srfSurfaceFace_t *sface;
|
||||
float d;
|
||||
|
||||
if ( r_nocull->integer==1 ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( *surface == SF_GRID ) {
|
||||
return R_CullGrid( (srfGridMesh_t *)surface );
|
||||
}
|
||||
|
||||
if ( *surface == SF_TRIANGLES ) {
|
||||
return R_CullTriSurf( (srfTriangles_t *)surface );
|
||||
}
|
||||
|
||||
if ( *surface != SF_FACE ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( shader->cullType == CT_TWO_SIDED ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// face culling
|
||||
if ( !r_facePlaneCull->integer ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
sface = ( srfSurfaceFace_t * ) surface;
|
||||
d = DotProduct (tr.ori.viewOrigin, sface->plane.normal);
|
||||
|
||||
// don't cull exactly on the plane, because there are levels of rounding
|
||||
// through the BSP, ICD, and hardware that may cause pixel gaps if an
|
||||
// epsilon isn't allowed here
|
||||
if ( shader->cullType == CT_FRONT_SIDED ) {
|
||||
if ( d < sface->plane.dist - 8 ) {
|
||||
return qtrue;
|
||||
}
|
||||
} else {
|
||||
if ( d > sface->plane.dist + 8 ) {
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static int R_DlightFace( srfSurfaceFace_t *face, int dlightBits ) {
|
||||
float d;
|
||||
int i;
|
||||
dlight_t *dl;
|
||||
|
||||
for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
|
||||
if ( ! ( dlightBits & ( 1 << i ) ) ) {
|
||||
continue;
|
||||
}
|
||||
dl = &tr.refdef.dlights[i];
|
||||
d = DotProduct( dl->origin, face->plane.normal ) - face->plane.dist;
|
||||
if ( !VectorCompare(face->plane.normal, vec3_origin) && (d < -dl->radius || d > dl->radius) ) {
|
||||
// dlight doesn't reach the plane
|
||||
dlightBits &= ~( 1 << i );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !dlightBits ) {
|
||||
tr.pc.c_dlightSurfacesCulled++;
|
||||
}
|
||||
|
||||
face->dlightBits = dlightBits;
|
||||
return dlightBits;
|
||||
}
|
||||
|
||||
static int R_DlightGrid( srfGridMesh_t *grid, int dlightBits ) {
|
||||
int i;
|
||||
dlight_t *dl;
|
||||
|
||||
for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
|
||||
if ( ! ( dlightBits & ( 1 << i ) ) ) {
|
||||
continue;
|
||||
}
|
||||
dl = &tr.refdef.dlights[i];
|
||||
if ( dl->origin[0] - dl->radius > grid->meshBounds[1][0]
|
||||
|| dl->origin[0] + dl->radius < grid->meshBounds[0][0]
|
||||
|| dl->origin[1] - dl->radius > grid->meshBounds[1][1]
|
||||
|| dl->origin[1] + dl->radius < grid->meshBounds[0][1]
|
||||
|| dl->origin[2] - dl->radius > grid->meshBounds[1][2]
|
||||
|| dl->origin[2] + dl->radius < grid->meshBounds[0][2] ) {
|
||||
// dlight doesn't reach the bounds
|
||||
dlightBits &= ~( 1 << i );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !dlightBits ) {
|
||||
tr.pc.c_dlightSurfacesCulled++;
|
||||
}
|
||||
|
||||
grid->dlightBits = dlightBits;
|
||||
return dlightBits;
|
||||
}
|
||||
|
||||
static int R_DlightTrisurf( srfTriangles_t *surf, int dlightBits ) {
|
||||
// FIXME: more dlight culling to trisurfs...
|
||||
surf->dlightBits = dlightBits;
|
||||
return dlightBits;
|
||||
#if 0
|
||||
int i;
|
||||
dlight_t *dl;
|
||||
|
||||
for ( i = 0 ; i < tr.refdef.num_dlights ; i++ ) {
|
||||
if ( ! ( dlightBits & ( 1 << i ) ) ) {
|
||||
continue;
|
||||
}
|
||||
dl = &tr.refdef.dlights[i];
|
||||
if ( dl->origin[0] - dl->radius > grid->meshBounds[1][0]
|
||||
|| dl->origin[0] + dl->radius < grid->meshBounds[0][0]
|
||||
|| dl->origin[1] - dl->radius > grid->meshBounds[1][1]
|
||||
|| dl->origin[1] + dl->radius < grid->meshBounds[0][1]
|
||||
|| dl->origin[2] - dl->radius > grid->meshBounds[1][2]
|
||||
|| dl->origin[2] + dl->radius < grid->meshBounds[0][2] ) {
|
||||
// dlight doesn't reach the bounds
|
||||
dlightBits &= ~( 1 << i );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !dlightBits ) {
|
||||
tr.pc.c_dlightSurfacesCulled++;
|
||||
}
|
||||
|
||||
grid->dlightBits = dlightBits;
|
||||
return dlightBits;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
R_DlightSurface
|
||||
|
||||
The given surface is going to be drawn, and it touches a leaf
|
||||
that is touched by one or more dlights, so try to throw out
|
||||
more dlights if possible.
|
||||
====================
|
||||
*/
|
||||
static int R_DlightSurface( msurface_t *surf, int dlightBits ) {
|
||||
if ( *surf->data == SF_FACE ) {
|
||||
dlightBits = R_DlightFace( (srfSurfaceFace_t *)surf->data, dlightBits );
|
||||
} else if ( *surf->data == SF_GRID ) {
|
||||
dlightBits = R_DlightGrid( (srfGridMesh_t *)surf->data, dlightBits );
|
||||
} else if ( *surf->data == SF_TRIANGLES ) {
|
||||
dlightBits = R_DlightTrisurf( (srfTriangles_t *)surf->data, dlightBits );
|
||||
} else {
|
||||
dlightBits = 0;
|
||||
}
|
||||
|
||||
if ( dlightBits ) {
|
||||
tr.pc.c_dlightSurfaces++;
|
||||
}
|
||||
|
||||
return dlightBits;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
R_AddWorldSurface
|
||||
======================
|
||||
*/
|
||||
static void R_AddWorldSurface( msurface_t *surf, int dlightBits, qboolean noViewCount = qfalse ) {
|
||||
/*
|
||||
if ( surf->viewCount == tr.viewCount ) {
|
||||
return; // already in this view
|
||||
}
|
||||
*/
|
||||
|
||||
//rww - changed this to be like sof2mp's so RMG will look right.
|
||||
//Will this affect anything that is non-rmg?
|
||||
|
||||
if (!noViewCount)
|
||||
{
|
||||
if ( surf->viewCount == tr.viewCount )
|
||||
{
|
||||
// already in this view, but lets make sure all the dlight bits are set
|
||||
if ( *surf->data == SF_FACE )
|
||||
{
|
||||
((srfSurfaceFace_t *)surf->data)->dlightBits |= dlightBits;
|
||||
}
|
||||
else if ( *surf->data == SF_GRID )
|
||||
{
|
||||
((srfGridMesh_t *)surf->data)->dlightBits |= dlightBits;
|
||||
}
|
||||
else if ( *surf->data == SF_TRIANGLES )
|
||||
{
|
||||
((srfTriangles_t *)surf->data)->dlightBits |= dlightBits;
|
||||
}
|
||||
return;
|
||||
}
|
||||
surf->viewCount = tr.viewCount;
|
||||
// FIXME: bmodel fog?
|
||||
}
|
||||
|
||||
// surf->viewCount = tr.viewCount;
|
||||
// FIXME: bmodel fog?
|
||||
|
||||
// try to cull before dlighting or adding
|
||||
if ( R_CullSurface( surf->data, surf->shader ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check for dlighting
|
||||
if ( dlightBits ) {
|
||||
dlightBits = R_DlightSurface( surf, dlightBits );
|
||||
dlightBits = ( dlightBits != 0 );
|
||||
}
|
||||
|
||||
R_AddDrawSurf( surf->data, surf->shader, surf->fogIndex, dlightBits );
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
BRUSH MODELS
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
R_AddBrushModelSurfaces
|
||||
=================
|
||||
*/
|
||||
void R_AddBrushModelSurfaces ( trRefEntity_t *ent ) {
|
||||
bmodel_t *bmodel;
|
||||
int clip;
|
||||
model_t *pModel;
|
||||
int i;
|
||||
|
||||
pModel = R_GetModelByHandle( ent->e.hModel );
|
||||
|
||||
bmodel = pModel->bmodel;
|
||||
|
||||
clip = R_CullLocalBox( bmodel->bounds );
|
||||
if ( clip == CULL_OUT ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(pModel->bspInstance)
|
||||
{
|
||||
R_SetupEntityLighting(&tr.refdef, ent);
|
||||
}
|
||||
|
||||
R_DlightBmodel( bmodel, qfalse );
|
||||
|
||||
for ( i = 0 ; i < bmodel->numSurfaces ; i++ ) {
|
||||
R_AddWorldSurface( bmodel->firstSurface + i, tr.currentEntity->dlightBits, qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
float GetQuadArea( vec3_t v1, vec3_t v2, vec3_t v3, vec3_t v4 )
|
||||
{
|
||||
vec3_t vec1, vec2, dis1, dis2;
|
||||
|
||||
// Get area of tri1
|
||||
VectorSubtract( v1, v2, vec1 );
|
||||
VectorSubtract( v1, v4, vec2 );
|
||||
CrossProduct( vec1, vec2, dis1 );
|
||||
VectorScale( dis1, 0.25f, dis1 );
|
||||
|
||||
// Get area of tri2
|
||||
VectorSubtract( v3, v2, vec1 );
|
||||
VectorSubtract( v3, v4, vec2 );
|
||||
CrossProduct( vec1, vec2, dis2 );
|
||||
VectorScale( dis2, 0.25f, dis2 );
|
||||
|
||||
// Return addition of disSqr of each tri area
|
||||
return ( dis1[0] * dis1[0] + dis1[1] * dis1[1] + dis1[2] * dis1[2] +
|
||||
dis2[0] * dis2[0] + dis2[1] * dis2[1] + dis2[2] * dis2[2] );
|
||||
}
|
||||
|
||||
void RE_GetBModelVerts( int bmodelIndex, vec3_t *verts, vec3_t normal )
|
||||
{
|
||||
msurface_t *surfs;
|
||||
srfSurfaceFace_t *face;
|
||||
bmodel_t *bmodel;
|
||||
model_t *pModel;
|
||||
int i;
|
||||
// Not sure if we really need to track the best two candidates
|
||||
int maxDist[2]={0,0};
|
||||
int maxIndx[2]={0,0};
|
||||
int dist = 0;
|
||||
float dot1, dot2;
|
||||
|
||||
pModel = R_GetModelByHandle( bmodelIndex );
|
||||
bmodel = pModel->bmodel;
|
||||
|
||||
// Loop through all surfaces on the brush and find the best two candidates
|
||||
for ( i = 0 ; i < bmodel->numSurfaces; i++ )
|
||||
{
|
||||
surfs = bmodel->firstSurface + i;
|
||||
face = ( srfSurfaceFace_t *)surfs->data;
|
||||
|
||||
// It seems that the safest way to handle this is by finding the area of the faces
|
||||
dist = GetQuadArea( face->points[0], face->points[1], face->points[2], face->points[3] );
|
||||
|
||||
// Check against the highest max
|
||||
if ( dist > maxDist[0] )
|
||||
{
|
||||
// Shuffle our current maxes down
|
||||
maxDist[1] = maxDist[0];
|
||||
maxIndx[1] = maxIndx[0];
|
||||
|
||||
maxDist[0] = dist;
|
||||
maxIndx[0] = i;
|
||||
}
|
||||
// Check against the second highest max
|
||||
else if ( dist >= maxDist[1] )
|
||||
{
|
||||
// just stomp the old
|
||||
maxDist[1] = dist;
|
||||
maxIndx[1] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Hopefully we've found two best case candidates. Now we should see which of these faces the viewer
|
||||
surfs = bmodel->firstSurface + maxIndx[0];
|
||||
face = ( srfSurfaceFace_t *)surfs->data;
|
||||
dot1 = DotProduct( face->plane.normal, tr.refdef.viewaxis[0] );
|
||||
|
||||
surfs = bmodel->firstSurface + maxIndx[1];
|
||||
face = ( srfSurfaceFace_t *)surfs->data;
|
||||
dot2 = DotProduct( face->plane.normal, tr.refdef.viewaxis[0] );
|
||||
|
||||
if ( dot2 < dot1 && dot2 < 0.0f )
|
||||
{
|
||||
i = maxIndx[1]; // use the second face
|
||||
}
|
||||
else if ( dot1 < dot2 && dot1 < 0.0f )
|
||||
{
|
||||
i = maxIndx[0]; // use the first face
|
||||
}
|
||||
else
|
||||
{ // Possibly only have one face, so may as well use the first face, which also should be the best one
|
||||
//i = rand() & 1; // ugh, we don't know which to use. I'd hope this would never happen
|
||||
i = maxIndx[0]; // use the first face
|
||||
}
|
||||
|
||||
surfs = bmodel->firstSurface + i;
|
||||
face = ( srfSurfaceFace_t *)surfs->data;
|
||||
|
||||
for ( int t = 0; t < 4; t++ )
|
||||
{
|
||||
VectorCopy( face->points[t], verts[t] );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
WORLD MODEL
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
R_RecursiveWorldNode
|
||||
================
|
||||
*/
|
||||
static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits ) {
|
||||
|
||||
do {
|
||||
int newDlights[2];
|
||||
|
||||
// if the node wasn't marked as potentially visible, exit
|
||||
if (node->visframe != tr.visCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the bounding volume is outside the frustum, nothing
|
||||
// inside can be visible OPTIMIZE: don't do this all the way to leafs?
|
||||
|
||||
if ( r_nocull->integer!=1 ) {
|
||||
int r;
|
||||
|
||||
if ( planeBits & 1 ) {
|
||||
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[0]);
|
||||
if (r == 2) {
|
||||
return; // culled
|
||||
}
|
||||
if ( r == 1 ) {
|
||||
planeBits &= ~1; // all descendants will also be in front
|
||||
}
|
||||
}
|
||||
|
||||
if ( planeBits & 2 ) {
|
||||
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[1]);
|
||||
if (r == 2) {
|
||||
return; // culled
|
||||
}
|
||||
if ( r == 1 ) {
|
||||
planeBits &= ~2; // all descendants will also be in front
|
||||
}
|
||||
}
|
||||
|
||||
if ( planeBits & 4 ) {
|
||||
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[2]);
|
||||
if (r == 2) {
|
||||
return; // culled
|
||||
}
|
||||
if ( r == 1 ) {
|
||||
planeBits &= ~4; // all descendants will also be in front
|
||||
}
|
||||
}
|
||||
|
||||
if ( planeBits & 8 ) {
|
||||
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[3]);
|
||||
if (r == 2) {
|
||||
return; // culled
|
||||
}
|
||||
if ( r == 1 ) {
|
||||
planeBits &= ~8; // all descendants will also be in front
|
||||
}
|
||||
}
|
||||
|
||||
if ( planeBits & 16 ) {
|
||||
r = BoxOnPlaneSide(node->mins, node->maxs, &tr.viewParms.frustum[4]);
|
||||
if (r == 2) {
|
||||
return; // culled
|
||||
}
|
||||
if ( r == 1 ) {
|
||||
planeBits &= ~16; // all descendants will also be in front
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( node->contents != -1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// determine which dlights are needed
|
||||
if ( r_nocull->integer!=2 )
|
||||
{
|
||||
newDlights[0] = 0;
|
||||
newDlights[1] = 0;
|
||||
if ( dlightBits )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0 ; i < tr.refdef.num_dlights ; i++ )
|
||||
{
|
||||
dlight_t *dl;
|
||||
float dist;
|
||||
|
||||
if ( dlightBits & ( 1 << i ) ) {
|
||||
dl = &tr.refdef.dlights[i];
|
||||
dist = DotProduct( dl->origin, node->plane->normal ) - node->plane->dist;
|
||||
|
||||
if ( dist > -dl->radius ) {
|
||||
newDlights[0] |= ( 1 << i );
|
||||
}
|
||||
if ( dist < dl->radius ) {
|
||||
newDlights[1] |= ( 1 << i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newDlights[0] = dlightBits;
|
||||
newDlights[1] = dlightBits;
|
||||
}
|
||||
// recurse down the children, front side first
|
||||
R_RecursiveWorldNode (node->children[0], planeBits, newDlights[0] );
|
||||
|
||||
// tail recurse
|
||||
node = node->children[1];
|
||||
dlightBits = newDlights[1];
|
||||
} while ( 1 );
|
||||
|
||||
{
|
||||
// leaf node, so add mark surfaces
|
||||
int c;
|
||||
msurface_t *surf, **mark;
|
||||
|
||||
tr.pc.c_leafs++;
|
||||
|
||||
// add to z buffer bounds
|
||||
if ( node->mins[0] < tr.viewParms.visBounds[0][0] ) {
|
||||
tr.viewParms.visBounds[0][0] = node->mins[0];
|
||||
}
|
||||
if ( node->mins[1] < tr.viewParms.visBounds[0][1] ) {
|
||||
tr.viewParms.visBounds[0][1] = node->mins[1];
|
||||
}
|
||||
if ( node->mins[2] < tr.viewParms.visBounds[0][2] ) {
|
||||
tr.viewParms.visBounds[0][2] = node->mins[2];
|
||||
}
|
||||
|
||||
if ( node->maxs[0] > tr.viewParms.visBounds[1][0] ) {
|
||||
tr.viewParms.visBounds[1][0] = node->maxs[0];
|
||||
}
|
||||
if ( node->maxs[1] > tr.viewParms.visBounds[1][1] ) {
|
||||
tr.viewParms.visBounds[1][1] = node->maxs[1];
|
||||
}
|
||||
if ( node->maxs[2] > tr.viewParms.visBounds[1][2] ) {
|
||||
tr.viewParms.visBounds[1][2] = node->maxs[2];
|
||||
}
|
||||
|
||||
// add the individual surfaces
|
||||
mark = node->firstmarksurface;
|
||||
c = node->nummarksurfaces;
|
||||
while (c--) {
|
||||
// the surface may have already been added if it
|
||||
// spans multiple leafs
|
||||
surf = *mark;
|
||||
R_AddWorldSurface( surf, dlightBits );
|
||||
mark++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_PointInLeaf
|
||||
===============
|
||||
*/
|
||||
static mnode_t *R_PointInLeaf( vec3_t p ) {
|
||||
mnode_t *node;
|
||||
float d;
|
||||
cplane_t *plane;
|
||||
|
||||
if ( !tr.world ) {
|
||||
Com_Error (ERR_DROP, "R_PointInLeaf: bad model");
|
||||
}
|
||||
|
||||
node = tr.world->nodes;
|
||||
while( 1 ) {
|
||||
if (node->contents != -1) {
|
||||
break;
|
||||
}
|
||||
plane = node->plane;
|
||||
|
||||
d = DotProduct (p,plane->normal) - plane->dist;
|
||||
if (d > 0) {
|
||||
node = node->children[0];
|
||||
} else {
|
||||
node = node->children[1];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_ClusterPVS
|
||||
==============
|
||||
*/
|
||||
static const byte *R_ClusterPVS (int cluster) {
|
||||
if (!tr.world || !tr.world->vis || cluster < 0 || cluster >= tr.world->numClusters ) {
|
||||
return tr.world->novis;
|
||||
}
|
||||
|
||||
return tr.world->vis + cluster * tr.world->clusterBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_inPVS
|
||||
=================
|
||||
*/
|
||||
|
||||
qboolean R_inPVS( vec3_t p1, vec3_t p2 ) {
|
||||
mnode_t *leaf;
|
||||
byte *vis;
|
||||
|
||||
leaf = R_PointInLeaf( p1 );
|
||||
vis = ri.CM_ClusterPVS( leaf->cluster );
|
||||
leaf = R_PointInLeaf( p2 );
|
||||
|
||||
if ( !(vis[leaf->cluster>>3] & (1<<(leaf->cluster&7))) ) {
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_MarkLeaves
|
||||
|
||||
Mark the leaves and nodes that are in the PVS for the current
|
||||
cluster
|
||||
===============
|
||||
*/
|
||||
static void R_MarkLeaves (void) {
|
||||
const byte *vis;
|
||||
mnode_t *leaf, *parent;
|
||||
int i;
|
||||
int cluster;
|
||||
|
||||
// lockpvs lets designers walk around to determine the
|
||||
// extent of the current pvs
|
||||
if ( r_lockpvs->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// current viewcluster
|
||||
leaf = R_PointInLeaf( tr.viewParms.pvsOrigin );
|
||||
cluster = leaf->cluster;
|
||||
|
||||
// if the cluster is the same and the area visibility matrix
|
||||
// hasn't changed, we don't need to mark everything again
|
||||
|
||||
// if r_showcluster was just turned on, remark everything
|
||||
if ( tr.viewCluster == cluster && !tr.refdef.areamaskModified
|
||||
&& !r_showcluster->modified ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( r_showcluster->modified || r_showcluster->integer ) {
|
||||
r_showcluster->modified = qfalse;
|
||||
if ( r_showcluster->integer ) {
|
||||
ri.Printf( PRINT_ALL, "cluster:%i area:%i\n", cluster, leaf->area );
|
||||
}
|
||||
}
|
||||
|
||||
tr.visCount++;
|
||||
tr.viewCluster = cluster;
|
||||
|
||||
if ( r_novis->integer || tr.viewCluster == -1 ) {
|
||||
for (i=0 ; i<tr.world->numnodes ; i++) {
|
||||
if (tr.world->nodes[i].contents != CONTENTS_SOLID) {
|
||||
tr.world->nodes[i].visframe = tr.visCount;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
vis = R_ClusterPVS (tr.viewCluster);
|
||||
|
||||
for (i=0,leaf=tr.world->nodes ; i<tr.world->numnodes ; i++, leaf++) {
|
||||
cluster = leaf->cluster;
|
||||
if ( cluster < 0 || cluster >= tr.world->numClusters ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check general pvs
|
||||
if ( !(vis[cluster>>3] & (1<<(cluster&7))) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for door connection
|
||||
if ( (tr.refdef.areamask[leaf->area>>3] & (1<<(leaf->area&7)) ) ) {
|
||||
continue; // not visible
|
||||
}
|
||||
|
||||
parent = leaf;
|
||||
do {
|
||||
if (parent->visframe == tr.visCount)
|
||||
break;
|
||||
parent->visframe = tr.visCount;
|
||||
parent = parent->parent;
|
||||
} while (parent);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_AddWorldSurfaces
|
||||
=============
|
||||
*/
|
||||
void R_AddWorldSurfaces (void) {
|
||||
if ( !r_drawworld->integer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
tr.currentEntityNum = REFENTITYNUM_WORLD;
|
||||
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_REFENTITYNUM_SHIFT;
|
||||
|
||||
// determine which leaves are in the PVS / areamask
|
||||
R_MarkLeaves ();
|
||||
|
||||
// clear out the visible min/max
|
||||
ClearBounds( tr.viewParms.visBounds[0], tr.viewParms.visBounds[1] );
|
||||
|
||||
// perform frustum culling and add all the potentially visible surfaces
|
||||
if ( tr.refdef.num_dlights > 32 ) {
|
||||
tr.refdef.num_dlights = 32 ;
|
||||
}
|
||||
|
||||
R_RecursiveWorldNode( tr.world->nodes, 31, ( 1 << tr.refdef.num_dlights ) - 1 );
|
||||
}
|
|
@ -214,7 +214,7 @@ public:
|
|||
const int entNum;
|
||||
const int modelIndex;
|
||||
const skin_t *skin;
|
||||
const jk_shader_t *cust_shader;
|
||||
const shader_t *cust_shader;
|
||||
intptr_t *TransformedVertsArray;
|
||||
const EG2_Collision eG2TraceType;
|
||||
bool hitOne;
|
||||
|
@ -243,7 +243,7 @@ public:
|
|||
int initentNum,
|
||||
int initmodelIndex,
|
||||
const skin_t *initskin,
|
||||
const jk_shader_t *initcust_shader,
|
||||
const shader_t *initcust_shader,
|
||||
intptr_t *initTransformedVertsArray,
|
||||
const EG2_Collision einitG2TraceType,
|
||||
#ifdef _G2_GORE
|
||||
|
@ -1181,7 +1181,7 @@ static bool G2_TracePolys(const mdxmSurface_t *surface, const mdxmSurfHierarchy_
|
|||
hitPoint, &x_pos, &y_pos,newCol.mBarycentricI,newCol.mBarycentricJ);
|
||||
|
||||
/*
|
||||
const jk_shader_t *shader = 0;
|
||||
const shader_t *shader = 0;
|
||||
// now, we know what surface this hit belongs to, we need to go get the shader handle so we can get the correct hit location and hit material info
|
||||
if ( cust_shader )
|
||||
{
|
||||
|
@ -1562,7 +1562,7 @@ void G2_TraceModels(CGhoul2Info_v &ghoul2, vec3_t rayStart, vec3_t rayEnd, CColl
|
|||
{
|
||||
int i, lod;
|
||||
skin_t *skin;
|
||||
jk_shader_t *cust_shader;
|
||||
shader_t *cust_shader;
|
||||
#if !defined(JK2_MODE) || defined(_G2_GORE)
|
||||
qboolean firstModelOnly = qfalse;
|
||||
#endif // !JK2_MODE || _G2_GORE
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -697,14 +697,6 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
// Record The Extents Of The World Incase No Other Weather Zones Exist
|
||||
//---------------------------------------------------------------------
|
||||
if (!mWeatherZones.size())
|
||||
{
|
||||
Com_Printf("WARNING: No Weather Zones Encountered\n");
|
||||
AddWeatherZone(tr.world->bmodels[0].bounds[0], tr.world->bmodels[0].bounds[1]);
|
||||
}
|
||||
|
||||
// all this piece of code does really is fill in the bool "SWeatherZone::mMarkedOutside", plus the mPointCache[] for each zone,
|
||||
// so we can diskload those. Maybe.
|
||||
fileHandle_t f = ReadCachedWeatherFile();
|
||||
|
@ -728,6 +720,15 @@ public:
|
|||
uint32_t contents;
|
||||
uint32_t bit;
|
||||
|
||||
|
||||
// Record The Extents Of The World Incase No Other Weather Zones Exist
|
||||
//---------------------------------------------------------------------
|
||||
if (!mWeatherZones.size())
|
||||
{
|
||||
Com_Printf("WARNING: No Weather Zones Encountered\n");
|
||||
AddWeatherZone(tr.world->bmodels[0].bounds[0], tr.world->bmodels[0].bounds[1]);
|
||||
}
|
||||
|
||||
f = WriteCachedWeatherFile();
|
||||
|
||||
// Iterate Over All Weather Zones
|
||||
|
@ -1060,17 +1061,7 @@ public:
|
|||
}
|
||||
|
||||
mVertexCount = VertexCount;
|
||||
#if defined(HAVE_GLES) // Check for point sprite use
|
||||
if(mVertexCount == 1)
|
||||
mGLModeEnum = GL_POINTS;
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
mGLModeEnum = (mVertexCount==3)?(GL_TRIANGLES):(GL_TRIANGLE_FAN);
|
||||
#else
|
||||
mGLModeEnum = (mVertexCount==3)?(GL_TRIANGLES):(GL_QUADS);
|
||||
#endif
|
||||
mGLModeEnum = (mVertexCount==3)?(GL_TRIANGLES):(GL_QUADS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1451,76 +1442,22 @@ public:
|
|||
|
||||
// Enable And Disable Things
|
||||
//---------------------------
|
||||
/*
|
||||
if (mGLModeEnum==GL_POINTS && qglPointParameteriNV)
|
||||
{
|
||||
qglEnable(GL_POINT_SPRITE_NV);
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
qglDisable(GL_CULL_FACE);
|
||||
|
||||
qglPointSize(mWidth);
|
||||
qglPointParameterfEXT( GL_POINT_SIZE_MIN_EXT, 4.0f );
|
||||
qglPointParameterfEXT( GL_POINT_SIZE_MAX_EXT, 2047.0f );
|
||||
|
||||
qglTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, GL_TRUE);
|
||||
}
|
||||
else
|
||||
*/
|
||||
#ifdef HAVE_GLES
|
||||
GLfloat tex[2*6*mParticleCount];
|
||||
GLfloat vtx[3*6*mParticleCount];
|
||||
GLfloat col[4*6*mParticleCount];
|
||||
GLfloat curcol[4];
|
||||
qglGetFloatv(GL_CURRENT_COLOR, curcol);
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (!glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
|
||||
if (mGLModeEnum==GL_POINTS)
|
||||
{
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
// Nothing to do ?!
|
||||
}
|
||||
#else
|
||||
//FIXME use this extension?
|
||||
const float attenuation[3] =
|
||||
{
|
||||
1, 0.0, 0.0004
|
||||
};
|
||||
if (mGLModeEnum == GL_POINTS && qglPointParameterfEXT)
|
||||
{ //fixme use custom parameters but gotta make sure it expects them on same scale first
|
||||
qglPointSize(10.0);
|
||||
qglPointParameterfEXT(GL_POINT_SIZE_MIN_EXT, 1.0);
|
||||
qglPointParameterfEXT(GL_POINT_SIZE_MAX_EXT, 4.0);
|
||||
qglPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, (float *)attenuation);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
//qglDisable(GL_CULL_FACE);
|
||||
//naughty, you are making the assumption that culling is on when you get here. -rww
|
||||
GL_Cull(CT_TWO_SIDED);
|
||||
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (mFilterMode==0)?(GL_LINEAR):(GL_NEAREST));
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (mFilterMode==0)?(GL_LINEAR):(GL_NEAREST));
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (mFilterMode==0)?(GL_LINEAR):(GL_NEAREST));
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (mFilterMode==0)?(GL_LINEAR):(GL_NEAREST));
|
||||
|
||||
|
||||
// Setup Matrix Mode And Translation
|
||||
//-----------------------------------
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
// Setup Matrix Mode And Translation
|
||||
//-----------------------------------
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
|
||||
}
|
||||
|
||||
// Begin
|
||||
//-------
|
||||
#ifdef HAVE_GLES
|
||||
int idx = 0;
|
||||
#else
|
||||
qglBegin(mGLModeEnum);
|
||||
#endif
|
||||
for (particleNum=0; particleNum<mParticleCount; particleNum++)
|
||||
{
|
||||
part = &(mParticles[particleNum]);
|
||||
|
@ -1529,64 +1466,45 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
// If Oriented With Velocity, We Want To Calculate Vertx Offsets Differently For Each Particle
|
||||
//---------------------------------------------------------------------------------------------
|
||||
if (mOrientWithVelocity)
|
||||
{
|
||||
partDirection = part->mVelocity;
|
||||
VectorNormalize(partDirection.v);
|
||||
mCameraDown = partDirection;
|
||||
mCameraDown *= (mHeight * -1);
|
||||
if (mVertexCount==4)
|
||||
{
|
||||
mCameraLeftPlusUp = (mCameraLeft - mCameraDown);
|
||||
mCameraLeftMinusUp = (mCameraLeft + mCameraDown);
|
||||
}
|
||||
else
|
||||
{
|
||||
mCameraLeftPlusUp = (mCameraDown + mCameraLeft);
|
||||
}
|
||||
}
|
||||
|
||||
// Blend Mode Zero -> Apply Alpha Just To Alpha Channel
|
||||
//------------------------------------------------------
|
||||
if (mBlendMode==0)
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
curcol[0]=mColor[0]; curcol[1]=mColor[1], curcol[2]=mColor[2]; curcol[3]=part->mAlpha;
|
||||
#else
|
||||
qglColor4f(mColor[0], mColor[1], mColor[2], part->mAlpha);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Otherwise Apply Alpha To All Channels
|
||||
//---------------------------------------
|
||||
// Otherwise Apply Alpha To All Channels
|
||||
//---------------------------------------
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
curcol[0]=mColor[0]*part->mAlpha; curcol[1]=mColor[1]*part->mAlpha, curcol[2]=mColor[2]*part->mAlpha; curcol[3]=mColor[3]*part->mAlpha;
|
||||
#else
|
||||
qglColor4f(mColor[0]*part->mAlpha, mColor[1]*part->mAlpha, mColor[2]*part->mAlpha, mColor[3]*part->mAlpha);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Render A Point
|
||||
//----------------
|
||||
if (mGLModeEnum==GL_POINTS)
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
memcpy(vtx+idx*3, part->mPosition.v, 3*sizeof(GLfloat));
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
idx++;
|
||||
#else
|
||||
qglVertex3fv(part->mPosition.v);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Render A Triangle
|
||||
//-------------------
|
||||
else if (mVertexCount==3)
|
||||
// Render A Triangle
|
||||
//-------------------
|
||||
if (mVertexCount==3)
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=1.0f; tex[idx*2+1]=0.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0];
|
||||
vtx[idx*3+1]=part->mPosition[1];
|
||||
vtx[idx*3+2]=part->mPosition[2];
|
||||
memcpy(col+idx*4+4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+2]=0.0f; tex[idx*2+3]=1.0f;
|
||||
vtx[idx*3+3]=part->mPosition[0] + mCameraLeft[0];
|
||||
vtx[idx*3+4]=part->mPosition[1] + mCameraLeft[1];
|
||||
vtx[idx*3+5]=part->mPosition[2] + mCameraLeft[2];
|
||||
memcpy(col+idx*4+8, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+4]=0.0f; tex[idx*2+5]=0.0f;
|
||||
vtx[idx*3+6]=part->mPosition[0] + mCameraLeftPlusUp[0];
|
||||
vtx[idx*3+7]=part->mPosition[1] + mCameraLeftPlusUp[1];
|
||||
vtx[idx*3+8]=part->mPosition[2] + mCameraLeftPlusUp[2];
|
||||
idx+=3;
|
||||
#else
|
||||
qglTexCoord2f(1.0, 0.0);
|
||||
qglTexCoord2f(1.0, 0.0);
|
||||
qglVertex3f(part->mPosition[0],
|
||||
part->mPosition[1],
|
||||
part->mPosition[2]);
|
||||
|
@ -1600,71 +1518,12 @@ public:
|
|||
qglVertex3f(part->mPosition[0] + mCameraLeftPlusUp[0],
|
||||
part->mPosition[1] + mCameraLeftPlusUp[1],
|
||||
part->mPosition[2] + mCameraLeftPlusUp[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Render A Quad
|
||||
//---------------
|
||||
// Render A Quad
|
||||
//---------------
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
/*tex[0]=0.0f; tex[1]=0.0f;
|
||||
vtx[0]=part->mPosition[0] - mCameraLeftMinusUp[0];
|
||||
vtx[1]=part->mPosition[1] - mCameraLeftMinusUp[1];
|
||||
vtx[2]=part->mPosition[2] - mCameraLeftMinusUp[2];
|
||||
tex[2]=1.0f; tex[3]=0.0f;
|
||||
vtx[3]=part->mPosition[0] - mCameraLeftPlusUp[0];
|
||||
vtx[4]=part->mPosition[1] - mCameraLeftPlusUp[1];
|
||||
vtx[5]=part->mPosition[2] - mCameraLeftPlusUp[2];
|
||||
tex[4]=1.0f; tex[5]=1.0f;
|
||||
vtx[6]=part->mPosition[0] + mCameraLeftMinusUp[0];
|
||||
vtx[7]=part->mPosition[1] + mCameraLeftMinusUp[1];
|
||||
vtx[8]=part->mPosition[2] + mCameraLeftMinusUp[2];
|
||||
tex[6]=0.0f; tex[7]=1.0f;
|
||||
vtx[9]=part->mPosition[0] + mCameraLeftPlusUp[0];
|
||||
vtx[10]=part->mPosition[1] + mCameraLeftPlusUp[1];
|
||||
vtx[11]=part->mPosition[2] + mCameraLeftPlusUp[2];
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 3, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );*/
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=0.0f; tex[idx*2+1]=0.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0] - mCameraLeftMinusUp[0];
|
||||
vtx[idx*3+1]=part->mPosition[1] - mCameraLeftMinusUp[1];
|
||||
vtx[idx*3+2]=part->mPosition[2] - mCameraLeftMinusUp[2];
|
||||
idx++;
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=1.0f; tex[idx*2+1]=0.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0] - mCameraLeftPlusUp[0];
|
||||
vtx[idx*3+1]=part->mPosition[1] - mCameraLeftPlusUp[1];
|
||||
vtx[idx*3+2]=part->mPosition[2] - mCameraLeftPlusUp[2];
|
||||
idx++;
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=1.0f; tex[idx*2+1]=1.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0] + mCameraLeftMinusUp[0];
|
||||
vtx[idx*3+1]=part->mPosition[1] + mCameraLeftMinusUp[1];
|
||||
vtx[idx*3+2]=part->mPosition[2] + mCameraLeftMinusUp[2];
|
||||
idx++;
|
||||
// triangle 2
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=0.0f; tex[idx*2+1]=0.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0] - mCameraLeftMinusUp[0];
|
||||
vtx[idx*3+1]=part->mPosition[1] - mCameraLeftMinusUp[1];
|
||||
vtx[idx*3+2]=part->mPosition[2] - mCameraLeftMinusUp[2];
|
||||
idx++;
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=1.0f; tex[idx*2+1]=1.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0] + mCameraLeftMinusUp[0];
|
||||
vtx[idx*3+1]=part->mPosition[1] + mCameraLeftMinusUp[1];
|
||||
vtx[idx*3+2]=part->mPosition[2] + mCameraLeftMinusUp[2];
|
||||
idx++;
|
||||
memcpy(col+idx*4, curcol, 4*sizeof(GLfloat));
|
||||
tex[idx*2+0]=0.0f; tex[idx*2+1]=1.0f;
|
||||
vtx[idx*3+0]=part->mPosition[0] + mCameraLeftPlusUp[0];
|
||||
vtx[idx*3+1]=part->mPosition[1] + mCameraLeftPlusUp[1];
|
||||
vtx[idx*3+2]=part->mPosition[2] + mCameraLeftPlusUp[2];
|
||||
idx++;
|
||||
#else
|
||||
// Left bottom.
|
||||
qglTexCoord2f( 0.0, 0.0 );
|
||||
qglVertex3f(part->mPosition[0] - mCameraLeftMinusUp[0],
|
||||
|
@ -1688,44 +1547,12 @@ public:
|
|||
qglVertex3f(part->mPosition[0] + mCameraLeftPlusUp[0],
|
||||
part->mPosition[1] + mCameraLeftPlusUp[1],
|
||||
part->mPosition[2] + mCameraLeftPlusUp[2] );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef HAVE_GLES
|
||||
qglEnd();
|
||||
#endif
|
||||
|
||||
if (mGLModeEnum==GL_POINTS)
|
||||
{
|
||||
//qglDisable(GL_POINT_SPRITE_NV);
|
||||
//qglTexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, GL_FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//qglEnable(GL_CULL_FACE);
|
||||
//you don't need to do this when you are properly setting cull state.
|
||||
#ifdef HAVE_GLES
|
||||
// if (mGLModeEnum==GL_TRIANGLES) {
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 3, GL_FLOAT, 0, vtx );
|
||||
qglColorPointer (4, GL_FLOAT, 0, col );
|
||||
qglDrawArrays( GL_TRIANGLES, 0, idx );
|
||||
// }
|
||||
#endif
|
||||
|
||||
qglPopMatrix();
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
if (!glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
if (mGLModeEnum == GL_POINTS ) {
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
} else {
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
}
|
||||
#endif
|
||||
qglEnable(GL_CULL_FACE);
|
||||
qglPopMatrix();
|
||||
|
||||
mParticlesRendered += mParticleCountRender;
|
||||
}
|
||||
|
@ -2142,13 +1969,8 @@ void R_WorldEffectCommand(const char *command)
|
|||
COM_EndParseSession();
|
||||
return;
|
||||
}
|
||||
int count = 1000;
|
||||
const char* tempStr;
|
||||
COM_ParseString(&command, &tempStr);
|
||||
COM_ParseInt(&command, &count);
|
||||
|
||||
CParticleCloud& nCloud = mParticleClouds.push_back();
|
||||
nCloud.Initialize(count, "gfx/effects/snowflake1.tga");
|
||||
nCloud.Initialize(1000, "gfx/effects/snowflake1.bmp");
|
||||
nCloud.mBlendMode = 1;
|
||||
nCloud.mRotationChangeNext = 0;
|
||||
nCloud.mColor = 0.75f;
|
||||
|
|
|
@ -109,7 +109,6 @@ const unsigned char g_strGlowPShaderARB[] =
|
|||
};
|
||||
/***********************************************************************************************************/
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
|
||||
#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
|
||||
|
||||
|
@ -191,4 +190,3 @@ void ARB_InitGlowShaders(void) {
|
|||
assert( iErrPos == -1 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -316,8 +316,8 @@ static void R_LoadVisibility( lump_t *l, world_t &worldData ) {
|
|||
ShaderForShaderNum
|
||||
===============
|
||||
*/
|
||||
static jk_shader_t *ShaderForShaderNum( int shaderNum, const int *lightmapNum, const byte *lightmapStyles, const byte *vertexStyles, world_t &worldData ) {
|
||||
jk_shader_t *shader;
|
||||
static shader_t *ShaderForShaderNum( int shaderNum, const int *lightmapNum, const byte *lightmapStyles, const byte *vertexStyles, world_t &worldData ) {
|
||||
shader_t *shader;
|
||||
dshader_t *dsh;
|
||||
const byte *styles;
|
||||
|
||||
|
@ -981,14 +981,14 @@ R_LoadFogs
|
|||
*/
|
||||
static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump, world_t &worldData, int index ) {
|
||||
int i;
|
||||
jk_fog_t *out;
|
||||
fog_t *out;
|
||||
dfog_t *fogs;
|
||||
dbrush_t *brushes, *brush;
|
||||
dbrushside_t *sides;
|
||||
int count, brushesCount, sidesCount;
|
||||
int sideNum;
|
||||
int planeNum;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
float d;
|
||||
int firstSide=0;
|
||||
int lightmaps[MAXLIGHTMAPS] = { LIGHTMAP_NONE } ;
|
||||
|
@ -1001,7 +1001,7 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump, world
|
|||
|
||||
// create fog strucutres for them
|
||||
worldData.numfogs = count + 1;
|
||||
worldData.fogs = (jk_fog_t *)R_Hunk_Alloc ( (worldData.numfogs+1)*sizeof(*out), qtrue);
|
||||
worldData.fogs = (fog_t *)R_Hunk_Alloc ( (worldData.numfogs+1)*sizeof(*out), qtrue);
|
||||
worldData.globalFog = -1;
|
||||
out = worldData.fogs + 1;
|
||||
|
||||
|
@ -1342,7 +1342,6 @@ void RE_LoadWorldMap_Actual( const char *name, world_t &worldData, int index ) {
|
|||
if (!index)
|
||||
{
|
||||
skyboxportal = 0;
|
||||
hasskybox = 0;
|
||||
|
||||
tr.sunDirection[0] = 0.45f;
|
||||
tr.sunDirection[1] = 0.3f;
|
||||
|
|
|
@ -312,7 +312,7 @@ void RE_LAGoggles( void )
|
|||
tr.refdef.rdflags |= (RDF_doLAGoggles|RDF_doFullbright);
|
||||
tr.refdef.doLAGoggles = qtrue;
|
||||
|
||||
jk_fog_t *fog = &tr.world->fogs[tr.world->numfogs];
|
||||
fog_t *fog = &tr.world->fogs[tr.world->numfogs];
|
||||
|
||||
fog->parms.color[0] = 0.75f;
|
||||
fog->parms.color[1] = 0.42f + Q_flrand(0.0f, 1.0f) * 0.025f;
|
||||
|
@ -383,7 +383,6 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
|
|||
//
|
||||
// do overdraw measurement
|
||||
//
|
||||
#ifndef HAVE_GLES
|
||||
if ( r_measureOverdraw->integer )
|
||||
{
|
||||
if ( glConfig.stencilBits < 4 )
|
||||
|
@ -418,7 +417,6 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
|
|||
r_measureOverdraw->modified = qfalse;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// texturemode stuff
|
||||
|
@ -459,13 +457,23 @@ void RE_BeginFrame( stereoFrame_t stereoFrame ) {
|
|||
}
|
||||
cmd->commandId = RC_DRAW_BUFFER;
|
||||
|
||||
{
|
||||
if ( glConfig.stereoEnabled ) {
|
||||
if ( stereoFrame == STEREO_LEFT ) {
|
||||
cmd->buffer = (int)0;
|
||||
cmd->buffer = (int)GL_BACK_LEFT;
|
||||
} else if ( stereoFrame == STEREO_RIGHT ) {
|
||||
cmd->buffer = (int)1;
|
||||
cmd->buffer = (int)GL_BACK_RIGHT;
|
||||
} else {
|
||||
ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
|
||||
Com_Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
|
||||
}
|
||||
} else {
|
||||
if ( stereoFrame != STEREO_CENTER ) {
|
||||
Com_Error( ERR_FATAL, "RE_BeginFrame: Stereo is disabled, but stereoFrame was %i", stereoFrame );
|
||||
}
|
||||
// if ( !Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) ) {
|
||||
// cmd->buffer = (int)GL_FRONT;
|
||||
// } else
|
||||
{
|
||||
cmd->buffer = (int)GL_BACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -479,30 +487,26 @@ Returns the number of msec spent in the back end
|
|||
=============
|
||||
*/
|
||||
void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) {
|
||||
swapBuffersCommand_t *cmd;
|
||||
swapBuffersCommand_t *cmd;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (swapBuffersCommand_t*)R_GetCommandBuffer(sizeof(*cmd));
|
||||
if (!cmd) {
|
||||
cmd = (swapBuffersCommand_t *) R_GetCommandBufferReserved( sizeof( *cmd ), 0 );
|
||||
if ( !cmd ) {
|
||||
return;
|
||||
}
|
||||
cmd->commandId = RC_SWAP_BUFFERS;
|
||||
|
||||
cmd->commandId = RC_FLUSH;
|
||||
R_IssueRenderCommands( qtrue );
|
||||
|
||||
R_IssueRenderCommands( qfalse );
|
||||
R_InitNextFrame();
|
||||
|
||||
// use the other buffers next frame, because another CPU
|
||||
// may still be rendering into the current ones
|
||||
R_InitNextFrame();
|
||||
|
||||
if (frontEndMsec) {
|
||||
if ( frontEndMsec ) {
|
||||
*frontEndMsec = tr.frontEndMsec;
|
||||
}
|
||||
tr.frontEndMsec = 0;
|
||||
if (backEndMsec) {
|
||||
if ( backEndMsec ) {
|
||||
*backEndMsec = backEnd.pc.msec;
|
||||
}
|
||||
backEnd.pc.msec = 0;
|
||||
|
@ -512,20 +516,3 @@ void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) {
|
|||
styleUpdated[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void RE_SubmitStereoFrame( ) {
|
||||
swapBuffersCommand_t *cmd;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = (swapBuffersCommand_t*)R_GetCommandBuffer(sizeof(*cmd));
|
||||
if (!cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
cmd->commandId = RC_SWAP_BUFFERS;
|
||||
|
||||
R_IssueRenderCommands( qtrue );
|
||||
}
|
||||
|
|
|
@ -77,13 +77,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
//don't do qglTexImage2D as this may end up doing a compressed image
|
||||
//on which we are not allowed to do further sub images
|
||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
#else
|
||||
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
#endif
|
||||
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
|
@ -132,34 +126,6 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
}
|
||||
qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f( tr.identityLight, tr.identityLight, tr.identityLight, 1.0f );
|
||||
GLfloat tex[] = {
|
||||
0.5 / cols, 0.5 / rows,
|
||||
( cols - 0.5 ) / cols , 0.5 / rows,
|
||||
( cols - 0.5 ) / cols, ( rows - 0.5 ) / rows,
|
||||
0.5 / cols, ( rows - 0.5 ) / rows
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
x, y,
|
||||
x + w, y,
|
||||
x + w, y + h,
|
||||
x, y + h
|
||||
};
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (glcol)
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
if (glcol)
|
||||
qglEnableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#else
|
||||
qglBegin (GL_QUADS);
|
||||
qglTexCoord2f ( 0.5f / cols, 0.5f / rows );
|
||||
qglVertex2f (x, y);
|
||||
|
@ -170,7 +136,6 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
qglTexCoord2f ( 0.5f / cols, ( rows - 0.5f ) / rows );
|
||||
qglVertex2f (x, y+h);
|
||||
qglEnd ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,11 +148,7 @@ void RE_UploadCinematic (int cols, int rows, const byte *data, int client, qbool
|
|||
if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
|
||||
tr.scratchImage[client]->width = cols;
|
||||
tr.scratchImage[client]->height = rows;
|
||||
#ifdef HAVE_GLES
|
||||
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
#else
|
||||
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
#endif
|
||||
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
|
@ -466,7 +427,6 @@ static void RE_Blit(float fX0, float fY0, float fX1, float fY1, float fX2, float
|
|||
qglColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
qglBegin (GL_QUADS);
|
||||
{
|
||||
// TL...
|
||||
|
@ -494,12 +454,10 @@ static void RE_Blit(float fX0, float fY0, float fX1, float fY1, float fX2, float
|
|||
qglVertex2f( fX3, fY3);
|
||||
}
|
||||
qglEnd ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void RE_KillDissolve(void)
|
||||
{
|
||||
#ifndef HAVE_GLES
|
||||
Dissolve.iStartTime = 0;
|
||||
|
||||
if (Dissolve.pImage)
|
||||
|
@ -507,7 +465,6 @@ static void RE_KillDissolve(void)
|
|||
R_Images_DeleteImage( Dissolve.pImage );
|
||||
Dissolve.pImage = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
// Draw the dissolve pic to the screen, over the top of what's already been rendered.
|
||||
//
|
||||
|
@ -516,7 +473,6 @@ static void RE_KillDissolve(void)
|
|||
#define iSAFETY_SPRITE_OVERLAP 2 // #pixels to overlap blit region by, in case some drivers leave onscreen seams
|
||||
qboolean RE_ProcessDissolve(void)
|
||||
{
|
||||
#ifndef HAVE_GLES
|
||||
if (Dissolve.iStartTime)
|
||||
{
|
||||
if (Dissolve.bTouchNeeded)
|
||||
|
@ -794,7 +750,7 @@ qboolean RE_ProcessDissolve(void)
|
|||
RE_KillDissolve();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -807,7 +763,6 @@ qboolean RE_InitDissolve(qboolean bForceCircularExtroWipe)
|
|||
// ri.Printf( PRINT_ALL, "RE_InitDissolve()\n");
|
||||
qboolean bReturn = qfalse;
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
if (//Dissolve.iStartTime == 0 // no point in interruping an existing one
|
||||
//&&
|
||||
tr.registered == qtrue // ... stops it crashing during first cinematic before the menus... :-)
|
||||
|
@ -1064,8 +1019,6 @@ qboolean RE_InitDissolve(qboolean bForceCircularExtroWipe)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
|
|
|
@ -658,7 +658,7 @@ class CRenderSurface
|
|||
public:
|
||||
int surfaceNum;
|
||||
surfaceInfo_v &rootSList;
|
||||
const jk_shader_t *cust_shader;
|
||||
const shader_t *cust_shader;
|
||||
int fogNum;
|
||||
qboolean personalModel;
|
||||
CBoneCache *boneCache;
|
||||
|
@ -668,14 +668,14 @@ public:
|
|||
int lod;
|
||||
boltInfo_v &boltList;
|
||||
#ifdef _G2_GORE
|
||||
jk_shader_t *gore_shader;
|
||||
shader_t *gore_shader;
|
||||
CGoreSet *gore_set;
|
||||
#endif
|
||||
|
||||
CRenderSurface(
|
||||
int initsurfaceNum,
|
||||
surfaceInfo_v &initrootSList,
|
||||
const jk_shader_t *initcust_shader,
|
||||
const shader_t *initcust_shader,
|
||||
int initfogNum,
|
||||
qboolean initpersonalModel,
|
||||
CBoneCache *initboneCache,
|
||||
|
@ -685,7 +685,7 @@ public:
|
|||
int initlod,
|
||||
#ifdef _G2_GORE
|
||||
boltInfo_v &initboltList,
|
||||
jk_shader_t *initgore_shader,
|
||||
shader_t *initgore_shader,
|
||||
CGoreSet *initgore_set):
|
||||
#else
|
||||
boltInfo_v &initboltList):
|
||||
|
@ -786,7 +786,7 @@ R_AComputeFogNum
|
|||
static int R_GComputeFogNum( trRefEntity_t *ent ) {
|
||||
|
||||
int i;
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
|
@ -2239,7 +2239,7 @@ void G2API_SetSurfaceOnOffFromSkin (CGhoul2Info *ghlInfo, qhandle_t renderSkin)
|
|||
void RenderSurfaces(CRenderSurface &RS)
|
||||
{
|
||||
int i;
|
||||
const jk_shader_t *shader = 0;
|
||||
const shader_t *shader = 0;
|
||||
int offFlags = 0;
|
||||
#ifdef _G2_GORE
|
||||
bool drawGore = true;
|
||||
|
@ -2385,7 +2385,7 @@ void RenderSurfaces(CRenderSurface &RS)
|
|||
newSurf2->scale=1.0f;
|
||||
}
|
||||
}
|
||||
jk_shader_t *gshader;
|
||||
shader_t *gshader;
|
||||
if ((*kcur).second.shader)
|
||||
{
|
||||
gshader=R_GetShaderByHandle((*kcur).second.shader);
|
||||
|
@ -2556,9 +2556,9 @@ R_AddGHOULSurfaces
|
|||
==============
|
||||
*/
|
||||
void R_AddGhoulSurfaces( trRefEntity_t *ent ) {
|
||||
jk_shader_t *cust_shader = 0;
|
||||
shader_t *cust_shader = 0;
|
||||
#ifdef _G2_GORE
|
||||
jk_shader_t *gore_shader = 0;
|
||||
shader_t *gore_shader = 0;
|
||||
#endif
|
||||
int fogNum = 0;
|
||||
qboolean personalModel;
|
||||
|
@ -3501,7 +3501,7 @@ qboolean R_LoadMDXM( model_t *mod, void *buffer, const char *mod_name, qboolean
|
|||
mdxmSurface_t *surf;
|
||||
int version;
|
||||
int size;
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
mdxmSurfHierarchy_t *surfInfo;
|
||||
|
||||
#ifdef Q3_BIG_ENDIAN
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -33,7 +33,7 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
#include "tr_WorldEffects.h"
|
||||
|
||||
glconfig_t glConfig;
|
||||
jk_glstate_t glState;
|
||||
glstate_t glState;
|
||||
window_t window;
|
||||
|
||||
static void GfxInfo_f( void );
|
||||
|
@ -185,14 +185,6 @@ cvar_t *com_buildScript;
|
|||
cvar_t *r_environmentMapping;
|
||||
cvar_t *r_screenshotJpegQuality;
|
||||
|
||||
void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
||||
void ( APIENTRY * qglActiveTextureARB )( GLenum texture );
|
||||
void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture );
|
||||
|
||||
void ( APIENTRY * qglLockArraysEXT )( GLint, GLint );
|
||||
void ( APIENTRY * qglUnlockArraysEXT )( void );
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
#if !defined(__APPLE__)
|
||||
PFNGLSTENCILOPSEPARATEPROC qglStencilOpSeparate;
|
||||
#endif
|
||||
|
@ -215,7 +207,6 @@ PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC qglGetCombinerOutputParameterfvNV;
|
|||
PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC qglGetCombinerOutputParameterivNV;
|
||||
PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC qglGetFinalCombinerInputParameterfvNV;
|
||||
PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC qglGetFinalCombinerInputParameterivNV;
|
||||
#endif
|
||||
|
||||
PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
|
||||
PFNGLBINDPROGRAMARBPROC qglBindProgramARB;
|
||||
|
@ -237,10 +228,8 @@ PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB;
|
|||
PFNGLGETPROGRAMSTRINGARBPROC qglGetProgramStringARB;
|
||||
PFNGLISPROGRAMARBPROC qglIsProgramARB;
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
PFNGLLOCKARRAYSEXTPROC qglLockArraysEXT;
|
||||
PFNGLUNLOCKARRAYSEXTPROC qglUnlockArraysEXT;
|
||||
#endif
|
||||
|
||||
bool g_bTextureRectangleHack = false;
|
||||
|
||||
|
@ -271,46 +260,16 @@ void R_Splash()
|
|||
const float y1 = 240 - height / 2;
|
||||
const float y2 = 240 + height / 2;
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
//GLimp_EndFrame();
|
||||
GLfloat tex[] = {
|
||||
0,0 ,
|
||||
1,0,
|
||||
0,1,
|
||||
1,1
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
x1, y1,
|
||||
x2, y1,
|
||||
x1, y2,
|
||||
x2, y2
|
||||
};
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (glcol)
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
qglEnableClientState( GL_VERTEX_ARRAY );
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
|
||||
if (glcol)
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#else
|
||||
qglBegin (GL_TRIANGLE_STRIP);
|
||||
qglTexCoord2f( 0, 0 );
|
||||
qglVertex2f(x1, y1);
|
||||
qglTexCoord2f( 1 , 0 );
|
||||
qglVertex2f(x2, y1);
|
||||
qglTexCoord2f( 0, 1 );
|
||||
qglVertex2f(x1, y2);
|
||||
qglTexCoord2f( 1, 1 );
|
||||
qglVertex2f(x2, y2);
|
||||
qglTexCoord2f( 0, 0 );
|
||||
qglVertex2f(x1, y1);
|
||||
qglTexCoord2f( 1 , 0 );
|
||||
qglVertex2f(x2, y1);
|
||||
qglTexCoord2f( 0, 1 );
|
||||
qglVertex2f(x1, y2);
|
||||
qglTexCoord2f( 1, 1 );
|
||||
qglVertex2f(x2, y2);
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
ri.WIN_Present( &window );
|
||||
|
@ -324,10 +283,6 @@ void R_Splash()
|
|||
|
||||
static void GLW_InitTextureCompression( void )
|
||||
{
|
||||
glConfig.textureCompression = TC_NONE;
|
||||
return;
|
||||
|
||||
|
||||
bool newer_tc, old_tc;
|
||||
// Check for available tc methods.
|
||||
newer_tc = ri.GL_ExtensionSupported("GL_ARB_texture_compression") && ri.GL_ExtensionSupported("GL_EXT_texture_compression_s3tc");
|
||||
|
@ -504,7 +459,6 @@ static void GLimp_InitExtensions( void )
|
|||
glConfig.clampToEdgeAvailable = qtrue;
|
||||
Com_Printf ("...using GL_EXT_texture_edge_clamp\n" );
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
// GL_ARB_multitexture
|
||||
qglMultiTexCoord2fARB = NULL;
|
||||
qglActiveTextureARB = NULL;
|
||||
|
@ -569,7 +523,6 @@ static void GLimp_InitExtensions( void )
|
|||
}
|
||||
|
||||
bool bNVRegisterCombiners = false;
|
||||
|
||||
// Register Combiners.
|
||||
if ( ri.GL_ExtensionSupported( "GL_NV_register_combiners" ) )
|
||||
{
|
||||
|
@ -617,7 +570,7 @@ static void GLimp_InitExtensions( void )
|
|||
bNVRegisterCombiners = false;
|
||||
Com_Printf ("...GL_NV_register_combiners not found\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE: Vertex and Fragment Programs are very dependant on each other - this is actually a
|
||||
// good thing! So, just check to see which we support (one or the other) and load the shared
|
||||
// function pointers. ARB rocks!
|
||||
|
@ -703,7 +656,6 @@ static void GLimp_InitExtensions( void )
|
|||
// Find out how many general combiners they have.
|
||||
#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
|
||||
GLint iNumGeneralCombiners = 0;
|
||||
bool bNVRegisterCombiners = false;
|
||||
if(bNVRegisterCombiners)
|
||||
qglGetIntegerv( GL_MAX_GENERAL_COMBINERS_NV, &iNumGeneralCombiners );
|
||||
|
||||
|
@ -722,13 +674,11 @@ static void GLimp_InitExtensions( void )
|
|||
}
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
#ifndef HAVE_GLES
|
||||
qglStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)ri.GL_GetProcAddress("glStencilOpSeparate");
|
||||
if (qglStencilOpSeparate)
|
||||
{
|
||||
glConfig.doStencilShadowsInOneDrawcall = qtrue;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
glConfig.doStencilShadowsInOneDrawcall = qtrue;
|
||||
#endif
|
||||
|
@ -779,7 +729,7 @@ static void InitOpenGL( void )
|
|||
|
||||
// set default state
|
||||
GL_SetDefaultState();
|
||||
//R_Splash(); //get something on screen asap
|
||||
R_Splash(); //get something on screen asap
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1218,19 +1168,14 @@ void GL_SetDefaultState( void )
|
|||
//
|
||||
glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
qglDepthMask( GL_TRUE );
|
||||
qglDisable( GL_DEPTH_TEST );
|
||||
qglEnable( GL_SCISSOR_TEST );
|
||||
qglDisable( GL_CULL_FACE );
|
||||
qglDisable( GL_BLEND );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
#endif
|
||||
qglDisable( GL_ALPHA_TEST );
|
||||
qglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1568,10 +1513,10 @@ void R_Register( void )
|
|||
//
|
||||
|
||||
r_allowExtensions = ri.Cvar_Get( "r_allowExtensions", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compress_textures", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_compressed_textures = ri.Cvar_Get( "r_ext_compress_textures", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_compressed_lightmaps = ri.Cvar_Get( "r_ext_compress_lightmaps", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_preferred_tc_method = ri.Cvar_Get( "r_ext_preferred_tc_method", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE_ND | CVAR_LATCH);
|
||||
r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE_ND | CVAR_LATCH);
|
||||
|
@ -1591,7 +1536,7 @@ void R_Register( void )
|
|||
r_detailTextures = ri.Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_texturebits = ri.Cvar_Get( "r_texturebits", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_texturebitslm = ri.Cvar_Get( "r_texturebitslm", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_mapOverBrightBits = ri.Cvar_Get( "r_mapOverBrightBits", "0", CVAR_ARCHIVE_ND|CVAR_LATCH );
|
||||
r_simpleMipMaps = ri.Cvar_Get( "r_simpleMipMaps", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
|
||||
r_vertexLight = ri.Cvar_Get( "r_vertexLight", "0", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
@ -1608,7 +1553,7 @@ void R_Register( void )
|
|||
//
|
||||
// archived variables that can change at any time
|
||||
//
|
||||
r_lodCurveError = ri.Cvar_Get( "r_lodCurveError", "1000", CVAR_ARCHIVE_ND );
|
||||
r_lodCurveError = ri.Cvar_Get( "r_lodCurveError", "250", CVAR_ARCHIVE_ND );
|
||||
r_lodbias = ri.Cvar_Get( "r_lodbias", "0", CVAR_ARCHIVE_ND );
|
||||
r_flares = ri.Cvar_Get ("r_flares", "1", CVAR_ARCHIVE_ND );
|
||||
r_lodscale = ri.Cvar_Get( "r_lodscale", "10", CVAR_ARCHIVE_ND );
|
||||
|
@ -1623,7 +1568,7 @@ void R_Register( void )
|
|||
// r_dlightBacks = ri.Cvar_Get( "r_dlightBacks", "0", CVAR_ARCHIVE );
|
||||
r_finish = ri.Cvar_Get ("r_finish", "0", CVAR_ARCHIVE_ND);
|
||||
r_textureMode = ri.Cvar_Get( "r_textureMode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
|
||||
r_gamma = ri.Cvar_Get( "r_gamma", "1.027344", CVAR_ARCHIVE_ND );
|
||||
r_gamma = ri.Cvar_Get( "r_gamma", "1", CVAR_ARCHIVE_ND );
|
||||
r_facePlaneCull = ri.Cvar_Get ("r_facePlaneCull", "1", CVAR_ARCHIVE_ND );
|
||||
|
||||
r_dlightStyle = ri.Cvar_Get ("r_dlightStyle", "1", CVAR_ARCHIVE_ND);
|
||||
|
@ -1686,7 +1631,7 @@ void R_Register( void )
|
|||
r_offsetUnits = ri.Cvar_Get( "r_offsetunits", "-2", CVAR_CHEAT );
|
||||
r_lockpvs = ri.Cvar_Get ("r_lockpvs", "0", CVAR_CHEAT);
|
||||
r_noportals = ri.Cvar_Get ("r_noportals", "0", CVAR_CHEAT);
|
||||
r_shadows = ri.Cvar_Get( "cg_shadows", "3", 0 );
|
||||
r_shadows = ri.Cvar_Get( "cg_shadows", "1", 0 );
|
||||
r_shadowRange = ri.Cvar_Get( "r_shadowRange", "1000", CVAR_ARCHIVE_ND );
|
||||
|
||||
/*
|
||||
|
@ -1844,7 +1789,6 @@ void RE_Shutdown( qboolean destroyWindow, qboolean restarting ) {
|
|||
for ( size_t i = 0; i < numCommands; i++ )
|
||||
ri.Cmd_RemoveCommand( commands[i].cmd );
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
if ( r_DynamicGlow && r_DynamicGlow->integer )
|
||||
{
|
||||
// Release the Glow Vertex Shader.
|
||||
|
@ -1877,7 +1821,6 @@ void RE_Shutdown( qboolean destroyWindow, qboolean restarting ) {
|
|||
// Release the blur texture.
|
||||
qglDeleteTextures( 1, &tr.blurImage );
|
||||
}
|
||||
#endif
|
||||
|
||||
R_ShutdownWorldEffects();
|
||||
R_ShutdownFonts();
|
||||
|
@ -2091,7 +2034,6 @@ extern "C" Q_EXPORT refexport_t* QDECL GetRefAPI ( int apiVersion, refimport_t *
|
|||
|
||||
REX(BeginFrame);
|
||||
REX(EndFrame);
|
||||
REX(SubmitStereoFrame);
|
||||
|
||||
REX(ProcessDissolve);
|
||||
REX(InitDissolve);
|
||||
|
|
|
@ -31,15 +31,10 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
#include "mdx_format.h"
|
||||
#include "qgl.h"
|
||||
|
||||
#if defined(_XBOX) || defined(HAVE_GLES)
|
||||
#define GL_INDEX_TYPE GL_UNSIGNED_SHORT
|
||||
typedef unsigned short glIndex_t;
|
||||
#else
|
||||
#define GL_INDEX_TYPE GL_UNSIGNED_INT
|
||||
typedef unsigned int glIndex_t;
|
||||
#endif
|
||||
|
||||
//extern refimport_t ri;
|
||||
extern refimport_t ri;
|
||||
|
||||
|
||||
// 13 bits
|
||||
|
@ -435,7 +430,7 @@ typedef struct {
|
|||
} fogParms_t;
|
||||
|
||||
|
||||
typedef struct jk_shader_s {
|
||||
typedef struct shader_s {
|
||||
char name[MAX_QPATH]; // game path, including extension
|
||||
int lightmapIndex[MAXLIGHTMAPS]; // for a shader to match, both name and lightmapIndex must match
|
||||
byte styles[MAXLIGHTMAPS];
|
||||
|
@ -482,9 +477,9 @@ typedef struct jk_shader_s {
|
|||
// True if this shader has a stage with glow in it (just an optimization).
|
||||
bool hasGlow;
|
||||
|
||||
// struct jk_shader_s *remappedShader; // current shader this one is remapped too
|
||||
struct jk_shader_s *next;
|
||||
} jk_shader_t;
|
||||
// struct shader_s *remappedShader; // current shader this one is remapped too
|
||||
struct shader_s *next;
|
||||
} shader_t;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -513,7 +508,7 @@ Ghoul2 Insert End
|
|||
// skins allow models to be retextured without modifying the model file
|
||||
typedef struct {
|
||||
char name[MAX_QPATH];
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
} skinSurface_t;
|
||||
|
||||
typedef struct skin_s {
|
||||
|
@ -534,7 +529,7 @@ typedef struct {
|
|||
// for clipping distance in fog when outside
|
||||
qboolean hasSurface;
|
||||
float surface[4];
|
||||
} jk_fog_t;
|
||||
} fog_t;
|
||||
|
||||
typedef struct {
|
||||
orientationr_t ori;
|
||||
|
@ -709,7 +704,7 @@ BRUSH MODELS
|
|||
|
||||
typedef struct msurface_s {
|
||||
int viewCount; // if == tr.viewCount, already added
|
||||
struct jk_shader_s *shader;
|
||||
struct shader_s *shader;
|
||||
int fogIndex;
|
||||
|
||||
surfaceType_t *data; // any of srf*_t
|
||||
|
@ -774,7 +769,7 @@ typedef struct {
|
|||
msurface_t **marksurfaces;
|
||||
|
||||
int numfogs;
|
||||
jk_fog_t *fogs;
|
||||
fog_t *fogs;
|
||||
int globalFog;
|
||||
|
||||
int startLightMapIndex;
|
||||
|
@ -907,7 +902,7 @@ typedef struct {
|
|||
#define FUNCTABLE_MASK (FUNCTABLE_SIZE-1)
|
||||
|
||||
|
||||
// the renderer front end should never modify jk_glstate_t
|
||||
// the renderer front end should never modify glstate_t
|
||||
typedef struct {
|
||||
int currenttextures[2];
|
||||
int currenttmu;
|
||||
|
@ -915,7 +910,7 @@ typedef struct {
|
|||
int texEnv[2];
|
||||
int faceCulling;
|
||||
uint32_t glStateBits;
|
||||
} jk_glstate_t;
|
||||
} glstate_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -1000,12 +995,12 @@ typedef struct {
|
|||
// Image used to downsample and blur scene to. - AReis
|
||||
GLuint blurImage;
|
||||
|
||||
jk_shader_t *defaultShader;
|
||||
jk_shader_t *shadowShader;
|
||||
jk_shader_t *distortionShader;
|
||||
jk_shader_t *projectionShadowShader;
|
||||
shader_t *defaultShader;
|
||||
shader_t *shadowShader;
|
||||
shader_t *distortionShader;
|
||||
shader_t *projectionShadowShader;
|
||||
|
||||
jk_shader_t *sunShader;
|
||||
shader_t *sunShader;
|
||||
|
||||
int numLightmaps;
|
||||
image_t *lightmaps[MAX_LIGHTMAPS];
|
||||
|
@ -1051,8 +1046,8 @@ typedef struct {
|
|||
// shader indexes from drawsurfs will be looked up in sortedShaders[]
|
||||
// lower indexed sortedShaders must be rendered first (opaque surfaces before translucent)
|
||||
int numShaders;
|
||||
jk_shader_t *shaders[MAX_SHADERS];
|
||||
jk_shader_t *sortedShaders[MAX_SHADERS];
|
||||
shader_t *shaders[MAX_SHADERS];
|
||||
shader_t *sortedShaders[MAX_SHADERS];
|
||||
int iNumDeniedShaders; // used for error-messages only
|
||||
|
||||
int numSkins;
|
||||
|
@ -1081,7 +1076,7 @@ void R_Images_DeleteImage(image_t *pImage);
|
|||
extern backEndState_t backEnd;
|
||||
extern trGlobals_t tr;
|
||||
extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init
|
||||
extern jk_glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init
|
||||
extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init
|
||||
extern window_t window;
|
||||
|
||||
|
||||
|
@ -1241,10 +1236,10 @@ void R_AddLightningBoltSurfaces( trRefEntity_t *e );
|
|||
|
||||
void R_AddPolygonSurfaces( void );
|
||||
|
||||
void R_DecomposeSort( unsigned sort, int *entityNum, jk_shader_t **shader,
|
||||
void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
|
||||
int *fogNum, int *dlightMap );
|
||||
|
||||
void R_AddDrawSurf( const surfaceType_t *surface, const jk_shader_t *shader, int fogIndex, int dlightMap );
|
||||
void R_AddDrawSurf( const surfaceType_t *surface, const shader_t *shader, int fogIndex, int dlightMap );
|
||||
|
||||
|
||||
#define CULL_IN 0 // completely unclipped
|
||||
|
@ -1314,7 +1309,7 @@ void RE_GetScreenShot(byte *data, int w, int h);
|
|||
byte* RE_TempRawImage_ReadFromFile(const char *psLocalFilename, int *piWidth, int *piHeight, byte *pbReSampleBuffer, qboolean qbVertFlip);
|
||||
void RE_TempRawImage_CleanUp();
|
||||
|
||||
void RE_BeginRegistration( glconfig_t *glconfig, intptr_t pVrClientInfo );
|
||||
void RE_BeginRegistration( glconfig_t *glconfig );
|
||||
void RE_LoadWorldMap( const char *mapname );
|
||||
void RE_SetWorldVisData( const byte *vis );
|
||||
qhandle_t RE_RegisterModel( const char *name );
|
||||
|
@ -1338,8 +1333,7 @@ model_t *R_AllocModel( void );
|
|||
void R_Init( void );
|
||||
image_t *R_FindImageFile( const char *name, qboolean mipmap, qboolean allowPicmip, qboolean allowTC, int glWrapClampMode );
|
||||
|
||||
image_t *R_CreateImage( const char *name, const byte *pic, int width, int height,
|
||||
GLenum format, qboolean mipmap, qboolean allowPicmip, qboolean allowTC, int glWrapClampMode, bool bRectangle = false );
|
||||
image_t *R_CreateImage( const char *name, const byte *pic, int width, int height, GLenum format, qboolean mipmap, qboolean allowPicmip, qboolean allowTC, int wrapClampMode);
|
||||
|
||||
qboolean R_GetModeInfo( int *width, int *height, int mode );
|
||||
|
||||
|
@ -1373,17 +1367,16 @@ extern const byte stylesDefault[MAXLIGHTMAPS];
|
|||
qhandle_t RE_RegisterShader( const char *name );
|
||||
qhandle_t RE_RegisterShaderNoMip( const char *name );
|
||||
|
||||
jk_shader_t *R_FindShader( const char *name, const int *lightmapIndex, const byte *styles, qboolean mipRawImage );
|
||||
jk_shader_t *R_GetShaderByHandle( qhandle_t hShader );
|
||||
shader_t *R_FindShader( const char *name, const int *lightmapIndex, const byte *styles, qboolean mipRawImage );
|
||||
shader_t *R_GetShaderByHandle( qhandle_t hShader );
|
||||
void R_InitShaders( void );
|
||||
void R_ShaderList_f( void );
|
||||
|
||||
//
|
||||
// tr_arb.c
|
||||
//
|
||||
#ifndef HAVE_GLES
|
||||
void ARB_InitGlowShaders( void );
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
@ -1424,7 +1417,7 @@ struct shaderCommands_s
|
|||
|
||||
stageVars_t svars QALIGN(16);
|
||||
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
int fogNum;
|
||||
|
||||
int dlightBits; // or together of all vertexDlightBits
|
||||
|
@ -1456,7 +1449,7 @@ extern shaderCommands_t tess;
|
|||
extern color4ub_t styleColors[MAX_LIGHT_STYLES];
|
||||
extern bool styleUpdated[MAX_LIGHT_STYLES];
|
||||
|
||||
void RB_BeginSurface(jk_shader_t *shader, int fogNum );
|
||||
void RB_BeginSurface(shader_t *shader, int fogNum );
|
||||
void RB_EndSurface(void);
|
||||
void RB_CheckOverflow( int verts, int indexes );
|
||||
#define RB_CHECKOVERFLOW(v,i) if (tess.numVertexes + (v) >= SHADER_MAX_VERTEXES || tess.numIndexes + (i) >= SHADER_MAX_INDEXES ) {RB_CheckOverflow(v,i);}
|
||||
|
@ -1737,7 +1730,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int commandId;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
float x, y;
|
||||
float w, h;
|
||||
float s1, t1;
|
||||
|
@ -1746,7 +1739,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int commandId;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
float x, y;
|
||||
float w, h;
|
||||
float s1, t1;
|
||||
|
@ -1785,7 +1778,6 @@ typedef enum {
|
|||
RC_DRAW_BUFFER,
|
||||
RC_SWAP_BUFFERS,
|
||||
RC_WORLD_EFFECTS,
|
||||
RC_FLUSH
|
||||
} renderCommand_t;
|
||||
|
||||
|
||||
|
@ -1826,7 +1818,6 @@ void RE_LAGoggles( void );
|
|||
void RE_Scissor ( float x, float y, float w, float h);
|
||||
void RE_BeginFrame( stereoFrame_t stereoFrame );
|
||||
void RE_EndFrame( int *frontEndMsec, int *backEndMsec );
|
||||
void RE_SubmitStereoFrame( );
|
||||
qboolean RE_ProcessDissolve(void);
|
||||
qboolean RE_InitDissolve(qboolean bForceCircularExtroWipe);
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
#include <JKVR/VrClientInfo.h>
|
||||
|
||||
#if !defined(G2_H_INC)
|
||||
#include "../ghoul2/G2.h"
|
||||
|
@ -35,8 +34,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
trGlobals_t tr;
|
||||
|
||||
vr_client_info_t *vr;
|
||||
|
||||
static float s_flipMatrix[16] = {
|
||||
// convert from our coordinate system (looking down X)
|
||||
// to OpenGL's coordinate system (looking down -Z)
|
||||
|
@ -894,7 +891,7 @@ static qboolean SurfIsOffscreen( const drawSurf_t *drawSurf, vec4_t clipDest[128
|
|||
float shortest = 1000000000;
|
||||
int entityNum;
|
||||
int numTriangles;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
int fogNum;
|
||||
int dlighted;
|
||||
vec4_t clip, eye;
|
||||
|
@ -1052,7 +1049,7 @@ See if a sprite is inside a fog volume
|
|||
*/
|
||||
int R_SpriteFogNum( trRefEntity_t *ent ) {
|
||||
int i;
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
|
||||
if ( tr.refdef.rdflags & RDF_NOWORLDMODEL ) {
|
||||
return 0;
|
||||
|
@ -1162,7 +1159,7 @@ static void R_RadixSort( drawSurf_t *source, int size )
|
|||
R_AddDrawSurf
|
||||
=================
|
||||
*/
|
||||
void R_AddDrawSurf( const surfaceType_t *surface, const jk_shader_t *shader, int fogIndex, int dlightMap )
|
||||
void R_AddDrawSurf( const surfaceType_t *surface, const shader_t *shader, int fogIndex, int dlightMap )
|
||||
{
|
||||
int index;
|
||||
|
||||
|
@ -1193,7 +1190,7 @@ void R_AddDrawSurf( const surfaceType_t *surface, const jk_shader_t *shader, int
|
|||
R_DecomposeSort
|
||||
=================
|
||||
*/
|
||||
void R_DecomposeSort( unsigned sort, int *entityNum, jk_shader_t **shader,
|
||||
void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
|
||||
int *fogNum, int *dlightMap ) {
|
||||
*fogNum = ( sort >> QSORT_FOGNUM_SHIFT ) & 31;
|
||||
*shader = tr.sortedShaders[ ( sort >> QSORT_SHADERNUM_SHIFT ) & (MAX_SHADERS-1) ];
|
||||
|
@ -1207,7 +1204,7 @@ R_SortDrawSurfs
|
|||
=================
|
||||
*/
|
||||
void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
int fogNum;
|
||||
int entityNum;
|
||||
int dlighted;
|
||||
|
@ -1263,7 +1260,7 @@ R_AddEntitySurfaces
|
|||
*/
|
||||
void R_AddEntitySurfaces (void) {
|
||||
trRefEntity_t *ent;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
|
||||
if ( !r_drawentities->integer ) {
|
||||
return;
|
||||
|
@ -1409,36 +1406,22 @@ void R_DebugPolygon( int color, int numPoints, float *points ) {
|
|||
|
||||
// draw solid shade
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f( color&1, (color>>1)&1, (color>>2)&1, 1.0f );
|
||||
qglVertexPointer ( 3, GL_FLOAT, 0, points );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, numPoints );
|
||||
#else
|
||||
qglColor3f( color&1, (color>>1)&1, (color>>2)&1 );
|
||||
qglBegin( GL_POLYGON );
|
||||
for ( i = 0 ; i < numPoints ; i++ ) {
|
||||
qglVertex3fv( points + i * 3 );
|
||||
}
|
||||
qglEnd();
|
||||
#endif
|
||||
|
||||
// draw wireframe outline
|
||||
#ifndef HAVE_GLES
|
||||
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
#endif
|
||||
qglDepthRange( 0, 0 );
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
qglVertexPointer ( 3, GL_FLOAT, 0, points );
|
||||
qglDrawArrays( GL_LINES, 0, numPoints );
|
||||
#else
|
||||
qglColor3f( 1, 1, 1 );
|
||||
qglBegin( GL_POLYGON );
|
||||
for ( i = 0 ; i < numPoints ; i++ ) {
|
||||
qglVertex3fv( points + i * 3 );
|
||||
}
|
||||
qglEnd();
|
||||
#endif
|
||||
qglDepthRange( 0, 1 );
|
||||
}
|
||||
|
||||
|
@ -1478,7 +1461,7 @@ void R_SetViewFogIndex (void)
|
|||
{
|
||||
if ( tr.world->numfogs > 1 )
|
||||
{//more than just the LA goggles
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
int contents = ri.SV_PointContents( tr.refdef.vieworg, 0 );
|
||||
if ( (contents&CONTENTS_FOG) )
|
||||
{//only take a tr.refdef.fogIndex if the tr.refdef.vieworg is actually *in* that fog brush (assumption: checks pointcontents for any CONTENTS_FOG, not that particular brush...)
|
||||
|
|
|
@ -242,7 +242,7 @@ R_ComputeFogNum
|
|||
*/
|
||||
static int R_ComputeFogNum( md3Header_t *header, trRefEntity_t *ent ) {
|
||||
int i;
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
md3Frame_t *md3Frame;
|
||||
vec3_t localOrigin;
|
||||
|
||||
|
@ -304,8 +304,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) {
|
|||
md3Header_t *header = 0;
|
||||
md3Surface_t *surface = 0;
|
||||
md3Shader_t *md3Shader = 0;
|
||||
jk_shader_t *shader = 0;
|
||||
jk_shader_t *main_shader = 0;
|
||||
shader_t *shader = 0;
|
||||
shader_t *main_shader = 0;
|
||||
int cull;
|
||||
int lod;
|
||||
int fogNum;
|
||||
|
|
|
@ -30,7 +30,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
#include "tr_local.h"
|
||||
#include "qcommon/matcomp.h"
|
||||
#include "../qcommon/sstring.h"
|
||||
#include <JKVR/VrClientInfo.h>
|
||||
|
||||
#define LL(x) x=LittleLong(x)
|
||||
#define LS(x) x=LittleShort(x)
|
||||
|
@ -224,7 +223,7 @@ void *RE_RegisterModels_Malloc(int iSize, void *pvDiskBufferIfJustLoaded, const
|
|||
const char *const psShaderName = &((char*)ModelBin.pModelDiskImage)[iShaderNameOffset];
|
||||
int *const piShaderPokePtr= (int *) &((char*)ModelBin.pModelDiskImage)[iShaderPokeOffset];
|
||||
|
||||
jk_shader_t *sh = R_FindShader( psShaderName, lightmapsNone, stylesDefault, qtrue );
|
||||
shader_t *sh = R_FindShader( psShaderName, lightmapsNone, stylesDefault, qtrue );
|
||||
|
||||
if ( sh->defaultShader )
|
||||
{
|
||||
|
@ -922,7 +921,7 @@ static qboolean R_LoadMD3 (model_t *mod, int lod, void *buffer, const char *mod_
|
|||
// register the shaders
|
||||
shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
|
||||
for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) {
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
|
||||
sh = R_FindShader( shader->name, lightmapsNone, stylesDefault, qtrue );
|
||||
if ( sh->defaultShader ) {
|
||||
|
@ -978,13 +977,12 @@ void CM_SetupShaderProperties(void);
|
|||
/*
|
||||
** RE_BeginRegistration
|
||||
*/
|
||||
void RE_BeginRegistration( glconfig_t *glconfigOut, intptr_t pVrClientInfo ) {
|
||||
void RE_BeginRegistration( glconfig_t *glconfigOut ) {
|
||||
ri.Hunk_ClearToMark();
|
||||
|
||||
R_Init();
|
||||
|
||||
*glconfigOut = glConfig;
|
||||
vr = (vr_client_info_t*)pVrClientInfo;
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ void CQuickSpriteSystem::Flush(void)
|
|||
if (mUseFog && r_drawfog->integer == 2 &&
|
||||
mFogIndex == tr.world->globalFog)
|
||||
{ //enable hardware fog when we draw this thing if applicable -rww
|
||||
jk_fog_t *fog = tr.world->fogs + mFogIndex;
|
||||
fog_t *fog = tr.world->fogs + mFogIndex;
|
||||
|
||||
qglFogf(GL_FOG_MODE, GL_EXP2);
|
||||
qglFogf(GL_FOG_DENSITY, logtestExp2 / fog->parms.depthForOpaque);
|
||||
|
@ -104,37 +104,6 @@ void CQuickSpriteSystem::Flush(void)
|
|||
//
|
||||
// set arrays and lock
|
||||
//
|
||||
#ifdef HAVE_GLES
|
||||
unsigned short indexes[(mNextVert/2)*3];
|
||||
int idx;
|
||||
// split TRIANGLE_FAN in 2 TRIANGLES
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
|
||||
qglEnableClientState( GL_COLOR_ARRAY);
|
||||
/*for (int i=0; i<mNextVert; i+=4) {
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, mTextureCoords+i);
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors+i );
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts+i);
|
||||
qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}*/
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords );
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, mColors );
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts);
|
||||
idx = 0;
|
||||
for (int i=0; i<mNextVert; i+=4) {
|
||||
// Triangle 1
|
||||
indexes[idx+0]=i;
|
||||
indexes[idx+1]=i+1;
|
||||
indexes[idx+2]=i+2;
|
||||
idx+=3;
|
||||
// Triangle 2
|
||||
indexes[idx+0]=i;
|
||||
indexes[idx+1]=i+2;
|
||||
indexes[idx+2]=i+3;
|
||||
idx+=3;
|
||||
}
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
|
||||
#else
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, mTextureCoords );
|
||||
|
||||
|
@ -150,7 +119,6 @@ void CQuickSpriteSystem::Flush(void)
|
|||
}
|
||||
|
||||
qglDrawArrays(GL_QUADS, 0, mNextVert);
|
||||
#endif
|
||||
|
||||
backEnd.pc.c_vertexes += mNextVert;
|
||||
backEnd.pc.c_indexes += mNextVert;
|
||||
|
@ -163,7 +131,7 @@ void CQuickSpriteSystem::Flush(void)
|
|||
if (mUseFog && (r_drawfog->integer != 2 || mFogIndex != tr.world->globalFog))
|
||||
#endif
|
||||
{
|
||||
jk_fog_t *fog = tr.world->fogs + mFogIndex;
|
||||
fog_t *fog = tr.world->fogs + mFogIndex;
|
||||
|
||||
//
|
||||
// render the fog pass
|
||||
|
@ -174,16 +142,6 @@ void CQuickSpriteSystem::Flush(void)
|
|||
//
|
||||
// set arrays and lock
|
||||
//
|
||||
#ifdef HAVE_GLES
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglColor4ubv((GLubyte *)&fog->colorInt);
|
||||
/*for (int i=0; i<mNextVert; i+=4) {
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, mFogTextureCoords+i);
|
||||
qglVertexPointer (3, GL_FLOAT, 16, mVerts+i);
|
||||
qglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}*/
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, mFogTextureCoords);
|
||||
// qglEnableClientState( GL_TEXTURE_COORD_ARRAY); // Done above
|
||||
|
||||
|
@ -193,7 +151,6 @@ void CQuickSpriteSystem::Flush(void)
|
|||
// qglVertexPointer (3, GL_FLOAT, 16, mVerts); // Done above
|
||||
|
||||
qglDrawArrays(GL_QUADS, 0, mNextVert);
|
||||
#endif
|
||||
|
||||
// Second pass from fog
|
||||
backEnd.pc.c_totalIndexes += mNextVert;
|
||||
|
|
|
@ -25,7 +25,6 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
#include "../server/exe_headers.h"
|
||||
|
||||
#include "tr_local.h"
|
||||
#include <JKVR/VrClientInfo.h>
|
||||
|
||||
int r_firstSceneDrawSurf;
|
||||
|
||||
|
@ -42,7 +41,6 @@ int r_numpolyverts;
|
|||
|
||||
int skyboxportal;
|
||||
int drawskyboxportal;
|
||||
int hasskybox; // Used to indicate whether the BSP contains a skybox (if not, then use fog colour if applicable)
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -100,7 +98,7 @@ Adds all the scene's polys into this view's drawsurf list
|
|||
*/
|
||||
void R_AddPolygonSurfaces( void ) {
|
||||
int i;
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
srfPoly_t *poly;
|
||||
|
||||
tr.currentEntityNum = REFENTITYNUM_WORLD;
|
||||
|
@ -122,7 +120,7 @@ void RE_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *vert
|
|||
srfPoly_t *poly;
|
||||
int i;
|
||||
int fogIndex = 0;
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
vec3_t bounds[2];
|
||||
|
||||
if ( !tr.registered ) {
|
||||
|
@ -298,11 +296,6 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
tr.refdef.fov_x = fd->fov_x;
|
||||
tr.refdef.fov_y = fd->fov_y;
|
||||
|
||||
memset( &parms, 0, sizeof( parms ) );
|
||||
VectorCopy( fd->viewaxis[0], parms.ori.axis[0] );
|
||||
VectorCopy( fd->viewaxis[1], parms.ori.axis[1] );
|
||||
VectorCopy( fd->viewaxis[2], parms.ori.axis[2] );
|
||||
|
||||
VectorCopy( fd->vieworg, tr.refdef.vieworg );
|
||||
VectorCopy( fd->viewaxis[0], tr.refdef.viewaxis[0] );
|
||||
VectorCopy( fd->viewaxis[1], tr.refdef.viewaxis[1] );
|
||||
|
@ -391,6 +384,7 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
// The refdef takes 0-at-the-top y coordinates, so
|
||||
// convert to GL's 0-at-the-bottom space
|
||||
//
|
||||
memset( &parms, 0, sizeof( parms ) );
|
||||
parms.viewportX = tr.refdef.x;
|
||||
parms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.refdef.height );
|
||||
parms.viewportWidth = tr.refdef.width;
|
||||
|
@ -401,9 +395,9 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
parms.fovY = tr.refdef.fov_y;
|
||||
|
||||
VectorCopy( fd->vieworg, parms.ori.origin );
|
||||
// VectorCopy( fd->viewaxis[0], parms.ori.axis[0] );
|
||||
// VectorCopy( fd->viewaxis[1], parms.ori.axis[1] );
|
||||
// VectorCopy( fd->viewaxis[2], parms.ori.axis[2] );
|
||||
VectorCopy( fd->viewaxis[0], parms.ori.axis[0] );
|
||||
VectorCopy( fd->viewaxis[1], parms.ori.axis[1] );
|
||||
VectorCopy( fd->viewaxis[2], parms.ori.axis[2] );
|
||||
|
||||
VectorCopy( fd->vieworg, parms.pvsOrigin );
|
||||
|
||||
|
|
|
@ -51,8 +51,6 @@ This is just for OpenGL conformance testing, it should never be the fastest
|
|||
================
|
||||
*/
|
||||
static void APIENTRY R_ArrayElementDiscrete( GLint index ) {
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
qglColor4ubv( tess.svars.colors[ index ] );
|
||||
if ( glState.currenttmu ) {
|
||||
qglMultiTexCoord2fARB( 0, tess.svars.texcoords[ 0 ][ index ][0], tess.svars.texcoords[ 0 ][ index ][1] );
|
||||
|
@ -61,7 +59,6 @@ static void APIENTRY R_ArrayElementDiscrete( GLint index ) {
|
|||
qglTexCoord2fv( tess.svars.texcoords[ 0 ][ index ] );
|
||||
}
|
||||
qglVertex3fv( tess.xyz[ index ] );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -70,7 +67,6 @@ R_DrawStripElements
|
|||
|
||||
===================
|
||||
*/
|
||||
#ifndef HAVE_GLES
|
||||
static int c_vertexes; // for seeing how long our average strips are
|
||||
static int c_begins;
|
||||
static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void ( APIENTRY *element )(GLint) ) {
|
||||
|
@ -78,14 +74,13 @@ static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void
|
|||
glIndex_t last[3];
|
||||
qboolean even;
|
||||
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
c_begins++;
|
||||
|
||||
if ( numIndexes <= 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
|
||||
// prime the strip
|
||||
element( indexes[0] );
|
||||
element( indexes[1] );
|
||||
|
@ -111,8 +106,8 @@ static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void
|
|||
assert( (int)indexes[i+2] < tess.numVertexes );
|
||||
even = qtrue;
|
||||
}
|
||||
// otherwise we're done with this strip so finish it and start
|
||||
// a new one
|
||||
// otherwise we're done with this strip so finish it and start
|
||||
// a new one
|
||||
else
|
||||
{
|
||||
qglEnd();
|
||||
|
@ -139,8 +134,8 @@ static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void
|
|||
|
||||
even = qfalse;
|
||||
}
|
||||
// otherwise we're done with this strip so finish it and start
|
||||
// a new one
|
||||
// otherwise we're done with this strip so finish it and start
|
||||
// a new one
|
||||
else
|
||||
{
|
||||
qglEnd();
|
||||
|
@ -165,8 +160,6 @@ static void R_DrawStripElements( int numIndexes, const glIndex_t *indexes, void
|
|||
|
||||
qglEnd();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
|
@ -193,37 +186,13 @@ static void R_DrawElements( int numIndexes, const glIndex_t *indexes ) {
|
|||
|
||||
|
||||
if ( primitives == 2 ) {
|
||||
qglDrawElements( GL_TRIANGLES,
|
||||
numIndexes,
|
||||
GL_INDEX_TYPE,
|
||||
indexes );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HAVE_GLES)
|
||||
if (primitives == 1 || primitives == 3)
|
||||
{
|
||||
// if (tess.useConstantColor)
|
||||
// {
|
||||
// qglDisableClientState( GL_COLOR_ARRAY );
|
||||
// qglColor4ubv( tess.constantColor );
|
||||
// }
|
||||
/*qglDrawElements( GL_TRIANGLES,
|
||||
numIndexes,
|
||||
GL_INDEX_TYPE,
|
||||
indexes );*/
|
||||
#if 1 // VVFIXME : Temporary solution to try and increase framerate
|
||||
//qglIndexedTriToStrip( numIndexes, indexes );
|
||||
|
||||
qglDrawElements( GL_TRIANGLES,
|
||||
numIndexes,
|
||||
GL_INDEX_TYPE,
|
||||
indexes );
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
#else // HAVE_GLES
|
||||
|
||||
if ( primitives == 1 ) {
|
||||
R_DrawStripElements( numIndexes, indexes, qglArrayElement );
|
||||
return;
|
||||
|
@ -233,13 +202,14 @@ static void R_DrawElements( int numIndexes, const glIndex_t *indexes ) {
|
|||
R_DrawStripElements( numIndexes, indexes, R_ArrayElementDiscrete );
|
||||
return;
|
||||
}
|
||||
#endif // HAVE_GLES
|
||||
|
||||
// anything else will cause no drawing
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
|
@ -316,34 +286,103 @@ DrawTris
|
|||
Draws triangle outlines for debugging
|
||||
================
|
||||
*/
|
||||
static void DrawTris (shaderCommands_t *input) {
|
||||
if (input->numVertexes <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void DrawTris (shaderCommands_t *input)
|
||||
{
|
||||
GL_Bind( tr.whiteImage );
|
||||
qglColor3f (1,1,1);
|
||||
|
||||
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
|
||||
qglDepthRange( 0, 0 );
|
||||
|
||||
qglDisableClientState (GL_COLOR_ARRAY);
|
||||
qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD
|
||||
|
||||
if (qglLockArraysEXT) {
|
||||
qglLockArraysEXT(0, input->numVertexes);
|
||||
GLimp_LogComment( "glLockArraysEXT\n" );
|
||||
if ( r_showtriscolor->integer )
|
||||
{
|
||||
int i = r_showtriscolor->integer;
|
||||
if (i == 42) {
|
||||
i = Q_irand(0,8);
|
||||
}
|
||||
switch (i)
|
||||
{
|
||||
case 1:
|
||||
qglColor3f( 1.0, 0.0, 0.0); //red
|
||||
break;
|
||||
case 2:
|
||||
qglColor3f( 0.0, 1.0, 0.0); //green
|
||||
break;
|
||||
case 3:
|
||||
qglColor3f( 1.0, 1.0, 0.0); //yellow
|
||||
break;
|
||||
case 4:
|
||||
qglColor3f( 0.0, 0.0, 1.0); //blue
|
||||
break;
|
||||
case 5:
|
||||
qglColor3f( 0.0, 1.0, 1.0); //cyan
|
||||
break;
|
||||
case 6:
|
||||
qglColor3f( 1.0, 0.0, 1.0); //magenta
|
||||
break;
|
||||
case 7:
|
||||
qglColor3f( 0.8f, 0.8f, 0.8f); //white/grey
|
||||
break;
|
||||
case 8:
|
||||
qglColor3f( 0.0, 0.0, 0.0); //black
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qglColor3f( 1.0, 1.0, 1.0); //white
|
||||
}
|
||||
|
||||
R_DrawElements( input->numIndexes, input->indexes );
|
||||
if ( r_showtris->integer == 2 )
|
||||
{
|
||||
// tries to do non-xray style showtris
|
||||
GL_State( GLS_POLYMODE_LINE );
|
||||
|
||||
if (qglUnlockArraysEXT) {
|
||||
qglUnlockArraysEXT();
|
||||
GLimp_LogComment( "glUnlockArraysEXT\n" );
|
||||
qglEnable( GL_POLYGON_OFFSET_LINE );
|
||||
qglPolygonOffset( -1, -2 );
|
||||
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
|
||||
qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); // padded for SIMD
|
||||
|
||||
if ( qglLockArraysEXT )
|
||||
{
|
||||
qglLockArraysEXT( 0, input->numVertexes );
|
||||
GLimp_LogComment( "glLockArraysEXT\n" );
|
||||
}
|
||||
|
||||
R_DrawElements( input->numIndexes, input->indexes );
|
||||
|
||||
if ( qglUnlockArraysEXT )
|
||||
{
|
||||
qglUnlockArraysEXT( );
|
||||
GLimp_LogComment( "glUnlockArraysEXT\n" );
|
||||
}
|
||||
|
||||
qglDisable( GL_POLYGON_OFFSET_LINE );
|
||||
}
|
||||
else
|
||||
{
|
||||
// same old showtris
|
||||
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
|
||||
qglDepthRange( 0, 0 );
|
||||
|
||||
qglDisableClientState (GL_COLOR_ARRAY);
|
||||
qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
qglVertexPointer (3, GL_FLOAT, 16, input->xyz); // padded for SIMD
|
||||
|
||||
if (qglLockArraysEXT) {
|
||||
qglLockArraysEXT(0, input->numVertexes);
|
||||
GLimp_LogComment( "glLockArraysEXT\n" );
|
||||
}
|
||||
|
||||
R_DrawElements( input->numIndexes, input->indexes );
|
||||
|
||||
if (qglUnlockArraysEXT) {
|
||||
qglUnlockArraysEXT();
|
||||
GLimp_LogComment( "glUnlockArraysEXT\n" );
|
||||
}
|
||||
|
||||
qglDepthRange( 0, 1 );
|
||||
}
|
||||
qglDepthRange( 0, 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -362,9 +401,6 @@ static void DrawNormals (shaderCommands_t *input) {
|
|||
qglDepthRange( 0, 0 ); // never occluded
|
||||
GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
/*SEB *TODO* */
|
||||
#else
|
||||
qglBegin (GL_LINES);
|
||||
for (i = 0 ; i < input->numVertexes ; i++) {
|
||||
qglVertex3fv (input->xyz[i]);
|
||||
|
@ -372,7 +408,6 @@ static void DrawNormals (shaderCommands_t *input) {
|
|||
qglVertex3fv (temp);
|
||||
}
|
||||
qglEnd ();
|
||||
#endif
|
||||
|
||||
qglDepthRange( 0, 1 );
|
||||
}
|
||||
|
@ -387,9 +422,9 @@ because a surface may be forced to perform a RB_End due
|
|||
to overflow.
|
||||
==============
|
||||
*/
|
||||
void RB_BeginSurface( jk_shader_t *shader, int fogNum ) {
|
||||
// jk_shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader;
|
||||
jk_shader_t *state = shader;
|
||||
void RB_BeginSurface( shader_t *shader, int fogNum ) {
|
||||
// shader_t *state = (shader->remappedShader) ? shader->remappedShader : shader;
|
||||
shader_t *state = shader;
|
||||
|
||||
tess.numIndexes = 0;
|
||||
tess.numVertexes = 0;
|
||||
|
@ -1296,7 +1331,7 @@ Blends a fog texture on top of everything else
|
|||
===================
|
||||
*/
|
||||
static void RB_FogPass( void ) {
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
int i;
|
||||
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
|
@ -1461,7 +1496,7 @@ static void ComputeColors( shaderStage_t *pStage, alphaGen_t forceAlphaGen, colo
|
|||
break;
|
||||
case CGEN_FOG:
|
||||
{
|
||||
const jk_fog_t *fog = tr.world->fogs + tess.fogNum;
|
||||
const fog_t *fog = tr.world->fogs + tess.fogNum;
|
||||
|
||||
for ( i = 0; i < tess.numVertexes; i++ ) {
|
||||
byteAlias_t *ba = (byteAlias_t *)&tess.svars.colors[i];
|
||||
|
@ -1769,7 +1804,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
|||
#ifndef JK2_MODE
|
||||
bool UseGLFog = false;
|
||||
bool FogColorChange = false;
|
||||
jk_fog_t *fog = NULL;
|
||||
fog_t *fog = NULL;
|
||||
|
||||
if (tess.fogNum && tess.shader->fogPass && (tess.fogNum == tr.world->globalFog || tess.fogNum == tr.world->numfogs)
|
||||
&& r_drawfog->value == 2)
|
||||
|
|
|
@ -821,7 +821,7 @@ void RB_CalcFogTexCoords( float *st ) {
|
|||
float s, t;
|
||||
float eyeT;
|
||||
qboolean eyeOutside;
|
||||
jk_fog_t *fog;
|
||||
fog_t *fog;
|
||||
vec3_t localVec;
|
||||
vec4_t fogDistanceVector, fogDepthVector;
|
||||
|
||||
|
@ -1057,12 +1057,6 @@ void RB_CalcSpecularAlpha( unsigned char *alphas ) {
|
|||
|
||||
alphas += 3;
|
||||
|
||||
//What the hell is this doing as a NaN?!?
|
||||
if (Q_isnan(backEnd.ori.viewOrigin[0]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
numVertexes = tess.numVertexes;
|
||||
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4, alphas += 4) {
|
||||
float ilength;
|
||||
|
|
|
@ -35,7 +35,7 @@ static char *s_shaderText;
|
|||
// the shader is parsed into these global variables, then copied into
|
||||
// dynamically allocated memory if it is valid.
|
||||
static shaderStage_t stages[MAX_SHADER_STAGES];
|
||||
static jk_shader_t shader;
|
||||
static shader_t shader;
|
||||
static texModInfo_t texMods[MAX_SHADER_STAGES][TR_MAX_TEXMODS];
|
||||
|
||||
// Hash value (generated using the generateHashValueForText function) for the original
|
||||
|
@ -48,7 +48,7 @@ static texModInfo_t texMods[MAX_SHADER_STAGES][TR_MAX_TEXMODS];
|
|||
|
||||
|
||||
#define FILE_HASH_SIZE 1024
|
||||
static jk_shader_t* sh_hashTable[FILE_HASH_SIZE];
|
||||
static shader_t* sh_hashTable[FILE_HASH_SIZE];
|
||||
|
||||
const int lightmapsNone[MAXLIGHTMAPS] =
|
||||
{
|
||||
|
@ -130,7 +130,7 @@ way to ask for different implicit lighting modes (vertex, lightmap, etc)
|
|||
*/
|
||||
qhandle_t RE_RegisterShaderLightMap( const char *name, const int *lightmapIndex, const byte *styles )
|
||||
{
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
Com_Printf( "Shader name exceeds MAX_QPATH\n" );
|
||||
|
@ -159,10 +159,10 @@ Will always return a valid shader, but it might be the
|
|||
default shader if the real one can't be found.
|
||||
==================
|
||||
*/
|
||||
jk_shader_t *R_FindShaderByName( const char *name ) {
|
||||
shader_t *R_FindShaderByName( const char *name ) {
|
||||
char strippedName[MAX_QPATH];
|
||||
int hash;
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
|
||||
if ( (name==NULL) || (name[0] == 0) ) { // bk001205
|
||||
return tr.defaultShader;
|
||||
|
@ -193,7 +193,7 @@ jk_shader_t *R_FindShaderByName( const char *name ) {
|
|||
void R_RemapShader(const char *shaderName, const char *newShaderName, const char *timeOffset) {
|
||||
char strippedName[MAX_QPATH];
|
||||
int hash;
|
||||
jk_shader_t *sh, *sh2;
|
||||
shader_t *sh, *sh2;
|
||||
qhandle_t h;
|
||||
|
||||
sh = R_FindShaderByName( shaderName );
|
||||
|
@ -2698,7 +2698,7 @@ static void FixRenderCommandList( int newShader ) {
|
|||
{
|
||||
int i;
|
||||
drawSurf_t *drawSurf;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
int fogNum;
|
||||
int entityNum;
|
||||
int dlightMap;
|
||||
|
@ -2758,7 +2758,7 @@ Sets shader->sortedIndex
|
|||
static void SortNewShader( void ) {
|
||||
int i;
|
||||
float sort;
|
||||
jk_shader_t *newShader;
|
||||
shader_t *newShader;
|
||||
|
||||
newShader = tr.shaders[ tr.numShaders - 1 ];
|
||||
sort = newShader->sort;
|
||||
|
@ -2785,8 +2785,8 @@ static void SortNewShader( void ) {
|
|||
GeneratePermanentShader
|
||||
====================
|
||||
*/
|
||||
static jk_shader_t *GeneratePermanentShader( void ) {
|
||||
jk_shader_t *newShader;
|
||||
static shader_t *GeneratePermanentShader( void ) {
|
||||
shader_t *newShader;
|
||||
int i, b;
|
||||
int size;
|
||||
|
||||
|
@ -2796,7 +2796,7 @@ static jk_shader_t *GeneratePermanentShader( void ) {
|
|||
return tr.defaultShader;
|
||||
}
|
||||
|
||||
newShader = (jk_shader_t *)R_Hunk_Alloc( sizeof( jk_shader_t ), qtrue );
|
||||
newShader = (shader_t *)R_Hunk_Alloc( sizeof( shader_t ), qtrue );
|
||||
|
||||
*newShader = shader;
|
||||
|
||||
|
@ -2967,7 +2967,7 @@ Returns a freshly allocated shader with all the needed info
|
|||
from the current global working shader
|
||||
=========================
|
||||
*/
|
||||
static jk_shader_t *FinishShader( void ) {
|
||||
static shader_t *FinishShader( void ) {
|
||||
int stage, lmStage, stageIndex;
|
||||
qboolean hasLightmapStage;
|
||||
|
||||
|
@ -3323,7 +3323,7 @@ static const char *FindShaderInShaderText( const char *shadername ) {
|
|||
#endif
|
||||
}
|
||||
|
||||
inline qboolean IsShader(jk_shader_t *sh, const char *name, const int *lightmapIndex, const byte *styles)
|
||||
inline qboolean IsShader(shader_t *sh, const char *name, const int *lightmapIndex, const byte *styles)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -3422,12 +3422,12 @@ and src*dest blending applied with the texture, as apropriate for
|
|||
most world construction surfaces.
|
||||
===============
|
||||
*/
|
||||
jk_shader_t *R_FindShader( const char *name, const int *lightmapIndex, const byte *styles, qboolean mipRawImage ) {
|
||||
shader_t *R_FindShader( const char *name, const int *lightmapIndex, const byte *styles, qboolean mipRawImage ) {
|
||||
char strippedName[MAX_QPATH];
|
||||
int hash;
|
||||
const char *shaderText;
|
||||
image_t *image;
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
|
||||
if ( strlen( name ) >= MAX_QPATH ) {
|
||||
Com_Printf( S_COLOR_RED"Shader name exceeds MAX_QPATH! %s\n",name );
|
||||
|
@ -3569,7 +3569,7 @@ way to ask for different implicit lighting modes (vertex, lightmap, etc)
|
|||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterShader( const char *name ) {
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
|
||||
sh = R_FindShader( name, lightmaps2d, stylesDefault, qtrue );
|
||||
|
||||
|
@ -3594,7 +3594,7 @@ For menu graphics that should never be picmiped
|
|||
====================
|
||||
*/
|
||||
qhandle_t RE_RegisterShaderNoMip( const char *name ) {
|
||||
jk_shader_t *sh;
|
||||
shader_t *sh;
|
||||
|
||||
sh = R_FindShader( name, lightmaps2d, stylesDefault, qfalse );
|
||||
|
||||
|
@ -3616,10 +3616,10 @@ qhandle_t RE_RegisterShaderNoMip( const char *name ) {
|
|||
R_GetShaderByHandle
|
||||
|
||||
When a handle is passed in by another module, this range checks
|
||||
it and returns a valid (possibly default) jk_shader_t to be used internally.
|
||||
it and returns a valid (possibly default) shader_t to be used internally.
|
||||
====================
|
||||
*/
|
||||
jk_shader_t *R_GetShaderByHandle( qhandle_t hShader ) {
|
||||
shader_t *R_GetShaderByHandle( qhandle_t hShader ) {
|
||||
if ( hShader < 0 ) {
|
||||
ri.Printf( PRINT_WARNING, "R_GetShaderByHandle: out of range hShader '%d'\n", hShader );
|
||||
return tr.defaultShader;
|
||||
|
@ -3642,7 +3642,7 @@ A second parameter will cause it to print in sorted order
|
|||
void R_ShaderList_f (void) {
|
||||
int i;
|
||||
int count;
|
||||
jk_shader_t *shader;
|
||||
shader_t *shader;
|
||||
|
||||
ri.Printf (PRINT_ALL, "-----------------------\n");
|
||||
|
||||
|
@ -3851,9 +3851,7 @@ static void CreateInternalShaders( void ) {
|
|||
tr.distortionShader = FinishShader();
|
||||
shader.defaultShader = true;
|
||||
|
||||
#ifndef HAVE_GLES
|
||||
ARB_InitGlowShaders();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void CreateExternalShaders( void ) {
|
||||
|
|
|
@ -49,10 +49,7 @@ static edgeDef_t edgeDefs[SHADER_MAX_VERTEXES][MAX_EDGE_DEFS];
|
|||
static int numEdgeDefs[SHADER_MAX_VERTEXES];
|
||||
static int facing[SHADER_MAX_INDEXES/3];
|
||||
static vec3_t shadowXyz[SHADER_MAX_VERTEXES];
|
||||
#ifdef HAVE_GLES
|
||||
static unsigned short indexes[6 * MAX_EDGE_DEFS * SHADER_MAX_VERTEXES + SHADER_MAX_INDEXES * 2];
|
||||
static int idx = 0;
|
||||
#endif
|
||||
|
||||
|
||||
void R_AddEdgeDef( int i1, int i2, int facing ) {
|
||||
int c;
|
||||
|
@ -72,8 +69,8 @@ void R_RenderShadowEdges( void ) {
|
|||
int c;
|
||||
int j;
|
||||
int i2;
|
||||
//int c_edges, c_rejected;
|
||||
#if 0
|
||||
int c_edges, c_rejected;
|
||||
int c2, k;
|
||||
int hit[2];
|
||||
#endif
|
||||
|
@ -91,10 +88,6 @@ void R_RenderShadowEdges( void ) {
|
|||
c_rejected = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
idx = 0;
|
||||
#endif
|
||||
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
|
||||
c = numEdgeDefs[ i ];
|
||||
for ( j = 0 ; j < c ; j++ ) {
|
||||
|
@ -107,23 +100,12 @@ void R_RenderShadowEdges( void ) {
|
|||
//we are going to render all edges even though it is a tiny bit slower. -rww
|
||||
#if 1
|
||||
i2 = edgeDefs[ i ][ j ].i2;
|
||||
#ifdef HAVE_GLES
|
||||
// A single drawing call is better than many. So I prefer a singe TRIANGLES call than many TRIANGLE_STRIP call
|
||||
// even if it seems less efficiant, it's faster on the PANDORA
|
||||
indexes[idx++] = i;
|
||||
indexes[idx++] = i + tess.numVertexes;
|
||||
indexes[idx++] = i2;
|
||||
indexes[idx++] = i2;
|
||||
indexes[idx++] = i + tess.numVertexes;
|
||||
indexes[idx++] = i2 + tess.numVertexes;
|
||||
#else
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
qglVertex3fv( tess.xyz[ i ] );
|
||||
qglVertex3fv( tess.xyz[ i + tess.numVertexes ] );
|
||||
qglVertex3fv( tess.xyz[ i2 ] );
|
||||
qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] );
|
||||
qglVertex3fv( tess.xyz[ i ] );
|
||||
qglVertex3fv( shadowXyz[ i ] );
|
||||
qglVertex3fv( tess.xyz[ i2 ] );
|
||||
qglVertex3fv( shadowXyz[ i2 ] );
|
||||
qglEnd();
|
||||
#endif
|
||||
#else
|
||||
hit[0] = 0;
|
||||
hit[1] = 0;
|
||||
|
@ -138,13 +120,12 @@ void R_RenderShadowEdges( void ) {
|
|||
|
||||
// if it doesn't share the edge with another front facing
|
||||
// triangle, it is a sil edge
|
||||
if (hit[1] != 1)
|
||||
{
|
||||
if ( hit[ 1 ] == 0 ) {
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
qglVertex3fv( tess.xyz[ i ] );
|
||||
qglVertex3fv( tess.xyz[ i + tess.numVertexes ] );
|
||||
qglVertex3fv( shadowXyz[ i ] );
|
||||
qglVertex3fv( tess.xyz[ i2 ] );
|
||||
qglVertex3fv( tess.xyz[ i2 + tess.numVertexes ] );
|
||||
qglVertex3fv( shadowXyz[ i2 ] );
|
||||
qglEnd();
|
||||
c_edges++;
|
||||
} else {
|
||||
|
@ -170,30 +151,17 @@ void R_RenderShadowEdges( void ) {
|
|||
o2 = tess.indexes[ i*3 + 1 ];
|
||||
o3 = tess.indexes[ i*3 + 2 ];
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
indexes[idx++]=o1;
|
||||
indexes[idx++]=o2;
|
||||
indexes[idx++]=o3;
|
||||
indexes[idx++]=o3 + tess.numVertexes;
|
||||
indexes[idx++]=o2 + tess.numVertexes;
|
||||
indexes[idx++]=o1 + tess.numVertexes;
|
||||
#else
|
||||
qglBegin(GL_TRIANGLES);
|
||||
qglVertex3fv(tess.xyz[o1]);
|
||||
qglVertex3fv(tess.xyz[o2]);
|
||||
qglVertex3fv(tess.xyz[o3]);
|
||||
qglVertex3fv(tess.xyz[o1]);
|
||||
qglVertex3fv(tess.xyz[o2]);
|
||||
qglVertex3fv(tess.xyz[o3]);
|
||||
qglEnd();
|
||||
qglBegin(GL_TRIANGLES);
|
||||
qglVertex3fv(tess.xyz[o3 + tess.numVertexes]);
|
||||
qglVertex3fv(tess.xyz[o2 + tess.numVertexes]);
|
||||
qglVertex3fv(tess.xyz[o1 + tess.numVertexes]);
|
||||
qglVertex3fv(shadowXyz[o3]);
|
||||
qglVertex3fv(shadowXyz[o2]);
|
||||
qglVertex3fv(shadowXyz[o1]);
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -260,11 +228,6 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
int numTris;
|
||||
vec3_t lightDir;
|
||||
|
||||
// we can only do this if we have enough space in the vertex buffers
|
||||
if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( glConfig.stencilBits < 4 ) {
|
||||
return;
|
||||
}
|
||||
|
@ -289,16 +252,16 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
VectorAdd(tess.xyz[i], backEnd.ori.origin, worldxyz);
|
||||
groundDist = worldxyz[2] - backEnd.currentEntity->e.shadowPlane;
|
||||
groundDist += 16.0f; //fudge factor
|
||||
VectorMA( tess.xyz[i], -groundDist, lightDir, tess.xyz[i+tess.numVertexes] );
|
||||
VectorMA( tess.xyz[i], -groundDist, lightDir, shadowXyz[i] );
|
||||
}
|
||||
#else
|
||||
if (lightPos)
|
||||
{
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ )
|
||||
{
|
||||
tess.xyz[i+tess.numVertexes][0] = tess.xyz[i][0]+(( tess.xyz[i][0]-lightPos[0] )*128.0f);
|
||||
tess.xyz[i+tess.numVertexes][1] = tess.xyz[i][1]+(( tess.xyz[i][1]-lightPos[1] )*128.0f);
|
||||
tess.xyz[i+tess.numVertexes][2] = tess.xyz[i][2]+(( tess.xyz[i][2]-lightPos[2] )*128.0f);
|
||||
shadowXyz[i][0] = tess.xyz[i][0]+(( tess.xyz[i][0]-lightPos[0] )*128.0f);
|
||||
shadowXyz[i][1] = tess.xyz[i][1]+(( tess.xyz[i][1]-lightPos[1] )*128.0f);
|
||||
shadowXyz[i][2] = tess.xyz[i][2]+(( tess.xyz[i][2]-lightPos[2] )*128.0f);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -307,7 +270,7 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
|
||||
// project vertexes away from light direction
|
||||
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
|
||||
VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
|
||||
VectorMA( tess.xyz[i], -512, lightDir, shadowXyz[i] );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -344,8 +307,8 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
planeEq[1] = v1[2]*(v2[0]-v3[0]) + v2[2]*(v3[0]-v1[0]) + v3[2]*(v1[0]-v2[0]);
|
||||
planeEq[2] = v1[0]*(v2[1]-v3[1]) + v2[0]*(v3[1]-v1[1]) + v3[0]*(v1[1]-v2[1]);
|
||||
planeEq[3] = -( v1[0]*( v2[1]*v3[2] - v3[1]*v2[2] ) +
|
||||
v2[0]*(v3[1]*v1[2] - v1[1]*v3[2]) +
|
||||
v3[0]*(v1[1]*v2[2] - v2[1]*v1[2]) );
|
||||
v2[0]*(v3[1]*v1[2] - v1[1]*v3[2]) +
|
||||
v3[0]*(v1[1]*v2[2] - v2[1]*v1[2]) );
|
||||
|
||||
d = planeEq[0]*lightPos[0]+
|
||||
planeEq[1]*lightPos[1]+
|
||||
|
@ -383,52 +346,30 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
//qglDisable(GL_DEPTH_TEST);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglVertexPointer (3, GL_FLOAT, 16, tess.xyz);
|
||||
#endif
|
||||
|
||||
#ifdef _STENCIL_REVERSE
|
||||
qglDepthFunc(GL_LESS);
|
||||
|
||||
//now using the Carmack Reverse<tm> -rww
|
||||
if ( backEnd.viewParms.isMirror ) {
|
||||
//qglCullFace( GL_BACK );
|
||||
GL_Cull(CT_BACK_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
|
||||
if (glConfig.doStencilShadowsInOneDrawcall)
|
||||
{
|
||||
GL_Cull(CT_TWO_SIDED);
|
||||
qglStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
|
||||
qglStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
|
||||
|
||||
R_RenderShadowEdges();
|
||||
|
||||
//qglCullFace( GL_FRONT );
|
||||
qglDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_Cull(CT_FRONT_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
} else {
|
||||
//qglCullFace( GL_FRONT );
|
||||
GL_Cull(CT_FRONT_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );
|
||||
qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||
|
||||
R_RenderShadowEdges();
|
||||
|
||||
//qglCullFace( GL_BACK );
|
||||
GL_Cull(CT_BACK_SIDED);
|
||||
qglStencilOp( GL_KEEP, GL_DECR, GL_KEEP );
|
||||
qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
}
|
||||
|
||||
qglDepthFunc(GL_LEQUAL);
|
||||
|
@ -443,11 +384,7 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
qglCullFace( GL_BACK );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
} else {
|
||||
qglCullFace( GL_BACK );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
|
||||
|
@ -457,24 +394,13 @@ void RB_DoShadowTessEnd( vec3_t lightPos )
|
|||
qglCullFace( GL_FRONT );
|
||||
qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
|
||||
#else
|
||||
R_RenderShadowEdges();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// reenable writing to the color buffer
|
||||
qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG_STENCIL_SHADOWS
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
|
@ -500,7 +426,7 @@ void RB_ShadowFinish( void ) {
|
|||
}
|
||||
|
||||
#ifdef _DEBUG_STENCIL_SHADOWS
|
||||
return;
|
||||
return;
|
||||
#endif
|
||||
|
||||
qglEnable( GL_STENCIL_TEST );
|
||||
|
@ -520,7 +446,7 @@ void RB_ShadowFinish( void ) {
|
|||
GL_Bind( tr.whiteImage );
|
||||
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity ();
|
||||
qglLoadIdentity ();
|
||||
|
||||
// qglColor3f( 0.6f, 0.6f, 0.6f );
|
||||
// GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO );
|
||||
|
@ -532,33 +458,12 @@ void RB_ShadowFinish( void ) {
|
|||
//GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
|
||||
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
GLfloat vtx[] = {
|
||||
-100, 100, -10,
|
||||
100, 100, -10,
|
||||
100, -100, -10,
|
||||
-100, -100, -10
|
||||
};
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
qglVertexPointer ( 3, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
#else
|
||||
qglBegin( GL_QUADS );
|
||||
qglVertex3f( -100, 100, -10 );
|
||||
qglVertex3f( 100, 100, -10 );
|
||||
qglVertex3f( 100, -100, -10 );
|
||||
qglVertex3f( -100, -100, -10 );
|
||||
qglEnd ();
|
||||
#endif
|
||||
|
||||
qglColor4f(1,1,1,1);
|
||||
qglDisable( GL_STENCIL_TEST );
|
||||
|
@ -677,11 +582,7 @@ void RB_CaptureScreenImage(void)
|
|||
cY = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cX, cY, radX, radY, 0);
|
||||
#else
|
||||
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, cX, cY, radX, radY, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -754,49 +655,20 @@ void RB_DistortionFill(void)
|
|||
GL_State(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
GLfloat tex[] = {
|
||||
0+spost2, 1-spost,
|
||||
0+spost2, 0+spost,
|
||||
1-spost2, 0+spost,
|
||||
1-spost2, 1-spost
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
0, 0,
|
||||
0, glConfig.vidHeight,
|
||||
glConfig.vidWidth, glConfig.vidHeight,
|
||||
glConfig.vidWidth, 0
|
||||
};
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
/* if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );*/
|
||||
#else
|
||||
qglBegin(GL_QUADS);
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
qglTexCoord2f(0+spost2, 1-spost);
|
||||
qglVertex2f(0, 0);
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
qglTexCoord2f(0+spost2, 1-spost);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
qglTexCoord2f(0+spost2, 0+spost);
|
||||
qglVertex2f(0, glConfig.vidHeight);
|
||||
qglTexCoord2f(0+spost2, 0+spost);
|
||||
qglVertex2f(0, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 0+spost);
|
||||
qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
|
||||
qglTexCoord2f(1-spost2, 0+spost);
|
||||
qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 1-spost);
|
||||
qglVertex2f(glConfig.vidWidth, 0);
|
||||
qglTexCoord2f(1-spost2, 1-spost);
|
||||
qglVertex2f(glConfig.vidWidth, 0);
|
||||
qglEnd();
|
||||
#endif
|
||||
|
||||
if (tr_distortionAlpha == 1.0f && tr_distortionStretch == 0.0f)
|
||||
{ //no overrides
|
||||
|
@ -825,52 +697,22 @@ void RB_DistortionFill(void)
|
|||
}
|
||||
spost2 *= 0.2f;
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
/* GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY );*/
|
||||
GLfloat tex[] = {
|
||||
0+spost2, 1-spost,
|
||||
0+spost2, 0+spost,
|
||||
1-spost2, 0+spost,
|
||||
1-spost2, 1-spost
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
0, 0,
|
||||
0, glConfig.vidHeight,
|
||||
glConfig.vidWidth, glConfig.vidHeight,
|
||||
glConfig.vidWidth, 0
|
||||
};
|
||||
qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
|
||||
qglVertexPointer ( 2, GL_FLOAT, 0, vtx );
|
||||
qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
|
||||
#else
|
||||
qglBegin(GL_QUADS);
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
qglTexCoord2f(0+spost2, 1-spost);
|
||||
qglVertex2f(0, 0);
|
||||
qglColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
qglTexCoord2f(0+spost2, 1-spost);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
qglTexCoord2f(0+spost2, 0+spost);
|
||||
qglVertex2f(0, glConfig.vidHeight);
|
||||
qglTexCoord2f(0+spost2, 0+spost);
|
||||
qglVertex2f(0, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 0+spost);
|
||||
qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
|
||||
qglTexCoord2f(1-spost2, 0+spost);
|
||||
qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
|
||||
|
||||
qglTexCoord2f(1-spost2, 1-spost);
|
||||
qglVertex2f(glConfig.vidWidth, 0);
|
||||
qglTexCoord2f(1-spost2, 1-spost);
|
||||
qglVertex2f(glConfig.vidWidth, 0);
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
if (glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY );
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#endif
|
||||
|
||||
//pop the view matrices back
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
|
|
|
@ -371,65 +371,25 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max
|
|||
int s, t;
|
||||
|
||||
GL_Bind( image );
|
||||
#ifdef HAVE_GLES
|
||||
GLfloat vtx[3*1024]; // arbitrary sized
|
||||
GLfloat tex[2*1024];
|
||||
int idx;
|
||||
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (glcol)
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#endif
|
||||
|
||||
|
||||
for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t < maxs[1]+HALF_SKY_SUBDIVISIONS; t++ )
|
||||
{
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
idx=0;
|
||||
#else
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
#endif
|
||||
|
||||
for ( s = mins[0]+HALF_SKY_SUBDIVISIONS; s <= maxs[0]+HALF_SKY_SUBDIVISIONS; s++ )
|
||||
{
|
||||
#ifdef HAVE_GLES
|
||||
memcpy(tex+idx*2, s_skyTexCoords[t][s], sizeof(GLfloat)*2);
|
||||
memcpy(vtx+idx*3, s_skyPoints[t][s], sizeof(GLfloat)*3);
|
||||
idx++;
|
||||
memcpy(tex+idx*2, s_skyTexCoords[t+1][s], sizeof(GLfloat)*2);
|
||||
memcpy(vtx+idx*3, s_skyPoints[t+1][s], sizeof(GLfloat)*3);
|
||||
idx++;
|
||||
#else
|
||||
qglTexCoord2fv( s_skyTexCoords[t][s] );
|
||||
qglVertex3fv( s_skyPoints[t][s] );
|
||||
|
||||
qglTexCoord2fv( s_skyTexCoords[t+1][s] );
|
||||
qglVertex3fv( s_skyPoints[t+1][s] );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
|
||||
qglVertexPointer (3, GL_FLOAT, 0, vtx);
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, tex);
|
||||
qglDrawArrays(GL_TRIANGLE_STRIP, 0, idx);
|
||||
#else
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_GLES
|
||||
if (glcol)
|
||||
qglEnableClientState(GL_COLOR_ARRAY);
|
||||
if (!text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DrawSkyBox( jk_shader_t *shader )
|
||||
static void DrawSkyBox( shader_t *shader )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -549,7 +509,7 @@ static void FillCloudySkySide( const int mins[2], const int maxs[2], qboolean ad
|
|||
}
|
||||
}
|
||||
|
||||
static void FillCloudBox( const jk_shader_t *shader, int stage )
|
||||
static void FillCloudBox( const shader_t *shader, int stage )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -845,8 +805,6 @@ void RB_StageIteratorSky( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
hasskybox = 1;
|
||||
|
||||
// go through all the polygons and project them onto
|
||||
// the sky box to see which blocks on each side need
|
||||
// to be drawn
|
||||
|
|
|
@ -1096,38 +1096,29 @@ static void RB_SurfaceBeam( void )
|
|||
|
||||
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
|
||||
qglColor3f( 1, 0, 0 );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (glcol)
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
GLfloat vtx[NUM_BEAM_SEGS*6+6];
|
||||
for ( i = 0; i <= NUM_BEAM_SEGS; i++ ) {
|
||||
memcpy(vtx+i*6, start_points[ i % NUM_BEAM_SEGS], sizeof(GLfloat)*3);
|
||||
memcpy(vtx+i*6+3, end_points[ i % NUM_BEAM_SEGS], sizeof(GLfloat)*3);
|
||||
switch(e->skinNum)
|
||||
{
|
||||
case 1://Green
|
||||
qglColor3f( 0, 1, 0 );
|
||||
break;
|
||||
case 2://Blue
|
||||
qglColor3f( 0.5, 0.5, 1 );
|
||||
break;
|
||||
case 0://red
|
||||
default:
|
||||
qglColor3f( 1, 0, 0 );
|
||||
break;
|
||||
}
|
||||
qglVertexPointer (3, GL_FLOAT, 0, vtx);
|
||||
qglDrawArrays(GL_TRIANGLE_STRIP, 0, NUM_BEAM_SEGS*2+2);
|
||||
if (glcol)
|
||||
qglEnableClientState(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
#else
|
||||
|
||||
qglBegin( GL_TRIANGLE_STRIP );
|
||||
for ( i = 0; i <= NUM_BEAM_SEGS; i++ ) {
|
||||
qglVertex3fv( start_points[ i % NUM_BEAM_SEGS] );
|
||||
qglVertex3fv( end_points[ i % NUM_BEAM_SEGS] );
|
||||
}
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------
|
||||
// DoSprite
|
||||
//------------------
|
||||
|
@ -1929,38 +1920,6 @@ static void RB_SurfaceAxis( void ) {
|
|||
GL_Bind( tr.whiteImage );
|
||||
GL_State( GLS_DEFAULT );
|
||||
qglLineWidth( 3 );
|
||||
|
||||
#ifdef HAVE_GLES
|
||||
GLfloat col[] = {
|
||||
1,0,0, 1,
|
||||
1,0,0, 1,
|
||||
0,1,0, 1,
|
||||
0,1,0, 1,
|
||||
0,0,1, 1,
|
||||
0,0,1, 1
|
||||
};
|
||||
GLfloat vtx[] = {
|
||||
0,0,0,
|
||||
16,0,0,
|
||||
0,0,0,
|
||||
0,16,0,
|
||||
0,0,0,
|
||||
0,0,16
|
||||
};
|
||||
GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
|
||||
GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
|
||||
if (text)
|
||||
qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (!glcol)
|
||||
qglEnableClientState( GL_COLOR_ARRAY);
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, col );
|
||||
qglVertexPointer (3, GL_FLOAT, 0, vtx);
|
||||
qglDrawArrays(GL_LINES, 0, 6);
|
||||
if (text)
|
||||
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
if (!glcol)
|
||||
qglDisableClientState( GL_COLOR_ARRAY);
|
||||
#else
|
||||
qglBegin( GL_LINES );
|
||||
qglColor3f( 1,0,0 );
|
||||
qglVertex3f( 0,0,0 );
|
||||
|
@ -1972,7 +1931,6 @@ static void RB_SurfaceAxis( void ) {
|
|||
qglVertex3f( 0,0,0 );
|
||||
qglVertex3f( 0,0,16 );
|
||||
qglEnd();
|
||||
#endif
|
||||
qglLineWidth( 1 );
|
||||
}
|
||||
|
||||
|
@ -2040,7 +1998,7 @@ static bool RB_TestZFlare( vec3_t point) {
|
|||
// if the point is off the screen, don't bother adding it
|
||||
// calculate screen coordinates and depth
|
||||
R_TransformModelToClip( point, backEnd.ori.modelMatrix,
|
||||
backEnd.viewParms.projectionMatrix, eye, clip );
|
||||
backEnd.viewParms.projectionMatrix, eye, clip );
|
||||
|
||||
// check to see if the point is completely off screen
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
|
@ -2052,7 +2010,7 @@ static bool RB_TestZFlare( vec3_t point) {
|
|||
R_TransformClipToWindow( clip, &backEnd.viewParms, normalized, window );
|
||||
|
||||
if ( window[0] < 0 || window[0] >= backEnd.viewParms.viewportWidth
|
||||
|| window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight ) {
|
||||
|| window[1] < 0 || window[1] >= backEnd.viewParms.viewportHeight ) {
|
||||
return qfalse; // shouldn't happen, since we check the clip[] above, except for FP rounding
|
||||
}
|
||||
|
||||
|
@ -2062,9 +2020,6 @@ static bool RB_TestZFlare( vec3_t point) {
|
|||
float screenZ;
|
||||
|
||||
// read back the z buffer contents
|
||||
#if defined(HAVE_GLES)
|
||||
depth = 0.0f;
|
||||
#else
|
||||
if ( r_flares->integer !=1 ) { //skipping the the z-test
|
||||
return true;
|
||||
}
|
||||
|
@ -2072,10 +2027,9 @@ static bool RB_TestZFlare( vec3_t point) {
|
|||
// don't bother with another sync
|
||||
glState.finishCalled = qfalse;
|
||||
qglReadPixels( backEnd.viewParms.viewportX + window[0],backEnd.viewParms.viewportY + window[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
|
||||
#endif
|
||||
|
||||
screenZ = backEnd.viewParms.projectionMatrix[14] /
|
||||
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
|
||||
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] );
|
||||
|
||||
visible = ( -eye[2] - -screenZ ) < 24;
|
||||
return visible;
|
||||
|
@ -2138,11 +2092,7 @@ void RB_SurfaceFlare( srfFlare_t *surf ) {
|
|||
void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
|
||||
// all appropriate state must be set in RB_BeginSurface
|
||||
// this isn't implemented yet...
|
||||
#ifdef HAVE_GLES
|
||||
assert(0);
|
||||
#else
|
||||
qglCallList( surf->listNum );
|
||||
#endif
|
||||
}
|
||||
|
||||
void RB_SurfaceSkip( void *surf ) {
|
||||
|
|
|
@ -113,7 +113,7 @@ added to the sorting list.
|
|||
This will also allow mirrors on both sides of a model without recursion.
|
||||
================
|
||||
*/
|
||||
static qboolean R_CullSurface( surfaceType_t *surface, jk_shader_t *shader ) {
|
||||
static qboolean R_CullSurface( surfaceType_t *surface, shader_t *shader ) {
|
||||
srfSurfaceFace_t *sface;
|
||||
float d;
|
||||
|
||||
|
|
Loading…
Reference in a new issue