Compare commits
No commits in common. "main" and "new_cmake" have entirely different histories.
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,3 +0,0 @@
|
|||||||
*.bmp filter=lfs diff=lfs merge=lfs -text
|
|
||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
|
||||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
|
||||||
319
CMakeLists.txt
319
CMakeLists.txt
@ -1,12 +1,10 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
project(space-game001 LANGUAGES CXX)
|
project(space_game001 LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(BUILD_CONFIGS Debug Release)
|
|
||||||
|
|
||||||
# ==============================
|
# ==============================
|
||||||
# Папка для всех сторонних либ
|
# Папка для всех сторонних либ
|
||||||
# ==============================
|
# ==============================
|
||||||
@ -18,7 +16,7 @@ macro(log msg)
|
|||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# 1) ZLIB (zlib131.zip → zlib-1.3.1) - без изменений
|
# 1) ZLIB (zlib131.zip → zlib-1.3.1)
|
||||||
# ===========================================
|
# ===========================================
|
||||||
set(ZLIB_ARCHIVE "${THIRDPARTY_DIR}/zlib131.zip")
|
set(ZLIB_ARCHIVE "${THIRDPARTY_DIR}/zlib131.zip")
|
||||||
set(ZLIB_SRC_DIR "${THIRDPARTY_DIR}/zlib-1.3.1")
|
set(ZLIB_SRC_DIR "${THIRDPARTY_DIR}/zlib-1.3.1")
|
||||||
@ -52,6 +50,9 @@ file(MAKE_DIRECTORY "${ZLIB_BUILD_DIR}")
|
|||||||
set(_have_zlib FALSE)
|
set(_have_zlib FALSE)
|
||||||
foreach(candidate
|
foreach(candidate
|
||||||
"${ZLIB_INSTALL_DIR}/lib/zlibstatic.lib"
|
"${ZLIB_INSTALL_DIR}/lib/zlibstatic.lib"
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlib.lib"
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlibd.lib"
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlib1.lib"
|
||||||
)
|
)
|
||||||
if(EXISTS "${candidate}")
|
if(EXISTS "${candidate}")
|
||||||
set(_have_zlib TRUE)
|
set(_have_zlib TRUE)
|
||||||
@ -59,7 +60,6 @@ foreach(candidate
|
|||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
|
||||||
if(NOT _have_zlib)
|
if(NOT _have_zlib)
|
||||||
log("Configuring zlib ...")
|
log("Configuring zlib ...")
|
||||||
execute_process(
|
execute_process(
|
||||||
@ -74,45 +74,51 @@ if(NOT _have_zlib)
|
|||||||
message(FATAL_ERROR "zlib configure failed")
|
message(FATAL_ERROR "zlib configure failed")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(cfg IN LISTS BUILD_CONFIGS)
|
log("Building zlib (Debug) ...")
|
||||||
log("Building ZLIB (${cfg}) ...")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
--build "${ZLIB_BUILD_DIR}" --config ${cfg}
|
--build "${ZLIB_BUILD_DIR}" --config Debug
|
||||||
RESULT_VARIABLE _zlib_build_res
|
RESULT_VARIABLE _zlib_build_res
|
||||||
)
|
)
|
||||||
if(NOT _zlib_build_res EQUAL 0)
|
if(NOT _zlib_build_res EQUAL 0)
|
||||||
message(FATAL_ERROR "ZLIB build failed for configuration ${cfg}")
|
message(FATAL_ERROR "zlib build failed")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
log("Installing ZLIB (${cfg}) ...")
|
log("Installing zlib (Debug) ...")
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
--install "${ZLIB_BUILD_DIR}" --config ${cfg}
|
--install "${ZLIB_BUILD_DIR}" --config Debug
|
||||||
RESULT_VARIABLE _zlib_inst_res
|
RESULT_VARIABLE _zlib_inst_res
|
||||||
)
|
)
|
||||||
if(NOT _zlib_inst_res EQUAL 0)
|
if(NOT _zlib_inst_res EQUAL 0)
|
||||||
message(FATAL_ERROR "ZLIB install failed for configuration ${cfg}")
|
message(FATAL_ERROR "zlib install failed")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ИСПРАВЛЕНИЕ: Используем свойства для конкретных конфигураций
|
set(ZLIB_LIB_FILE "")
|
||||||
|
foreach(candidate
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlibstatic.lib"
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlib.lib"
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlibd.lib"
|
||||||
|
"${ZLIB_INSTALL_DIR}/lib/zlib1.lib"
|
||||||
|
)
|
||||||
|
if(EXISTS "${candidate}")
|
||||||
|
set(ZLIB_LIB_FILE "${candidate}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(ZLIB_LIB_FILE STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Could not find zlib library in ${ZLIB_INSTALL_DIR}/lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(zlib_external_lib UNKNOWN IMPORTED GLOBAL)
|
add_library(zlib_external_lib UNKNOWN IMPORTED GLOBAL)
|
||||||
set_target_properties(zlib_external_lib PROPERTIES
|
set_target_properties(zlib_external_lib PROPERTIES
|
||||||
# Динамическая линковка (если zlib.lib - это импорт-библиотека для zlibd.dll)
|
IMPORTED_LOCATION "${ZLIB_LIB_FILE}"
|
||||||
#IMPORTED_LOCATION_DEBUG "${ZLIB_INSTALL_DIR}/lib/zlibd.lib"
|
|
||||||
#IMPORTED_LOCATION_RELEASE "${ZLIB_INSTALL_DIR}/lib/zlib.lib"
|
|
||||||
|
|
||||||
# Можно также указать статические библиотеки, если вы хотите их использовать
|
|
||||||
IMPORTED_LOCATION_DEBUG "${ZLIB_INSTALL_DIR}/lib/zlibstaticd.lib"
|
|
||||||
IMPORTED_LOCATION_RELEASE "${ZLIB_INSTALL_DIR}/lib/zlibstatic.lib"
|
|
||||||
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INSTALL_DIR}/include"
|
INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INSTALL_DIR}/include"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# 2) SDL2 (release-2.32.10.zip → SDL-release-2.32.10) - без изменений
|
# 2) SDL2 (release-2.32.10.zip → SDL-release-2.32.10)
|
||||||
# ===========================================
|
# ===========================================
|
||||||
set(SDL2_ARCHIVE "${THIRDPARTY_DIR}/release-2.32.10.zip")
|
set(SDL2_ARCHIVE "${THIRDPARTY_DIR}/release-2.32.10.zip")
|
||||||
set(SDL2_SRC_DIR "${THIRDPARTY_DIR}/SDL-release-2.32.10")
|
set(SDL2_SRC_DIR "${THIRDPARTY_DIR}/SDL-release-2.32.10")
|
||||||
@ -169,56 +175,66 @@ if(NOT _have_sdl2)
|
|||||||
message(FATAL_ERROR "SDL2 configure failed")
|
message(FATAL_ERROR "SDL2 configure failed")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --- ИЗМЕНЕНИЕ: Цикл по конфигурациям Debug и Release ---
|
log("Building SDL2 (Debug) ...")
|
||||||
foreach(cfg IN LISTS BUILD_CONFIGS)
|
|
||||||
log("Building SDL2 (${cfg}) ...")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
--build "${SDL2_BUILD_DIR}" --config ${cfg}
|
--build "${SDL2_BUILD_DIR}" --config Debug
|
||||||
RESULT_VARIABLE _sdl_build_res
|
RESULT_VARIABLE _sdl_build_res
|
||||||
)
|
)
|
||||||
if(NOT _sdl_build_res EQUAL 0)
|
if(NOT _sdl_build_res EQUAL 0)
|
||||||
message(FATAL_ERROR "SDL2 build failed for configuration ${cfg}")
|
message(FATAL_ERROR "SDL2 build failed")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
log("Installing SDL2 (${cfg}) ...")
|
log("Installing SDL2 (Debug) ...")
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
--install "${SDL2_BUILD_DIR}" --config ${cfg}
|
--install "${SDL2_BUILD_DIR}" --config Debug
|
||||||
RESULT_VARIABLE _sdl_inst_res
|
RESULT_VARIABLE _sdl_inst_res
|
||||||
)
|
)
|
||||||
if(NOT _sdl_inst_res EQUAL 0)
|
if(NOT _sdl_inst_res EQUAL 0)
|
||||||
message(FATAL_ERROR "SDL2 install failed for configuration ${cfg}")
|
message(FATAL_ERROR "SDL2 install failed")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
|
||||||
# ------------------------------------------------------
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(SDL2_LIB_FILE "")
|
||||||
|
foreach(candidate
|
||||||
|
"${SDL2_INSTALL_DIR}/lib/SDL2.lib"
|
||||||
|
"${SDL2_INSTALL_DIR}/lib/SDL2-static.lib"
|
||||||
|
"${SDL2_INSTALL_DIR}/lib/SDL2d.lib"
|
||||||
|
)
|
||||||
|
if(EXISTS "${candidate}")
|
||||||
|
set(SDL2_LIB_FILE "${candidate}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(SDL2_LIB_FILE STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Could not find SDL2 library in ${SDL2_INSTALL_DIR}/lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(SDL2MAIN_LIB_FILE "")
|
||||||
|
if(EXISTS "${SDL2_INSTALL_DIR}/lib/SDL2main.lib")
|
||||||
|
set(SDL2MAIN_LIB_FILE "${SDL2_INSTALL_DIR}/lib/SDL2main.lib")
|
||||||
|
endif()
|
||||||
|
|
||||||
# ИСПРАВЛЕНИЕ: SDL2: Используем свойства для конкретных конфигураций
|
|
||||||
add_library(SDL2_external_lib UNKNOWN IMPORTED GLOBAL)
|
add_library(SDL2_external_lib UNKNOWN IMPORTED GLOBAL)
|
||||||
set_target_properties(SDL2_external_lib PROPERTIES
|
set_target_properties(SDL2_external_lib PROPERTIES
|
||||||
# Динамическая линковка SDL2
|
IMPORTED_LOCATION "${SDL2_LIB_FILE}"
|
||||||
IMPORTED_LOCATION_DEBUG "${SDL2_INSTALL_DIR}/lib/SDL2d.lib"
|
|
||||||
IMPORTED_LOCATION_RELEASE "${SDL2_INSTALL_DIR}/lib/SDL2.lib"
|
|
||||||
# Оба include-пути: и include, и include/SDL2
|
# Оба include-пути: и include, и include/SDL2
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INSTALL_DIR}/include;${SDL2_INSTALL_DIR}/include/SDL2"
|
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INSTALL_DIR}/include;${SDL2_INSTALL_DIR}/include/SDL2"
|
||||||
)
|
)
|
||||||
|
|
||||||
# SDL2main (обычно статическая)
|
if(NOT SDL2MAIN_LIB_FILE STREQUAL "")
|
||||||
add_library(SDL2main_external_lib UNKNOWN IMPORTED GLOBAL)
|
add_library(SDL2main_external_lib UNKNOWN IMPORTED GLOBAL)
|
||||||
set_target_properties(SDL2main_external_lib PROPERTIES
|
set_target_properties(SDL2main_external_lib PROPERTIES
|
||||||
# ИСПРАВЛЕНО: Указываем пути для Debug и Release, используя
|
IMPORTED_LOCATION "${SDL2MAIN_LIB_FILE}"
|
||||||
# соглашение, что Debug имеет суффикс 'd', а Release — нет.
|
|
||||||
IMPORTED_LOCATION_DEBUG "${SDL2_INSTALL_DIR}/lib/SDL2maind.lib"
|
|
||||||
IMPORTED_LOCATION_RELEASE "${SDL2_INSTALL_DIR}/lib/SDL2main.lib"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INSTALL_DIR}/include"
|
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INSTALL_DIR}/include"
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
log("-----${SDL2_INSTALL_DIR}/lib/SDL2maind.lib")
|
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# 3) libpng (v1.6.51.zip → libpng-1.6.51) - без изменений
|
# 3) libpng (v1.6.51.zip → libpng-1.6.51)
|
||||||
|
# ВАЖНО: не вызываем "cmake --install",
|
||||||
|
# берём .lib из build/Debug
|
||||||
# ===========================================
|
# ===========================================
|
||||||
set(LIBPNG_ARCHIVE "${THIRDPARTY_DIR}/v1.6.51.zip")
|
set(LIBPNG_ARCHIVE "${THIRDPARTY_DIR}/v1.6.51.zip")
|
||||||
set(LIBPNG_SRC_DIR "${THIRDPARTY_DIR}/libpng-1.6.51")
|
set(LIBPNG_SRC_DIR "${THIRDPARTY_DIR}/libpng-1.6.51")
|
||||||
@ -249,12 +265,18 @@ endif()
|
|||||||
file(MAKE_DIRECTORY "${LIBPNG_BUILD_DIR}")
|
file(MAKE_DIRECTORY "${LIBPNG_BUILD_DIR}")
|
||||||
|
|
||||||
# Проверяем, есть ли уже .lib (build/Debug или install/lib)
|
# Проверяем, есть ли уже .lib (build/Debug или install/lib)
|
||||||
|
set(_have_png FALSE)
|
||||||
set(_libpng_candidates
|
set(_libpng_candidates
|
||||||
"${LIBPNG_BUILD_DIR}/Debug/libpng16_staticd.lib"
|
"${LIBPNG_BUILD_DIR}/Debug/libpng16_staticd.lib"
|
||||||
"${LIBPNG_BUILD_DIR}/Release/libpng16_static.lib"
|
"${LIBPNG_BUILD_DIR}/Debug/libpng16d.lib"
|
||||||
|
"${LIBPNG_BUILD_DIR}/Debug/png16d.lib"
|
||||||
|
"${LIBPNG_BUILD_DIR}/libpng16_staticd.lib"
|
||||||
|
"${LIBPNG_BUILD_DIR}/libpng16d.lib"
|
||||||
|
"${LIBPNG_INSTALL_DIR}/lib/libpng16_staticd.lib"
|
||||||
|
"${LIBPNG_INSTALL_DIR}/lib/libpng16d.lib"
|
||||||
|
"${LIBPNG_INSTALL_DIR}/lib/png16d.lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(_have_png FALSE)
|
|
||||||
foreach(candidate IN LISTS _libpng_candidates)
|
foreach(candidate IN LISTS _libpng_candidates)
|
||||||
if(EXISTS "${candidate}")
|
if(EXISTS "${candidate}")
|
||||||
set(_have_png TRUE)
|
set(_have_png TRUE)
|
||||||
@ -278,141 +300,42 @@ if(NOT _have_png)
|
|||||||
message(FATAL_ERROR "libpng configure failed")
|
message(FATAL_ERROR "libpng configure failed")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --- ИЗМЕНЕНИЕ: Цикл по конфигурациям Debug и Release ---
|
log("Building libpng (Debug) ...")
|
||||||
foreach(cfg IN LISTS BUILD_CONFIGS)
|
|
||||||
log("Building libpng (${cfg}) ...")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
--build "${LIBPNG_BUILD_DIR}" --config ${cfg}
|
--build "${LIBPNG_BUILD_DIR}" --config Debug
|
||||||
RESULT_VARIABLE _png_build_res
|
RESULT_VARIABLE _png_build_res
|
||||||
)
|
)
|
||||||
if(NOT _png_build_res EQUAL 0)
|
if(NOT _png_build_res EQUAL 0)
|
||||||
message(FATAL_ERROR "libpng build failed for configuration ${cfg}")
|
message(FATAL_ERROR "libpng build failed")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Поскольку вы не используете "cmake --install" для libpng,
|
# без --install, чтобы не упереться в INSTALL target
|
||||||
# здесь нет необходимости в дополнительном шаге установки.
|
endif()
|
||||||
# Файлы .lib будут сгенерированы в подкаталоге ${LIBPNG_BUILD_DIR}/${cfg} (например, build/Debug или build/Release).
|
|
||||||
|
|
||||||
endforeach()
|
# Ищем конкретный .lib для линковки
|
||||||
# ------------------------------------------------------
|
set(LIBPNG_LIB_FILE "")
|
||||||
|
foreach(candidate IN LISTS _libpng_candidates)
|
||||||
|
if(EXISTS "${candidate}")
|
||||||
|
set(LIBPNG_LIB_FILE "${candidate}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
if(LIBPNG_LIB_FILE STREQUAL "")
|
||||||
|
message(FATAL_ERROR "Could not find libpng library (checked build/Debug and install/lib)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(libpng_external_lib UNKNOWN IMPORTED GLOBAL)
|
add_library(libpng_external_lib UNKNOWN IMPORTED GLOBAL)
|
||||||
set_target_properties(libpng_external_lib PROPERTIES
|
set_target_properties(libpng_external_lib PROPERTIES
|
||||||
# Предполагая, что libpng использует статический вариант
|
IMPORTED_LOCATION "${LIBPNG_LIB_FILE}"
|
||||||
IMPORTED_LOCATION_DEBUG "${LIBPNG_BUILD_DIR}/Debug/libpng16_staticd.lib"
|
|
||||||
IMPORTED_LOCATION_RELEASE "${LIBPNG_BUILD_DIR}/Release/libpng16_static.lib"
|
|
||||||
|
|
||||||
# png.h, pngconf.h – в SRC, pnglibconf.h – в BUILD
|
# png.h, pngconf.h – в SRC, pnglibconf.h – в BUILD
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${LIBPNG_SRC_DIR};${LIBPNG_BUILD_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "${LIBPNG_SRC_DIR};${LIBPNG_BUILD_DIR}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# 4) libzip (v1.11.4.zip → libzip-1.11.4) - НОВАЯ ЗАВИСИМОСТЬ
|
# Основной проект space_game001
|
||||||
# ===========================================
|
# ===========================================
|
||||||
set(LIBZIP_ARCHIVE "${THIRDPARTY_DIR}/v1.11.4.zip")
|
add_executable(space_game001
|
||||||
set(LIBZIP_SRC_DIR "${THIRDPARTY_DIR}/libzip-1.11.4")
|
|
||||||
set(LIBZIP_BUILD_DIR "${LIBZIP_SRC_DIR}/build")
|
|
||||||
#set(LIBZIP_INSTALL_DIR "${LIBZIP_SRC_DIR}/install")
|
|
||||||
set(LIBZIP_BASE_DIR "${LIBZIP_SRC_DIR}/install")
|
|
||||||
|
|
||||||
if(NOT EXISTS "${LIBZIP_ARCHIVE}")
|
|
||||||
log("Downloading libzip v1.11.4.zip ...")
|
|
||||||
file(DOWNLOAD
|
|
||||||
"https://github.com/nih-at/libzip/archive/refs/tags/v1.11.4.zip"
|
|
||||||
"${LIBZIP_ARCHIVE}"
|
|
||||||
SHOW_PROGRESS
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT EXISTS "${LIBZIP_SRC_DIR}/CMakeLists.txt")
|
|
||||||
log("Extracting libzip v1.11.4.zip to libzip-1.11.4 ...")
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E tar xvf "${LIBZIP_ARCHIVE}"
|
|
||||||
WORKING_DIRECTORY "${THIRDPARTY_DIR}"
|
|
||||||
RESULT_VARIABLE _zip_extract_res
|
|
||||||
)
|
|
||||||
if(NOT _zip_extract_res EQUAL 0)
|
|
||||||
message(FATAL_ERROR "Failed to extract libzip archive")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(MAKE_DIRECTORY "${LIBZIP_BUILD_DIR}")
|
|
||||||
|
|
||||||
# Проверяем, собран ли уже libzip
|
|
||||||
set(_have_zip FALSE)
|
|
||||||
foreach(candidate
|
|
||||||
"${LIBZIP_BASE_DIR}-Debug/lib/zip.lib"
|
|
||||||
"${LIBZIP_BASE_DIR}-Release/lib/zip.lib"
|
|
||||||
)
|
|
||||||
if(EXISTS "${candidate}")
|
|
||||||
set(_have_zip TRUE)
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
|
|
||||||
if(NOT _have_zip)
|
|
||||||
foreach(cfg IN LISTS BUILD_CONFIGS)
|
|
||||||
log("Configuring libzip (${cfg})...")
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-G "${CMAKE_GENERATOR}"
|
|
||||||
-S "${LIBZIP_SRC_DIR}"
|
|
||||||
-B "${LIBZIP_SRC_DIR}/build-${cfg}"
|
|
||||||
-DCMAKE_INSTALL_PREFIX=${LIBZIP_BASE_DIR}-${cfg}
|
|
||||||
-DCMAKE_PREFIX_PATH=${ZLIB_INSTALL_DIR}
|
|
||||||
-DZLIB_ROOT=${ZLIB_INSTALL_DIR}
|
|
||||||
-DENABLE_COMMONCRYPTO=OFF
|
|
||||||
-DENABLE_GNUTLS=OFF
|
|
||||||
-DENABLE_MBEDTLS=OFF
|
|
||||||
-DENABLE_OPENSSL=OFF
|
|
||||||
-DENABLE_WINDOWS_CRYPTO=OFF
|
|
||||||
-DENABLE_FUZZ=OFF
|
|
||||||
RESULT_VARIABLE _zip_cfg_res
|
|
||||||
)
|
|
||||||
if(NOT _zip_cfg_res EQUAL 0)
|
|
||||||
message(FATAL_ERROR "libzip configure failed")
|
|
||||||
endif()
|
|
||||||
log("Building libzip (${cfg}) ...")
|
|
||||||
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${CMAKE_COMMAND} --build "${LIBZIP_SRC_DIR}/build-${cfg}" --config ${cfg} -v
|
|
||||||
RESULT_VARIABLE _zip_build_res
|
|
||||||
)
|
|
||||||
if(NOT _zip_build_res EQUAL 0)
|
|
||||||
message(FATAL_ERROR "libzip build failed for configuration ${cfg}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
log("Installing libzip (${cfg}) ...")
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${CMAKE_COMMAND} --install "${LIBZIP_SRC_DIR}/build-${cfg}" --config ${cfg} -v
|
|
||||||
RESULT_VARIABLE _zip_inst_res
|
|
||||||
)
|
|
||||||
if(NOT _zip_inst_res EQUAL 0)
|
|
||||||
message(FATAL_ERROR "libzip install failed for configuration ${cfg}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
add_library(libzip_external_lib UNKNOWN IMPORTED GLOBAL)
|
|
||||||
set_target_properties(libzip_external_lib PROPERTIES
|
|
||||||
IMPORTED_LOCATION_DEBUG "${LIBZIP_BASE_DIR}-Debug/lib/zip.lib" # ИСПРАВЛЕНО
|
|
||||||
IMPORTED_LOCATION_RELEASE "${LIBZIP_BASE_DIR}-Release/lib/zip.lib" # ИСПРАВЛЕНО
|
|
||||||
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "$<IF:$<CONFIG:Debug>,${LIBZIP_BASE_DIR}-Debug/include,${LIBZIP_BASE_DIR}-Release/include>"
|
|
||||||
# libzip требует zlib для линковки
|
|
||||||
INTERFACE_LINK_LIBRARIES zlib_external_lib
|
|
||||||
)
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# Основной проект space-game001
|
|
||||||
# ===========================================
|
|
||||||
add_executable(space-game001
|
|
||||||
main.cpp
|
main.cpp
|
||||||
Game.cpp
|
Game.cpp
|
||||||
Game.h
|
Game.h
|
||||||
@ -430,86 +353,68 @@ add_executable(space-game001
|
|||||||
AudioPlayerAsync.h
|
AudioPlayerAsync.h
|
||||||
BoneAnimatedModel.cpp
|
BoneAnimatedModel.cpp
|
||||||
BoneAnimatedModel.h
|
BoneAnimatedModel.h
|
||||||
ZLMath.cpp
|
Math.cpp
|
||||||
ZLMath.h
|
ZLMath.h
|
||||||
OpenGlExtensions.cpp
|
OpenGlExtensions.cpp
|
||||||
OpenGlExtensions.h
|
OpenGlExtensions.h
|
||||||
Utils.cpp
|
Utils.cpp
|
||||||
Utils.h
|
Utils.h
|
||||||
SparkEmitter.cpp
|
|
||||||
SparkEmitter.h
|
|
||||||
PlanetObject.cpp
|
|
||||||
PlanetObject.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Установка проекта по умолчанию для Visual Studio
|
|
||||||
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT space-game001)
|
|
||||||
|
|
||||||
# include-пути проекта
|
# include-пути проекта
|
||||||
target_include_directories(space-game001 PRIVATE
|
target_include_directories(space_game001 PRIVATE
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
#"${CMAKE_CURRENT_SOURCE_DIR}/gl"
|
"${CMAKE_CURRENT_SOURCE_DIR}/gl"
|
||||||
#"${CMAKE_CURRENT_SOURCE_DIR}/cmakeaudioplayer/include"
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmakeaudioplayer/include"
|
||||||
#"${SDL2_INSTALL_DIR}/include"
|
"${SDL2_INSTALL_DIR}/include"
|
||||||
#"${SDL2_INSTALL_DIR}/include/SDL2"
|
"${SDL2_INSTALL_DIR}/include/SDL2"
|
||||||
#"${LIBZIP_INSTALL_DIR}-Release/include" # Добавил include-путь для libzip
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(space-game001 PROPERTIES
|
set_target_properties(space_game001 PROPERTIES
|
||||||
OUTPUT_NAME "space-game001"
|
OUTPUT_NAME "space-game001"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Определения препроцессора:
|
# Определения препроцессора:
|
||||||
# PNG_ENABLED – включает код PNG в TextureManager
|
# PNG_ENABLED – включает код PNG в TextureManager
|
||||||
# SDL_MAIN_HANDLED – отключает переопределение main -> SDL_main
|
# SDL_MAIN_HANDLED – отключает переопределение main -> SDL_main
|
||||||
target_compile_definitions(space-game001 PRIVATE
|
target_compile_definitions(space_game001 PRIVATE
|
||||||
PNG_ENABLED
|
PNG_ENABLED
|
||||||
SDL_MAIN_HANDLED
|
SDL_MAIN_HANDLED
|
||||||
)
|
)
|
||||||
|
|
||||||
# Линкуем с SDL2main, если он вообще установлен
|
# Линкуем с SDL2main, если он вообще установлен
|
||||||
target_link_libraries(space-game001 PRIVATE SDL2main_external_lib)
|
if(TARGET SDL2main_external_lib)
|
||||||
|
target_link_libraries(space_game001 PRIVATE SDL2main_external_lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Линкуем сторонние библиотеки
|
# Линкуем сторонние библиотеки
|
||||||
target_link_libraries(space-game001 PRIVATE
|
target_link_libraries(space_game001 PRIVATE
|
||||||
SDL2_external_lib
|
SDL2_external_lib
|
||||||
libpng_external_lib
|
libpng_external_lib
|
||||||
zlib_external_lib
|
zlib_external_lib
|
||||||
libzip_external_lib
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Линкуем OpenGL (Windows)
|
# Линкуем OpenGL (Windows)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_link_libraries(space-game001 PRIVATE opengl32)
|
target_link_libraries(space_game001 PRIVATE opengl32)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# Копирование SDL2d.dll и zlibd.dll рядом с exe
|
# Копирование SDL2d.dll и zlibd.dll рядом с exe
|
||||||
# ===========================================
|
# ===========================================
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
add_custom_command(TARGET space_game001 POST_BUILD
|
||||||
# SDL2: в Debug - SDL2d.dll, в Release - SDL2.dll
|
COMMAND ${CMAKE_COMMAND} -E echo "Copying SDL2d.dll and zlibd.dll to output folder..."
|
||||||
set(SDL2_DLL_SRC "$<IF:$<CONFIG:Debug>,${SDL2_INSTALL_DIR}/bin/SDL2d.dll,${SDL2_INSTALL_DIR}/bin/SDL2.dll>")
|
|
||||||
set(SDL2_DLL_DST "$<IF:$<CONFIG:Debug>,$<TARGET_FILE_DIR:space-game001>/SDL2d.dll,$<TARGET_FILE_DIR:space-game001>/SDL2.dll>")
|
|
||||||
|
|
||||||
|
|
||||||
set(LIBZIP_DLL_SRC "$<IF:$<CONFIG:Debug>,${LIBZIP_BASE_DIR}-Debug/bin/zip.dll,${LIBZIP_BASE_DIR}-Release/bin/zip.dll>")
|
|
||||||
|
|
||||||
add_custom_command(TARGET space-game001 POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying DLLs to output folder..."
|
|
||||||
|
|
||||||
# Копируем SDL2 (целевое имя всегда SDL2.dll)
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
"${SDL2_DLL_SRC}"
|
"${SDL2_BUILD_DIR}/Debug/SDL2d.dll"
|
||||||
"${SDL2_DLL_DST}"
|
"$<TARGET_FILE_DIR:space_game001>/SDL2d.dll"
|
||||||
|
|
||||||
# Копируем LIBZIP (целевое имя всегда zip.dll)
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
"${LIBZIP_DLL_SRC}"
|
"${ZLIB_BUILD_DIR}/Debug/zlibd.dll"
|
||||||
"$<TARGET_FILE_DIR:space-game001>/zip.dll"
|
"$<TARGET_FILE_DIR:space_game001>/zlibd.dll"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# ===========================================
|
# ===========================================
|
||||||
# Копирование ресурсов после сборки
|
# Копирование ресурсов после сборки
|
||||||
# ===========================================
|
# ===========================================
|
||||||
@ -522,12 +427,12 @@ set(RUNTIME_RESOURCE_DIRS
|
|||||||
|
|
||||||
# Копируем ресурсы и шейдеры в папку exe и в корень build/
|
# Копируем ресурсы и шейдеры в папку exe и в корень build/
|
||||||
foreach(resdir IN LISTS RUNTIME_RESOURCE_DIRS)
|
foreach(resdir IN LISTS RUNTIME_RESOURCE_DIRS)
|
||||||
add_custom_command(TARGET space-game001 POST_BUILD
|
add_custom_command(TARGET space_game001 POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "Copying ${resdir} to runtime folders..."
|
COMMAND ${CMAKE_COMMAND} -E echo "Copying ${resdir} to runtime folders..."
|
||||||
# 1) туда, где лежит exe (build/Debug, build/Release и т.п.)
|
# 1) туда, где лежит exe (build/Debug, build/Release и т.п.)
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
"${CMAKE_SOURCE_DIR}/${resdir}"
|
"${CMAKE_SOURCE_DIR}/${resdir}"
|
||||||
"$<TARGET_FILE_DIR:space-game001>/${resdir}"
|
"$<TARGET_FILE_DIR:space_game001>/${resdir}"
|
||||||
# 2) в корень build, если захочешь запускать из этой папки
|
# 2) в корень build, если захочешь запускать из этой папки
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
"${CMAKE_SOURCE_DIR}/${resdir}"
|
"${CMAKE_SOURCE_DIR}/${resdir}"
|
||||||
|
|||||||
@ -8,13 +8,19 @@ namespace ZL {
|
|||||||
int Environment::windowHeaderHeight = 0;
|
int Environment::windowHeaderHeight = 0;
|
||||||
int Environment::width = 0;
|
int Environment::width = 0;
|
||||||
int Environment::height = 0;
|
int Environment::height = 0;
|
||||||
float Environment::zoom = 18.f;
|
float Environment::zoom = 20.f;
|
||||||
|
|
||||||
bool Environment::leftPressed = false;
|
bool Environment::leftPressed = false;
|
||||||
bool Environment::rightPressed = false;
|
bool Environment::rightPressed = false;
|
||||||
bool Environment::upPressed = false;
|
bool Environment::upPressed = false;
|
||||||
bool Environment::downPressed = false;
|
bool Environment::downPressed = false;
|
||||||
|
|
||||||
|
Vector3f Environment::cameraShift = {0, 0, 0};
|
||||||
|
Vector3f Environment::characterPos = {0, 0, 0};
|
||||||
|
|
||||||
|
float Environment::cameraPhi = 0.f;
|
||||||
|
float Environment::cameraAlpha = 0.3*M_PI / 2.0;
|
||||||
|
|
||||||
bool Environment::settings_inverseVertical = false;
|
bool Environment::settings_inverseVertical = false;
|
||||||
|
|
||||||
SDL_Window* Environment::window = nullptr;
|
SDL_Window* Environment::window = nullptr;
|
||||||
@ -23,21 +29,6 @@ bool Environment::showMouse = false;
|
|||||||
|
|
||||||
bool Environment::exitGameLoop = false;
|
bool Environment::exitGameLoop = false;
|
||||||
|
|
||||||
Matrix3f Environment::shipMatrix = Matrix3f::Identity();
|
|
||||||
Matrix3f Environment::inverseShipMatrix = Matrix3f::Identity();
|
|
||||||
|
|
||||||
|
|
||||||
bool Environment::tapDownHold = false;
|
|
||||||
Vector2f Environment::tapDownStartPos = { 0, 0 };
|
|
||||||
Vector2f Environment::tapDownCurrentPos = { 0, 0 };
|
|
||||||
|
|
||||||
Vector3f Environment::shipPosition = {0,0,45000.f};
|
|
||||||
|
|
||||||
float Environment::shipVelocity = 0.f;
|
|
||||||
|
|
||||||
|
|
||||||
const float Environment::CONST_Z_NEAR = 5.f;
|
|
||||||
const float Environment::CONST_Z_FAR = 5000.f;
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
|
|||||||
@ -19,10 +19,14 @@ public:
|
|||||||
static bool upPressed;
|
static bool upPressed;
|
||||||
static bool downPressed;
|
static bool downPressed;
|
||||||
|
|
||||||
static bool settings_inverseVertical;
|
static Vector3f cameraShift;
|
||||||
|
static Vector3f characterPos;
|
||||||
|
static float cameraPhi;
|
||||||
|
static float cameraAlpha;
|
||||||
|
|
||||||
static Matrix3f shipMatrix;
|
|
||||||
static Matrix3f inverseShipMatrix;
|
|
||||||
|
static bool settings_inverseVertical;
|
||||||
|
|
||||||
static SDL_Window* window;
|
static SDL_Window* window;
|
||||||
|
|
||||||
@ -30,18 +34,6 @@ public:
|
|||||||
static bool exitGameLoop;
|
static bool exitGameLoop;
|
||||||
|
|
||||||
|
|
||||||
static bool tapDownHold;
|
|
||||||
static Vector2f tapDownStartPos;
|
|
||||||
static Vector2f tapDownCurrentPos;
|
|
||||||
|
|
||||||
static Vector3f shipPosition;
|
|
||||||
static float shipVelocity;
|
|
||||||
|
|
||||||
static const float CONST_Z_NEAR;
|
|
||||||
static const float CONST_Z_FAR;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
|
|||||||
600
Game.cpp
600
Game.cpp
@ -1,4 +1,4 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "AnimatedModel.h"
|
#include "AnimatedModel.h"
|
||||||
#include "BoneAnimatedModel.h"
|
#include "BoneAnimatedModel.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
@ -6,131 +6,20 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
#include "TextModel.h"
|
#include "TextModel.h"
|
||||||
#include <random>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
const char* CONST_ZIP_FILE = "space-game001.zip";
|
|
||||||
#else
|
|
||||||
const char* CONST_ZIP_FILE = "";
|
const char* CONST_ZIP_FILE = "";
|
||||||
#endif
|
|
||||||
|
|
||||||
Vector4f generateRandomQuaternion(std::mt19937& gen)
|
Game::Game()
|
||||||
{
|
|
||||||
// Ðàñïðåäåëåíèå äëÿ ãåíåðàöèè ñëó÷àéíûõ êîîðäèíàò êâàòåðíèîíà
|
|
||||||
std::normal_distribution<> distrib(0.0, 1.0);
|
|
||||||
|
|
||||||
// Ãåíåðèðóåì ÷åòûðå ñëó÷àéíûõ ÷èñëà èç íîðìàëüíîãî ðàñïðåäåëåíèÿ N(0, 1).
|
|
||||||
// Íîðìàëèçàöèÿ ýòîãî âåêòîðà äàåò ðàâíîìåðíîå ðàñïðåäåëåíèå ïî 4D-ñôåðå (ò.å. êâàòåðíèîí åäèíè÷íîé äëèíû).
|
|
||||||
Vector4f randomQuat = {
|
|
||||||
(float)distrib(gen),
|
|
||||||
(float)distrib(gen),
|
|
||||||
(float)distrib(gen),
|
|
||||||
(float)distrib(gen)
|
|
||||||
};
|
|
||||||
|
|
||||||
return randomQuat.normalized();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- Îñíîâíàÿ ôóíêöèÿ ãåíåðàöèè ---
|
|
||||||
std::vector<BoxCoords> generateRandomBoxCoords(int N)
|
|
||||||
{
|
|
||||||
// Êîíñòàíòû
|
|
||||||
const float MIN_DISTANCE = 3.0f;
|
|
||||||
const float MIN_DISTANCE_SQUARED = MIN_DISTANCE * MIN_DISTANCE; // Ðàáîòàåì ñ êâàäðàòîì ðàññòîÿíèÿ
|
|
||||||
const float MIN_COORD = -100.0f;
|
|
||||||
const float MAX_COORD = 100.0f;
|
|
||||||
const int MAX_ATTEMPTS = 1000; // Îãðàíè÷åíèå íà êîëè÷åñòâî ïîïûòîê, ÷òîáû èçáåæàòü áåñêîíå÷íîãî öèêëà
|
|
||||||
|
|
||||||
std::vector<BoxCoords> boxCoordsArr;
|
|
||||||
boxCoordsArr.reserve(N); // Ðåçåðâèðóåì ïàìÿòü
|
|
||||||
|
|
||||||
// 1. Èíèöèàëèçàöèÿ ãåíåðàòîðà ïñåâäîñëó÷àéíûõ ÷èñåë
|
|
||||||
// Èñïîëüçóåì Mersenne Twister (mt19937) êàê âûñîêîêà÷åñòâåííûé ãåíåðàòîð
|
|
||||||
std::random_device rd;
|
|
||||||
std::mt19937 gen(rd());
|
|
||||||
|
|
||||||
// 2. Îïðåäåëåíèå ðàâíîìåðíîãî ðàñïðåäåëåíèÿ äëÿ êîîðäèíàò [MIN_COORD, MAX_COORD]
|
|
||||||
std::uniform_real_distribution<> distrib(MIN_COORD, MAX_COORD);
|
|
||||||
|
|
||||||
int generatedCount = 0;
|
|
||||||
|
|
||||||
while (generatedCount < N)
|
|
||||||
{
|
|
||||||
bool accepted = false;
|
|
||||||
int attempts = 0;
|
|
||||||
|
|
||||||
// Ïîïûòêà íàéòè ïîäõîäÿùèå êîîðäèíàòû
|
|
||||||
while (!accepted && attempts < MAX_ATTEMPTS)
|
|
||||||
{
|
|
||||||
// Ãåíåðèðóåì íîâûå ñëó÷àéíûå êîîðäèíàòû
|
|
||||||
Vector3f newPos(
|
|
||||||
(float)distrib(gen),
|
|
||||||
(float)distrib(gen),
|
|
||||||
(float)distrib(gen)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Ïðîâåðêà ðàññòîÿíèÿ äî âñåõ óæå ñóùåñòâóþùèõ îáúåêòîâ
|
|
||||||
accepted = true; // Ïðåäïîëàãàåì, ÷òî ïîäõîäèò, ïîêà íå äîêàçàíî îáðàòíîå
|
|
||||||
for (const auto& existingBox : boxCoordsArr)
|
|
||||||
{
|
|
||||||
// Ðàñ÷åò âåêòîðà ðàçíîñòè
|
|
||||||
Vector3f diff = newPos - existingBox.pos;
|
|
||||||
|
|
||||||
// Ðàñ÷åò êâàäðàòà ðàññòîÿíèÿ
|
|
||||||
float distanceSquared = diff.squaredNorm();
|
|
||||||
|
|
||||||
// Åñëè êâàäðàò ðàññòîÿíèÿ ìåíüøå êâàäðàòà ìèíèìàëüíîãî ðàññòîÿíèÿ
|
|
||||||
if (distanceSquared < MIN_DISTANCE_SQUARED)
|
|
||||||
{
|
|
||||||
accepted = false; // Îòêëîíÿåì, ñëèøêîì áëèçêî
|
|
||||||
break; // Íåò ñìûñëà ïðîâåðÿòü äàëüøå, åñëè îäíî íàðóøåíèå íàéäåíî
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accepted)
|
|
||||||
{
|
|
||||||
// 2. Ãåíåðèðóåì ñëó÷àéíûé êâàòåðíèîí
|
|
||||||
Vector4f randomQuat = generateRandomQuaternion(gen);
|
|
||||||
|
|
||||||
// 3. Ïðåîáðàçóåì åãî â ìàòðèöó âðàùåíèÿ
|
|
||||||
Matrix3f randomMatrix = QuatToMatrix(randomQuat);
|
|
||||||
|
|
||||||
// 4. Äîáàâëÿåì îáúåêò ñ íîâîé ñëó÷àéíîé ìàòðèöåé
|
|
||||||
boxCoordsArr.emplace_back(BoxCoords{ newPos, randomMatrix });
|
|
||||||
generatedCount++;
|
|
||||||
}
|
|
||||||
attempts++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Åñëè ïðåâûøåíî ìàêñèìàëüíîå êîëè÷åñòâî ïîïûòîê, âûõîäèì èç öèêëà,
|
|
||||||
// ÷òîáû èçáåæàòü çàâèñàíèÿ, åñëè N ñëèøêîì âåëèêî èëè äèàïàçîí ñëèøêîì ìàë.
|
|
||||||
if (!accepted) {
|
|
||||||
std::cerr << "Ïðåäóïðåæäåíèå: Íå óäàëîñü ñãåíåðèðîâàòü " << N << " îáúåêòîâ. Ñãåíåðèðîâàíî: " << generatedCount << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return boxCoordsArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Game::Game()
|
|
||||||
: window(nullptr)
|
: window(nullptr)
|
||||||
, glContext(nullptr)
|
, glContext(nullptr)
|
||||||
, newTickCount(0)
|
, newTickCount(0)
|
||||||
, lastTickCount(0)
|
, lastTickCount(0)
|
||||||
{
|
{
|
||||||
std::vector<Vector3f> emissionPoints = {
|
}
|
||||||
Vector3f{-2.1f, 0.9f, 5.0f},
|
|
||||||
Vector3f{2.1f, 0.9f, 5.0f}
|
|
||||||
};
|
|
||||||
sparkEmitter = SparkEmitter(emissionPoints, 100.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Game::~Game() {
|
Game::~Game() {
|
||||||
if (glContext) {
|
if (glContext) {
|
||||||
SDL_GL_DeleteContext(glContext);
|
SDL_GL_DeleteContext(glContext);
|
||||||
}
|
}
|
||||||
@ -138,9 +27,9 @@ namespace ZL
|
|||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
}
|
}
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::setup() {
|
void Game::setup() {
|
||||||
glContext = SDL_GL_CreateContext(ZL::Environment::window);
|
glContext = SDL_GL_CreateContext(ZL::Environment::window);
|
||||||
|
|
||||||
ZL::BindOpenGlFunctions();
|
ZL::BindOpenGlFunctions();
|
||||||
@ -151,351 +40,65 @@ namespace ZL
|
|||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_web.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env.vertex", "./shaders/env_web.fragment", CONST_ZIP_FILE);
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("default", "./shaders/default.vertex", "./shaders/default_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor_fog.vertex", "./shaders/defaultColor_fog_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColor", "./shaders/defaultColor.vertex", "./shaders/defaultColor_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("env", "./shaders/env_sky.vertex", "./shaders/env_sky_desktop.fragment", CONST_ZIP_FILE);
|
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cubemapTexture = std::make_shared<Texture>(
|
|
||||||
std::array<TextureDataStruct, 6>{
|
|
||||||
CreateTextureDataFromBmp24("./resources/sky/space_rt.bmp", CONST_ZIP_FILE),
|
|
||||||
CreateTextureDataFromBmp24("./resources/sky/space_lf.bmp", CONST_ZIP_FILE),
|
|
||||||
CreateTextureDataFromBmp24("./resources/sky/space_up.bmp", CONST_ZIP_FILE),
|
|
||||||
CreateTextureDataFromBmp24("./resources/sky/space_dn.bmp", CONST_ZIP_FILE),
|
|
||||||
CreateTextureDataFromBmp24("./resources/sky/space_bk.bmp", CONST_ZIP_FILE),
|
|
||||||
CreateTextureDataFromBmp24("./resources/sky/space_ft.bmp", CONST_ZIP_FILE)
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
cubemap.data = ZL::CreateCubemap(500);
|
|
||||||
cubemap.RefreshVBO();
|
|
||||||
|
|
||||||
//Load texture
|
//Load texture
|
||||||
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/DefaultMaterial_BaseColor.png", CONST_ZIP_FILE));
|
spaceshipTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sship001x.png"));
|
||||||
spaceshipBase = LoadFromTextFile02("./resources/spaceship005.txt", CONST_ZIP_FILE);
|
spaceshipBase = LoadFromTextFile02("./resources/spaceship004.txt");
|
||||||
spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0)));
|
spaceshipBase.RotateByMatrix(QuatToMatrix(QuatFromRotateAroundY(M_PI / 2.0)));
|
||||||
//spaceshipBase.Move(Vector3f{ -0.52998, -13, 0 });
|
|
||||||
spaceshipBase.Move(Vector3f{ -0.52998, -10, 10 });
|
|
||||||
|
|
||||||
spaceship.AssignFrom(spaceshipBase);
|
spaceship.AssignFrom(spaceshipBase);
|
||||||
spaceship.RefreshVBO();
|
spaceship.RefreshVBO();
|
||||||
|
|
||||||
//Boxes
|
|
||||||
boxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/box/box.png", CONST_ZIP_FILE));
|
|
||||||
boxBase = LoadFromTextFile02("./resources/box/box.txt", CONST_ZIP_FILE);
|
|
||||||
|
|
||||||
boxCoordsArr = generateRandomBoxCoords(50);
|
|
||||||
|
|
||||||
boxRenderArr.resize(boxCoordsArr.size());
|
|
||||||
|
|
||||||
for (int i = 0; i < boxCoordsArr.size(); i++)
|
|
||||||
{
|
|
||||||
boxRenderArr[i].AssignFrom(boxBase);
|
|
||||||
boxRenderArr[i].RefreshVBO();
|
|
||||||
}
|
|
||||||
|
|
||||||
sparkTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/spark.png", CONST_ZIP_FILE));
|
|
||||||
|
|
||||||
sparkEmitter.setTexture(sparkTexture);
|
|
||||||
|
|
||||||
|
|
||||||
buttonTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/button.png", CONST_ZIP_FILE));
|
|
||||||
|
|
||||||
button.data.PositionData.push_back({ 100, 100, 0 });
|
|
||||||
button.data.PositionData.push_back({ 100, 150, 0 });
|
|
||||||
button.data.PositionData.push_back({ 300, 150, 0 });
|
|
||||||
button.data.PositionData.push_back({ 100, 100, 0 });
|
|
||||||
button.data.PositionData.push_back({ 300, 150, 0 });
|
|
||||||
button.data.PositionData.push_back({ 300, 100, 0 });
|
|
||||||
|
|
||||||
button.data.TexCoordData.push_back({ 0,0 });
|
|
||||||
button.data.TexCoordData.push_back({ 0,1 });
|
|
||||||
button.data.TexCoordData.push_back({ 1,1 });
|
|
||||||
button.data.TexCoordData.push_back({ 0,0 });
|
|
||||||
button.data.TexCoordData.push_back({ 1,1 });
|
|
||||||
button.data.TexCoordData.push_back({ 1,0 });
|
|
||||||
|
|
||||||
button.RefreshVBO();
|
|
||||||
|
|
||||||
musicVolumeBarTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/musicVolumeBarTexture.png", CONST_ZIP_FILE));
|
|
||||||
|
|
||||||
musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 });
|
|
||||||
musicVolumeBar.data.PositionData.push_back({ 1190, 600, 0 });
|
|
||||||
musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 });
|
|
||||||
musicVolumeBar.data.PositionData.push_back({ 1190, 100, 0 });
|
|
||||||
musicVolumeBar.data.PositionData.push_back({ 1200, 600, 0 });
|
|
||||||
musicVolumeBar.data.PositionData.push_back({ 1200, 100, 0 });
|
|
||||||
|
|
||||||
musicVolumeBar.data.TexCoordData.push_back({ 0,0 });
|
|
||||||
musicVolumeBar.data.TexCoordData.push_back({ 0,1 });
|
|
||||||
musicVolumeBar.data.TexCoordData.push_back({ 1,1 });
|
|
||||||
musicVolumeBar.data.TexCoordData.push_back({ 0,0 });
|
|
||||||
musicVolumeBar.data.TexCoordData.push_back({ 1,1 });
|
|
||||||
musicVolumeBar.data.TexCoordData.push_back({ 1,0 });
|
|
||||||
|
|
||||||
musicVolumeBar.RefreshVBO();
|
|
||||||
|
|
||||||
|
|
||||||
musicVolumeBarButtonTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/musicVolumeBarButton.png", CONST_ZIP_FILE));
|
|
||||||
|
|
||||||
float musicVolumeBarButtonButtonCenterY = 350.0f;
|
|
||||||
|
|
||||||
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 });
|
|
||||||
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 });
|
|
||||||
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 });
|
|
||||||
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 });
|
|
||||||
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 });
|
|
||||||
musicVolumeBarButton.data.PositionData.push_back({ musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 });
|
|
||||||
|
|
||||||
musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 });
|
|
||||||
musicVolumeBarButton.data.TexCoordData.push_back({ 0,1 });
|
|
||||||
musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 });
|
|
||||||
musicVolumeBarButton.data.TexCoordData.push_back({ 0,0 });
|
|
||||||
musicVolumeBarButton.data.TexCoordData.push_back({ 1,1 });
|
|
||||||
musicVolumeBarButton.data.TexCoordData.push_back({ 1,0 });
|
|
||||||
|
|
||||||
musicVolumeBarButton.RefreshVBO();
|
|
||||||
renderer.InitOpenGL();
|
renderer.InitOpenGL();
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
planetObject.init();
|
}
|
||||||
|
|
||||||
}
|
void Game::drawScene() {
|
||||||
|
|
||||||
void Game::drawCubemap(float skyPercent)
|
|
||||||
{
|
|
||||||
static const std::string defaultShaderName = "default";
|
static const std::string defaultShaderName = "default";
|
||||||
static const std::string envShaderName = "env";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
static const std::string skyPercentUniformName = "skyPercent";
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(envShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.RenderUniform1f(skyPercentUniformName, skyPercent);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
|
||||||
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(cubemap);
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawShip()
|
|
||||||
{
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string envShaderName = "env";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
static const std::string vPositionName = "vPosition";
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
static const std::string textureUniformName = "Texture";
|
static const std::string textureUniformName = "Texture";
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
|
||||||
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
|
||||||
renderer.PushMatrix();
|
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
|
||||||
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(spaceship);
|
|
||||||
sparkEmitter.draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawBoxes()
|
|
||||||
{
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string envShaderName = "env";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
|
||||||
Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
|
||||||
|
|
||||||
for (int i = 0; i < boxCoordsArr.size(); i++)
|
|
||||||
{
|
|
||||||
renderer.PushMatrix();
|
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
|
||||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
|
||||||
renderer.TranslateMatrix(-Environment::shipPosition);
|
|
||||||
renderer.TranslateMatrix(boxCoordsArr[i].pos);
|
|
||||||
renderer.RotateMatrix(boxCoordsArr[i].m);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, boxTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(boxRenderArr[i]);
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
}
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
}
|
|
||||||
void Game::UpdateVolumeKnob() {
|
|
||||||
float musicVolumeBarButtonButtonCenterY = volumeBarMinY + musicVolume * (volumeBarMaxY - volumeBarMinY);
|
|
||||||
|
|
||||||
auto& pos = musicVolumeBarButton.data.PositionData;
|
|
||||||
|
|
||||||
pos[0] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 };
|
|
||||||
pos[1] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 };
|
|
||||||
pos[2] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 };
|
|
||||||
pos[3] = { musicVolumeBarButtonButtonCenterX - musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 };
|
|
||||||
pos[4] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY + musicVolumeBarButtonButtonRadius, 0 };
|
|
||||||
pos[5] = { musicVolumeBarButtonButtonCenterX + musicVolumeBarButtonButtonRadius, musicVolumeBarButtonButtonCenterY - musicVolumeBarButtonButtonRadius, 0 };
|
|
||||||
|
|
||||||
musicVolumeBarButton.RefreshVBO();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::UpdateVolumeFromMouse(int mouseX, int mouseY) {
|
|
||||||
|
|
||||||
int uiX = mouseX;
|
|
||||||
int uiY = Environment::height - mouseY;
|
|
||||||
Environment::shipVelocity = (musicVolume) * (20.0);
|
|
||||||
if (uiY < volumeBarMinY || uiY > volumeBarMaxY)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float t = (uiY - volumeBarMinY) / (volumeBarMaxY - volumeBarMinY);
|
|
||||||
if (t < 0.0f) t = 0.0f;
|
|
||||||
if (t > 1.0f) t = 1.0f;
|
|
||||||
musicVolume = t;
|
|
||||||
UpdateVolumeKnob();
|
|
||||||
}
|
|
||||||
void Game::drawUI()
|
|
||||||
{
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string envShaderName = "env";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.PushProjectionMatrix(Environment::width, Environment::height, -1, 1);
|
|
||||||
renderer.PushMatrix();
|
|
||||||
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, buttonTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(button);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, musicVolumeBarTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(musicVolumeBar);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, musicVolumeBarButtonTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(musicVolumeBarButton);
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::drawScene() {
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string envShaderName = "env";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glViewport(0, 0, Environment::width, Environment::height);
|
glViewport(0, 0, Environment::width, Environment::height);
|
||||||
|
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
|
|
||||||
float skyPercent = 0.0;
|
renderer.shaderManager.PushShader(defaultShaderName);
|
||||||
float distance = planetObject.distanceToPlanetSurface();
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
if (distance > 2000.f)
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
{
|
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||||
skyPercent = 0.0f;
|
|
||||||
}
|
|
||||||
else if (distance < 1000.f)
|
|
||||||
{
|
|
||||||
skyPercent = 1.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
skyPercent = (2000.f - distance) / 1000.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
drawCubemap(skyPercent);
|
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
||||||
planetObject.draw(renderer);
|
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
||||||
if (planetObject.planetIsFar())
|
1, 1000);
|
||||||
{
|
renderer.PushMatrix();
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
drawShip();
|
|
||||||
//drawBoxes();
|
|
||||||
|
|
||||||
drawUI();
|
renderer.LoadIdentity();
|
||||||
|
renderer.TranslateMatrix({ 0,0, -1.0f*Environment::zoom });
|
||||||
|
renderer.RotateMatrix(QuatFromRotateAroundX(M_PI/6.0));
|
||||||
|
//renderer.RotateMatrix(QuatFromRotateAroundX(Environment::cameraAlpha));
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, spaceshipTexture->getTexID());
|
||||||
|
renderer.DrawVertexRenderStruct(spaceship);
|
||||||
|
|
||||||
|
renderer.PopMatrix();
|
||||||
|
renderer.PopProjectionMatrix();
|
||||||
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
|
|
||||||
|
renderer.shaderManager.PopShader();
|
||||||
|
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::processTickCount() {
|
void Game::processTickCount() {
|
||||||
|
|
||||||
if (lastTickCount == 0) {
|
if (lastTickCount == 0) {
|
||||||
lastTickCount = SDL_GetTicks64();
|
lastTickCount = SDL_GetTicks64();
|
||||||
@ -508,54 +111,14 @@ namespace ZL
|
|||||||
CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount;
|
CONST_MAX_TIME_INTERVAL : newTickCount - lastTickCount;
|
||||||
|
|
||||||
//gameObjects.updateScene(delta);
|
//gameObjects.updateScene(delta);
|
||||||
sparkEmitter.update(static_cast<float>(delta));
|
|
||||||
|
|
||||||
if (Environment::tapDownHold) {
|
Environment::cameraAlpha = Environment::cameraAlpha + delta * M_PI / 10000.f;
|
||||||
|
|
||||||
float diffx = Environment::tapDownCurrentPos.v[0] - Environment::tapDownStartPos.v[0];
|
|
||||||
float diffy = Environment::tapDownCurrentPos.v[1] - Environment::tapDownStartPos.v[1];
|
|
||||||
|
|
||||||
|
|
||||||
if (abs(diffy) > 5.0 || abs(diffx) > 5.0) //threshold
|
|
||||||
{
|
|
||||||
|
|
||||||
float rotationPower = sqrtf(diffx * diffx + diffy * diffy);
|
|
||||||
|
|
||||||
//std::cout << rotationPower << std::endl;
|
|
||||||
|
|
||||||
float deltaAlpha = rotationPower * delta * M_PI / 500000.f;
|
|
||||||
|
|
||||||
Vector3f rotationDirection = { diffy, diffx, 0 };
|
|
||||||
|
|
||||||
rotationDirection = rotationDirection.normalized();
|
|
||||||
|
|
||||||
Vector4f rotateQuat = {
|
|
||||||
rotationDirection.v[0] * sin(deltaAlpha * 0.5f),
|
|
||||||
rotationDirection.v[1] * sin(deltaAlpha * 0.5f),
|
|
||||||
rotationDirection.v[2] * sin(deltaAlpha * 0.5f),
|
|
||||||
cos(deltaAlpha * 0.5f) };
|
|
||||||
|
|
||||||
Matrix3f rotateMat = QuatToMatrix(rotateQuat);
|
|
||||||
|
|
||||||
Environment::shipMatrix = MultMatrixMatrix(Environment::shipMatrix, rotateMat);
|
|
||||||
Environment::inverseShipMatrix = InverseMatrix(Environment::shipMatrix);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fabs(Environment::shipVelocity) > 0.01f)
|
|
||||||
{
|
|
||||||
Vector3f velocityDirection = { 0,0, -Environment::shipVelocity * delta / 1000.f };
|
|
||||||
Vector3f velocityDirectionAdjusted = MultMatrixVector(Environment::shipMatrix, velocityDirection);
|
|
||||||
|
|
||||||
Environment::shipPosition = Environment::shipPosition + velocityDirectionAdjusted;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTickCount = newTickCount;
|
lastTickCount = newTickCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::render() {
|
void Game::render() {
|
||||||
SDL_GL_MakeCurrent(ZL::Environment::window, glContext);
|
SDL_GL_MakeCurrent(ZL::Environment::window, glContext);
|
||||||
ZL::CheckGlError();
|
ZL::CheckGlError();
|
||||||
|
|
||||||
@ -566,59 +129,15 @@ namespace ZL
|
|||||||
processTickCount();
|
processTickCount();
|
||||||
|
|
||||||
SDL_GL_SwapWindow(ZL::Environment::window);
|
SDL_GL_SwapWindow(ZL::Environment::window);
|
||||||
}
|
}
|
||||||
void Game::update() {
|
|
||||||
|
void Game::update() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
if (event.type == SDL_QUIT) {
|
if (event.type == SDL_QUIT) {
|
||||||
Environment::exitGameLoop = true;
|
Environment::exitGameLoop = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (event.type == SDL_MOUSEBUTTONDOWN) {
|
|
||||||
// 1. Îáðàáîòêà íàæàòèÿ êíîïêè ìûøè
|
|
||||||
|
|
||||||
int mx = event.button.x;
|
|
||||||
int my = event.button.y;
|
|
||||||
|
|
||||||
std::cout << mx << " " << my << '\n';
|
|
||||||
int uiX = mx;
|
|
||||||
int uiY = Environment::height - my;
|
|
||||||
if (uiX >= volumeBarMinX - 40 && uiX <= volumeBarMaxX + 40 &&
|
|
||||||
uiY >= volumeBarMinY - 40 && uiY <= volumeBarMaxY + 40) {
|
|
||||||
isDraggingVolume = true;
|
|
||||||
UpdateVolumeFromMouse(mx, my);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Environment::tapDownHold = true;
|
|
||||||
// Êîîðäèíàòû íà÷àëüíîãî íàæàòèÿ
|
|
||||||
Environment::tapDownStartPos.v[0] = event.button.x;
|
|
||||||
Environment::tapDownStartPos.v[1] = event.button.y;
|
|
||||||
// Íà÷àëüíàÿ ïîçèöèÿ òàêæå ñòàíîâèòñÿ òåêóùåé
|
|
||||||
Environment::tapDownCurrentPos.v[0] = event.button.x;
|
|
||||||
Environment::tapDownCurrentPos.v[1] = event.button.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (event.type == SDL_MOUSEBUTTONUP) {
|
|
||||||
// 2. Îáðàáîòêà îòïóñêàíèÿ êíîïêè ìûøè
|
|
||||||
isDraggingVolume = false;
|
|
||||||
Environment::tapDownHold = false;
|
|
||||||
}
|
|
||||||
else if (event.type == SDL_MOUSEMOTION) {
|
|
||||||
// 3. Îáðàáîòêà ïåðåìåùåíèÿ ìûøè
|
|
||||||
int mx = event.motion.x;
|
|
||||||
int my = event.motion.y;
|
|
||||||
|
|
||||||
if (isDraggingVolume) {
|
|
||||||
// Äâèãàåì ìûøü ïî ñëàéäåðó — ìåíÿåì ãðîìêîñòü è ïîçèöèþ êðóæêà
|
|
||||||
UpdateVolumeFromMouse(mx, my);
|
|
||||||
}
|
|
||||||
if (Environment::tapDownHold) {
|
|
||||||
// Îáíîâëåíèå òåêóùåé ïîçèöèè, åñëè êíîïêà óäåðæèâàåòñÿ
|
|
||||||
Environment::tapDownCurrentPos.v[0] = event.motion.x;
|
|
||||||
Environment::tapDownCurrentPos.v[1] = event.motion.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event.type == SDL_MOUSEWHEEL) {
|
else if (event.type == SDL_MOUSEWHEEL) {
|
||||||
static const float zoomstep = 2.0f;
|
static const float zoomstep = 2.0f;
|
||||||
if (event.wheel.y > 0) {
|
if (event.wheel.y > 0) {
|
||||||
@ -630,28 +149,17 @@ namespace ZL
|
|||||||
if (Environment::zoom < zoomstep) {
|
if (Environment::zoom < zoomstep) {
|
||||||
Environment::zoom = zoomstep;
|
Environment::zoom = zoomstep;
|
||||||
}
|
}
|
||||||
}
|
/*if (Environment::zoom > 4) {
|
||||||
else if (event.type == SDL_KEYUP)
|
Environment::zoom = 4;
|
||||||
{
|
}*/
|
||||||
if (event.key.keysym.sym == SDLK_i)
|
|
||||||
{
|
//this->modelMeshRender.data.Scale(0.5);
|
||||||
Environment::shipVelocity += 500.f;
|
//this->modelMeshRender.RefreshVBO();
|
||||||
}
|
|
||||||
if (event.key.keysym.sym == SDLK_k)
|
|
||||||
{
|
|
||||||
Environment::shipVelocity -= 500.f;
|
|
||||||
}
|
|
||||||
if (event.key.keysym.sym == SDLK_o)
|
|
||||||
{
|
|
||||||
Environment::shipVelocity += 50.f;
|
|
||||||
}
|
|
||||||
if (event.key.keysym.sym == SDLK_l)
|
|
||||||
{
|
|
||||||
Environment::shipVelocity -= 50.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
62
Game.h
62
Game.h
@ -1,24 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "OpenGlExtensions.h"
|
#include "OpenGlExtensions.h"
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "Environment.h"
|
#include "Environment.h"
|
||||||
#include "TextureManager.h"
|
#include "TextureManager.h"
|
||||||
#include "SparkEmitter.h"
|
|
||||||
#include "PlanetObject.h"
|
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
|
|
||||||
|
class Game {
|
||||||
struct BoxCoords
|
public:
|
||||||
{
|
|
||||||
Vector3f pos;
|
|
||||||
Matrix3f m;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Game {
|
|
||||||
public:
|
|
||||||
Game();
|
Game();
|
||||||
~Game();
|
~Game();
|
||||||
|
|
||||||
@ -26,16 +16,11 @@ namespace ZL {
|
|||||||
void update();
|
void update();
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
|
|
||||||
bool shouldExit() const { return Environment::exitGameLoop; }
|
bool shouldExit() const { return Environment::exitGameLoop; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void processTickCount();
|
void processTickCount();
|
||||||
void drawScene();
|
void drawScene();
|
||||||
void drawCubemap(float skyPercent);
|
|
||||||
void drawShip();
|
|
||||||
void drawBoxes();
|
|
||||||
void drawUI();
|
|
||||||
|
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_GLContext glContext;
|
SDL_GLContext glContext;
|
||||||
@ -44,49 +29,12 @@ namespace ZL {
|
|||||||
size_t newTickCount;
|
size_t newTickCount;
|
||||||
size_t lastTickCount;
|
size_t lastTickCount;
|
||||||
|
|
||||||
|
|
||||||
std::vector<BoxCoords> boxCoordsArr;
|
|
||||||
std::vector<VertexRenderStruct> boxRenderArr;
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> buttonTexture;
|
|
||||||
VertexRenderStruct button;
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> musicVolumeBarTexture;
|
|
||||||
VertexRenderStruct musicVolumeBar;
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> musicVolumeBarButtonTexture;
|
|
||||||
VertexRenderStruct musicVolumeBarButton;
|
|
||||||
|
|
||||||
|
|
||||||
bool isDraggingVolume = false;
|
|
||||||
float musicVolume = 0.0f;
|
|
||||||
float volumeBarMinX = 1190.0f;
|
|
||||||
float volumeBarMaxX = 1200.0f;
|
|
||||||
float volumeBarMinY = 100.0f;
|
|
||||||
float volumeBarMaxY = 600.0f;
|
|
||||||
float musicVolumeBarButtonButtonCenterX = 1195.0f;
|
|
||||||
float musicVolumeBarButtonButtonRadius = 25.0f;
|
|
||||||
void UpdateVolumeFromMouse(int mouseX, int mouseY);
|
|
||||||
void UpdateVolumeKnob();
|
|
||||||
|
|
||||||
static const size_t CONST_TIMER_INTERVAL = 10;
|
static const size_t CONST_TIMER_INTERVAL = 10;
|
||||||
static const size_t CONST_MAX_TIME_INTERVAL = 1000;
|
static const size_t CONST_MAX_TIME_INTERVAL = 1000;
|
||||||
|
|
||||||
std::shared_ptr<Texture> sparkTexture;
|
|
||||||
std::shared_ptr<Texture> spaceshipTexture;
|
std::shared_ptr<Texture> spaceshipTexture;
|
||||||
std::shared_ptr<Texture> cubemapTexture;
|
|
||||||
VertexDataStruct spaceshipBase;
|
VertexDataStruct spaceshipBase;
|
||||||
VertexRenderStruct spaceship;
|
VertexRenderStruct spaceship;
|
||||||
|
};
|
||||||
VertexRenderStruct cubemap;
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> boxTexture;
|
|
||||||
VertexDataStruct boxBase;
|
|
||||||
|
|
||||||
SparkEmitter sparkEmitter;
|
|
||||||
PlanetObject planetObject;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ZL
|
} // namespace ZL
|
||||||
23
ZLMath.cpp → Math.cpp
Normal file → Executable file
23
ZLMath.cpp → Math.cpp
Normal file → Executable file
@ -45,16 +45,6 @@ namespace ZL {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f operator-(const Vector3f& x)
|
|
||||||
{
|
|
||||||
Vector3f result;
|
|
||||||
|
|
||||||
result.v[0] = -x.v[0];
|
|
||||||
result.v[1] = -x.v[1];
|
|
||||||
result.v[2] = -x.v[2];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector4f operator+(const Vector4f& x, const Vector4f& y)
|
Vector4f operator+(const Vector4f& x, const Vector4f& y)
|
||||||
{
|
{
|
||||||
Vector4f result;
|
Vector4f result;
|
||||||
@ -77,8 +67,6 @@ namespace ZL {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Matrix3f Matrix3f::Identity()
|
Matrix3f Matrix3f::Identity()
|
||||||
{
|
{
|
||||||
Matrix3f r;
|
Matrix3f r;
|
||||||
@ -667,17 +655,6 @@ namespace ZL {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3f MultMatrixVector(Matrix3f mt, Vector3f v)
|
|
||||||
{
|
|
||||||
Vector3f r;
|
|
||||||
|
|
||||||
r.v[0] = v.v[0] * mt.m[0] + v.v[1] * mt.m[3] + v.v[2] * mt.m[6];
|
|
||||||
r.v[1] = v.v[0] * mt.m[1] + v.v[1] * mt.m[4] + v.v[2] * mt.m[7];
|
|
||||||
r.v[2] = v.v[0] * mt.m[2] + v.v[1] * mt.m[5] + v.v[2] * mt.m[8];
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector4f slerp(const Vector4f& q1, const Vector4f& q2, float t)
|
Vector4f slerp(const Vector4f& q1, const Vector4f& q2, float t)
|
||||||
{
|
{
|
||||||
const float epsilon = 1e-6f;
|
const float epsilon = 1e-6f;
|
||||||
582
PlanetObject.cpp
582
PlanetObject.cpp
@ -1,582 +0,0 @@
|
|||||||
#include "PlanetObject.h"
|
|
||||||
#include <random>
|
|
||||||
#include <cmath>
|
|
||||||
#include "OpenGlExtensions.h"
|
|
||||||
#include "Environment.h"
|
|
||||||
|
|
||||||
namespace ZL {
|
|
||||||
|
|
||||||
static constexpr float PLANET_RADIUS = 20000.f;
|
|
||||||
static Vector3f PLANET_CENTER_OFFSET = Vector3f{ 0.f, 0.f, 0.0f };
|
|
||||||
//static Vector3f PLANET_CENTER_OFFSET = Vector3f{ 0.f, 0.f, -45000.f };
|
|
||||||
|
|
||||||
// --- 1. Дальний диапазон (FAR) ---
|
|
||||||
static constexpr float FAR_Z_NEAR = 2000.0f;
|
|
||||||
static constexpr float FAR_Z_FAR = 200000.0f;
|
|
||||||
|
|
||||||
// Дистанция, где НАЧИНАЕТСЯ переход FAR -> MIDDLE
|
|
||||||
static constexpr float TRANSITION_FAR_START = 3000.0f;
|
|
||||||
|
|
||||||
// --- 2. Средний диапазон (MIDDLE) ---
|
|
||||||
static constexpr float MIDDLE_Z_NEAR = 500.f;
|
|
||||||
static constexpr float MIDDLE_Z_FAR = 50000.f;
|
|
||||||
|
|
||||||
|
|
||||||
// Дистанция, где ЗАВЕРШАЕТСЯ переход FAR -> MIDDLE и НАЧИНАЕТСЯ MIDDLE -> NEAR
|
|
||||||
static constexpr float TRANSITION_MIDDLE_START = 500.f;
|
|
||||||
|
|
||||||
// --- 3. Ближний диапазон (NEAR) ---
|
|
||||||
// Новые константы для максимальной точности
|
|
||||||
static constexpr float NEAR_Z_NEAR = 100.0f;
|
|
||||||
static constexpr float NEAR_Z_FAR = 10000.0f;
|
|
||||||
|
|
||||||
|
|
||||||
// Дистанция, где ЗАВЕРШАЕТСЯ переход MIDDLE -> NEAR
|
|
||||||
static constexpr float TRANSITION_NEAR_END = 100.f;
|
|
||||||
|
|
||||||
// --- 3. Ближний диапазон (NEAR) ---
|
|
||||||
// Новые константы для максимальной точности
|
|
||||||
static constexpr float SUPER_NEAR_Z_NEAR = 5.0f;
|
|
||||||
static constexpr float SUPER_NEAR_Z_FAR = 5000.0f;
|
|
||||||
|
|
||||||
|
|
||||||
// Дистанция, где ЗАВЕРШАЕТСЯ переход MIDDLE -> NEAR
|
|
||||||
static constexpr float TRANSITION_SUPER_NEAR_END = 10.f;
|
|
||||||
|
|
||||||
std::pair<float, float> calculateZRange(const Vector3f& shipPosition) {
|
|
||||||
|
|
||||||
// 1. Вычисление расстояния до поверхности планеты
|
|
||||||
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
|
||||||
const float distanceToPlanetCenter = (planetWorldPosition - shipPosition).length();
|
|
||||||
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
|
||||||
std::cout << "distanceToPlanetSurface " << distanceToPlanetSurface << std::endl;
|
|
||||||
|
|
||||||
float currentZNear;
|
|
||||||
float currentZFar;
|
|
||||||
float alpha; // Коэффициент интерполяции для текущего сегмента
|
|
||||||
|
|
||||||
// Диапазон I: Далеко (FAR) -> Средне (MIDDLE)
|
|
||||||
if (distanceToPlanetSurface >= TRANSITION_FAR_START) {
|
|
||||||
// Полностью дальний диапазон
|
|
||||||
currentZNear = FAR_Z_NEAR;
|
|
||||||
currentZFar = FAR_Z_FAR;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (distanceToPlanetSurface > TRANSITION_MIDDLE_START) {
|
|
||||||
// Плавный переход от FAR к MIDDLE
|
|
||||||
const float transitionLength = TRANSITION_FAR_START - TRANSITION_MIDDLE_START;
|
|
||||||
|
|
||||||
// Нормализация расстояния, 0 при TRANSITION_FAR_START (Далеко), 1 при TRANSITION_MIDDLE_START (Близко)
|
|
||||||
float normalizedDist = (distanceToPlanetSurface - TRANSITION_MIDDLE_START) / transitionLength;
|
|
||||||
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
|
||||||
|
|
||||||
// Интерполяция: FAR * (1-alpha) + MIDDLE * alpha
|
|
||||||
currentZNear = FAR_Z_NEAR * (1.0f - alpha) + MIDDLE_Z_NEAR * alpha;
|
|
||||||
currentZFar = FAR_Z_FAR * (1.0f - alpha) + MIDDLE_Z_FAR * alpha;
|
|
||||||
|
|
||||||
// Диапазон II: Средне (MIDDLE) -> Близко (NEAR)
|
|
||||||
}
|
|
||||||
else if (distanceToPlanetSurface > TRANSITION_NEAR_END) {
|
|
||||||
// Плавный переход от MIDDLE к NEAR
|
|
||||||
const float transitionLength = TRANSITION_MIDDLE_START - TRANSITION_NEAR_END;
|
|
||||||
|
|
||||||
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
|
|
||||||
float normalizedDist = (distanceToPlanetSurface - TRANSITION_NEAR_END) / transitionLength;
|
|
||||||
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
|
||||||
|
|
||||||
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
|
|
||||||
currentZNear = MIDDLE_Z_NEAR * (1.0f - alpha) + NEAR_Z_NEAR * alpha;
|
|
||||||
currentZFar = MIDDLE_Z_FAR * (1.0f - alpha) + NEAR_Z_FAR * alpha;
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (distanceToPlanetSurface > TRANSITION_SUPER_NEAR_END) {
|
|
||||||
// Плавный переход от MIDDLE к NEAR
|
|
||||||
const float transitionLength = TRANSITION_NEAR_END - TRANSITION_SUPER_NEAR_END;
|
|
||||||
|
|
||||||
// Нормализация расстояния, 0 при TRANSITION_MIDDLE_START (Далеко), 1 при TRANSITION_NEAR_END (Близко)
|
|
||||||
float normalizedDist = (distanceToPlanetSurface - TRANSITION_SUPER_NEAR_END) / transitionLength;
|
|
||||||
alpha = 1.0f - normalizedDist; // alpha = 0 (Далеко) ... 1 (Близко)
|
|
||||||
|
|
||||||
// Интерполяция: MIDDLE * (1-alpha) + NEAR * alpha
|
|
||||||
currentZNear = NEAR_Z_NEAR * (1.0f - alpha) + SUPER_NEAR_Z_NEAR * alpha;
|
|
||||||
currentZFar = NEAR_Z_FAR * (1.0f - alpha) + SUPER_NEAR_Z_FAR * alpha;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Полностью ближний диапазон (distanceToPlanetSurface <= TRANSITION_NEAR_END)
|
|
||||||
currentZNear = SUPER_NEAR_Z_NEAR;
|
|
||||||
currentZFar = SUPER_NEAR_Z_FAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { currentZNear, currentZFar };
|
|
||||||
}
|
|
||||||
|
|
||||||
PerlinNoise::PerlinNoise() {
|
|
||||||
p.resize(256);
|
|
||||||
std::iota(p.begin(), p.end(), 0);
|
|
||||||
// Перемешиваем для случайности (можно задать seed)
|
|
||||||
std::default_random_engine engine(77777);
|
|
||||||
std::shuffle(p.begin(), p.end(), engine);
|
|
||||||
p.insert(p.end(), p.begin(), p.end()); // Дублируем для переполнения
|
|
||||||
}
|
|
||||||
|
|
||||||
PerlinNoise::PerlinNoise(uint64_t seed) {
|
|
||||||
p.resize(256);
|
|
||||||
std::iota(p.begin(), p.end(), 0);
|
|
||||||
// Перемешиваем для случайности (используем переданный seed)
|
|
||||||
std::default_random_engine engine(seed); // <-- Использование сида
|
|
||||||
std::shuffle(p.begin(), p.end(), engine);
|
|
||||||
p.insert(p.end(), p.begin(), p.end()); // Дублируем для переполнения
|
|
||||||
}
|
|
||||||
|
|
||||||
float PerlinNoise::fade(float t) { return t * t * t * (t * (t * 6 - 15) + 10); }
|
|
||||||
float PerlinNoise::lerp(float t, float a, float b) { return a + t * (b - a); }
|
|
||||||
float PerlinNoise::grad(int hash, float x, float y, float z) {
|
|
||||||
int h = hash & 15;
|
|
||||||
float u = h < 8 ? x : y;
|
|
||||||
float v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
|
|
||||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PerlinNoise::noise(float x, float y, float z) {
|
|
||||||
int X = (int)floor(x) & 255;
|
|
||||||
int Y = (int)floor(y) & 255;
|
|
||||||
int Z = (int)floor(z) & 255;
|
|
||||||
|
|
||||||
|
|
||||||
x -= floor(x);
|
|
||||||
y -= floor(y);
|
|
||||||
z -= floor(z);
|
|
||||||
|
|
||||||
float u = fade(x);
|
|
||||||
float v = fade(y);
|
|
||||||
float w = fade(z);
|
|
||||||
|
|
||||||
int A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z;
|
|
||||||
int B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z;
|
|
||||||
|
|
||||||
return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z)),
|
|
||||||
lerp(u, grad(p[AB], x, y - 1, z), grad(p[BB], x - 1, y - 1, z))),
|
|
||||||
lerp(v, lerp(u, grad(p[AA + 1], x, y, z - 1), grad(p[BA + 1], x - 1, y, z - 1)),
|
|
||||||
lerp(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1))));
|
|
||||||
}
|
|
||||||
|
|
||||||
float PerlinNoise::getSurfaceHeight(Vector3f pos) {
|
|
||||||
// Частота шума (чем больше, тем больше "холмов")
|
|
||||||
float frequency = 7.0f;
|
|
||||||
|
|
||||||
|
|
||||||
// Получаем значение шума (обычно от -1 до 1)
|
|
||||||
float noiseValue = noise(pos.v[0] * frequency, pos.v[1] * frequency, pos.v[2] * frequency);
|
|
||||||
|
|
||||||
// Переводим из диапазона [-1, 1] в [0, 1]
|
|
||||||
//noiseValue = (noiseValue + 1.0f) * 0.5f;
|
|
||||||
|
|
||||||
// Масштабируем: хотим отклонение от 1.0 до 1.1
|
|
||||||
// Значит амплитуда = 0.1
|
|
||||||
float height = 1.0f; // * 0.2 даст вариацию высоты
|
|
||||||
//float height = 1.0f - (noiseValue * 0.01f); // * 0.2 даст вариацию высоты
|
|
||||||
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool PlanetObject::planetIsFar()
|
|
||||||
{
|
|
||||||
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
|
||||||
const float distanceToPlanetCenter = (planetWorldPosition - Environment::shipPosition).length();
|
|
||||||
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
|
||||||
|
|
||||||
return distanceToPlanetSurface > 0.1*TRANSITION_MIDDLE_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
float PlanetObject::distanceToPlanetSurface()
|
|
||||||
{
|
|
||||||
const Vector3f planetWorldPosition = PLANET_CENTER_OFFSET;
|
|
||||||
const float distanceToPlanetCenter = (planetWorldPosition - Environment::shipPosition).length();
|
|
||||||
const float distanceToPlanetSurface = distanceToPlanetCenter - PLANET_RADIUS;
|
|
||||||
return distanceToPlanetSurface;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PlanetObject::PlanetObject()
|
|
||||||
: perlin(77777)
|
|
||||||
, colorPerlin(123123)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanetObject::init() {
|
|
||||||
|
|
||||||
planetMesh = generateSphere(8);
|
|
||||||
|
|
||||||
planetMesh.Scale(PLANET_RADIUS);
|
|
||||||
planetMesh.Move(PLANET_CENTER_OFFSET);
|
|
||||||
|
|
||||||
planetRenderStruct.data = planetMesh;
|
|
||||||
planetRenderStruct.RefreshVBO();
|
|
||||||
|
|
||||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand.png", ""));
|
|
||||||
//sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", ""));
|
|
||||||
|
|
||||||
planetAtmosphere.data = generateSphere(5);
|
|
||||||
planetAtmosphere.data.Scale(PLANET_RADIUS*1.03);
|
|
||||||
planetAtmosphere.data.Move(PLANET_CENTER_OFFSET);
|
|
||||||
|
|
||||||
planetAtmosphere.RefreshVBO();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanetObject::prepareDrawData() {
|
|
||||||
if (!drawDataDirty) return;
|
|
||||||
|
|
||||||
drawDataDirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanetObject::draw(Renderer& renderer) {
|
|
||||||
|
|
||||||
prepareDrawData();
|
|
||||||
|
|
||||||
static const std::string defaultShaderName = "defaultColor";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vColorName = "vColor";
|
|
||||||
static const std::string vNormalName = "vNormal";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
//static const std::string vTexCoord3Name = "vTexCoord3";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vColorName);
|
|
||||||
renderer.EnableVertexAttribArray(vNormalName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
//renderer.EnableVertexAttribArray(vTexCoord3Name);
|
|
||||||
|
|
||||||
const auto zRange = calculateZRange(Environment::shipPosition);
|
|
||||||
const float currentZNear = zRange.first;
|
|
||||||
const float currentZFar = zRange.second;
|
|
||||||
|
|
||||||
// 2. Применяем динамическую матрицу проекции
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
|
||||||
currentZNear, currentZFar);
|
|
||||||
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
|
||||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
|
||||||
renderer.TranslateMatrix(-Environment::shipPosition);
|
|
||||||
|
|
||||||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
|
||||||
|
|
||||||
|
|
||||||
Vector3f lightDir_World = Vector3f(1.0f, 0.0f, -1.0f).normalized();
|
|
||||||
// В OpenGL/шейдерах удобнее работать с вектором, указывающим ОТ источника к поверхности.
|
|
||||||
Vector3f lightDirection_World = -lightDir_World; // Вектор, направленный от источника
|
|
||||||
Vector3f lightDirection_View;
|
|
||||||
|
|
||||||
lightDirection_View.v[0] = viewMatrix.m[0] * lightDirection_World.v[0] + viewMatrix.m[4] * lightDirection_World.v[1] + viewMatrix.m[8] * lightDirection_World.v[2];
|
|
||||||
lightDirection_View.v[1] = viewMatrix.m[1] * lightDirection_World.v[0] + viewMatrix.m[5] * lightDirection_World.v[1] + viewMatrix.m[9] * lightDirection_World.v[2];
|
|
||||||
lightDirection_View.v[2] = viewMatrix.m[2] * lightDirection_World.v[0] + viewMatrix.m[6] * lightDirection_World.v[1] + viewMatrix.m[10] * lightDirection_World.v[2];
|
|
||||||
lightDirection_View = lightDirection_View.normalized(); // Нормализуем на всякий случай
|
|
||||||
|
|
||||||
// Установка uniform-переменной
|
|
||||||
// Предполагается, что RenderUniform3fv определена в Renderer.h
|
|
||||||
renderer.RenderUniform3fv("uLightDirection", &lightDirection_View.v[0]);
|
|
||||||
renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]);
|
|
||||||
|
|
||||||
float dist = distanceToPlanetSurface();
|
|
||||||
|
|
||||||
|
|
||||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
|
||||||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
|
||||||
//glEnable(GL_BLEND);
|
|
||||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
|
||||||
renderer.DrawVertexRenderStruct(planetRenderStruct);
|
|
||||||
//glDisable(GL_BLEND);
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
//renderer.DisableVertexAttribArray(vTexCoord3Name);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
renderer.DisableVertexAttribArray(vNormalName);
|
|
||||||
renderer.DisableVertexAttribArray(vColorName);
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
drawAtmosphere(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanetObject::drawAtmosphere(Renderer& renderer) {
|
|
||||||
static const std::string defaultShaderName = "defaultAtmosphere";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vNormalName = "vNormal";
|
|
||||||
//glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
glDepthMask(GL_FALSE);
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vNormalName);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const auto zRange = calculateZRange(Environment::shipPosition);
|
|
||||||
const float currentZNear = zRange.first;
|
|
||||||
const float currentZFar = zRange.second;
|
|
||||||
|
|
||||||
// 2. Применяем динамическую матрицу проекции
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5,
|
|
||||||
static_cast<float>(Environment::width) / static_cast<float>(Environment::height),
|
|
||||||
currentZNear, currentZFar);
|
|
||||||
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
|
||||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
|
||||||
renderer.TranslateMatrix(-Environment::shipPosition);
|
|
||||||
|
|
||||||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
|
||||||
|
|
||||||
Vector3f color = { 0.0, 0.5, 1.0 };
|
|
||||||
|
|
||||||
renderer.RenderUniform3fv("uColor", &color.v[0]);
|
|
||||||
|
|
||||||
renderer.RenderUniformMatrix4fv("ModelViewMatrix", false, &viewMatrix.m[0]);
|
|
||||||
|
|
||||||
float dist = distanceToPlanetSurface();
|
|
||||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
|
||||||
|
|
||||||
renderer.DrawVertexRenderStruct(planetAtmosphere);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glDepthMask(GL_TRUE);
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
|
|
||||||
renderer.DisableVertexAttribArray(vNormalName);
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlanetObject::update(float deltaTimeMs) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Triangle> PlanetObject::subdivideTriangles(const std::vector<Triangle>& inputTriangles) {
|
|
||||||
std::vector<Triangle> output;
|
|
||||||
output.reserve(inputTriangles.size() * 4);
|
|
||||||
|
|
||||||
for (const auto& t : inputTriangles) {
|
|
||||||
Vector3f a = t.data[0];
|
|
||||||
Vector3f b = t.data[1];
|
|
||||||
Vector3f c = t.data[2];
|
|
||||||
|
|
||||||
// 1. Вычисляем "сырые" середины
|
|
||||||
Vector3f m_ab = (a + b) * 0.5f;
|
|
||||||
Vector3f m_bc = (b + c) * 0.5f;
|
|
||||||
Vector3f m_ac = (a + c) * 0.5f;
|
|
||||||
|
|
||||||
// 2. Нормализуем их (получаем идеальную сферу радиуса 1)
|
|
||||||
m_ab = m_ab.normalized();
|
|
||||||
m_bc = m_bc.normalized();
|
|
||||||
m_ac = m_ac.normalized();
|
|
||||||
|
|
||||||
// 3. ПРИМЕНЯЕМ ШУМ: Смещаем точку по радиусу
|
|
||||||
m_ab = m_ab * perlin.getSurfaceHeight(m_ab);
|
|
||||||
m_bc = m_bc * perlin.getSurfaceHeight(m_bc);
|
|
||||||
m_ac = m_ac * perlin.getSurfaceHeight(m_ac);
|
|
||||||
|
|
||||||
// 4. Формируем новые треугольники
|
|
||||||
output.emplace_back(a, m_ab, m_ac);
|
|
||||||
output.emplace_back(m_ab, b, m_bc);
|
|
||||||
output.emplace_back(m_ac, m_bc, c);
|
|
||||||
output.emplace_back(m_ab, m_bc, m_ac);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f PlanetObject::calculateSurfaceNormal(Vector3f p_sphere) {
|
|
||||||
// p_sphere - это нормализованный вектор (точка на идеальной сфере)
|
|
||||||
|
|
||||||
float theta = 0.01f; // Шаг для "щупанья" соседей (epsilon)
|
|
||||||
|
|
||||||
// Нам нужно найти два вектора, касательных к сфере в точке p_sphere.
|
|
||||||
// Для этого берем любой вектор (например UP), делаем Cross Product, чтобы получить касательную.
|
|
||||||
// Если p_sphere совпадает с UP, берем RIGHT.
|
|
||||||
Vector3f up = Vector3f(0.0f, 1.0f, 0.0f);
|
|
||||||
if (abs(p_sphere.dot(up)) > 0.99f) {
|
|
||||||
up = Vector3f(1.0f, 0.0f, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f tangentX = (up.cross(p_sphere)).normalized();
|
|
||||||
Vector3f tangentY = (p_sphere.cross(tangentX)).normalized();
|
|
||||||
|
|
||||||
// Точки на идеальной сфере со смещением
|
|
||||||
Vector3f p0_dir = p_sphere;
|
|
||||||
Vector3f p1_dir = (p_sphere + tangentX * theta).normalized();
|
|
||||||
Vector3f p2_dir = (p_sphere + tangentY * theta).normalized();
|
|
||||||
|
|
||||||
// Реальные точки на искаженной поверхности
|
|
||||||
// p = dir * height(dir)
|
|
||||||
Vector3f p0 = p0_dir * perlin.getSurfaceHeight(p0_dir);
|
|
||||||
Vector3f p1 = p1_dir * perlin.getSurfaceHeight(p1_dir);
|
|
||||||
Vector3f p2 = p2_dir * perlin.getSurfaceHeight(p2_dir);
|
|
||||||
|
|
||||||
// Вектора от центральной точки к соседям
|
|
||||||
Vector3f v1 = p1 - p0;
|
|
||||||
Vector3f v2 = p2 - p0;
|
|
||||||
|
|
||||||
// Нормаль - это перпендикуляр к этим двум векторам
|
|
||||||
// Порядок (v2, v1) или (v1, v2) зависит от системы координат,
|
|
||||||
// здесь подбираем так, чтобы нормаль смотрела наружу.
|
|
||||||
return (-v2.cross(v1)).normalized();
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexDataStruct PlanetObject::trianglesToVertices(const std::vector<Triangle>& triangles) {
|
|
||||||
VertexDataStruct buffer;
|
|
||||||
buffer.PositionData.reserve(triangles.size() * 3);
|
|
||||||
buffer.NormalData.reserve(triangles.size() * 3);
|
|
||||||
buffer.TexCoordData.reserve(triangles.size() * 3); // <-- РЕЗЕРВИРУЕМ
|
|
||||||
//buffer.TexCoord3Data.reserve(triangles.size() * 3); // <-- РЕЗЕРВИРУЕМ
|
|
||||||
|
|
||||||
// Стандартные UV-координаты для покрытия одного треугольника
|
|
||||||
// Покрывает текстурой всю грань.
|
|
||||||
const std::array<Vector2f, 3> triangleUVs = {
|
|
||||||
Vector2f(0.0f, 0.0f),
|
|
||||||
Vector2f(1.0f, 0.0f),
|
|
||||||
Vector2f(0.0f, 1.0f)
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
const std::array<Vector3f, 3> barycentricCoords = {
|
|
||||||
Vector3f(1.0f, 0.0f, 0.0f), // Вершина 1
|
|
||||||
Vector3f(0.0f, 1.0f, 0.0f), // Вершина 2
|
|
||||||
Vector3f(0.0f, 0.0f, 1.0f) // Вершина 3
|
|
||||||
};*/
|
|
||||||
|
|
||||||
for (const auto& t : triangles) {
|
|
||||||
// Проходим по всем 3 вершинам треугольника
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
// p_geometry - это уже точка на поверхности (с шумом)
|
|
||||||
Vector3f p_geometry = t.data[i];
|
|
||||||
|
|
||||||
// Нам нужно восстановить направление от центра к этой точке,
|
|
||||||
// чтобы передать его в функцию расчета нормали.
|
|
||||||
// Так как (0,0,0) - центр, то normalize(p) даст нам направление.
|
|
||||||
Vector3f p_dir = p_geometry.normalized();
|
|
||||||
|
|
||||||
// Считаем аналитическую нормаль для этой конкретной точки
|
|
||||||
Vector3f normal = calculateSurfaceNormal(p_dir);
|
|
||||||
|
|
||||||
buffer.PositionData.push_back({ p_geometry });
|
|
||||||
buffer.NormalData.push_back({ normal });
|
|
||||||
//buffer.TexCoord3Data.push_back(barycentricCoords[i]);
|
|
||||||
buffer.TexCoordData.push_back(triangleUVs[i]);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VertexDataStruct PlanetObject::generateSphere(int subdivisions) {
|
|
||||||
// 1. Исходный октаэдр
|
|
||||||
std::vector<Triangle> geometry = {
|
|
||||||
Triangle{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}}, // Top-Front-Right
|
|
||||||
Triangle{{ 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // Top-Right-Back
|
|
||||||
Triangle{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}}, // Top-Back-Left
|
|
||||||
Triangle{{ 0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // Top-Left-Front
|
|
||||||
Triangle{{ 0.0f, -1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // Bottom-Right-Front
|
|
||||||
Triangle{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}}, // Bottom-Front-Left
|
|
||||||
Triangle{{ 0.0f, -1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // Bottom-Left-Back
|
|
||||||
Triangle{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}} // Bottom-Back-Right
|
|
||||||
};
|
|
||||||
|
|
||||||
// 2. ПРИМЕНЯЕМ ШУМ К ИСХОДНЫМ ВЕРШИНАМ
|
|
||||||
for (auto& t : geometry) {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
Vector3f dir = t.data[i].normalized();
|
|
||||||
t.data[i] = dir * perlin.getSurfaceHeight(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Разбиваем N раз
|
|
||||||
for (int i = 0; i < subdivisions; i++) {
|
|
||||||
geometry = subdivideTriangles(geometry);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Генерируем вершины И НОРМАЛИ с помощью trianglesToVertices
|
|
||||||
// ЭТО ЗАПОЛНИТ PositionData И NormalData
|
|
||||||
VertexDataStruct buffer = trianglesToVertices(geometry);
|
|
||||||
|
|
||||||
// Теперь нам нужно заполнить ColorData, используя ту же логику, что и раньше.
|
|
||||||
// Сначала резервируем место, так как trianglesToVertices не заполняет ColorData
|
|
||||||
buffer.ColorData.reserve(geometry.size() * 3);
|
|
||||||
|
|
||||||
// Базовый цвет и параметры
|
|
||||||
const Vector3f baseColor = { 0.498f, 0.416f, 0.0f };
|
|
||||||
const float colorFrequency = 5.0f;
|
|
||||||
const float colorAmplitude = 0.2f;
|
|
||||||
const Vector3f offsetR = { 0.1f, 0.2f, 0.3f };
|
|
||||||
const Vector3f offsetG = { 0.5f, 0.4f, 0.6f };
|
|
||||||
const Vector3f offsetB = { 0.9f, 0.8f, 0.7f };
|
|
||||||
|
|
||||||
|
|
||||||
for (const auto& t : geometry) {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
// ВАЖНО: Мы используем геометрию из t.data[i] для получения направления,
|
|
||||||
// а не PositionData из buffer, поскольку там может не быть нужного порядка.
|
|
||||||
Vector3f p_geometry = t.data[i];
|
|
||||||
Vector3f dir = p_geometry.normalized();
|
|
||||||
|
|
||||||
// Вычисление цветового шума (как вы делали)
|
|
||||||
float noiseR = colorPerlin.noise(
|
|
||||||
(dir.v[0] + offsetR.v[0]) * colorFrequency,
|
|
||||||
(dir.v[1] + offsetR.v[1]) * colorFrequency,
|
|
||||||
(dir.v[2] + offsetR.v[2]) * colorFrequency
|
|
||||||
);
|
|
||||||
float noiseG = colorPerlin.noise(
|
|
||||||
(dir.v[0] + offsetG.v[0]) * colorFrequency,
|
|
||||||
(dir.v[1] + offsetG.v[1]) * colorFrequency,
|
|
||||||
(dir.v[2] + offsetG.v[2]) * colorFrequency
|
|
||||||
);
|
|
||||||
float noiseB = colorPerlin.noise(
|
|
||||||
(dir.v[0] + offsetB.v[0]) * colorFrequency,
|
|
||||||
(dir.v[1] + offsetB.v[1]) * colorFrequency,
|
|
||||||
(dir.v[2] + offsetB.v[2]) * colorFrequency
|
|
||||||
);
|
|
||||||
|
|
||||||
Vector3f colorOffset = {
|
|
||||||
noiseR * colorAmplitude,
|
|
||||||
noiseG * colorAmplitude,
|
|
||||||
noiseB * colorAmplitude
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector3f finalColor = baseColor + colorOffset;
|
|
||||||
|
|
||||||
finalColor.v[0] = max(0.0f, min(1.0f, finalColor.v[0]));
|
|
||||||
finalColor.v[1] = max(0.0f, min(1.0f, finalColor.v[1]));
|
|
||||||
finalColor.v[2] = max(0.0f, min(1.0f, finalColor.v[2]));
|
|
||||||
|
|
||||||
// ДОБАВЛЯЕМ ТОЛЬКО ЦВЕТ, так как PositionData и NormalData уже заполнены!
|
|
||||||
buffer.ColorData.push_back(finalColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace ZL
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ZLMath.h"
|
|
||||||
#include "Renderer.h"
|
|
||||||
#include "TextureManager.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <chrono>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <array>
|
|
||||||
#include <numeric>
|
|
||||||
#include <random>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace ZL {
|
|
||||||
|
|
||||||
struct Triangle
|
|
||||||
{
|
|
||||||
std::array<Vector3f, 3> data;
|
|
||||||
|
|
||||||
Triangle(Vector3f p1, Vector3f p2, Vector3f p3)
|
|
||||||
: data{ p1, p2, p3 }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PerlinNoise {
|
|
||||||
std::vector<int> p;
|
|
||||||
public:
|
|
||||||
PerlinNoise();
|
|
||||||
PerlinNoise(uint64_t seed);
|
|
||||||
|
|
||||||
float fade(float t);
|
|
||||||
float lerp(float t, float a, float b);
|
|
||||||
float grad(int hash, float x, float y, float z);
|
|
||||||
|
|
||||||
float noise(float x, float y, float z);
|
|
||||||
|
|
||||||
float getSurfaceHeight(Vector3f pos);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PlanetObject {
|
|
||||||
private:
|
|
||||||
PerlinNoise perlin;
|
|
||||||
PerlinNoise colorPerlin;
|
|
||||||
void prepareDrawData();
|
|
||||||
VertexDataStruct planetMesh;
|
|
||||||
VertexRenderStruct planetRenderStruct;
|
|
||||||
|
|
||||||
VertexRenderStruct planetAtmosphere;
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Texture> sandTexture;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PlanetObject();
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
void update(float deltaTimeMs);
|
|
||||||
|
|
||||||
void draw(Renderer& renderer);
|
|
||||||
void drawAtmosphere(Renderer& renderer);
|
|
||||||
|
|
||||||
bool planetIsFar();
|
|
||||||
float distanceToPlanetSurface();
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool drawDataDirty = true;
|
|
||||||
|
|
||||||
std::vector<Triangle> subdivideTriangles(const std::vector<Triangle>& inputTriangles);
|
|
||||||
Vector3f calculateSurfaceNormal(Vector3f p_sphere);
|
|
||||||
VertexDataStruct trianglesToVertices(const std::vector<Triangle>& triangles);
|
|
||||||
VertexDataStruct generateSphere(int subdivisions);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ZL
|
|
||||||
10
Readme.md
10
Readme.md
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
download from https://cmake.org/download/
|
download from https://cmake.org/download/
|
||||||
|
|
||||||
|
|
||||||
Windows x64 Installer: cmake-4.2.0-windows-x86_64.msi
|
Windows x64 Installer: cmake-4.2.0-windows-x86_64.msi
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +83,7 @@ zlibstaticd.lib;libpng16_staticd.lib;SDL2d.lib;SDL2maind.lib;opengl32.lib;glu32.
|
|||||||
```
|
```
|
||||||
C:\Work\Projects\emsdk\emsdk.bat activate latest
|
C:\Work\Projects\emsdk\emsdk.bat activate latest
|
||||||
C:\Work\Projects\emsdk\emsdk_env.bat
|
C:\Work\Projects\emsdk\emsdk_env.bat
|
||||||
emcc main.cpp Game.cpp Math.cpp Physics.cpp Renderer.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -sTOTAL_MEMORY=33554432 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS="[""png""]" -sUSE_SDL=2 --preload-file background.bmp --preload-file bird.bmp32 --preload-file default.fragment --preload-file default.vertex --preload-file game_over.bmp32 --preload-file pipe.bmp32 -o space-game001.html
|
emcc main.cpp Game.cpp Math.cpp Physics.cpp Renderer.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -sTOTAL_MEMORY=33554432 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS="[""png""]" -sUSE_SDL=2 --preload-file background.bmp --preload-file bird.bmp32 --preload-file default.fragment --preload-file default.vertex --preload-file game_over.bmp32 --preload-file pipe.bmp32 -o jumpingbird.html
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -144,12 +143,7 @@ emcc main.cpp Game.cpp Environment.cpp GameObjectManager.cpp BoneAnimatedModel.c
|
|||||||
|
|
||||||
|
|
||||||
# Windows:
|
# Windows:
|
||||||
emcc --clear-cache
|
emcc main.cpp Game.cpp Environment.cpp GameObjectManager.cpp BoneAnimatedModel.cpp GameWorld.cpp InputManager.cpp Inventory.cpp ObjLoader.cpp QuestScripts.cpp RenderSystem.cpp Math.cpp Physics.cpp Renderer.cpp TextModel.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 --preload-file data.zip -o viola.html
|
||||||
embuilder build sdl2 sdl2_ttf sdl2_image sdl2_image_jpg sdl2_image_png
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
emcc main.cpp Game.cpp Environment.cpp BoneAnimatedModel.cpp ZLMath.cpp Renderer.cpp TextModel.cpp ShaderManager.cpp TextureManager.cpp Utils.cpp OpenGlExtensions.cpp -O2 -std=c++14 -pthread -sUSE_PTHREADS=1 -sPTHREAD_POOL_SIZE=4 -sTOTAL_MEMORY=4294967296 -sINITIAL_MEMORY=3221225472 -sMAXIMUM_MEMORY=4294967296 -sALLOW_MEMORY_GROWTH=1 -I./thirdparty/libzip-1.11.3/build-emcmake/install/include -L./thirdparty/libzip-1.11.3/build-emcmake/install/lib -lzip -lz -sUSE_SDL_IMAGE=2 -sUSE_SDL=2 -sUSE_LIBPNG=1 --preload-file space-game001.zip -o space-game001.html
|
|
||||||
|
|
||||||
emrun --no_browser --port 8080 .
|
emrun --no_browser --port 8080 .
|
||||||
```
|
```
|
||||||
|
|||||||
139
Renderer.cpp
139
Renderer.cpp
@ -196,71 +196,6 @@ namespace ZL {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexDataStruct CreateCubemap(float scale)
|
|
||||||
{
|
|
||||||
VertexDataStruct cubemapVertexDataStruct;
|
|
||||||
|
|
||||||
// +x
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale });
|
|
||||||
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale });
|
|
||||||
|
|
||||||
// -x
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale });
|
|
||||||
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale });
|
|
||||||
|
|
||||||
|
|
||||||
// +y
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale });
|
|
||||||
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale });
|
|
||||||
|
|
||||||
|
|
||||||
// -y
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale });
|
|
||||||
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale });
|
|
||||||
|
|
||||||
|
|
||||||
// +z
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale });
|
|
||||||
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, scale });
|
|
||||||
|
|
||||||
// -z
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale });
|
|
||||||
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, -scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ scale, scale, -scale });
|
|
||||||
cubemapVertexDataStruct.PositionData.push_back({ -scale, scale, -scale });
|
|
||||||
|
|
||||||
return cubemapVertexDataStruct;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VertexRenderStruct::RefreshVBO()
|
void VertexRenderStruct::RefreshVBO()
|
||||||
{
|
{
|
||||||
//Check if main thread, check if data is not empty...
|
//Check if main thread, check if data is not empty...
|
||||||
@ -294,18 +229,6 @@ namespace ZL {
|
|||||||
glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, data.TexCoordData.size() * 8, &data.TexCoordData[0], GL_STATIC_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.TexCoord3Data.size() > 0)
|
|
||||||
{
|
|
||||||
if (!texCoord3VBO)
|
|
||||||
{
|
|
||||||
texCoord3VBO = std::make_shared<VBOHolder>();
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, texCoord3VBO->getBuffer());
|
|
||||||
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, data.TexCoord3Data.size() * 12, &data.TexCoord3Data[0], GL_STATIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (data.NormalData.size() > 0)
|
if (data.NormalData.size() > 0)
|
||||||
{
|
{
|
||||||
@ -471,12 +394,6 @@ namespace ZL {
|
|||||||
return ProjectionModelViewMatrix;
|
return ProjectionModelViewMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4f Renderer::GetCurrentModelViewMatrix()
|
|
||||||
{
|
|
||||||
return ModelviewMatrixStack.top();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::SetMatrix()
|
void Renderer::SetMatrix()
|
||||||
{
|
{
|
||||||
if (ProjectionMatrixStack.size() <= 0)
|
if (ProjectionMatrixStack.size() <= 0)
|
||||||
@ -489,16 +406,15 @@ namespace ZL {
|
|||||||
throw std::runtime_error("Modelview matrix stack out!");
|
throw std::runtime_error("Modelview matrix stack out!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix4f& modelViewMatrix = ModelviewMatrixStack.top();
|
ProjectionModelViewMatrix = ProjectionMatrixStack.top() * ModelviewMatrixStack.top();
|
||||||
ProjectionModelViewMatrix = ProjectionMatrixStack.top() * modelViewMatrix;
|
|
||||||
|
|
||||||
static const std::string ProjectionModelViewMatrixName = "ProjectionModelViewMatrix";
|
static const std::string ProjectionModelViewMatrixName = "ProjectionModelViewMatrix";
|
||||||
|
|
||||||
|
//static const std::string ProjectionMatrixName = "ProjectionMatrix";
|
||||||
|
|
||||||
RenderUniformMatrix4fv(ProjectionModelViewMatrixName, false, &ProjectionModelViewMatrix.m[0]);
|
RenderUniformMatrix4fv(ProjectionModelViewMatrixName, false, &ProjectionModelViewMatrix.m[0]);
|
||||||
|
|
||||||
static const std::string ModelViewMatrixName = "ModelViewMatrix";
|
//RenderUniformMatrix4fv(ProjectionMatrixName, false, &ProjectionMatrixStack.top().m[0]);
|
||||||
|
|
||||||
RenderUniformMatrix4fv(ModelViewMatrixName, false, &modelViewMatrix.m[0]);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,35 +538,6 @@ namespace ZL {
|
|||||||
SetMatrix();
|
SetMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RotateMatrix(const Matrix3f& m3)
|
|
||||||
{
|
|
||||||
Matrix4f m = Matrix4f::Identity();
|
|
||||||
m.m[0] = m3.m[0];
|
|
||||||
m.m[1] = m3.m[1];
|
|
||||||
m.m[2] = m3.m[2];
|
|
||||||
|
|
||||||
m.m[4] = m3.m[3];
|
|
||||||
m.m[5] = m3.m[4];
|
|
||||||
m.m[6] = m3.m[5];
|
|
||||||
|
|
||||||
m.m[8] = m3.m[6];
|
|
||||||
m.m[9] = m3.m[7];
|
|
||||||
m.m[10] = m3.m[8];
|
|
||||||
|
|
||||||
m = ModelviewMatrixStack.top() * m;
|
|
||||||
|
|
||||||
if (ModelviewMatrixStack.size() == 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("Modelview matrix stack underflow!!!!");
|
|
||||||
}
|
|
||||||
|
|
||||||
ModelviewMatrixStack.pop();
|
|
||||||
ModelviewMatrixStack.push(m);
|
|
||||||
|
|
||||||
|
|
||||||
SetMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Renderer::PushSpecialMatrix(const Matrix4f& m)
|
void Renderer::PushSpecialMatrix(const Matrix4f& m)
|
||||||
{
|
{
|
||||||
if (ModelviewMatrixStack.size() > 64)
|
if (ModelviewMatrixStack.size() > 64)
|
||||||
@ -727,18 +614,6 @@ namespace ZL {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::RenderUniform1f(const std::string& uniformName, float value)
|
|
||||||
{
|
|
||||||
auto shader = shaderManager.GetCurrentShader();
|
|
||||||
|
|
||||||
auto uniform = shader->uniformList.find(uniformName);
|
|
||||||
|
|
||||||
if (uniform != shader->uniformList.end())
|
|
||||||
{
|
|
||||||
glUniform1fv(uniform->second, 1, &value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer)
|
void Renderer::VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer)
|
||||||
@ -764,7 +639,6 @@ namespace ZL {
|
|||||||
static const std::string vBinormal("vBinormal");
|
static const std::string vBinormal("vBinormal");
|
||||||
static const std::string vColor("vColor");
|
static const std::string vColor("vColor");
|
||||||
static const std::string vTexCoord("vTexCoord");
|
static const std::string vTexCoord("vTexCoord");
|
||||||
static const std::string vTexCoord3("vTexCoord3");
|
|
||||||
static const std::string vPosition("vPosition");
|
static const std::string vPosition("vPosition");
|
||||||
|
|
||||||
//glBindVertexArray(VertexRenderStruct.vao->getBuffer());
|
//glBindVertexArray(VertexRenderStruct.vao->getBuffer());
|
||||||
@ -795,11 +669,6 @@ namespace ZL {
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoordVBO->getBuffer());
|
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoordVBO->getBuffer());
|
||||||
VertexAttribPointer2fv(vTexCoord, 0, NULL);
|
VertexAttribPointer2fv(vTexCoord, 0, NULL);
|
||||||
}
|
}
|
||||||
if (VertexRenderStruct.data.TexCoord3Data.size() > 0)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.texCoord3VBO->getBuffer());
|
|
||||||
VertexAttribPointer2fv(vTexCoord3, 0, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer());
|
glBindBuffer(GL_ARRAY_BUFFER, VertexRenderStruct.positionVBO->getBuffer());
|
||||||
VertexAttribPointer3fv(vPosition, 0, NULL);
|
VertexAttribPointer3fv(vPosition, 0, NULL);
|
||||||
|
|||||||
@ -44,7 +44,6 @@ namespace ZL {
|
|||||||
{
|
{
|
||||||
std::vector<Vector3f> PositionData;
|
std::vector<Vector3f> PositionData;
|
||||||
std::vector<Vector2f> TexCoordData;
|
std::vector<Vector2f> TexCoordData;
|
||||||
std::vector<Vector3f> TexCoord3Data;
|
|
||||||
std::vector<Vector3f> NormalData;
|
std::vector<Vector3f> NormalData;
|
||||||
std::vector<Vector3f> TangentData;
|
std::vector<Vector3f> TangentData;
|
||||||
std::vector<Vector3f> BinormalData;
|
std::vector<Vector3f> BinormalData;
|
||||||
@ -64,7 +63,6 @@ namespace ZL {
|
|||||||
std::shared_ptr<VAOHolder> vao;
|
std::shared_ptr<VAOHolder> vao;
|
||||||
std::shared_ptr<VBOHolder> positionVBO;
|
std::shared_ptr<VBOHolder> positionVBO;
|
||||||
std::shared_ptr<VBOHolder> texCoordVBO;
|
std::shared_ptr<VBOHolder> texCoordVBO;
|
||||||
std::shared_ptr<VBOHolder> texCoord3VBO;
|
|
||||||
std::shared_ptr<VBOHolder> normalVBO;
|
std::shared_ptr<VBOHolder> normalVBO;
|
||||||
std::shared_ptr<VBOHolder> tangentVBO;
|
std::shared_ptr<VBOHolder> tangentVBO;
|
||||||
std::shared_ptr<VBOHolder> binormalVBO;
|
std::shared_ptr<VBOHolder> binormalVBO;
|
||||||
@ -77,7 +75,6 @@ namespace ZL {
|
|||||||
VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel);
|
VertexDataStruct CreateRect2D(Vector2f center, Vector2f halfWidthHeight, float zLevel);
|
||||||
VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount);
|
VertexDataStruct CreateRectHorizontalSections2D(Vector2f center, Vector2f halfWidthHeight, float zLevel, size_t sectionCount);
|
||||||
VertexDataStruct CreateCube3D(float scale);
|
VertexDataStruct CreateCube3D(float scale);
|
||||||
VertexDataStruct CreateCubemap(float scale = 1000.f);
|
|
||||||
|
|
||||||
|
|
||||||
class Renderer
|
class Renderer
|
||||||
@ -104,13 +101,11 @@ namespace ZL {
|
|||||||
void ScaleMatrix(float scale);
|
void ScaleMatrix(float scale);
|
||||||
void ScaleMatrix(const Vector3f& scale);
|
void ScaleMatrix(const Vector3f& scale);
|
||||||
void RotateMatrix(const Vector4f& q);
|
void RotateMatrix(const Vector4f& q);
|
||||||
void RotateMatrix(const Matrix3f& m3);
|
|
||||||
void PushSpecialMatrix(const Matrix4f& m);
|
void PushSpecialMatrix(const Matrix4f& m);
|
||||||
void PopMatrix();
|
void PopMatrix();
|
||||||
|
|
||||||
|
|
||||||
Matrix4f GetProjectionModelViewMatrix();
|
Matrix4f GetProjectionModelViewMatrix();
|
||||||
Matrix4f GetCurrentModelViewMatrix();
|
|
||||||
|
|
||||||
void SetMatrix();
|
void SetMatrix();
|
||||||
|
|
||||||
@ -124,7 +119,7 @@ namespace ZL {
|
|||||||
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
|
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
|
||||||
void RenderUniform1i(const std::string& uniformName, const int value);
|
void RenderUniform1i(const std::string& uniformName, const int value);
|
||||||
void RenderUniform3fv(const std::string& uniformName, const float* value);
|
void RenderUniform3fv(const std::string& uniformName, const float* value);
|
||||||
void RenderUniform1f(const std::string& uniformName, float value);
|
|
||||||
|
|
||||||
void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer);
|
void VertexAttribPointer2fv(const std::string& attribName, int stride, const char* pointer);
|
||||||
|
|
||||||
|
|||||||
299
SparkEmitter.cpp
299
SparkEmitter.cpp
@ -1,299 +0,0 @@
|
|||||||
#include "SparkEmitter.h"
|
|
||||||
#include <random>
|
|
||||||
#include <cmath>
|
|
||||||
#include "OpenGlExtensions.h"
|
|
||||||
#include "Environment.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace ZL {
|
|
||||||
|
|
||||||
SparkEmitter::SparkEmitter()
|
|
||||||
: emissionRate(100.0f), isActive(true), drawDataDirty(true), maxParticles(200) {
|
|
||||||
particles.resize(maxParticles);
|
|
||||||
drawPositions.reserve(maxParticles * 6);
|
|
||||||
drawTexCoords.reserve(maxParticles * 6);
|
|
||||||
lastEmissionTime = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
sparkQuad.data = VertexDataStruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions, float rate)
|
|
||||||
: emissionPoints(positions), emissionRate(rate), isActive(true),
|
|
||||||
drawDataDirty(true), maxParticles(positions.size() * 100) {
|
|
||||||
particles.resize(maxParticles);
|
|
||||||
drawPositions.reserve(maxParticles * 6);
|
|
||||||
drawTexCoords.reserve(maxParticles * 6);
|
|
||||||
lastEmissionTime = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
sparkQuad.data = VertexDataStruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
SparkEmitter::SparkEmitter(const std::vector<Vector3f>& positions,
|
|
||||||
std::shared_ptr<Texture> tex,
|
|
||||||
float rate)
|
|
||||||
: emissionPoints(positions), texture(tex), emissionRate(rate),
|
|
||||||
isActive(true), drawDataDirty(true), maxParticles(positions.size() * 100) {
|
|
||||||
particles.resize(maxParticles);
|
|
||||||
drawPositions.reserve(maxParticles * 6);
|
|
||||||
drawTexCoords.reserve(maxParticles * 6);
|
|
||||||
lastEmissionTime = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
sparkQuad.data = VertexDataStruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::setTexture(std::shared_ptr<Texture> tex) {
|
|
||||||
texture = tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::prepareDrawData() {
|
|
||||||
if (!drawDataDirty) return;
|
|
||||||
|
|
||||||
drawPositions.clear();
|
|
||||||
drawTexCoords.clear();
|
|
||||||
|
|
||||||
if (getActiveParticleCount() == 0) {
|
|
||||||
drawDataDirty = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<const SparkParticle*, float>> sortedParticles;
|
|
||||||
sortedParticles.reserve(getActiveParticleCount());
|
|
||||||
|
|
||||||
for (const auto& particle : particles) {
|
|
||||||
if (particle.active) {
|
|
||||||
sortedParticles.push_back({ &particle, particle.position.v[2] });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(sortedParticles.begin(), sortedParticles.end(),
|
|
||||||
[](const auto& a, const auto& b) {
|
|
||||||
return a.second > b.second;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const auto& [particlePtr, depth] : sortedParticles) {
|
|
||||||
const auto& particle = *particlePtr;
|
|
||||||
Vector3f pos = particle.position;
|
|
||||||
float size = 0.04f * particle.scale;
|
|
||||||
|
|
||||||
drawPositions.push_back({ pos.v[0] - size, pos.v[1] - size, pos.v[2] });
|
|
||||||
drawTexCoords.push_back({ 0.0f, 0.0f });
|
|
||||||
|
|
||||||
drawPositions.push_back({ pos.v[0] - size, pos.v[1] + size, pos.v[2] });
|
|
||||||
drawTexCoords.push_back({ 0.0f, 1.0f });
|
|
||||||
|
|
||||||
drawPositions.push_back({ pos.v[0] + size, pos.v[1] + size, pos.v[2] });
|
|
||||||
drawTexCoords.push_back({ 1.0f, 1.0f });
|
|
||||||
|
|
||||||
drawPositions.push_back({ pos.v[0] - size, pos.v[1] - size, pos.v[2] });
|
|
||||||
drawTexCoords.push_back({ 0.0f, 0.0f });
|
|
||||||
|
|
||||||
drawPositions.push_back({ pos.v[0] + size, pos.v[1] + size, pos.v[2] });
|
|
||||||
drawTexCoords.push_back({ 1.0f, 1.0f });
|
|
||||||
|
|
||||||
drawPositions.push_back({ pos.v[0] + size, pos.v[1] - size, pos.v[2] });
|
|
||||||
drawTexCoords.push_back({ 1.0f, 0.0f });
|
|
||||||
}
|
|
||||||
|
|
||||||
drawDataDirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight) {
|
|
||||||
if (getActiveParticleCount() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!texture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareDrawData();
|
|
||||||
|
|
||||||
if (drawPositions.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sparkQuad.data.PositionData = drawPositions;
|
|
||||||
sparkQuad.data.TexCoordData = drawTexCoords;
|
|
||||||
sparkQuad.RefreshVBO();
|
|
||||||
|
|
||||||
static const std::string defaultShaderName = "default";
|
|
||||||
static const std::string vPositionName = "vPosition";
|
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
|
||||||
static const std::string textureUniformName = "Texture";
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName);
|
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
|
||||||
|
|
||||||
float aspectRatio = static_cast<float>(screenWidth) / static_cast<float>(screenHeight);
|
|
||||||
renderer.PushPerspectiveProjectionMatrix(1.0 / 1.5, aspectRatio, Environment::CONST_Z_NEAR, Environment::CONST_Z_FAR);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
|
||||||
|
|
||||||
renderer.PushMatrix();
|
|
||||||
renderer.LoadIdentity();
|
|
||||||
renderer.TranslateMatrix({ 0, 0, -1.0f * zoom });
|
|
||||||
|
|
||||||
renderer.DrawVertexRenderStruct(sparkQuad);
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
|
||||||
renderer.PopProjectionMatrix();
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
|
||||||
renderer.shaderManager.PopShader();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::update(float deltaTimeMs) {
|
|
||||||
auto currentTime = std::chrono::steady_clock::now();
|
|
||||||
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
||||||
currentTime - lastEmissionTime).count();
|
|
||||||
|
|
||||||
if (isActive && elapsed >= emissionRate) {
|
|
||||||
emit();
|
|
||||||
lastEmissionTime = currentTime;
|
|
||||||
drawDataDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool anyChanged = false;
|
|
||||||
for (auto& particle : particles) {
|
|
||||||
if (particle.active) {
|
|
||||||
Vector3f oldPosition = particle.position;
|
|
||||||
float oldScale = particle.scale;
|
|
||||||
|
|
||||||
particle.position.v[0] += particle.velocity.v[0] * deltaTimeMs / 1000.0f;
|
|
||||||
particle.position.v[1] += particle.velocity.v[1] * deltaTimeMs / 1000.0f;
|
|
||||||
particle.position.v[2] += particle.velocity.v[2] * deltaTimeMs / 1000.0f;
|
|
||||||
|
|
||||||
particle.lifeTime += deltaTimeMs;
|
|
||||||
|
|
||||||
if (particle.lifeTime >= particle.maxLifeTime) {
|
|
||||||
particle.active = false;
|
|
||||||
anyChanged = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
float lifeRatio = particle.lifeTime / particle.maxLifeTime;
|
|
||||||
particle.scale = 1.0f - lifeRatio * 0.8f;
|
|
||||||
|
|
||||||
if (oldPosition.v[0] != particle.position.v[0] ||
|
|
||||||
oldPosition.v[1] != particle.position.v[1] ||
|
|
||||||
oldPosition.v[2] != particle.position.v[2] ||
|
|
||||||
oldScale != particle.scale) {
|
|
||||||
anyChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anyChanged) {
|
|
||||||
drawDataDirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::emit() {
|
|
||||||
if (emissionPoints.empty()) return;
|
|
||||||
bool emitted = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < emissionPoints.size(); ++i) {
|
|
||||||
bool particleFound = false;
|
|
||||||
|
|
||||||
for (auto& particle : particles) {
|
|
||||||
if (!particle.active) {
|
|
||||||
initParticle(particle, i);
|
|
||||||
particle.active = true;
|
|
||||||
particle.lifeTime = 0;
|
|
||||||
particle.position = emissionPoints[i];
|
|
||||||
particle.emitterIndex = i;
|
|
||||||
particleFound = true;
|
|
||||||
emitted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!particleFound && !particles.empty()) {
|
|
||||||
size_t oldestIndex = 0;
|
|
||||||
float maxLifeTime = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < particles.size(); ++j) {
|
|
||||||
if (particles[j].lifeTime > maxLifeTime) {
|
|
||||||
maxLifeTime = particles[j].lifeTime;
|
|
||||||
oldestIndex = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initParticle(particles[oldestIndex], i);
|
|
||||||
particles[oldestIndex].active = true;
|
|
||||||
particles[oldestIndex].lifeTime = 0;
|
|
||||||
particles[oldestIndex].position = emissionPoints[i];
|
|
||||||
particles[oldestIndex].emitterIndex = i;
|
|
||||||
emitted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (emitted) {
|
|
||||||
drawDataDirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::setEmissionPoints(const std::vector<Vector3f>& positions) {
|
|
||||||
emissionPoints = positions;
|
|
||||||
maxParticles = positions.size() * 100;
|
|
||||||
particles.resize(maxParticles);
|
|
||||||
drawDataDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SparkEmitter::initParticle(SparkParticle& particle, int emitterIndex) {
|
|
||||||
particle.velocity = getRandomVelocity(emitterIndex);
|
|
||||||
particle.scale = 1.0f;
|
|
||||||
particle.maxLifeTime = 800.0f + (rand() % 400);
|
|
||||||
particle.emitterIndex = emitterIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f SparkEmitter::getRandomVelocity(int emitterIndex) {
|
|
||||||
static std::random_device rd;
|
|
||||||
static std::mt19937 gen(rd());
|
|
||||||
static std::uniform_real_distribution<> angleDist(0, 2 * M_PI);
|
|
||||||
static std::uniform_real_distribution<> speedDist(0.5f, 2.0f);
|
|
||||||
static std::uniform_real_distribution<> zSpeedDist(1.0f, 3.0f);
|
|
||||||
|
|
||||||
float angle = angleDist(gen);
|
|
||||||
float speed = speedDist(gen);
|
|
||||||
float zSpeed = zSpeedDist(gen);
|
|
||||||
|
|
||||||
if (emitterIndex == 0) {
|
|
||||||
return Vector3f{
|
|
||||||
cosf(angle) * speed - 0.3f,
|
|
||||||
sinf(angle) * speed,
|
|
||||||
zSpeed
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return Vector3f{
|
|
||||||
cosf(angle) * speed + 0.3f,
|
|
||||||
sinf(angle) * speed,
|
|
||||||
zSpeed
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<SparkParticle>& SparkEmitter::getParticles() const {
|
|
||||||
return particles;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SparkEmitter::getActiveParticleCount() const {
|
|
||||||
size_t count = 0;
|
|
||||||
for (const auto& particle : particles) {
|
|
||||||
if (particle.active) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZL
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ZLMath.h"
|
|
||||||
#include "Renderer.h"
|
|
||||||
#include "TextureManager.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
namespace ZL {
|
|
||||||
|
|
||||||
struct SparkParticle {
|
|
||||||
Vector3f position;
|
|
||||||
Vector3f velocity;
|
|
||||||
float scale;
|
|
||||||
float lifeTime;
|
|
||||||
float maxLifeTime;
|
|
||||||
bool active;
|
|
||||||
int emitterIndex;
|
|
||||||
|
|
||||||
SparkParticle() : position({ 0,0,0 }), velocity({ 0,0,0 }), scale(1.0f),
|
|
||||||
lifeTime(0), maxLifeTime(1000.0f), active(false), emitterIndex(0) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SparkEmitter {
|
|
||||||
private:
|
|
||||||
std::vector<SparkParticle> particles;
|
|
||||||
std::vector<Vector3f> emissionPoints;
|
|
||||||
std::chrono::steady_clock::time_point lastEmissionTime;
|
|
||||||
float emissionRate;
|
|
||||||
bool isActive;
|
|
||||||
|
|
||||||
std::vector<Vector3f> drawPositions;
|
|
||||||
std::vector<Vector2f> drawTexCoords;
|
|
||||||
bool drawDataDirty;
|
|
||||||
VertexRenderStruct sparkQuad;
|
|
||||||
std::shared_ptr<Texture> texture;
|
|
||||||
|
|
||||||
int maxParticles;
|
|
||||||
|
|
||||||
void prepareDrawData();
|
|
||||||
|
|
||||||
public:
|
|
||||||
SparkEmitter();
|
|
||||||
SparkEmitter(const std::vector<Vector3f>& positions, float rate = 100.0f);
|
|
||||||
SparkEmitter(const std::vector<Vector3f>& positions,
|
|
||||||
std::shared_ptr<Texture> tex,
|
|
||||||
float rate = 100.0f);
|
|
||||||
|
|
||||||
void setEmissionPoints(const std::vector<Vector3f>& positions);
|
|
||||||
void setTexture(std::shared_ptr<Texture> tex);
|
|
||||||
|
|
||||||
void update(float deltaTimeMs);
|
|
||||||
void emit();
|
|
||||||
|
|
||||||
void draw(Renderer& renderer, float zoom, int screenWidth, int screenHeight);
|
|
||||||
|
|
||||||
const std::vector<SparkParticle>& getParticles() const;
|
|
||||||
size_t getActiveParticleCount() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initParticle(SparkParticle& particle, int emitterIndex);
|
|
||||||
Vector3f getRandomVelocity(int emitterIndex);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ZL
|
|
||||||
@ -2,7 +2,6 @@
|
|||||||
#ifdef PNG_ENABLED
|
#ifdef PNG_ENABLED
|
||||||
#include "png.h"
|
#include "png.h"
|
||||||
#endif
|
#endif
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
@ -47,85 +46,6 @@ namespace ZL
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(const std::array<TextureDataStruct, 6>& texDataArray)
|
|
||||||
{
|
|
||||||
// Ïðîâåðêà, ÷òî âñå ãðàíè èìåþò îäèíàêîâûå ðàçìåðû
|
|
||||||
width = texDataArray[0].width;
|
|
||||||
height = texDataArray[0].height;
|
|
||||||
|
|
||||||
for (size_t i = 1; i < 6; ++i) {
|
|
||||||
if (texDataArray[i].width != width || texDataArray[i].height != height) {
|
|
||||||
throw std::runtime_error("Cubemap faces must have the same dimensions");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glGenTextures(1, &texID);
|
|
||||||
|
|
||||||
if (texID == 0)
|
|
||||||
{
|
|
||||||
throw std::runtime_error("glGenTextures did not work for cubemap");
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, texID);
|
|
||||||
|
|
||||||
CheckGlError();
|
|
||||||
|
|
||||||
// Íàñòðîéêà ïàðàìåòðîâ äëÿ Cubemap
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
// Èñïîëüçóåì GL_LINEAR äëÿ MIN_FILTER, òàê êàê ìèïìàïû çäåñü íå ãåíåðèðóþòñÿ
|
|
||||||
// Åñëè áû èñïîëüçîâàëèñü ìèïìàïû (e.g., GL_LINEAR_MIPMAP_LINEAR), íóæíî áûëî áû âûçâàòü glGenerateMipmap.
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
|
|
||||||
// Îáÿçàòåëüíûå ïàðàìåòðû îáåðòêè äëÿ Cubemap
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
|
|
||||||
// GL_TEXTURE_WRAP_R íå ïîääåðæèâàåòñÿ â WebGL 1.0/OpenGL ES 2.0 è âûçûâàåò îøèáêó.
|
|
||||||
// Îãðàíè÷èâàåì åãî âûçîâ òîëüêî äëÿ íàñòîëüíûõ ïëàòôîðì.
|
|
||||||
#ifndef EMSCRIPTEN
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CheckGlError(); // Ïðîâåðêà ïîñëå óñòàíîâêè ïàðàìåòðîâ
|
|
||||||
|
|
||||||
// Çàãðóçêà äàííûõ äëÿ êàæäîé èç 6 ãðàíåé
|
|
||||||
// GL_TEXTURE_CUBE_MAP_POSITIVE_X + i äàåò ãðàíè: +X (0), -X (1), +Y (2), -Y (3), +Z (4), -Z (5)
|
|
||||||
for (int i = 0; i < 6; ++i)
|
|
||||||
{
|
|
||||||
GLint internalFormat;
|
|
||||||
GLenum format;
|
|
||||||
|
|
||||||
// Â WebGL 1.0/OpenGL ES 2.0 âíóòðåííèé ôîðìàò (internalFormat)
|
|
||||||
// äîëæåí ñòðîãî ñîîòâåòñòâîâàòü ôîðìàòó äàííûõ (format).
|
|
||||||
if (texDataArray[i].bitSize == TextureDataStruct::BS_24BIT)
|
|
||||||
{
|
|
||||||
internalFormat = GL_RGB; // internalFormat
|
|
||||||
format = GL_RGB; // format
|
|
||||||
}
|
|
||||||
else // BS_32BIT
|
|
||||||
{
|
|
||||||
internalFormat = GL_RGBA; // internalFormat
|
|
||||||
format = GL_RGBA; // format
|
|
||||||
}
|
|
||||||
|
|
||||||
glTexImage2D(
|
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, // Öåëåâàÿ ãðàíü
|
|
||||||
0, // Óðîâåíü MIP-òåêñòóðû
|
|
||||||
internalFormat, // Âíóòðåííèé ôîðìàò (äîëæåí ñîâïàäàòü ñ ôîðìàòîì)
|
|
||||||
static_cast<GLsizei>(width),
|
|
||||||
static_cast<GLsizei>(height),
|
|
||||||
0, // Ãðàíèöà (âñåãäà 0)
|
|
||||||
format, // Ôîðìàò èñõîäíûõ äàííûõ
|
|
||||||
GL_UNSIGNED_BYTE, // Òèï äàííûõ
|
|
||||||
texDataArray[i].data.data() // Óêàçàòåëü íà äàííûå
|
|
||||||
);
|
|
||||||
CheckGlError();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ñíèìàåì ïðèâÿçêó äëÿ ÷èñòîòû
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &texID);
|
glDeleteTextures(1, &texID);
|
||||||
@ -250,84 +170,36 @@ namespace ZL
|
|||||||
|
|
||||||
#ifdef PNG_ENABLED
|
#ifdef PNG_ENABLED
|
||||||
|
|
||||||
// Ñòðóêòóðà äëÿ õðàíåíèÿ äàííûõ î ôàéëå/ìàññèâå è òåêóùåé ïîçèöèè ÷òåíèÿ
|
TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName)
|
||||||
struct png_data_t {
|
|
||||||
const char* data;
|
|
||||||
size_t size;
|
|
||||||
size_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ïîëüçîâàòåëüñêàÿ ôóíêöèÿ ÷òåíèÿ äëÿ libpng
|
|
||||||
// 'png_ptr' - óêàçàòåëü íà ñòðóêòóðó png
|
|
||||||
// 'out_ptr' - êóäà çàïèñûâàòü ïðî÷èòàííûå äàííûå
|
|
||||||
// 'bytes_to_read' - ñêîëüêî áàéò íóæíî ïðî÷èòàòü
|
|
||||||
void user_read_data(png_structp png_ptr, png_bytep out_ptr, png_size_t bytes_to_read) {
|
|
||||||
// Ïîëó÷àåì óêàçàòåëü íà íàøó ñòðóêòóðó png_data_t, êîòîðóþ ìû óñòàíîâèëè ñ ïîìîùüþ png_set_read_fn
|
|
||||||
png_data_t* data = (png_data_t*)png_get_io_ptr(png_ptr);
|
|
||||||
|
|
||||||
if (data->offset + bytes_to_read > data->size) {
|
|
||||||
// Ïîïûòêà ïðî÷èòàòü áîëüøå, ÷åì åñòü â ìàññèâå.
|
|
||||||
// Âìåñòî âûçîâà ñòàíäàðòíîé îøèáêè, ìû ìîæåì ïðîñòî ïðî÷èòàòü îñòàòîê èëè âûçâàòü îøèáêó.
|
|
||||||
//  ýòîì ñëó÷àå ìû âûçîâåì îøèáêó libpng.
|
|
||||||
png_error(png_ptr, "PNG Read Error: Attempted to read past end of data buffer.");
|
|
||||||
bytes_to_read = data->size - data->offset; // Óñòàíàâëèâàåì, ÷òîáû ïðî÷èòàòü îñòàâøååñÿ
|
|
||||||
}
|
|
||||||
|
|
||||||
// Êîïèðóåì äàííûå èç íàøåãî ìàññèâà â áóôåð libpng
|
|
||||||
std::memcpy(out_ptr, data->data + data->offset, bytes_to_read);
|
|
||||||
|
|
||||||
// Îáíîâëÿåì ñìåùåíèå
|
|
||||||
data->offset += bytes_to_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ïîëüçîâàòåëüñêàÿ ôóíêöèÿ ïðåäóïðåæäåíèé (ïî æåëàíèþ, ìîæíî èñïîëüçîâàòü nullptr)
|
|
||||||
void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) {
|
|
||||||
// Çäåñü ìîæíî ðåàëèçîâàòü ëîãèðîâàíèå ïðåäóïðåæäåíèé
|
|
||||||
//throw std::runtime_error();
|
|
||||||
std::cout << "PNG Warning: " << warning_msg << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ïîëüçîâàòåëüñêàÿ ôóíêöèÿ îøèáîê (îáÿçàòåëüíà äëÿ setjmp)
|
|
||||||
void user_error_fn(png_structp png_ptr, png_const_charp error_msg) {
|
|
||||||
// Çäåñü ìîæíî ðåàëèçîâàòü ëîãèðîâàíèå îøèáîê
|
|
||||||
std::cout << "PNG Error: " << error_msg << std::endl;
|
|
||||||
// Îáÿçàòåëüíî âûçûâàåì longjmp äëÿ âûõîäà èç ïðîöåññà ÷òåíèÿ/çàïèñè PNG
|
|
||||||
longjmp(png_jmpbuf(png_ptr), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureDataStruct CreateTextureDataFromPng(const std::vector<char>& fileArr)
|
|
||||||
{
|
{
|
||||||
TextureDataStruct texData;
|
TextureDataStruct texData;
|
||||||
|
|
||||||
// Ñòðóêòóðà äëÿ óïðàâëåíèÿ ÷òåíèåì èç ìàññèâà
|
FILE* file = fopen(fullFileName.c_str(), "rb");
|
||||||
png_data_t png_data = { fileArr.data(), fileArr.size(), 0 };
|
if (!file) {
|
||||||
|
fclose(file);
|
||||||
|
throw std::runtime_error("Could not open file " + fullFileName);
|
||||||
|
}
|
||||||
|
|
||||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||||
if (!png) {
|
if (!png) {
|
||||||
|
fclose(file);
|
||||||
throw std::runtime_error("Could not create PNG read structure");
|
throw std::runtime_error("Could not create PNG read structure");
|
||||||
}
|
}
|
||||||
|
|
||||||
png_infop info = png_create_info_struct(png);
|
png_infop info = png_create_info_struct(png);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
|
fclose(file);
|
||||||
png_destroy_read_struct(&png, nullptr, nullptr);
|
png_destroy_read_struct(&png, nullptr, nullptr);
|
||||||
throw std::runtime_error("Could not create PNG info structure");
|
throw std::runtime_error("Could not create PNG info structure");
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Óñòàíîâêà ïîëüçîâàòåëüñêèõ ôóíêöèé ÷òåíèÿ è îáðàáîòêè îøèáîê ===
|
|
||||||
// 1. Óñòàíîâêà îáðàáîò÷èêà îøèáîê è longjmp
|
|
||||||
if (setjmp(png_jmpbuf(png))) {
|
if (setjmp(png_jmpbuf(png))) {
|
||||||
png_destroy_read_struct(&png, &info, nullptr);
|
png_destroy_read_struct(&png, &info, nullptr);
|
||||||
throw std::runtime_error("Error during PNG read (longjmp was executed)");
|
fclose(file);
|
||||||
|
throw std::runtime_error("Error during PNG read");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Óñòàíîâêà ïîëüçîâàòåëüñêèõ ôóíêöèé äëÿ îáðàáîòêè îøèáîê è ïðåäóïðåæäåíèé
|
png_init_io(png, file);
|
||||||
// Âìåñòî nullptr â error_ptr è warning_ptr ìîæíî ïåðåäàòü óêàçàòåëü íà ñâîþ ñòðóêòóðó äàííûõ, åñëè íåîáõîäèìî
|
|
||||||
png_set_error_fn(png, nullptr, user_error_fn, user_warning_fn);
|
|
||||||
|
|
||||||
// 3. Óñòàíîâêà ïîëüçîâàòåëüñêîé ôóíêöèè ÷òåíèÿ è ïåðåäà÷à åé íàøåé ñòðóêòóðû png_data
|
|
||||||
png_set_read_fn(png, &png_data, user_read_data);
|
|
||||||
// ===================================================================
|
|
||||||
|
|
||||||
png_read_info(png, info);
|
png_read_info(png, info);
|
||||||
|
|
||||||
texData.width = png_get_image_width(png, info);
|
texData.width = png_get_image_width(png, info);
|
||||||
@ -335,7 +207,6 @@ namespace ZL
|
|||||||
png_byte color_type = png_get_color_type(png, info);
|
png_byte color_type = png_get_color_type(png, info);
|
||||||
png_byte bit_depth = png_get_bit_depth(png, info);
|
png_byte bit_depth = png_get_bit_depth(png, info);
|
||||||
|
|
||||||
// === Áëîê ïðåîáðàçîâàíèé (îñòàâëåí áåç èçìåíåíèé) ===
|
|
||||||
if (bit_depth == 16)
|
if (bit_depth == 16)
|
||||||
png_set_strip_16(png);
|
png_set_strip_16(png);
|
||||||
|
|
||||||
@ -358,9 +229,8 @@ namespace ZL
|
|||||||
png_set_gray_to_rgb(png);
|
png_set_gray_to_rgb(png);
|
||||||
|
|
||||||
png_read_update_info(png, info);
|
png_read_update_info(png, info);
|
||||||
// ====================================================
|
|
||||||
|
|
||||||
// === ×òåíèå ïèêñåëåé (îñòàâëåí áåç èçìåíåíèé) ===
|
|
||||||
png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * texData.height);
|
png_bytep* row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * texData.height);
|
||||||
for (int y = 0; y < texData.height; y++) {
|
for (int y = 0; y < texData.height; y++) {
|
||||||
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
|
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info));
|
||||||
@ -368,6 +238,8 @@ namespace ZL
|
|||||||
|
|
||||||
png_read_image(png, row_pointers);
|
png_read_image(png, row_pointers);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
bool has_alpha = (color_type & PNG_COLOR_MASK_ALPHA) || (png_get_valid(png, info, PNG_INFO_tRNS));
|
bool has_alpha = (color_type & PNG_COLOR_MASK_ALPHA) || (png_get_valid(png, info, PNG_INFO_tRNS));
|
||||||
|
|
||||||
size_t dataSize;
|
size_t dataSize;
|
||||||
@ -387,7 +259,9 @@ namespace ZL
|
|||||||
texData.data.resize(dataSize);
|
texData.data.resize(dataSize);
|
||||||
|
|
||||||
|
|
||||||
for (int y = texData.height - 1; y >= 0; y--) {
|
//for (int y = 0; y < texData.height; y++) { //Go in reverse because of UV coord start point
|
||||||
|
for (int y = texData.height-1; y >= 0; y--) {
|
||||||
|
//png_bytep row = row_pointers[y];//Go in reverse because of UV coord start point
|
||||||
png_bytep row = row_pointers[texData.height - 1 - y];
|
png_bytep row = row_pointers[texData.height - 1 - y];
|
||||||
for (int x = 0; x < texData.width; x++) {
|
for (int x = 0; x < texData.width; x++) {
|
||||||
png_bytep px = &(row[x * 4]);
|
png_bytep px = &(row[x * 4]);
|
||||||
@ -398,33 +272,14 @@ namespace ZL
|
|||||||
texData.data[(y * texData.width + x) * channels + 3] = px[3]; // A
|
texData.data[(y * texData.width + x) * channels + 3] = px[3]; // A
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(row_pointers[texData.height - 1 - y]);
|
//free(row_pointers[y]);//Go in reverse because of UV coord start point
|
||||||
|
free(row_pointers[texData.height - 1 - y]);//Go in reverse because of UV coord start point
|
||||||
}
|
}
|
||||||
free(row_pointers);
|
free(row_pointers);
|
||||||
// ==================================================
|
|
||||||
|
|
||||||
png_destroy_read_struct(&png, &info, nullptr);
|
png_destroy_read_struct(&png, &info, nullptr);
|
||||||
|
|
||||||
return texData;
|
return texData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName, const std::string& ZIPFileName)
|
|
||||||
{
|
|
||||||
std::vector<char> fileArr;
|
|
||||||
|
|
||||||
fileArr = !ZIPFileName.empty() ? readFileFromZIP(fullFileName, ZIPFileName) : readFile(fullFileName);
|
|
||||||
|
|
||||||
if (fileArr.empty()) {
|
|
||||||
throw std::runtime_error("Could not read file data into memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Âûçûâàåì íîâóþ ôóíêöèþ, êîòîðàÿ ðàáîòàåò ñ ìàññèâîì áàéò
|
|
||||||
return CreateTextureDataFromPng(fileArr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3,10 +3,6 @@
|
|||||||
#include "OpenGlExtensions.h"
|
#include "OpenGlExtensions.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
|
||||||
#define PNG_ENABLED
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -33,9 +29,6 @@ namespace ZL
|
|||||||
|
|
||||||
Texture(const TextureDataStruct& texData);
|
Texture(const TextureDataStruct& texData);
|
||||||
|
|
||||||
//Cubemap texture:
|
|
||||||
Texture(const std::array<TextureDataStruct, 6>& texDataArray);
|
|
||||||
|
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
GLuint getTexID();
|
GLuint getTexID();
|
||||||
@ -49,8 +42,6 @@ namespace ZL
|
|||||||
TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName, const std::string& ZIPFileName="");
|
TextureDataStruct CreateTextureDataFromBmp24(const std::string& fullFileName, const std::string& ZIPFileName="");
|
||||||
TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName, const std::string& ZIPFileName="");
|
TextureDataStruct CreateTextureDataFromBmp32(const std::string& fullFileName, const std::string& ZIPFileName="");
|
||||||
#ifdef PNG_ENABLED
|
#ifdef PNG_ENABLED
|
||||||
TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName, const std::string& ZIPFileName = "");
|
TextureDataStruct CreateTextureDataFromPng(const std::string& fullFileName);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
Utils.cpp
11
Utils.cpp
@ -5,9 +5,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#ifdef EMSCRIPTEN
|
//#include <zip.h>
|
||||||
#include <zip.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
@ -44,8 +42,7 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> readFileFromZIP(const std::string& filename, const std::string& zipfilename) {
|
std::vector<char> readFileFromZIP(const std::string& filename, const std::string& zipfilename) {
|
||||||
#ifdef EMSCRIPTEN
|
/*const std::string zipPath = zipfilename;
|
||||||
const std::string zipPath = zipfilename;
|
|
||||||
int zipErr;
|
int zipErr;
|
||||||
zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr);
|
zip_t* archive = zip_open(zipPath.c_str(), ZIP_RDONLY, &zipErr);
|
||||||
if (!archive) {
|
if (!archive) {
|
||||||
@ -80,10 +77,8 @@ namespace ZL
|
|||||||
zip_fclose(zipFile);
|
zip_fclose(zipFile);
|
||||||
zip_close(archive);
|
zip_close(archive);
|
||||||
|
|
||||||
return fileData;
|
return fileData;*/
|
||||||
#else
|
|
||||||
return {};
|
return {};
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findString(const char* in, char* list)
|
bool findString(const char* in, char* list)
|
||||||
|
|||||||
61
ZLMath.h
Executable file → Normal file
61
ZLMath.h
Executable file → Normal file
@ -31,68 +31,11 @@ namespace ZL {
|
|||||||
struct Vector3f
|
struct Vector3f
|
||||||
{
|
{
|
||||||
std::array<float, 3> v = { 0.f, 0.f, 0.f };
|
std::array<float, 3> v = { 0.f, 0.f, 0.f };
|
||||||
|
|
||||||
Vector3f()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f(float x, float y, float z)
|
|
||||||
: v{x,y,z}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f normalized() const {
|
|
||||||
double norm = std::sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
|
||||||
Vector3f r;
|
|
||||||
|
|
||||||
r.v[0] = v[0] / norm;
|
|
||||||
r.v[1] = v[1] / norm;
|
|
||||||
r.v[2] = v[2] / norm;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
float squaredNorm() const {
|
|
||||||
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
float length() const
|
|
||||||
{
|
|
||||||
return sqrt(squaredNorm());
|
|
||||||
}
|
|
||||||
|
|
||||||
float dot(const Vector3f& other) const {
|
|
||||||
return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3f cross(const Vector3f& other) const {
|
|
||||||
return Vector3f(
|
|
||||||
v[1] * other.v[2] - v[2] * other.v[1],
|
|
||||||
v[2] * other.v[0] - v[0] * other.v[2],
|
|
||||||
v[0] * other.v[1] - v[1] * other.v[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Îïåðàòîð âû÷èòàíèÿ
|
|
||||||
/*Vector3f operator-(const Vector3f& other) const {
|
|
||||||
return Vector3f(v[0] - other.v[0], v[1] - other.v[1], v[2] - other.v[2]);
|
|
||||||
}*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Vector2f
|
struct Vector2f
|
||||||
{
|
{
|
||||||
std::array<float, 2> v = {0.f, 0.f};
|
std::array<float, 2> v = {0.f, 0.f};
|
||||||
|
|
||||||
Vector2f()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2f(float x, float y)
|
|
||||||
: v{ x,y }
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector2f operator+(const Vector2f& x, const Vector2f& y);
|
Vector2f operator+(const Vector2f& x, const Vector2f& y);
|
||||||
@ -106,8 +49,6 @@ namespace ZL {
|
|||||||
|
|
||||||
Vector4f operator-(const Vector4f& x, const Vector4f& y);
|
Vector4f operator-(const Vector4f& x, const Vector4f& y);
|
||||||
|
|
||||||
Vector3f operator-(const Vector3f& x);
|
|
||||||
|
|
||||||
|
|
||||||
struct Matrix3f
|
struct Matrix3f
|
||||||
{
|
{
|
||||||
@ -158,7 +99,6 @@ namespace ZL {
|
|||||||
Vector3f MultVectorMatrix(Vector3f v, Matrix3f mt);
|
Vector3f MultVectorMatrix(Vector3f v, Matrix3f mt);
|
||||||
Vector4f MultVectorMatrix(Vector4f v, Matrix4f mt);
|
Vector4f MultVectorMatrix(Vector4f v, Matrix4f mt);
|
||||||
Vector4f MultMatrixVector(Matrix4f mt, Vector4f v);
|
Vector4f MultMatrixVector(Matrix4f mt, Vector4f v);
|
||||||
Vector3f MultMatrixVector(Matrix3f mt, Vector3f v);
|
|
||||||
|
|
||||||
Vector4f slerp(const Vector4f& q1, const Vector4f& q2, float t);
|
Vector4f slerp(const Vector4f& q1, const Vector4f& q2, float t);
|
||||||
Matrix3f InverseMatrix(const Matrix3f& m);
|
Matrix3f InverseMatrix(const Matrix3f& m);
|
||||||
@ -168,3 +108,4 @@ namespace ZL {
|
|||||||
Matrix4f MakeMatrix4x4(const Matrix3f& m, const Vector3f pos);
|
Matrix4f MakeMatrix4x4(const Matrix3f& m, const Vector3f pos);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,86 +0,0 @@
|
|||||||
import bpy
|
|
||||||
import bmesh
|
|
||||||
|
|
||||||
mesh_name = "chassis_low"
|
|
||||||
output_path = "C:\\Work\\Projects\\space-game001\\blender scripts\\output\\spaceship005.txt"
|
|
||||||
|
|
||||||
mesh_obj = bpy.data.objects.get(mesh_name)
|
|
||||||
|
|
||||||
if mesh_obj and mesh_obj.type == 'MESH':
|
|
||||||
# Обязательно применяем трансформации, чтобы координаты были актуальными
|
|
||||||
# Но для чистоты эксперимента берем mesh data как есть
|
|
||||||
|
|
||||||
# Работаем с копией меша, чтобы применить триангуляцию (если нужно)
|
|
||||||
# и не испортить сцену, но пока используем bmesh напрямую
|
|
||||||
bm = bmesh.new()
|
|
||||||
bm.from_mesh(mesh_obj.data)
|
|
||||||
|
|
||||||
# Получаем слой UV
|
|
||||||
uv_layer = bm.loops.layers.uv.active
|
|
||||||
|
|
||||||
# Словарь для хранения уникальных вершин:
|
|
||||||
# Ключ: (x, y, z, nx, ny, nz, u, v) -> Значение: новый_индекс
|
|
||||||
unique_verts_map = {}
|
|
||||||
final_vertices = [] # Список для записи в файл
|
|
||||||
final_indices = [] # Список индексов треугольников
|
|
||||||
|
|
||||||
# Проходим по всем фейсам
|
|
||||||
for face in bm.faces:
|
|
||||||
face_indices = []
|
|
||||||
|
|
||||||
# Проходим по углам (loops) фейса
|
|
||||||
for loop in face.loops:
|
|
||||||
vert = loop.vert
|
|
||||||
|
|
||||||
# 1. Координаты (округляем для надежности сравнения float)
|
|
||||||
co = (round(vert.co.x, 6), round(vert.co.y, 6), round(vert.co.z, 6))
|
|
||||||
|
|
||||||
# 2. Нормаль (если используете Smooth shading, берите vert.normal, если Flat - face.normal)
|
|
||||||
# Для простоты берем нормаль вершины
|
|
||||||
no = (round(vert.normal.x, 6), round(vert.normal.y, 6), round(vert.normal.z, 6))
|
|
||||||
|
|
||||||
# 3. UV координаты
|
|
||||||
if uv_layer:
|
|
||||||
raw_uv = loop[uv_layer].uv
|
|
||||||
uv = (round(raw_uv.x, 6), round(raw_uv.y, 6))
|
|
||||||
else:
|
|
||||||
uv = (0.0, 0.0)
|
|
||||||
|
|
||||||
# Собираем уникальный ключ данных вершины
|
|
||||||
vert_data_key = (co, no, uv)
|
|
||||||
|
|
||||||
# Проверяем, есть ли такая комбинация уже
|
|
||||||
if vert_data_key in unique_verts_map:
|
|
||||||
index = unique_verts_map[vert_data_key]
|
|
||||||
else:
|
|
||||||
index = len(final_vertices)
|
|
||||||
unique_verts_map[vert_data_key] = index
|
|
||||||
final_vertices.append(vert_data_key)
|
|
||||||
|
|
||||||
face_indices.append(index)
|
|
||||||
|
|
||||||
# Триангуляция "на лету" (если фейс - квадрат, делим на два треугольника)
|
|
||||||
# Простейший метод fan (0, 1, 2), (0, 2, 3)...
|
|
||||||
for i in range(1, len(face_indices) - 1):
|
|
||||||
final_indices.append(face_indices[0])
|
|
||||||
final_indices.append(face_indices[i])
|
|
||||||
final_indices.append(face_indices[i+1])
|
|
||||||
|
|
||||||
# --- ЗАПИСЬ В ФАЙЛ ---
|
|
||||||
with open(output_path, "w") as file:
|
|
||||||
file.write(f"===Vertices (Split by UV/Normal): {len(final_vertices)}\n")
|
|
||||||
# Формат строки: ID: X Y Z | NX NY NZ | U V
|
|
||||||
for idx, v_data in enumerate(final_vertices):
|
|
||||||
co, no, uv = v_data
|
|
||||||
file.write(f"V {idx}: Pos({co[0]}, {co[1]}, {co[2]}) Norm({no[0]}, {no[1]}, {no[2]}) UV({uv[0]}, {uv[1]})\n")
|
|
||||||
|
|
||||||
file.write(f"\n===Triangles (Indices): {len(final_indices) // 3}\n")
|
|
||||||
# Записываем тройками
|
|
||||||
for i in range(0, len(final_indices), 3):
|
|
||||||
file.write(f"Tri: {final_indices[i]} {final_indices[i+1]} {final_indices[i+2]}\n")
|
|
||||||
|
|
||||||
bm.free()
|
|
||||||
print(f"Export done. Original verts: {len(mesh_obj.data.vertices)}, Split verts: {len(final_vertices)}")
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("Mesh not found")
|
|
||||||
10
main.cpp
10
main.cpp
@ -1,14 +1,10 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "Environment.h"
|
#include "Environment.h"
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
ZL::Game game;
|
ZL::Game game;
|
||||||
void MainLoop() {
|
void MainLoop() {
|
||||||
game.update();
|
game.update();
|
||||||
}
|
}
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
try
|
|
||||||
{
|
|
||||||
constexpr int CONST_WIDTH = 1280;
|
constexpr int CONST_WIDTH = 1280;
|
||||||
constexpr int CONST_HEIGHT = 720;
|
constexpr int CONST_HEIGHT = 720;
|
||||||
|
|
||||||
@ -78,11 +74,5 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
std::cout << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
resources/DefaultMaterial_BaseColor.png
(Stored with Git LFS)
BIN
resources/DefaultMaterial_BaseColor.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/box/box.png
(Stored with Git LFS)
BIN
resources/box/box.png
(Stored with Git LFS)
Binary file not shown.
@ -1,29 +0,0 @@
|
|||||||
===Vertices (Split by UV/Normal): 14
|
|
||||||
V 0: Pos(1.0, 1.0, 1.0) Norm(0.57735, 0.57735, 0.57735) UV(0.5, 0.5)
|
|
||||||
V 1: Pos(-1.0, 1.0, 1.0) Norm(-0.57735, 0.57735, 0.57735) UV(0.75, 0.5)
|
|
||||||
V 2: Pos(-1.0, -1.0, 1.0) Norm(-0.57735, -0.57735, 0.57735) UV(0.75, 0.75)
|
|
||||||
V 3: Pos(1.0, -1.0, 1.0) Norm(0.57735, -0.57735, 0.57735) UV(0.5, 0.75)
|
|
||||||
V 4: Pos(1.0, -1.0, -1.0) Norm(0.57735, -0.57735, -0.57735) UV(0.25, 0.75)
|
|
||||||
V 5: Pos(-1.0, -1.0, 1.0) Norm(-0.57735, -0.57735, 0.57735) UV(0.5, 1.0)
|
|
||||||
V 6: Pos(-1.0, -1.0, -1.0) Norm(-0.57735, -0.57735, -0.57735) UV(0.25, 1.0)
|
|
||||||
V 7: Pos(-1.0, -1.0, -1.0) Norm(-0.57735, -0.57735, -0.57735) UV(0.25, 0.0)
|
|
||||||
V 8: Pos(-1.0, -1.0, 1.0) Norm(-0.57735, -0.57735, 0.57735) UV(0.5, 0.0)
|
|
||||||
V 9: Pos(-1.0, 1.0, 1.0) Norm(-0.57735, 0.57735, 0.57735) UV(0.5, 0.25)
|
|
||||||
V 10: Pos(-1.0, 1.0, -1.0) Norm(-0.57735, 0.57735, -0.57735) UV(0.25, 0.25)
|
|
||||||
V 11: Pos(-1.0, 1.0, -1.0) Norm(-0.57735, 0.57735, -0.57735) UV(0.0, 0.5)
|
|
||||||
V 12: Pos(1.0, 1.0, -1.0) Norm(0.57735, 0.57735, -0.57735) UV(0.25, 0.5)
|
|
||||||
V 13: Pos(-1.0, -1.0, -1.0) Norm(-0.57735, -0.57735, -0.57735) UV(0.0, 0.75)
|
|
||||||
|
|
||||||
===Triangles (Indices): 12
|
|
||||||
Tri: 0 1 2
|
|
||||||
Tri: 0 2 3
|
|
||||||
Tri: 4 3 5
|
|
||||||
Tri: 4 5 6
|
|
||||||
Tri: 7 8 9
|
|
||||||
Tri: 7 9 10
|
|
||||||
Tri: 11 12 4
|
|
||||||
Tri: 11 4 13
|
|
||||||
Tri: 12 0 3
|
|
||||||
Tri: 12 3 4
|
|
||||||
Tri: 10 9 0
|
|
||||||
Tri: 10 0 12
|
|
||||||
BIN
resources/button.png
(Stored with Git LFS)
BIN
resources/button.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/musicVolumeBarButton.png
(Stored with Git LFS)
BIN
resources/musicVolumeBarButton.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/musicVolumeBarTexture.png
(Stored with Git LFS)
BIN
resources/musicVolumeBarTexture.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/rock.png
(Stored with Git LFS)
BIN
resources/rock.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sand.png
(Stored with Git LFS)
BIN
resources/sand.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sky/space_bk.bmp
(Stored with Git LFS)
BIN
resources/sky/space_bk.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sky/space_dn.bmp
(Stored with Git LFS)
BIN
resources/sky/space_dn.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sky/space_ft.bmp
(Stored with Git LFS)
BIN
resources/sky/space_ft.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sky/space_lf.bmp
(Stored with Git LFS)
BIN
resources/sky/space_lf.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sky/space_rt.bmp
(Stored with Git LFS)
BIN
resources/sky/space_rt.bmp
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sky/space_up.bmp
(Stored with Git LFS)
BIN
resources/sky/space_up.bmp
(Stored with Git LFS)
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
resources/spark.png
(Stored with Git LFS)
BIN
resources/spark.png
(Stored with Git LFS)
Binary file not shown.
BIN
resources/sship001.png
Normal file
BIN
resources/sship001.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 653 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 599 KiB |
@ -1,48 +0,0 @@
|
|||||||
// Фрагментный шейдер:
|
|
||||||
uniform vec3 uColor;
|
|
||||||
uniform float uDistanceToPlanetSurface; // Расстояние корабля до поверхности
|
|
||||||
|
|
||||||
// Константы затухания, определенные прямо в шейдере
|
|
||||||
const float DIST_FOG_MAX = 2000.0;
|
|
||||||
const float DIST_FOG_MIN = 1000.0;
|
|
||||||
|
|
||||||
varying vec3 vViewNormal;
|
|
||||||
varying vec3 vViewPosition;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
// --- 1. Расчет плотности по Френелю (краевой эффект) ---
|
|
||||||
vec3 viewVector = normalize(-vViewPosition);
|
|
||||||
float NdotV = dot(vViewNormal, viewVector);
|
|
||||||
float factor = 1.0 - abs(NdotV);
|
|
||||||
float atmosphereDensity = pow(factor, 5.0);
|
|
||||||
|
|
||||||
// --- 2. Расчет коэффициента затухания по дистанции ---
|
|
||||||
|
|
||||||
float distanceFactor = 1.0;
|
|
||||||
|
|
||||||
if (uDistanceToPlanetSurface > DIST_FOG_MAX)
|
|
||||||
{
|
|
||||||
// Дистанция > 2000.0: Полностью видно (Factor = 1.0)
|
|
||||||
distanceFactor = 1.0;
|
|
||||||
}
|
|
||||||
else if (uDistanceToPlanetSurface < DIST_FOG_MIN)
|
|
||||||
{
|
|
||||||
// Дистанция < 1000.0: Полностью не видно (Factor = 0.0)
|
|
||||||
distanceFactor = 0.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Плавный переход (линейная интерполяция)
|
|
||||||
// normalizedDistance: от 0.0 (на DIST_FOG_MIN) до 1.0 (на DIST_FOG_MAX)
|
|
||||||
float normalizedDistance = (uDistanceToPlanetSurface - DIST_FOG_MIN) / (DIST_FOG_MAX - DIST_FOG_MIN);
|
|
||||||
|
|
||||||
distanceFactor = clamp(normalizedDistance, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 3. Финальный цвет и прозрачность ---
|
|
||||||
|
|
||||||
float finalAlpha = atmosphereDensity * distanceFactor;
|
|
||||||
|
|
||||||
gl_FragColor = vec4(uColor, finalAlpha);
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
// Вершинный шейдер:
|
|
||||||
attribute vec3 vPosition;
|
|
||||||
attribute vec3 vNormal; // <-- Новый атрибут
|
|
||||||
|
|
||||||
uniform mat4 ProjectionModelViewMatrix;
|
|
||||||
uniform mat4 ModelViewMatrix;
|
|
||||||
|
|
||||||
// Выходные переменные (передаются во фрагментный шейдер)
|
|
||||||
varying vec3 vViewNormal;
|
|
||||||
varying vec3 vViewPosition;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
// 1. Позиция в пространстве вида (View Space)
|
|
||||||
vec4 positionView = ModelViewMatrix * vec4(vPosition, 1.0);
|
|
||||||
vViewPosition = positionView.xyz;
|
|
||||||
|
|
||||||
// 2. Нормаль в пространстве вида (View Space)
|
|
||||||
// Преобразуем нормаль, используя ModelViewMatrix. Поскольку нормаль - это вектор,
|
|
||||||
// трансляционная часть (четвертый столбец) матрицы нам не нужна.
|
|
||||||
// Если бы было неединообразное масштабирование, потребовалась бы Inverse Transpose Matrix.
|
|
||||||
// В вашем случае, где есть только униформное масштабирование и вращение,
|
|
||||||
// достаточно просто умножить на ModelViewMatrix:
|
|
||||||
vViewNormal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
|
||||||
// W=0.0 для векторов, чтобы игнорировать трансляцию
|
|
||||||
|
|
||||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
|
||||||
}
|
|
||||||
@ -1,23 +1,11 @@
|
|||||||
attribute vec3 vPosition;
|
attribute vec3 vPosition;
|
||||||
attribute vec3 vColor;
|
attribute vec3 vColor;
|
||||||
attribute vec3 vNormal;
|
|
||||||
attribute vec2 vTexCoord; // <-- Обычные UV (если используются)
|
|
||||||
|
|
||||||
varying vec3 color;
|
varying vec3 color;
|
||||||
varying vec3 normal;
|
|
||||||
|
|
||||||
varying vec2 TexCoord; // <-- Передаем UV
|
|
||||||
|
|
||||||
uniform mat4 ProjectionModelViewMatrix;
|
uniform mat4 ProjectionModelViewMatrix;
|
||||||
uniform mat4 ModelViewMatrix;
|
|
||||||
uniform vec3 uLightDirection;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
||||||
|
|
||||||
normal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
|
||||||
|
|
||||||
color = vColor;
|
color = vColor;
|
||||||
TexCoord = vTexCoord;
|
|
||||||
}
|
}
|
||||||
@ -1,22 +1,9 @@
|
|||||||
varying vec3 color; // Цвет вершины (с шумом)
|
//precision mediump float;
|
||||||
varying vec3 normal;
|
varying vec3 color;
|
||||||
varying vec3 lightDirection_VS;
|
|
||||||
varying vec2 TexCoord; // UV-координаты
|
|
||||||
|
|
||||||
uniform sampler2D Texture;
|
|
||||||
uniform vec3 uLightDirection;
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// 1. Получаем цвет из текстуры и смешиваем с цветовым шумом
|
//gl_FragColor = vec4(color, 1.0);
|
||||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
gl_FragColor = vec4(1.0, 1.0, 0.5, 1.0);
|
||||||
vec3 finalColor = textureColor.rgb * color;
|
|
||||||
|
|
||||||
// 3. Расчет освещения
|
|
||||||
float diffuse = max(0.0, dot(normal, uLightDirection));
|
|
||||||
float ambient = 0.2;
|
|
||||||
float lightingFactor = min(1.0, ambient + diffuse);
|
|
||||||
|
|
||||||
|
|
||||||
gl_FragColor = vec4(finalColor * lightingFactor, 1.0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,35 +0,0 @@
|
|||||||
// Вершинный шейдер (Vertex Shader)
|
|
||||||
|
|
||||||
attribute vec3 vPosition;
|
|
||||||
attribute vec3 vColor;
|
|
||||||
attribute vec3 vNormal;
|
|
||||||
attribute vec2 vTexCoord;
|
|
||||||
|
|
||||||
varying vec3 color;
|
|
||||||
varying vec3 normal;
|
|
||||||
varying vec2 TexCoord;
|
|
||||||
varying float viewZ; // <--- НОВОЕ: Z-координата в пространстве вида (View Space)
|
|
||||||
varying vec3 pos;
|
|
||||||
|
|
||||||
uniform mat4 ProjectionModelViewMatrix;
|
|
||||||
uniform mat4 ModelViewMatrix; // Нужна для преобразования vPosition в View Space
|
|
||||||
uniform vec3 uLightDirection;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
// Преобразование позиции в пространство вида (View Space)
|
|
||||||
vec4 viewPosition = ModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
|
||||||
|
|
||||||
// Сохраняем отрицательную Z-координату. В OpenGL Z-координата (глубина)
|
|
||||||
// в пространстве вида обычно отрицательна, но для расчета тумана
|
|
||||||
// удобнее использовать положительное значение.
|
|
||||||
viewZ = -viewPosition.z;
|
|
||||||
|
|
||||||
pos = vPosition.xyz;
|
|
||||||
|
|
||||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
|
||||||
|
|
||||||
normal = normalize((ModelViewMatrix * vec4(vNormal, 0.0)).xyz);
|
|
||||||
color = vColor;
|
|
||||||
TexCoord = vTexCoord;
|
|
||||||
}
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
// ---Фрагментный шейдер (Fragment Shader)
|
|
||||||
|
|
||||||
varying vec3 color;
|
|
||||||
varying vec3 normal;
|
|
||||||
varying vec2 TexCoord;
|
|
||||||
varying float viewZ;
|
|
||||||
varying vec3 pos;
|
|
||||||
|
|
||||||
uniform sampler2D Texture;
|
|
||||||
uniform vec3 uLightDirection;
|
|
||||||
uniform float uDistanceToPlanetSurface;
|
|
||||||
uniform float uCurrentZFar;
|
|
||||||
|
|
||||||
// Константы для тумана:
|
|
||||||
const vec4 FOG_COLOR = vec4(0.0, 0.5, 1.0, 1.0); // Синий туман
|
|
||||||
|
|
||||||
// Параметры "Distance Fog"
|
|
||||||
const float DIST_FOG_MAX = 2000.0;
|
|
||||||
const float DIST_FOG_MIN = 1000.0;
|
|
||||||
|
|
||||||
// Параметры "Z-Far Fog"
|
|
||||||
// Насколько близко к Zfar должен начинаться туман (например, 10% от Zfar)
|
|
||||||
const float Z_FOG_START_RATIO = 0.9;
|
|
||||||
// Какую долю от Zfar должен покрывать туман (например, 10% от Zfar)
|
|
||||||
const float Z_FOG_RANGE_RATIO = 0.1;
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
// ... (1. Получаем цвет и 2. Расчет освещения)
|
|
||||||
vec4 textureColor = texture2D(Texture, TexCoord);
|
|
||||||
vec3 finalColor = textureColor.rgb * color;
|
|
||||||
|
|
||||||
float diffuse = max(0.0, dot(normal, uLightDirection));
|
|
||||||
float ambient = 0.2;
|
|
||||||
float lightingFactor = min(1.0, ambient + diffuse);
|
|
||||||
vec3 litColor = finalColor * lightingFactor;
|
|
||||||
|
|
||||||
|
|
||||||
// 3. Расчет коэффициента тумана (fogFactor)
|
|
||||||
float fogFactor = 0.0;
|
|
||||||
|
|
||||||
// --- 3.1. Расчет коэффициента тумана на основе расстояния до поверхности (Distance Fog) ---
|
|
||||||
// Этот туман работает на больших расстояниях и постепенно исчезает,
|
|
||||||
// уступая место Z-Far Fog при приближении к планете.
|
|
||||||
|
|
||||||
if (uDistanceToPlanetSurface >= DIST_FOG_MIN && uDistanceToPlanetSurface <DIST_FOG_MAX) {
|
|
||||||
// Нормализация: 0.0f при DIST_FOG_MAX, 1.0f при DIST_FOG_MIN
|
|
||||||
float distRange = DIST_FOG_MAX - DIST_FOG_MIN;
|
|
||||||
float distNormalized = clamp((uDistanceToPlanetSurface - DIST_FOG_MIN) / distRange, 0.0, 1.0);
|
|
||||||
|
|
||||||
// alpha = 0.0 (Далеко) ... 1.0 (Близко к 1000.f)
|
|
||||||
fogFactor = 1.0 - distNormalized;
|
|
||||||
}
|
|
||||||
if (uDistanceToPlanetSurface < DIST_FOG_MIN)
|
|
||||||
{
|
|
||||||
fogFactor = 1.0;
|
|
||||||
}
|
|
||||||
// Если uDistanceToPlanetSurface < 1000.0f, то fogFactor = 0.0f (пока не пересчитан ниже),
|
|
||||||
// что позволяет Z-Far Fog взять контроль.
|
|
||||||
|
|
||||||
|
|
||||||
// --- 3.2. Расчет коэффициента тумана на основе Z-глубины (Z-Far Fog) ---
|
|
||||||
// Этот туман работает всегда, но его эффект усиливается при уменьшении uCurrentZFar,
|
|
||||||
// гарантируя, что все, что подходит к границе uCurrentZFar, будет скрыто.
|
|
||||||
|
|
||||||
// Точка начала тумана: 90% от uCurrentZFar
|
|
||||||
float farFogStart = 2000.f;//uCurrentZFar * 0.7;
|
|
||||||
// Длина перехода тумана: 10% от uCurrentZFar
|
|
||||||
float depthRange = 2000.f;//uCurrentZFar * 0.25;
|
|
||||||
|
|
||||||
if (abs(uDistanceToPlanetSurface) < 410.f)
|
|
||||||
{
|
|
||||||
farFogStart = 1800.f * abs(uDistanceToPlanetSurface-10.f) * 0.0025 + 200.f;
|
|
||||||
depthRange = farFogStart;
|
|
||||||
}
|
|
||||||
if (abs(uDistanceToPlanetSurface) < 10.f)
|
|
||||||
{
|
|
||||||
farFogStart = 200.f;
|
|
||||||
depthRange = 200.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float farFogFactor = 0.0;
|
|
||||||
|
|
||||||
if (depthRange > 0.0) {
|
|
||||||
// Нормализация Z-глубины: 0.0f при farFogStart, 1.0f при farFogStart + depthRange
|
|
||||||
farFogFactor = clamp((abs(viewZ) - farFogStart) / depthRange, 0.0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 3.3. Объединение ---
|
|
||||||
|
|
||||||
// Когда мы далеко (fogFactor > 0.0), Distance Fog доминирует.
|
|
||||||
// Когда мы близко (fogFactor = 0.0), Z-Far Fog берет управление.
|
|
||||||
// Если оба активны, берем максимум (например, когда фрагмент далек от игрока, но игрок все еще в зоне Distance Fog).
|
|
||||||
//fogFactor = max(fogFactor, farFogFactor);
|
|
||||||
fogFactor = fogFactor * farFogFactor;
|
|
||||||
|
|
||||||
|
|
||||||
// 4. Смешивание цвета с туманом
|
|
||||||
|
|
||||||
//vec3 mountainColor = vec3((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.5,0.0);
|
|
||||||
gl_FragColor = mix(vec4(finalColor.rgb, 0.5), FOG_COLOR, fogFactor);
|
|
||||||
//gl_FragColor = vec4((length(pos+vec3(0.0,0.0,45000.0))-20000.0)/100.0, 0.0,0.0, 1.0);
|
|
||||||
//gl_FragColor = vec4(fogFactor, 0.5,0.5, 1.0);
|
|
||||||
}
|
|
||||||
@ -5,8 +5,8 @@ varying vec2 texCoord;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 color = texture2D(Texture,texCoord).rgba;
|
vec4 color = texture2D(Texture,texCoord).rgba;
|
||||||
//gl_FragColor = vec4(color.rgb*0.9 + vec3(0.1, 0.1, 0.1), 1.0);
|
gl_FragColor = vec4(color.rgb*0.9 + vec3(0.1, 0.1, 0.1), 1.0);
|
||||||
|
|
||||||
gl_FragColor = color;
|
//gl_FragColor = color;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,13 +0,0 @@
|
|||||||
uniform samplerCube Texture;
|
|
||||||
|
|
||||||
varying vec3 dir;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
|
||||||
//if (dir.z < 0)
|
|
||||||
//{
|
|
||||||
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
|
||||||
//}
|
|
||||||
//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
attribute vec3 vPosition;
|
|
||||||
|
|
||||||
uniform mat4 ProjectionModelViewMatrix;
|
|
||||||
|
|
||||||
varying vec3 dir;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
vec4 realVertexPos = vec4(vPosition.xyz, 1.0);
|
|
||||||
gl_Position = ProjectionModelViewMatrix * realVertexPos;
|
|
||||||
|
|
||||||
dir = vPosition;
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
uniform samplerCube Texture;
|
|
||||||
|
|
||||||
varying vec3 dir;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
attribute vec3 vPosition;
|
|
||||||
|
|
||||||
uniform mat4 ProjectionModelViewMatrix;
|
|
||||||
|
|
||||||
varying vec3 dir;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
vec4 realVertexPos = vec4(vPosition.xyz, 1.0);
|
|
||||||
gl_Position = ProjectionModelViewMatrix * realVertexPos;
|
|
||||||
|
|
||||||
dir = vPosition;
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
uniform samplerCube Texture;
|
|
||||||
uniform float skyPercent;
|
|
||||||
|
|
||||||
varying vec3 dir;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
vec4 skyBoxColor = textureCube(Texture, normalize(dir));
|
|
||||||
vec4 skyColor = vec4(0.0, 0.5, 1.0, 1.0);
|
|
||||||
gl_FragColor = skyPercent*skyColor + (1.0 - skyPercent) * skyBoxColor;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
precision mediump float;
|
|
||||||
uniform samplerCube Texture;
|
|
||||||
varying vec3 dir;
|
|
||||||
|
|
||||||
void main(){
|
|
||||||
gl_FragColor = textureCube(Texture, normalize(dir));
|
|
||||||
}
|
|
||||||
31
space-game001.sln
Normal file
31
space-game001.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.31402.337
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "space-game001", "space-game001.vcxproj", "{400A41AE-F904-4D49-9DBC-95934D0EF82E}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{400A41AE-F904-4D49-9DBC-95934D0EF82E}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {C3D1B89D-D5F1-4E33-8439-56D6C43B07A2}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
184
space-game001.vcxproj
Normal file
184
space-game001.vcxproj
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{400a41ae-f904-4d49-9dbc-95934d0ef82e}</ProjectGuid>
|
||||||
|
<RootNamespace>ZeptoLabTest1</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>space-game001</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<TargetName>Viola</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>PNG_ENABLED;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\SDL-release-2.32.10\include;..\libpng-1.6.51\build\install\include;C:\Work\OpenAL 1.1 SDK\include;..\Projects\libogg\include;..\vorbis\include</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>zlibstaticd.lib;libpng16_staticd.lib;SDL2d.lib;SDL2maind.lib;opengl32.lib;glu32.lib;shell32.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>..\SDL-release-2.32.10\build\install\lib;..\libpng-1.6.51\build\install\lib;..\zlib-1.3.1\build\install\lib</AdditionalLibraryDirectories>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>C:\Work\SDL2-2.28.3\include;C:\Work\Projects\lpng1645\build\install\include;C:\Work\OpenAL 1.1 SDK\include;C:\Work\Projects\libogg\include;C:\Work\Projects\vorbis\include</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>libogg_static.lib;audioplayer.lib;vorbisfile.lib;vorbis.lib;OpenAL32.lib;SDL2.lib;SDL2main.lib;opengl32.lib;glu32.lib;shell32.lib;opengl32.lib;glu32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>C:\Work\Projects\ZeptoLabTest1\cmakeaudioplayer\build\Release;C:\Work\SDL2-2.28.3\lib\x64;C:\Work\Projects\vorbis\build\lib\Release;C:\Work\OpenAL 1.1 SDK\libs\Win64;C:\Work\Projects\libogg\win32\VS2010\x64\Release</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="AudioPlayerAsync.cpp" />
|
||||||
|
<ClCompile Include="BoneAnimatedModel.cpp" />
|
||||||
|
<ClCompile Include="Environment.cpp" />
|
||||||
|
<ClCompile Include="Game.cpp" />
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="Math.cpp" />
|
||||||
|
<ClCompile Include="OpenGlExtensions.cpp" />
|
||||||
|
<ClCompile Include="Renderer.cpp" />
|
||||||
|
<ClCompile Include="ShaderManager.cpp" />
|
||||||
|
<ClCompile Include="TextModel.cpp" />
|
||||||
|
<ClCompile Include="TextureManager.cpp" />
|
||||||
|
<ClCompile Include="Utils.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="AnimatedModel.h" />
|
||||||
|
<ClInclude Include="AudioPlayerAsync.h" />
|
||||||
|
<ClInclude Include="BoneAnimatedModel.h" />
|
||||||
|
<ClInclude Include="Environment.h" />
|
||||||
|
<ClInclude Include="Game.h" />
|
||||||
|
<ClInclude Include="Math.h" />
|
||||||
|
<ClInclude Include="OpenGlExtensions.h" />
|
||||||
|
<ClInclude Include="Renderer.h" />
|
||||||
|
<ClInclude Include="ShaderManager.h" />
|
||||||
|
<ClInclude Include="TextModel.h" />
|
||||||
|
<ClInclude Include="TextureManager.h" />
|
||||||
|
<ClInclude Include="Utils.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
93
space-game001.vcxproj.filters
Normal file
93
space-game001.vcxproj.filters
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="main.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="TextureManager.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Renderer.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ShaderManager.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="OpenGlExtensions.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Math.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Utils.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Game.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="BoneAnimatedModel.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="TextModel.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Environment.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="AudioPlayerAsync.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="TextureManager.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Renderer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ShaderManager.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="OpenGlExtensions.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Math.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Utils.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Game.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="AnimatedModel.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="BoneAnimatedModel.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="TextModel.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Environment.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="AudioPlayerAsync.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@ -1,100 +0,0 @@
|
|||||||
<!doctypehtml>
|
|
||||||
<html lang=en-us>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<meta content="text/html; charset=utf-8" http-equiv=Content-Type>
|
|
||||||
<title>Space Game</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: arial;
|
|
||||||
margin: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0;
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emscripten {
|
|
||||||
padding-right: 0;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
display: block
|
|
||||||
}
|
|
||||||
|
|
||||||
div.emscripten {
|
|
||||||
text-align: center
|
|
||||||
}
|
|
||||||
|
|
||||||
div.emscripten_border {
|
|
||||||
border: 1px solid #000
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.emscripten {
|
|
||||||
border: 0 none;
|
|
||||||
background-color: #000;
|
|
||||||
width: 90%;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes rotation {
|
|
||||||
from {
|
|
||||||
-webkit-transform: rotate(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
-webkit-transform: rotate(360deg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@-moz-keyframes rotation {
|
|
||||||
from {
|
|
||||||
-moz-transform: rotate(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
-moz-transform: rotate(360deg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@-o-keyframes rotation {
|
|
||||||
from {
|
|
||||||
-o-transform: rotate(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
-o-transform: rotate(360deg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes rotation {
|
|
||||||
from {
|
|
||||||
transform: rotate(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#status {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#progress {
|
|
||||||
height: 20px;
|
|
||||||
width: 300px
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class=emscripten id=status></div>
|
|
||||||
<div class=emscripten><progress hidden id=progress max=100 value=0></progress></div>
|
|
||||||
<div class=emscripten_border><canvas class=emscripten id=canvas oncontextmenu=event.preventDefault()
|
|
||||||
tabindex=-1></canvas></div>
|
|
||||||
<script>var statusElement = document.getElementById("status"), progressElement = document.getElementById("progress"), spinnerElement = document.getElementById("spinner"), Module = { print: function () { var e = document.getElementById("output"); return e && (e.value = ""), function (t) { arguments.length > 1 && (t = Array.prototype.slice.call(arguments).join(" ")), console.log(t), e && (e.value += t + "\n", e.scrollTop = e.scrollHeight) } }(), canvas: (() => { var e = document.getElementById("canvas"); return e.addEventListener("webglcontextlost", (e => { alert("WebGL context lost. You will need to reload the page."), e.preventDefault() }), !1), e })(), setStatus: e => { if (Module.setStatus.last || (Module.setStatus.last = { time: Date.now(), text: "" }), e !== Module.setStatus.last.text) { var t = e.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/), n = Date.now(); t && n - Module.setStatus.last.time < 30 || (Module.setStatus.last.time = n, Module.setStatus.last.text = e, t ? (e = t[1], progressElement.value = 100 * parseInt(t[2]), progressElement.max = 100 * parseInt(t[4]), progressElement.hidden = !1, spinnerElement.hidden = !1) : (progressElement.value = null, progressElement.max = null, progressElement.hidden = !0, e || (spinnerElement.style.display = "none")), statusElement.innerHTML = e) } }, totalDependencies: 0, monitorRunDependencies: e => { this.totalDependencies = Math.max(this.totalDependencies, e), Module.setStatus(e ? "Preparing... (" + (this.totalDependencies - e) + "/" + this.totalDependencies + ")" : "All downloads complete.") } }; Module.setStatus("Downloading..."), window.onerror = e => { Module.setStatus("Exception thrown, see JavaScript console"), spinnerElement.style.display = "none", Module.setStatus = e => { e && console.error("[post-exception status] " + e) } }</script>
|
|
||||||
<script async src=space-game001.js></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
Loading…
Reference in New Issue
Block a user