目标:(九十一)中的问题173
答案:是的。
思路是将着色器文件的源码都放入一个cpp文件的变量中,再编译链接,就将着色器文件写死在动态库中了。
秘密在rex引擎目录下的文件Shaders.cpp.in(最终该模板变成AutoGenShaders.cpp)
// ***DO NOT EDIT THIS FILE - IT IS AUTOMATICALLY GENERATED BY CMAKE***
#include <osgEarthDrivers/engine_rex/Shaders>
using namespace osgEarth::Drivers::RexTerrainEngine;
Shaders::Shaders()
{
ENGINE_VERT_MODEL = "RexEngine.vert.glsl";
_sources[ENGINE_VERT_MODEL] = "@RexEngine.vert.glsl@";
ENGINE_ELEVATION_MODEL = "RexEngine.elevation.glsl";
_sources[ENGINE_ELEVATION_MODEL] = "@RexEngine.elevation.glsl@";
MORPHING_VERT = "RexEngine.Morphing.vert.glsl";
_sources[MORPHING_VERT] = "@RexEngine.Morphing.vert.glsl@";
ENGINE_VERT_VIEW = "RexEngine.vert.view.glsl";
_sources[ENGINE_VERT_VIEW] = "@RexEngine.vert.view.glsl@";
ENGINE_FRAG = "RexEngine.frag.glsl";
_sources[ENGINE_FRAG] = "@RexEngine.frag.glsl@";
NORMAL_MAP_VERT = "RexEngine.NormalMap.vert.glsl";
_sources[NORMAL_MAP_VERT] = "@RexEngine.NormalMap.vert.glsl@";
NORMAL_MAP_FRAG = "RexEngine.NormalMap.frag.glsl";
_sources[NORMAL_MAP_FRAG] = "@RexEngine.NormalMap.frag.glsl@";
ENGINE_GEOM = "RexEngine.gs.glsl";
_sources[ENGINE_GEOM] = "@RexEngine.gs.glsl@";
SDK = "RexEngine.SDK.vert.glsl";
_sources[SDK] = "@RexEngine.SDK.vert.glsl@";
}
CMake工程对该文件做如下处理:
set(TARGET_GLSL
RexEngine.vert.glsl
RexEngine.elevation.glsl
RexEngine.vert.view.glsl
RexEngine.tcs.glsl
RexEngine.tes.glsl
RexEngine.gs.glsl
RexEngine.frag.glsl
RexEngine.NormalMap.vert.glsl
RexEngine.NormalMap.frag.glsl
RexEngine.Morphing.vert.glsl
RexEngine.SDK.vert.glsl)
set(SHADERS_CPP "${CMAKE_CURRENT_BINARY_DIR}/AutoGenShaders.cpp")
configure_shaders(
Shaders.cpp.in
${SHADERS_CPP}
${TARGET_GLSL} )
configure_shaders定义如下:
CMakeModules/OsgEarthMacroUtils.cmake
# -----------------------------------------------------------------------
# configure_shaders -gw
#
# Bakes GLSL shaders to make into a CPP file at runtime.
# Example:
#
# configure_shaders( MyTemplate.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/AutoGen.cpp file1.glsl file2.glsl )
#
macro(configure_shaders templateFile autoGenCppFile)
# set up configure variables:
set(TEMPLATE_FILE ${templateFile} )
set(GLSL_FILES ${ARGN} )
set(OUTPUT_CPP_FILE ${autoGenCppFile})
# generate the build-time script that will create out cpp file with inline shaders:
configure_file(
"${CMAKE_SOURCE_DIR}/CMakeModules/ConfigureShaders.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ConfigureShaders.cmake"
@ONLY)
# add the custom build-time command to run the script:
add_custom_command(
OUTPUT
"${autoGenCppFile}"
COMMAND
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/ConfigureShaders.cmake"
DEPENDS
${GLSL_FILES}
"${TEMPLATE_FILE}"
"${CMAKE_SOURCE_DIR}/CMakeModules/ConfigureShaders.cmake.in" )
endmacro(configure_shaders)
经过变换后,AutoGenShaders.cpp的内容为:
// ***DO NOT EDIT THIS FILE - IT IS AUTOMATICALLY GENERATED BY CMAKE***
#include <osgEarthDrivers/engine_rex/Shaders>
using namespace osgEarth::Drivers::RexTerrainEngine;
Shaders::Shaders()
{
ENGINE_VERT_MODEL = "RexEngine.vert.glsl";
_sources[ENGINE_VERT_MODEL] = "#version $GLSL_VERSION_STR%EOL%$GLSL_DEFAULT_PRECISION_FLOAT%EOL%%EOL%#pragma vp_name REX Engine - Vertex%EOL%#pragma vp_entryPoint oe_rexEngine_vert%EOL%#pragma vp_location vertex_model%EOL%#pragma vp_order 0.0%EOL%%EOL%// uniforms%EOL%uniform vec4 oe_terrain_color;%EOL%%EOL%// outputs%EOL%out vec4 vp_Color;%EOL%out vec3 vp_Normal;%EOL%%EOL%out vec4 oe_layer_texc;%EOL%out vec4 oe_layer_tilec;%EOL%out vec3 oe_UpVectorView;%EOL%%EOL%out float oe_rex_morphFactor;%EOL%%EOL%void oe_rexEngine_vert(inout vec4 vertexModel)%EOL%{%EOL% // Texture coordinate for the tile (always 0..1)%EOL% oe_layer_tilec = gl_MultiTexCoord0;%EOL%%EOL% // Color of the underlying map geometry (untextured)%EOL% vp_Color = oe_terrain_color;%EOL% %EOL% // %QUOTE%up%QUOTE% vector at this vertex in view space, which we will later%EOL% // need in order to elevate the terrain%EOL% oe_UpVectorView = normalize(gl_NormalMatrix*vp_Normal);%EOL%%EOL% // initialize:%EOL% oe_rex_morphFactor = 0.0;%EOL%}%EOL%%EOL%";
ENGINE_ELEVATION_MODEL = "RexEngine.elevation.glsl";
_sources[ENGINE_ELEVATION_MODEL] = "#version $GLSL_VERSION_STR%EOL%%EOL%#pragma vp_name REX Engine - Elevation%EOL%#pragma vp_entryPoint oe_rexEngine_elevation%EOL%#pragma vp_location vertex_model%EOL%#pragma vp_order 0.7%EOL%%EOL%#pragma import_defines(OE_TERRAIN_RENDER_ELEVATION)%EOL%%EOL%// Vertex Markers:%EOL%#define MASK_MARKER_DISCARD 0.0%EOL%#define MASK_MARKER_NORMAL 1.0%EOL%#define MASK_MARKER_PATCH 2.0%EOL%#define MASK_MARKER_BOUNDARY 3.0%EOL%%EOL%// stage%EOL%vec3 vp_Normal; // up vector%EOL%vec4 oe_layer_texc;%EOL%vec4 oe_layer_tilec;%EOL%%EOL%// SDK functions:%EOL%float oe_terrain_getElevation(in vec2 uv);%EOL%%EOL%void oe_rexEngine_elevation(inout vec4 vertexModel)%EOL%{ %EOL%#ifdef OE_TERRAIN_RENDER_ELEVATION%EOL% float elev = %EOL% oe_layer_tilec.z == MASK_MARKER_BOUNDARY || oe_layer_tilec.z == MASK_MARKER_DISCARD ? 0.0f%EOL% : oe_terrain_getElevation( oe_layer_tilec.st );%EOL%%EOL% vertexModel.xyz += normalize(vp_Normal) * elev;%EOL%#endif%EOL%}%EOL%%EOL%";
MORPHING_VERT = "RexEngine.Morphing.vert.glsl";
_sources[MORPHING_VERT] = "#version $GLSL_VERSION_STR%EOL%$GLSL_DEFAULT_PRECISION_FLOAT%EOL%%EOL%#pragma vp_name REX Engine - Morphing%EOL%#pragma vp_entryPoint oe_rexEngine_morph%EOL%#pragma vp_location vertex_model%EOL%#pragma vp_order 0.5%EOL%%EOL%#pragma import_defines(OE_TERRAIN_MORPH_GEOMETRY, OE_TERRAIN_RENDER_ELEVATION)%EOL%%EOL%%EOL%// stage%EOL%vec3 vp_Normal; // up vector%EOL%%EOL%vec4 oe_layer_texc;%EOL%vec4 oe_layer_tilec;%EOL%%EOL%out float oe_rex_morphFactor;%EOL%%EOL%uniform vec2 oe_tile_morph;%EOL%uniform float oe_tile_size;%EOL%%EOL%// SDK functions:%EOL%float oe_terrain_getElevation(in vec2 uv);%EOL%%EOL%// Vertex Markers:%EOL%#define MASK_MARKER_DISCARD 0.0%EOL%#define MASK_MARKER_NORMAL 1.0%EOL%#define MASK_MARKER_PATCH 2.0%EOL%#define MASK_MARKER_BOUNDARY 3.0%EOL%%EOL%%EOL%// Morphs a vertex using a neig