TESTGLSLGEOM: added geometry shader test application
also only regenerate the shader headers if something really changed for the c++ interface added ScopedVertexBuffer moved general imgui controls into TestApp changed default gl versions improved geometry shader supportmaster
parent
85d0a3b582
commit
4c0e4d1ce5
|
@ -8,3 +8,5 @@
|
||||||
gmon.out
|
gmon.out
|
||||||
/*.sync
|
/*.sync
|
||||||
/perf.data*
|
/perf.data*
|
||||||
|
luac.out
|
||||||
|
*.patch
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -167,7 +167,7 @@ doc: cmake
|
||||||
$(call COMPILE, codegen)
|
$(call COMPILE, codegen)
|
||||||
$(call COMPILE, $@)
|
$(call COMPILE, $@)
|
||||||
|
|
||||||
server client voxedit shapetool mapedit shadertool noisetool databasetool uitool tests tests-math tests-core tests-persistence tests-voxel benchmarks-voxel tests-noise tests-computeshadertool testmesh testcamera testdepthbuffer testnuklear testtexture testvoxelfont testplane testimgui testoctree testglslcomp testluaui testoctreevisit testshapebuilder tests-shadertool flatc computeshadertool: cmake
|
server client voxedit shapetool mapedit shadertool noisetool databasetool uitool tests tests-math tests-core tests-persistence tests-voxel benchmarks-voxel tests-noise tests-computeshadertool testmesh testcamera testdepthbuffer testnuklear testtexture testvoxelfont testplane testimgui testoctree testglslgeom testglslcomp testluaui testoctreevisit testshapebuilder tests-shadertool flatc computeshadertool: cmake
|
||||||
$(call COMPILE, $@)
|
$(call COMPILE, $@)
|
||||||
$(call COMPILE, copy-data-shared)
|
$(call COMPILE, copy-data-shared)
|
||||||
$(call COMPILE, copy-data-$@)
|
$(call COMPILE, copy-data-$@)
|
||||||
|
|
4
TODO.md
4
TODO.md
|
@ -14,10 +14,6 @@ INFO: (0) Validation output: shaders/world
|
||||||
active samplers with a different type refer to the same texture image unit
|
active samplers with a different type refer to the same texture image unit
|
||||||
```
|
```
|
||||||
|
|
||||||
## Code generation
|
|
||||||
|
|
||||||
Only replace the files if something has really changed. (`configure_file`?)
|
|
||||||
|
|
||||||
# Data handling
|
# Data handling
|
||||||
|
|
||||||
The current approach with data dir must be extended/redone someone. There are way too many files installed per artifact atm. Also there should be CPack support to generate debian packages.
|
The current approach with data dir must be extended/redone someone. There are way too many files installed per artifact atm. Also there should be CPack support to generate debian packages.
|
||||||
|
|
|
@ -48,115 +48,122 @@ endmacro()
|
||||||
macro(generate_shaders TARGET)
|
macro(generate_shaders TARGET)
|
||||||
set(files ${ARGV})
|
set(files ${ARGV})
|
||||||
list(REMOVE_AT files 0)
|
list(REMOVE_AT files 0)
|
||||||
set(_headers)
|
|
||||||
set(GEN_DIR ${GENERATE_DIR}/shaders/${TARGET}/)
|
set(GEN_DIR ${GENERATE_DIR}/shaders/${TARGET}/)
|
||||||
set(_template ${ROOT_DIR}/src/tools/shadertool/ShaderTemplate.h.in)
|
set(_template ${ROOT_DIR}/src/tools/shadertool/ShaderTemplate.h.in)
|
||||||
set(_template_ub ${ROOT_DIR}/src/tools/shadertool/UniformBufferTemplate.h.in)
|
set(_template_ub ${ROOT_DIR}/src/tools/shadertool/UniformBufferTemplate.h.in)
|
||||||
file(MAKE_DIRECTORY ${GEN_DIR})
|
file(MAKE_DIRECTORY ${GEN_DIR})
|
||||||
target_include_directories(${TARGET} PUBLIC ${GEN_DIR})
|
target_include_directories(${TARGET} PUBLIC ${GEN_DIR})
|
||||||
foreach (shader_dir "${TARGET}" shared)
|
set(_headers)
|
||||||
set(_dir ${ROOT_DIR}/${GAME_BASE_DIR}/${shader_dir}/shaders)
|
add_custom_target(UpdateShaders${TARGET})
|
||||||
if (IS_DIRECTORY ${_dir})
|
file(WRITE ${CMAKE_BINARY_DIR}/GenerateShaderHeader${TARGET}.cmake "configure_file(\${SRC} \${DST} @ONLY)")
|
||||||
foreach (_file ${files})
|
foreach (_file ${files})
|
||||||
convert_to_camel_case(${_file} _f)
|
set(_shaders)
|
||||||
set(_shaderfile "${_f}Shader.h")
|
set(_lastdir)
|
||||||
set(_shader "${GEN_DIR}${_shaderfile}")
|
foreach (shader_dir "${TARGET}" shared)
|
||||||
if (EXISTS ${_dir}/${_file}.frag AND EXISTS ${_dir}/${_file}.vert)
|
set(_dir ${ROOT_DIR}/${GAME_BASE_DIR}/${shader_dir}/shaders)
|
||||||
add_custom_command(
|
if (EXISTS ${_dir}/${_file}.frag AND EXISTS ${_dir}/${_file}.vert)
|
||||||
OUTPUT ${_shader}
|
list(APPEND _shaders ${_dir}/${_file}.frag ${_dir}/${_file}.vert)
|
||||||
IMPLICIT_DEPENDS C ${_dir}/${_file}.frag C ${_dir}/${_file}.vert
|
set(_lastdir ${_dir})
|
||||||
COMMENT "Validate ${_file} and generate ${_shaderfile}"
|
endif()
|
||||||
COMMAND ${CMAKE_BINARY_DIR}/shadertool --glslang ${CMAKE_BINARY_DIR}/glslangValidator --shader ${_dir}/${_file} --shadertemplate ${_template} --buffertemplate ${_template_ub} --sourcedir ${GEN_DIR}
|
if (EXISTS ${_dir}/${_file}.geom)
|
||||||
DEPENDS shadertool ${_dir}/${_file}.frag ${_dir}/${_file}.vert ${_template} ${_template_ub}
|
list(APPEND _shaders ${_dir}/${_file}.geom)
|
||||||
)
|
set(_lastdir ${_dir})
|
||||||
list(APPEND _headers ${_shader})
|
endif()
|
||||||
elseif (EXISTS ${_dir}/${_file}.comp)
|
if (EXISTS ${_dir}/${_file}.comp)
|
||||||
add_custom_command(
|
list(APPEND _shaders ${_dir}/${_file}.comp)
|
||||||
OUTPUT ${_shader}
|
set(_lastdir ${_dir})
|
||||||
IMPLICIT_DEPENDS C ${_dir}/${_file}.comp
|
endif()
|
||||||
COMMENT "Validate ${_file} and generate ${_shaderfile}"
|
endforeach()
|
||||||
COMMAND ${CMAKE_BINARY_DIR}/shadertool --glslang ${CMAKE_BINARY_DIR}/glslangValidator --shader ${_dir}/${_file} --shadertemplate ${_template} --buffertemplate ${_template_ub} --sourcedir ${GEN_DIR}
|
if (_shaders)
|
||||||
DEPENDS shadertool ${_dir}/${_file}.comp ${_template} ${_template_ub}
|
convert_to_camel_case(${_file} _f)
|
||||||
)
|
set(_shaderfile "${_f}Shader.h")
|
||||||
list(APPEND _headers ${_shader})
|
set(_shader "${GEN_DIR}${_shaderfile}")
|
||||||
endif()
|
add_custom_command(
|
||||||
endforeach()
|
OUTPUT ${_shader}.in
|
||||||
|
IMPLICIT_DEPENDS C ${_shaders}
|
||||||
|
COMMENT "Validate ${_file} and generate ${_shaderfile}"
|
||||||
|
COMMAND ${CMAKE_BINARY_DIR}/shadertool --glslang ${CMAKE_BINARY_DIR}/glslangValidator --postfix .in --shader ${_lastdir}/${_file} --shadertemplate ${_template} --buffertemplate ${_template_ub} --sourcedir ${GEN_DIR}
|
||||||
|
DEPENDS shadertool ${_shaders} ${_template} ${_template_ub}
|
||||||
|
)
|
||||||
|
list(APPEND _headers ${_shader})
|
||||||
|
add_custom_command(OUTPUT ${_shader} COMMAND ${CMAKE_COMMAND} -D SRC=${_shader}.in -D DST=${_shader} -P ${CMAKE_BINARY_DIR}/GenerateShaderHeader${TARGET}.cmake DEPENDS ${_shader}.in)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Could not find any shader files for ${_file} and target '${TARGET}'")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
convert_to_camel_case(${TARGET} _filetarget)
|
convert_to_camel_case(${TARGET} _filetarget)
|
||||||
# TODO: not regenerated if files were added, renamed or removed
|
|
||||||
set(_h ${GEN_DIR}/${_filetarget}Shaders.h)
|
set(_h ${GEN_DIR}/${_filetarget}Shaders.h)
|
||||||
file(WRITE ${_h}.in "#pragma once\n")
|
file(WRITE ${_h}.in "#pragma once\n")
|
||||||
foreach(header_path ${_headers})
|
foreach (header_path ${_headers})
|
||||||
string(REPLACE "${GEN_DIR}" "" header "${header_path}")
|
string(REPLACE "${GEN_DIR}" "" header "${header_path}")
|
||||||
file(APPEND ${_h}.in "#include \"${header}\"\n")
|
file(APPEND ${_h}.in "#include \"${header}\"\n")
|
||||||
endforeach()
|
endforeach()
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${_h}
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
ARGS -E copy_if_different ${_h}.in ${_h}
|
|
||||||
COMMENT "Generate ${_h}"
|
|
||||||
)
|
|
||||||
add_custom_target(GenerateShaderBindings${TARGET}
|
add_custom_target(GenerateShaderBindings${TARGET}
|
||||||
DEPENDS ${_headers} ${_h}
|
DEPENDS ${_headers}
|
||||||
COMMENT "Generate shader bindings for ${TARGET} in ${GEN_DIR}"
|
COMMENT "Generate shader bindings for ${TARGET} in ${GEN_DIR}"
|
||||||
)
|
)
|
||||||
#target_sources(${TARGET} PUBLIC ${_headers} ${_h})
|
set_source_files_properties(${_headers} ${_h} PROPERTIES GENERATED TRUE)
|
||||||
set_source_files_properties(${_headers} ${_h} ${_h}.in PROPERTIES GENERATED TRUE)
|
add_custom_target(GenerateShaderHeader${TARGET} ${CMAKE_COMMAND} -D SRC=${_h}.in -D DST=${_h} -P ${CMAKE_BINARY_DIR}/GenerateShaderHeader${TARGET}.cmake)
|
||||||
add_dependencies(${TARGET} GenerateShaderBindings${TARGET})
|
add_dependencies(${TARGET} GenerateShaderHeader${TARGET} UpdateShaders${TARGET})
|
||||||
add_dependencies(codegen GenerateShaderBindings${TARGET})
|
add_dependencies(GenerateShaderHeader${TARGET} GenerateShaderBindings${TARGET})
|
||||||
|
add_dependencies(codegen GenerateShaderHeader${TARGET} UpdateShaders${TARGET})
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
macro(generate_compute_shaders TARGET)
|
macro(generate_compute_shaders TARGET)
|
||||||
set(files ${ARGV})
|
set(files ${ARGV})
|
||||||
list(REMOVE_AT files 0)
|
list(REMOVE_AT files 0)
|
||||||
set(_headers)
|
|
||||||
set(GEN_DIR ${GENERATE_DIR}/compute-shaders/${TARGET}/)
|
set(GEN_DIR ${GENERATE_DIR}/compute-shaders/${TARGET}/)
|
||||||
set(_template ${ROOT_DIR}/src/tools/computeshadertool/ComputeShaderTemplate.h.in)
|
set(_template ${ROOT_DIR}/src/tools/computeshadertool/ComputeShaderTemplate.h.in)
|
||||||
file(MAKE_DIRECTORY ${GEN_DIR})
|
file(MAKE_DIRECTORY ${GEN_DIR})
|
||||||
target_include_directories(${TARGET} PUBLIC ${GEN_DIR})
|
target_include_directories(${TARGET} PUBLIC ${GEN_DIR})
|
||||||
foreach (shader_dir "${TARGET}" shared)
|
set(_headers)
|
||||||
set(_dir ${ROOT_DIR}/${GAME_BASE_DIR}/${shader_dir}/shaders)
|
add_custom_target(UpdateComputeShaders${TARGET})
|
||||||
if (IS_DIRECTORY ${_dir})
|
file(WRITE ${CMAKE_BINARY_DIR}/GenerateComputeShaderHeader${TARGET}.cmake "configure_file(\${SRC} \${DST} @ONLY)")
|
||||||
foreach (_file ${files})
|
foreach (_file ${files})
|
||||||
if (EXISTS ${_dir}/${_file}.cl)
|
set(_shaders)
|
||||||
convert_to_camel_case(${_file} _f)
|
set(_lastdir)
|
||||||
set(_shaderfile "${_f}Shader.h")
|
foreach (shader_dir "${TARGET}" shared)
|
||||||
set(_shader "${GEN_DIR}${_shaderfile}")
|
set(_dir ${ROOT_DIR}/${GAME_BASE_DIR}/${shader_dir}/shaders)
|
||||||
add_custom_command(
|
if (EXISTS ${_dir}/${_file}.cl)
|
||||||
OUTPUT ${_shader}
|
list(APPEND _shaders ${_dir}/${_file}.cl)
|
||||||
IMPLICIT_DEPENDS C ${_dir}/${_file}.cl
|
set(_lastdir ${_dir})
|
||||||
COMMENT "Generate ${_shaderfile}"
|
endif()
|
||||||
COMMAND ${CMAKE_BINARY_DIR}/computeshadertool --shader ${_dir}/${_file} --shadertemplate ${_template} --sourcedir ${GEN_DIR}
|
endforeach()
|
||||||
DEPENDS computeshadertool ${_dir}/${_file}.cl ${_template}
|
if (_shaders)
|
||||||
)
|
convert_to_camel_case(${_file} _f)
|
||||||
list(APPEND _headers ${_shader})
|
set(_shaderfile "${_f}Shader.h")
|
||||||
endif()
|
set(_shader "${GEN_DIR}${_shaderfile}")
|
||||||
endforeach()
|
add_custom_command(
|
||||||
|
OUTPUT ${_shader}.in
|
||||||
|
IMPLICIT_DEPENDS C ${_shaders}
|
||||||
|
COMMENT "Validate ${_file} and generate ${_shaderfile}"
|
||||||
|
COMMAND ${CMAKE_BINARY_DIR}/computeshadertool --shader ${_dir}/${_file} --postfix .in --shadertemplate ${_template} --sourcedir ${GEN_DIR}
|
||||||
|
DEPENDS computeshadertool ${_shaders} ${_template}
|
||||||
|
)
|
||||||
|
list(APPEND _headers ${_shader})
|
||||||
|
add_custom_command(OUTPUT ${_shader} COMMAND ${CMAKE_COMMAND} -D SRC=${_shader}.in -D DST=${_shader} -P ${CMAKE_BINARY_DIR}/GenerateComputeShaderHeader${TARGET}.cmake DEPENDS ${_shader}.in)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Could not find any shader files for ${_file} and target '${TARGET}'")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
convert_to_camel_case(${TARGET} _filetarget)
|
convert_to_camel_case(${TARGET} _filetarget)
|
||||||
# TODO: not regenerated if files were added, renamed or removed
|
|
||||||
set(_h ${GEN_DIR}/${_filetarget}Shaders.h)
|
set(_h ${GEN_DIR}/${_filetarget}Shaders.h)
|
||||||
file(WRITE ${_h}.in "#pragma once\n")
|
file(WRITE ${_h}.in "#pragma once\n")
|
||||||
foreach(header_path ${_headers})
|
foreach (header_path ${_headers})
|
||||||
string(REPLACE "${GEN_DIR}" "" header "${header_path}")
|
string(REPLACE "${GEN_DIR}" "" header "${header_path}")
|
||||||
file(APPEND ${_h}.in "#include \"${header}\"\n")
|
file(APPEND ${_h}.in "#include \"${header}\"\n")
|
||||||
endforeach()
|
endforeach()
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${_h}
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
ARGS -E copy_if_different ${_h}.in ${_h}
|
|
||||||
COMMENT "Generate ${_h}"
|
|
||||||
)
|
|
||||||
add_custom_target(GenerateComputeShaderBindings${TARGET}
|
add_custom_target(GenerateComputeShaderBindings${TARGET}
|
||||||
DEPENDS ${_headers} ${_h}
|
DEPENDS ${_headers}
|
||||||
COMMENT "Generate compute shader bindings for ${TARGET} in ${GEN_DIR}"
|
COMMENT "Generate shader bindings for ${TARGET} in ${GEN_DIR}"
|
||||||
)
|
)
|
||||||
#target_sources(${TARGET} PUBLIC ${_headers} ${_h})
|
set_source_files_properties(${_headers} ${_h} PROPERTIES GENERATED TRUE)
|
||||||
set_source_files_properties(${_headers} ${_h} ${_h}.in PROPERTIES GENERATED TRUE)
|
add_custom_target(GenerateComputeShaderHeader${TARGET} ${CMAKE_COMMAND} -D SRC=${_h}.in -D DST=${_h} -P ${CMAKE_BINARY_DIR}/GenerateComputeShaderHeader${TARGET}.cmake)
|
||||||
add_dependencies(${TARGET} GenerateComputeShaderBindings${TARGET})
|
add_dependencies(${TARGET} GenerateComputeShaderHeader${TARGET} UpdateComputeShaders${TARGET})
|
||||||
add_dependencies(codegen GenerateComputeShaderBindings${TARGET})
|
add_dependencies(GenerateComputeShaderHeader${TARGET} GenerateComputeShaderBindings${TARGET})
|
||||||
|
add_dependencies(codegen GenerateComputeShaderHeader${TARGET} UpdateComputeShaders${TARGET})
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
macro(generate_db_models TARGET INPUT OUTPUT)
|
macro(generate_db_models TARGET INPUT OUTPUT)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
$in vec3 v_color;
|
||||||
|
$out vec4 o_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
o_color = vec4(v_color, 1.0);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
layout(points) in;
|
||||||
|
layout(line_strip, max_vertices = 64) out;
|
||||||
|
|
||||||
|
$in vec3 g_color[];
|
||||||
|
$out vec3 v_color;
|
||||||
|
|
||||||
|
uniform int u_sides;
|
||||||
|
uniform float u_radius;
|
||||||
|
uniform mat4 u_projection;
|
||||||
|
|
||||||
|
const float PI = 3.1415926;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
v_color = g_color[0];
|
||||||
|
|
||||||
|
float delta = PI * 2.0 / float(u_sides);
|
||||||
|
float ang = 0.0f;
|
||||||
|
for (int i = 0; i <= u_sides; i++) {
|
||||||
|
vec4 offset = vec4(cos(ang) * u_radius, -sin(ang) * u_radius, 0.0, 0.0);
|
||||||
|
gl_Position = u_projection * (gl_in[0].gl_Position + offset);
|
||||||
|
ang += delta;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
$in vec4 a_pos;
|
||||||
|
$in vec3 a_color;
|
||||||
|
uniform mat4 u_view;
|
||||||
|
$out vec3 g_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = u_view * a_pos;
|
||||||
|
g_color = a_color;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
w +move_forward
|
||||||
|
a +move_left
|
||||||
|
s +move_backward
|
||||||
|
d +move_right
|
||||||
|
ctrl+q quit
|
|
@ -38,10 +38,9 @@ void TextureRenderer::render(const glm::mat4& projection) {
|
||||||
video::ScopedShader scoped(_textureShader);
|
video::ScopedShader scoped(_textureShader);
|
||||||
_textureShader.setProjection(projection);
|
_textureShader.setProjection(projection);
|
||||||
_textureShader.setTexture(video::TextureUnit::Zero);
|
_textureShader.setTexture(video::TextureUnit::Zero);
|
||||||
_texturedFullscreenQuad.bind();
|
video::ScopedVertexBuffer scopedBuf(_texturedFullscreenQuad);
|
||||||
const int elements = _texturedFullscreenQuad.elements(0, _textureShader.getComponentsPos());
|
const int elements = _texturedFullscreenQuad.elements(0, _textureShader.getComponentsPos());
|
||||||
video::drawArrays(video::Primitive::Triangles, elements);
|
video::drawArrays(video::Primitive::Triangles, elements);
|
||||||
_texturedFullscreenQuad.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureRenderer::shutdown() {
|
void TextureRenderer::shutdown() {
|
||||||
|
|
|
@ -115,6 +115,19 @@ void TestApp::onRenderUI() {
|
||||||
if (ImGui::Checkbox("Toggle profiler", &temp)) {
|
if (ImGui::Checkbox("Toggle profiler", &temp)) {
|
||||||
_renderTracing = toggleTrace();
|
_renderTracing = toggleTrace();
|
||||||
}
|
}
|
||||||
|
if (ImGui::Checkbox("Render axis", &_renderAxis)) {
|
||||||
|
setRenderAxis(_renderAxis);
|
||||||
|
}
|
||||||
|
if (ImGui::Checkbox("Render plane", &_renderPlane)) {
|
||||||
|
setRenderPlane(_renderPlane);
|
||||||
|
}
|
||||||
|
if (ImGui::Checkbox("Camera motion", &_cameraMotion)) {
|
||||||
|
setCameraMotion(_cameraMotion);
|
||||||
|
}
|
||||||
|
if (ImGui::InputFloat("Camera speed", &_cameraSpeed, 0.02f, 0.1f)) {
|
||||||
|
setCameraSpeed(_cameraSpeed);
|
||||||
|
}
|
||||||
|
ImGui::InputVarFloat("Rotation speed", _rotationSpeed, 0.01f, 0.1f);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::Button("Quit")) {
|
if (ImGui::Button("Quit")) {
|
||||||
requestQuit();
|
requestQuit();
|
||||||
|
|
|
@ -145,9 +145,6 @@ void TestMeshApp::onRenderUI() {
|
||||||
ImGui::CheckboxVar("Show shadow cascades", _debugShadowCascade);
|
ImGui::CheckboxVar("Show shadow cascades", _debugShadowCascade);
|
||||||
static const char* items[] = { "Disable", "First", "Second", "Third", "Fourth" };
|
static const char* items[] = { "Disable", "First", "Second", "Third", "Fourth" };
|
||||||
ImGui::Combo("Bone weight", &_boneInfluence, items, IM_ARRAYSIZE(items));
|
ImGui::Combo("Bone weight", &_boneInfluence, items, IM_ARRAYSIZE(items));
|
||||||
if (ImGui::Checkbox("Render axis", &_renderAxis)) {
|
|
||||||
setRenderAxis(_renderAxis);
|
|
||||||
}
|
|
||||||
ImGui::Checkbox("Render mesh", &_renderMesh);
|
ImGui::Checkbox("Render mesh", &_renderMesh);
|
||||||
ImGui::Checkbox("Render normals", &_renderNormals);
|
ImGui::Checkbox("Render normals", &_renderNormals);
|
||||||
ImGui::Checkbox("Render bones", &_renderBones);
|
ImGui::Checkbox("Render bones", &_renderBones);
|
||||||
|
@ -158,15 +155,6 @@ void TestMeshApp::onRenderUI() {
|
||||||
ImGui::PopTextWrapPos();
|
ImGui::PopTextWrapPos();
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
if (ImGui::Checkbox("Render plane", &_renderPlane)) {
|
|
||||||
setRenderPlane(_renderPlane);
|
|
||||||
}
|
|
||||||
if (ImGui::Checkbox("Camera motion", &_cameraMotion)) {
|
|
||||||
setCameraMotion(_cameraMotion);
|
|
||||||
}
|
|
||||||
if (ImGui::InputFloat("Camera speed", &_cameraSpeed, 0.02f, 0.1f)) {
|
|
||||||
setCameraSpeed(_cameraSpeed);
|
|
||||||
}
|
|
||||||
if (ImGui::InputFloat3("Camera omega", glm::value_ptr(_omega))) {
|
if (ImGui::InputFloat3("Camera omega", glm::value_ptr(_omega))) {
|
||||||
_camera.setOmega(_omega);
|
_camera.setOmega(_omega);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +162,6 @@ void TestMeshApp::onRenderUI() {
|
||||||
ImGui::InputFloat("Shadow bias slope", &_shadowBiasSlope, 0.01f, 0.1f);
|
ImGui::InputFloat("Shadow bias slope", &_shadowBiasSlope, 0.01f, 0.1f);
|
||||||
ImGui::InputFloat("Shadow range", &_shadowRangeZ, 0.01f, 0.1f);
|
ImGui::InputFloat("Shadow range", &_shadowRangeZ, 0.01f, 0.1f);
|
||||||
ImGui::InputFloat("Fog range", &_fogRange, 0.01f, 0.1f);
|
ImGui::InputFloat("Fog range", &_fogRange, 0.01f, 0.1f);
|
||||||
ImGui::InputVarFloat("Rotation speed", _rotationSpeed, 0.01f, 0.1f);
|
|
||||||
if (_mesh->animations() > 1 && ImGui::InputVarInt("Animation index", _animationIndex, 1, 1)) {
|
if (_mesh->animations() > 1 && ImGui::InputVarInt("Animation index", _animationIndex, 1, 1)) {
|
||||||
_animationIndex->setVal(_mesh->currentAnimation());
|
_animationIndex->setVal(_mesh->currentAnimation());
|
||||||
}
|
}
|
||||||
|
@ -320,7 +307,7 @@ void TestMeshApp::doRender() {
|
||||||
_shadowMapRenderShader.setNear(_camera.nearPlane());
|
_shadowMapRenderShader.setNear(_camera.nearPlane());
|
||||||
|
|
||||||
// bind buffers
|
// bind buffers
|
||||||
core_assert_always(_shadowMapDebugBuffer.bind());
|
video::ScopedVertexBuffer scopedBuf(_shadowMapDebugBuffer);
|
||||||
|
|
||||||
// configure shadow map texture
|
// configure shadow map texture
|
||||||
video::bindTexture(video::TextureUnit::Zero, _depthBuffer);
|
video::bindTexture(video::TextureUnit::Zero, _depthBuffer);
|
||||||
|
@ -341,9 +328,6 @@ void TestMeshApp::doRender() {
|
||||||
if (_depthBuffer.depthCompare()) {
|
if (_depthBuffer.depthCompare()) {
|
||||||
video::setupDepthCompareTexture(video::TextureUnit::Zero, _depthBuffer.textureType(), _depthBuffer.texture());
|
video::setupDepthCompareTexture(video::TextureUnit::Zero, _depthBuffer.textureType(), _depthBuffer.texture());
|
||||||
}
|
}
|
||||||
|
|
||||||
// unbind buffer
|
|
||||||
_shadowMapDebugBuffer.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oldDepth) {
|
if (!oldDepth) {
|
||||||
|
|
|
@ -342,7 +342,7 @@ core::AppState IMGUIApp::onRunning() {
|
||||||
|
|
||||||
core_assert_always(_vbo.update(_bufferIndex, cmdList->VtxBuffer.Data, cmdList->VtxBuffer.Size * sizeof(ImDrawVert)));
|
core_assert_always(_vbo.update(_bufferIndex, cmdList->VtxBuffer.Data, cmdList->VtxBuffer.Size * sizeof(ImDrawVert)));
|
||||||
core_assert_always(_vbo.update(_indexBufferIndex, cmdList->IdxBuffer.Data, cmdList->IdxBuffer.Size * sizeof(ImDrawIdx)));
|
core_assert_always(_vbo.update(_indexBufferIndex, cmdList->IdxBuffer.Data, cmdList->IdxBuffer.Size * sizeof(ImDrawIdx)));
|
||||||
core_assert_always(_vbo.bind());
|
video::ScopedVertexBuffer scopedBuf(_vbo);
|
||||||
|
|
||||||
for (int i = 0; i < cmdList->CmdBuffer.Size; ++i) {
|
for (int i = 0; i < cmdList->CmdBuffer.Size; ++i) {
|
||||||
const ImDrawCmd* cmd = &cmdList->CmdBuffer[i];
|
const ImDrawCmd* cmd = &cmdList->CmdBuffer[i];
|
||||||
|
@ -356,7 +356,6 @@ core::AppState IMGUIApp::onRunning() {
|
||||||
}
|
}
|
||||||
idxBufferOffset += cmd->ElemCount;
|
idxBufferOffset += cmd->ElemCount;
|
||||||
}
|
}
|
||||||
_vbo.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
video::scissor(0, 0, renderTargetW, renderTargetH);
|
video::scissor(0, 0, renderTargetW, renderTargetH);
|
||||||
|
|
|
@ -592,7 +592,7 @@ int Mesh::render() {
|
||||||
if (_state != io::IOSTATE_LOADED) {
|
if (_state != io::IOSTATE_LOADED) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_vertexBuffer.bind();
|
video::ScopedVertexBuffer scopedBuf(_vertexBuffer);
|
||||||
int drawCalls = 0;
|
int drawCalls = 0;
|
||||||
for (const RenderMeshData& mesh : _meshData) {
|
for (const RenderMeshData& mesh : _meshData) {
|
||||||
const uint32_t matIdx = mesh.materialIndex;
|
const uint32_t matIdx = mesh.materialIndex;
|
||||||
|
@ -602,8 +602,6 @@ int Mesh::render() {
|
||||||
video::drawElementsBaseVertex<Indices::value_type>(video::Primitive::Triangles, mesh.noOfIndices, mesh.baseIndex, mesh.baseVertex);
|
video::drawElementsBaseVertex<Indices::value_type>(video::Primitive::Triangles, mesh.noOfIndices, mesh.baseIndex, mesh.baseVertex);
|
||||||
++drawCalls;
|
++drawCalls;
|
||||||
}
|
}
|
||||||
_vertexBuffer.unbind();
|
|
||||||
|
|
||||||
return drawCalls;
|
return drawCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,11 +636,10 @@ int Mesh::renderBones(video::Shader& shader) {
|
||||||
boneData.reserve(_boneMapping.size() * 2);
|
boneData.reserve(_boneMapping.size() * 2);
|
||||||
traverseBones(boneData, _scene->mRootNode, glm::mat4(1.0f), glm::vec3(0), false);
|
traverseBones(boneData, _scene->mRootNode, glm::mat4(1.0f), glm::vec3(0), false);
|
||||||
_vertexBufferLines.update(_vertexBufferLinesIndex, boneData.data);
|
_vertexBufferLines.update(_vertexBufferLinesIndex, boneData.data);
|
||||||
_vertexBufferLines.bind();
|
video::ScopedVertexBuffer scopedBuf(_vertexBufferLines);
|
||||||
ScopedLineWidth lineWidth(2.0f);
|
ScopedLineWidth lineWidth(2.0f);
|
||||||
const int elements = _vertexBufferLines.elements(_vertexBufferLinesIndex, 2);
|
const int elements = _vertexBufferLines.elements(_vertexBufferLinesIndex, 2);
|
||||||
video::drawArrays(video::Primitive::Lines, elements);
|
video::drawArrays(video::Primitive::Lines, elements);
|
||||||
_vertexBufferLines.unbind();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -681,11 +678,10 @@ int Mesh::renderNormals(video::Shader& shader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_vertexBufferLines.update(_vertexBufferLinesIndex, normalData.data);
|
_vertexBufferLines.update(_vertexBufferLinesIndex, normalData.data);
|
||||||
_vertexBufferLines.bind();
|
video::ScopedVertexBuffer scopedBuf(_vertexBufferLines);
|
||||||
ScopedLineWidth lineWidth(2.0f);
|
ScopedLineWidth lineWidth(2.0f);
|
||||||
const int elements = _vertexBufferLines.elements(_vertexBufferLinesIndex, 2);
|
const int elements = _vertexBufferLines.elements(_vertexBufferLinesIndex, 2);
|
||||||
video::drawArrays(video::Primitive::Lines, elements);
|
video::drawArrays(video::Primitive::Lines, elements);
|
||||||
_vertexBufferLines.unbind();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
namespace video {
|
namespace video {
|
||||||
|
|
||||||
#ifdef GL_ES_VERSION_2_0
|
#ifdef GL_ES_VERSION_3_1
|
||||||
// default to opengles3
|
// default to opengles3
|
||||||
int Shader::glslVersion = GLSLVersion::V300;
|
int Shader::glslVersion = GLSLVersion::V310;
|
||||||
#else
|
#else
|
||||||
// default to opengl3
|
// default to opengl4
|
||||||
int Shader::glslVersion = GLSLVersion::V330;
|
int Shader::glslVersion = GLSLVersion::V430;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Shader::Shader() {
|
Shader::Shader() {
|
||||||
|
@ -327,14 +327,12 @@ std::string Shader::getSource(ShaderType shaderType, const std::string& buffer,
|
||||||
}
|
}
|
||||||
std::string src;
|
std::string src;
|
||||||
src.append("#version ");
|
src.append("#version ");
|
||||||
if (shaderType == ShaderType::Compute) {
|
src.append(std::to_string(glslVersion));
|
||||||
src.append("430");
|
|
||||||
} else {
|
|
||||||
src.append(std::to_string(glslVersion));
|
|
||||||
}
|
|
||||||
src.append("\n");
|
src.append("\n");
|
||||||
if (glslVersion < GLSLVersion::V140) {
|
if (shaderType == ShaderType::Compute) {
|
||||||
//src.append("#extension GL_EXT_draw_instanced : enable\n");
|
src.append("#extension GL_ARB_compute_shader : enable\n");
|
||||||
|
src.append("#extension GL_ARB_shader_storage_buffer_object : enable\n");
|
||||||
|
src.append("#extension GL_ARB_compute_variable_group_size : enable\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
core::Var::visitSorted([&] (const core::VarPtr& var) {
|
core::Var::visitSorted([&] (const core::VarPtr& var) {
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*/
|
||||||
|
|
||||||
#include "ShaderManager.h"
|
#include "ShaderManager.h"
|
||||||
#include "core/Var.h"
|
#include "core/Var.h"
|
||||||
#include "core/Log.h"
|
#include "core/Log.h"
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
namespace video {
|
namespace video {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Register @c Shader instances here to let them automatically recompile
|
||||||
|
* on @c core::CV_SHADER @c core::CVar change.
|
||||||
|
*
|
||||||
* @ingroup Video
|
* @ingroup Video
|
||||||
*/
|
*/
|
||||||
class ShaderManager {
|
class ShaderManager {
|
||||||
|
|
|
@ -144,7 +144,11 @@ enum class VertexBufferMode {
|
||||||
enum class Primitive {
|
enum class Primitive {
|
||||||
Points,
|
Points,
|
||||||
Lines,
|
Lines,
|
||||||
|
LinesAdjacency,
|
||||||
Triangles,
|
Triangles,
|
||||||
|
TrianglesAdjacency,
|
||||||
|
LineStrip,
|
||||||
|
TriangleStrip,
|
||||||
|
|
||||||
Max
|
Max
|
||||||
};
|
};
|
||||||
|
|
|
@ -170,4 +170,18 @@ inline void VertexBuffer::setMode(int32_t idx, VertexBufferMode mode) {
|
||||||
_modes[idx] = mode;
|
_modes[idx] = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ScopedVertexBuffer {
|
||||||
|
private:
|
||||||
|
const VertexBuffer& _buf;
|
||||||
|
public:
|
||||||
|
ScopedVertexBuffer(const VertexBuffer& buf) :
|
||||||
|
_buf(buf) {
|
||||||
|
buf.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopedVertexBuffer() {
|
||||||
|
_buf.unbind();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,11 @@ static_assert(std::enum_value(Face::Max) == lengthof(Faces), "Array sizes don't
|
||||||
static GLenum Primitives[] {
|
static GLenum Primitives[] {
|
||||||
GL_POINTS,
|
GL_POINTS,
|
||||||
GL_LINES,
|
GL_LINES,
|
||||||
GL_TRIANGLES
|
GL_LINES_ADJACENCY,
|
||||||
|
GL_TRIANGLES,
|
||||||
|
GL_TRIANGLES_ADJACENCY,
|
||||||
|
GL_LINE_STRIP,
|
||||||
|
GL_TRIANGLE_STRIP,
|
||||||
};
|
};
|
||||||
static_assert(std::enum_value(Primitive::Max) == lengthof(Primitives), "Array sizes don't match Max");
|
static_assert(std::enum_value(Primitive::Max) == lengthof(Primitives), "Array sizes don't match Max");
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,6 @@ else()
|
||||||
target_compile_options(${LIB} PRIVATE -O3)
|
target_compile_options(${LIB} PRIVATE -O3)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
generate_compute_shaders(voxel meshextractor)
|
|
||||||
|
|
||||||
set(TEST_SRCS
|
set(TEST_SRCS
|
||||||
tests/AbstractVoxelTest.h
|
tests/AbstractVoxelTest.h
|
||||||
tests/AbstractVoxFormatTest.h tests/AbstractVoxFormatTest.cpp
|
tests/AbstractVoxFormatTest.h tests/AbstractVoxFormatTest.cpp
|
||||||
|
|
|
@ -115,9 +115,8 @@ void OctreeRenderer::renderOctreeNode(const video::Camera& camera, RenderOctreeN
|
||||||
const int numIndices = renderNode->_vb.elements(renderNode->_indexBuffer, 1, sizeof(voxel::IndexType));
|
const int numIndices = renderNode->_vb.elements(renderNode->_indexBuffer, 1, sizeof(voxel::IndexType));
|
||||||
if (numIndices > 0 && renderNode->_renderThisNode) {
|
if (numIndices > 0 && renderNode->_renderThisNode) {
|
||||||
if (camera.isVisible(renderNode->_aabb)) {
|
if (camera.isVisible(renderNode->_aabb)) {
|
||||||
renderNode->_vb.bind();
|
video::ScopedVertexBuffer scopedBuf(renderNode->_vb);
|
||||||
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
||||||
renderNode->_vb.unbind();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ void RawVolumeRenderer::render(const video::Camera& camera) {
|
||||||
if (nIndices == 0) {
|
if (nIndices == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
core_assert_always(_vertexBuffer[idx].bind());
|
video::ScopedVertexBuffer scopedBuf(_vertexBuffer[idx]);
|
||||||
_shadowMapShader.setModel(glm::translate(_offsets[idx]));
|
_shadowMapShader.setModel(glm::translate(_offsets[idx]));
|
||||||
for (int i = 0; i < maxDepthBuffers; ++i) {
|
for (int i = 0; i < maxDepthBuffers; ++i) {
|
||||||
_depthBuffer.bindTexture(i);
|
_depthBuffer.bindTexture(i);
|
||||||
|
@ -228,7 +228,6 @@ void RawVolumeRenderer::render(const video::Camera& camera) {
|
||||||
static_assert(sizeof(voxel::IndexType) == sizeof(uint32_t), "Index type doesn't match");
|
static_assert(sizeof(voxel::IndexType) == sizeof(uint32_t), "Index type doesn't match");
|
||||||
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, nIndices);
|
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, nIndices);
|
||||||
}
|
}
|
||||||
_vertexBuffer[idx].unbind();
|
|
||||||
}
|
}
|
||||||
video::cullFace(video::Face::Back);
|
video::cullFace(video::Face::Back);
|
||||||
if (oldBlend) {
|
if (oldBlend) {
|
||||||
|
@ -255,11 +254,10 @@ void RawVolumeRenderer::render(const video::Camera& camera) {
|
||||||
if (nIndices == 0) {
|
if (nIndices == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
core_assert_always(_vertexBuffer[idx].bind());
|
video::ScopedVertexBuffer scopedBuf(_vertexBuffer[idx]);
|
||||||
_worldShader.setModel(glm::translate(_offsets[idx]));
|
_worldShader.setModel(glm::translate(_offsets[idx]));
|
||||||
static_assert(sizeof(voxel::IndexType) == sizeof(uint32_t), "Index type doesn't match");
|
static_assert(sizeof(voxel::IndexType) == sizeof(uint32_t), "Index type doesn't match");
|
||||||
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, nIndices);
|
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, nIndices);
|
||||||
_vertexBuffer[idx].unbind();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_whiteTexture->unbind();
|
_whiteTexture->unbind();
|
||||||
|
|
|
@ -339,9 +339,8 @@ bool WorldRenderer::renderOpaqueBuffers() {
|
||||||
if (numIndices == 0u) {
|
if (numIndices == 0u) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_opaqueBuffer.bind();
|
video::ScopedVertexBuffer scopedBuf(_opaqueBuffer);
|
||||||
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
||||||
_opaqueBuffer.unbind();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,9 +349,8 @@ bool WorldRenderer::renderWaterBuffers() {
|
||||||
if (numIndices == 0u) {
|
if (numIndices == 0u) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_waterBuffer.bind();
|
video::ScopedVertexBuffer scopedBuf(_waterBuffer);
|
||||||
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
||||||
_waterBuffer.unbind();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +362,7 @@ int WorldRenderer::renderPlants(const std::list<PlantBuffer*>& vbos, int* vertic
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
vbo->vb.bind();
|
video::ScopedVertexBuffer scopedBuf(vbo->vb);
|
||||||
if (vbo->amount == 1) {
|
if (vbo->amount == 1) {
|
||||||
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
video::drawElements<voxel::IndexType>(video::Primitive::Triangles, numIndices);
|
||||||
} else {
|
} else {
|
||||||
|
@ -557,7 +555,7 @@ int WorldRenderer::renderWorld(const video::Camera& camera, int* vertices) {
|
||||||
_shadowMapRenderShader.setNear(camera.nearPlane());
|
_shadowMapRenderShader.setNear(camera.nearPlane());
|
||||||
|
|
||||||
// bind buffers
|
// bind buffers
|
||||||
core_assert_always(_shadowMapDebugBuffer.bind());
|
video::ScopedVertexBuffer scopedBuf(_shadowMapDebugBuffer);
|
||||||
|
|
||||||
// configure shadow map texture
|
// configure shadow map texture
|
||||||
video::bindTexture(video::TextureUnit::Zero, _depthBuffer);
|
video::bindTexture(video::TextureUnit::Zero, _depthBuffer);
|
||||||
|
@ -578,9 +576,6 @@ int WorldRenderer::renderWorld(const video::Camera& camera, int* vertices) {
|
||||||
if (_depthBuffer.depthCompare()) {
|
if (_depthBuffer.depthCompare()) {
|
||||||
video::setupDepthCompareTexture(video::TextureUnit::Zero, _depthBuffer.textureType(), _depthBuffer.texture());
|
video::setupDepthCompareTexture(video::TextureUnit::Zero, _depthBuffer.textureType(), _depthBuffer.texture());
|
||||||
}
|
}
|
||||||
|
|
||||||
// unbind buffer
|
|
||||||
_shadowMapDebugBuffer.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_renderAABBs->boolVal()) {
|
if (_renderAABBs->boolVal()) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ add_subdirectory(testmesh)
|
||||||
add_subdirectory(testtexture)
|
add_subdirectory(testtexture)
|
||||||
add_subdirectory(testplane)
|
add_subdirectory(testplane)
|
||||||
add_subdirectory(testglslcomp)
|
add_subdirectory(testglslcomp)
|
||||||
|
add_subdirectory(testglslgeom)
|
||||||
add_subdirectory(testimgui)
|
add_subdirectory(testimgui)
|
||||||
add_subdirectory(testnuklear)
|
add_subdirectory(testnuklear)
|
||||||
add_subdirectory(testluaui)
|
add_subdirectory(testluaui)
|
||||||
|
|
|
@ -15,11 +15,10 @@ void TestDepthBuffer::doRender() {
|
||||||
const int quadHeight = (int) (height / 3.0f);
|
const int quadHeight = (int) (height / 3.0f);
|
||||||
video::ScopedShader scopedShader(_shadowMapRenderShader);
|
video::ScopedShader scopedShader(_shadowMapRenderShader);
|
||||||
video::ScopedViewPort scopedViewport(width - quadWidth, 0, quadWidth, quadHeight);
|
video::ScopedViewPort scopedViewport(width - quadWidth, 0, quadWidth, quadHeight);
|
||||||
core_assert_always(_texturedFullscreenQuad.bind());
|
video::ScopedVertexBuffer scopedBuf(_texturedFullscreenQuad);
|
||||||
video::bindTexture(video::TextureUnit::Zero, _depthBuffer);
|
video::bindTexture(video::TextureUnit::Zero, _depthBuffer);
|
||||||
_shadowMapRenderShader.setShadowmap(video::TextureUnit::Zero);
|
_shadowMapRenderShader.setShadowmap(video::TextureUnit::Zero);
|
||||||
video::drawArrays(video::Primitive::Triangles, _texturedFullscreenQuad.elements(0));
|
video::drawArrays(video::Primitive::Triangles, _texturedFullscreenQuad.elements(0));
|
||||||
_texturedFullscreenQuad.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
core::AppState TestDepthBuffer::onInit() {
|
core::AppState TestDepthBuffer::onInit() {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
project(testglslgeom)
|
||||||
|
set(SRCS
|
||||||
|
TestGLSLGeom.h TestGLSLGeom.cpp
|
||||||
|
)
|
||||||
|
engine_add_executable(TARGET ${PROJECT_NAME} SRCS ${SRCS} WINDOWED NOINSTALL)
|
||||||
|
engine_target_link_libraries(TARGET ${PROJECT_NAME} DEPENDENCIES testcore imgui)
|
||||||
|
generate_shaders(${PROJECT_NAME} test)
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*/
|
||||||
|
#include "TestGLSLGeom.h"
|
||||||
|
#include "io/Filesystem.h"
|
||||||
|
#include "core/Color.h"
|
||||||
|
#include "video/Camera.h"
|
||||||
|
#include "video/ScopedViewPort.h"
|
||||||
|
|
||||||
|
TestGLSLGeom::TestGLSLGeom(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider) :
|
||||||
|
Super(metric, filesystem, eventBus, timeProvider) {
|
||||||
|
init(ORGANISATION, "testglslgeom");
|
||||||
|
}
|
||||||
|
|
||||||
|
core::AppState TestGLSLGeom::onInit() {
|
||||||
|
core::AppState state = Super::onInit();
|
||||||
|
if (state != core::AppState::Running) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_testShader.setup()) {
|
||||||
|
Log::error("Failed to init the compute shader");
|
||||||
|
return core::AppState::InitFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
_testShader.recordUsedUniforms(true);
|
||||||
|
|
||||||
|
struct Buf {
|
||||||
|
glm::vec4 pos{0, 0, 0, 1};
|
||||||
|
glm::vec3 color{1, 1, 1};
|
||||||
|
};
|
||||||
|
Buf buf;
|
||||||
|
int32_t bufIndex = _buffer.create(&buf, sizeof(buf));
|
||||||
|
_buffer.setMode(bufIndex, video::VertexBufferMode::Static);
|
||||||
|
|
||||||
|
video::Attribute attributePos;
|
||||||
|
attributePos.bufferIndex = bufIndex;
|
||||||
|
attributePos.index = _testShader.getLocationPos();
|
||||||
|
attributePos.size = _testShader.getComponentsPos();
|
||||||
|
attributePos.offset = offsetof(Buf, pos);
|
||||||
|
attributePos.stride = sizeof(Buf);
|
||||||
|
_buffer.addAttribute(attributePos);
|
||||||
|
|
||||||
|
video::Attribute attributeColor;
|
||||||
|
attributeColor.bufferIndex = bufIndex;
|
||||||
|
attributeColor.index = _testShader.getLocationColor();
|
||||||
|
attributeColor.size = _testShader.getComponentsColor();
|
||||||
|
attributeColor.offset = offsetof(Buf, color);
|
||||||
|
attributeColor.stride = sizeof(Buf);
|
||||||
|
_buffer.addAttribute(attributeColor);
|
||||||
|
|
||||||
|
video::clearColor(::core::Color::Black);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
core::AppState TestGLSLGeom::onCleanup() {
|
||||||
|
core::AppState state = Super::onCleanup();
|
||||||
|
_testShader.shutdown();
|
||||||
|
_buffer.shutdown();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestGLSLGeom::onRenderUI() {
|
||||||
|
ImGui::SliderFloat("radius", &_radius, 1.0f, 20.0f);
|
||||||
|
ImGui::SliderInt("sides", &_sides, 2, _testShader.getMaxGeometryVertices());
|
||||||
|
Super::onRenderUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestGLSLGeom::doRender() {
|
||||||
|
video::ScopedShader scopedShd(_testShader);
|
||||||
|
_testShader.setSides(_sides);
|
||||||
|
_testShader.setRadius(_radius);
|
||||||
|
_testShader.setView(_camera.viewMatrix());
|
||||||
|
_testShader.setProjection(_camera.projectionMatrix());
|
||||||
|
video::ScopedVertexBuffer scopedBuf(_buffer);
|
||||||
|
const int elements = _buffer.elements(0, _testShader.getComponentsPos());
|
||||||
|
video::drawArrays(_testShader.getPrimitiveTypeIn(), elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_APP(TestGLSLGeom)
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "testcore/TestApp.h"
|
||||||
|
#include "video/VertexBuffer.h"
|
||||||
|
#include "TestglslgeomShaders.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Visual test for GLSL geometry shaders
|
||||||
|
*
|
||||||
|
* This test application is using a geometry shader to build a sphere from a single point.
|
||||||
|
*/
|
||||||
|
class TestGLSLGeom: public TestApp {
|
||||||
|
private:
|
||||||
|
using Super = TestApp;
|
||||||
|
shader::TestShader _testShader;
|
||||||
|
video::VertexBuffer _buffer;
|
||||||
|
int _sides = 16;
|
||||||
|
float _radius = 10.0f;
|
||||||
|
|
||||||
|
void doRender() override;
|
||||||
|
public:
|
||||||
|
TestGLSLGeom(const metric::MetricPtr& metric, const io::FilesystemPtr& filesystem, const core::EventBusPtr& eventBus, const core::TimeProviderPtr& timeProvider);
|
||||||
|
|
||||||
|
virtual void onRenderUI() override;
|
||||||
|
virtual core::AppState onInit() override;
|
||||||
|
virtual core::AppState onCleanup() override;
|
||||||
|
};
|
|
@ -171,9 +171,6 @@ void TestShapeBuilder::onRenderUI() {
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::Checkbox("Render Axis", &_renderAxis);
|
|
||||||
ImGui::Checkbox("Render Plane", &_renderPlane);
|
|
||||||
|
|
||||||
if (ImGui::Button("Clear")) {
|
if (ImGui::Button("Clear")) {
|
||||||
for (int i = 0; i < _meshCount; ++i) {
|
for (int i = 0; i < _meshCount; ++i) {
|
||||||
_shapeRenderer.deleteMesh(_meshes[i]);
|
_shapeRenderer.deleteMesh(_meshes[i]);
|
||||||
|
|
|
@ -41,6 +41,7 @@ core::AppState ComputeShaderTool::onRunning() {
|
||||||
_shaderDirectory = getArgVal("--shaderdir");
|
_shaderDirectory = getArgVal("--shaderdir");
|
||||||
_sourceDirectory = getArgVal("--sourcedir",
|
_sourceDirectory = getArgVal("--sourcedir",
|
||||||
_filesystem->basePath() + "src/modules/" + _namespaceSrc + "/");
|
_filesystem->basePath() + "src/modules/" + _namespaceSrc + "/");
|
||||||
|
_postfix = getArgVal("--postfix", "");
|
||||||
|
|
||||||
if (!core::string::endsWith(_shaderDirectory, "/")) {
|
if (!core::string::endsWith(_shaderDirectory, "/")) {
|
||||||
_shaderDirectory = _shaderDirectory + "/";
|
_shaderDirectory = _shaderDirectory + "/";
|
||||||
|
@ -68,7 +69,7 @@ core::AppState ComputeShaderTool::onRunning() {
|
||||||
return core::AppState::Cleanup;
|
return core::AppState::Cleanup;
|
||||||
}
|
}
|
||||||
const std::string& templateShader = filesystem()->load(_shaderTemplateFile);
|
const std::string& templateShader = filesystem()->load(_shaderTemplateFile);
|
||||||
if (!computeshadertool::generateSrc(filesystem(), templateShader, _name, _namespaceSrc, _shaderDirectory, _sourceDirectory, _kernels, _structs)) {
|
if (!computeshadertool::generateSrc(filesystem(), templateShader, _name, _namespaceSrc, _shaderDirectory, _sourceDirectory, _kernels, _structs, _postfix)) {
|
||||||
_exitCode = 100;
|
_exitCode = 100;
|
||||||
return core::AppState::Cleanup;
|
return core::AppState::Cleanup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ private:
|
||||||
protected:
|
protected:
|
||||||
std::string _namespaceSrc;
|
std::string _namespaceSrc;
|
||||||
std::string _sourceDirectory;
|
std::string _sourceDirectory;
|
||||||
|
std::string _postfix;
|
||||||
std::string _shaderDirectory;
|
std::string _shaderDirectory;
|
||||||
std::string _computeFilename;
|
std::string _computeFilename;
|
||||||
std::string _shaderTemplateFile;
|
std::string _shaderTemplateFile;
|
||||||
|
|
|
@ -214,7 +214,8 @@ bool generateSrc(const io::FilesystemPtr& filesystem,
|
||||||
const std::string& shaderDirectory,
|
const std::string& shaderDirectory,
|
||||||
const std::string& sourceDirectory,
|
const std::string& sourceDirectory,
|
||||||
const std::vector<Kernel>& _kernels,
|
const std::vector<Kernel>& _kernels,
|
||||||
const std::vector<Struct>& _structs) {
|
const std::vector<Struct>& _structs,
|
||||||
|
const std::string& postfix) {
|
||||||
const std::string name = _name + "Shader";
|
const std::string name = _name + "Shader";
|
||||||
|
|
||||||
std::vector<std::string> shaderNameParts;
|
std::vector<std::string> shaderNameParts;
|
||||||
|
@ -267,7 +268,7 @@ bool generateSrc(const io::FilesystemPtr& filesystem,
|
||||||
src = core::string::replaceAll(src, "$shutdown$", shutdown.str());
|
src = core::string::replaceAll(src, "$shutdown$", shutdown.str());
|
||||||
src = core::string::replaceAll(src, "$structs$", structs.str());
|
src = core::string::replaceAll(src, "$structs$", structs.str());
|
||||||
src = core::string::replaceAll(src, "$createkernels$", createKernels.str());
|
src = core::string::replaceAll(src, "$createkernels$", createKernels.str());
|
||||||
const std::string targetFile = sourceDirectory + filename + ".h";
|
const std::string targetFile = sourceDirectory + filename + ".h" + postfix;
|
||||||
Log::info("Generate shader bindings for %s at %s", _name.c_str(), targetFile.c_str());
|
Log::info("Generate shader bindings for %s at %s", _name.c_str(), targetFile.c_str());
|
||||||
if (!filesystem->syswrite(targetFile, src)) {
|
if (!filesystem->syswrite(targetFile, src)) {
|
||||||
Log::error("Failed to write %s", targetFile.c_str());
|
Log::error("Failed to write %s", targetFile.c_str());
|
||||||
|
|
|
@ -18,6 +18,7 @@ extern bool generateSrc(const io::FilesystemPtr& filesystem,
|
||||||
const std::string& sourceDirectory,
|
const std::string& sourceDirectory,
|
||||||
const std::string& templateShader,
|
const std::string& templateShader,
|
||||||
const std::vector<Kernel>& kernels,
|
const std::vector<Kernel>& kernels,
|
||||||
const std::vector<Struct>& structs);
|
const std::vector<Struct>& structs,
|
||||||
|
const std::string& postfix);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ static const char *convertToTexUnit(int unit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool generateSrc(const std::string& templateShader, const std::string& templateUniformBuffer, const ShaderStruct& shaderStruct,
|
bool generateSrc(const std::string& templateShader, const std::string& templateUniformBuffer, const ShaderStruct& shaderStruct,
|
||||||
const io::FilesystemPtr& filesystem, const std::string& namespaceSrc, const std::string& sourceDirectory, const std::string& shaderDirectory) {
|
const io::FilesystemPtr& filesystem, const std::string& namespaceSrc, const std::string& sourceDirectory, const std::string& shaderDirectory, const std::string& postfix) {
|
||||||
std::string src(templateShader);
|
std::string src(templateShader);
|
||||||
const std::string& name = shaderStruct.name + "Shader";
|
const std::string& name = shaderStruct.name + "Shader";
|
||||||
|
|
||||||
|
@ -93,15 +93,30 @@ bool generateSrc(const std::string& templateShader, const std::string& templateU
|
||||||
attributes << "// no attributes";
|
attributes << "// no attributes";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream setters;
|
std::stringstream methods;
|
||||||
if (uniformSize > 0 || attributeSize > 0) {
|
if (uniformSize > 0 || attributeSize > 0) {
|
||||||
setters << "\n";
|
methods << "\n";
|
||||||
|
}
|
||||||
|
if (shaderStruct.out.layout.maxGeometryVertices > 0) {
|
||||||
|
methods << "\tint getMaxGeometryVertices() const {\n";
|
||||||
|
methods << "\t\treturn " << shaderStruct.out.layout.maxGeometryVertices << ";\n";
|
||||||
|
methods << "\t}\n\n;";
|
||||||
|
}
|
||||||
|
if (shaderStruct.out.layout.primitiveType != video::Primitive::Max) {
|
||||||
|
methods << "\tvideo::Primitive getPrimitiveTypeOut() const {\n";
|
||||||
|
methods << "\t\treturn video::Primitive::" << util::getPrimitiveTypeString(shaderStruct.out.layout.primitiveType) << ";\n";
|
||||||
|
methods << "\t}\n\n;";
|
||||||
|
}
|
||||||
|
if (shaderStruct.in.layout.primitiveType != video::Primitive::Max) {
|
||||||
|
methods << "\tvideo::Primitive getPrimitiveTypeIn() const {\n";
|
||||||
|
methods << "\t\treturn video::Primitive::" << util::getPrimitiveTypeString(shaderStruct.in.layout.primitiveType) << ";\n";
|
||||||
|
methods << "\t}\n\n;";
|
||||||
}
|
}
|
||||||
for (int i = 0; i < uniformSize; ++i) {
|
for (int i = 0; i < uniformSize; ++i) {
|
||||||
const Variable& v = shaderStruct.uniforms[i];
|
const Variable& v = shaderStruct.uniforms[i];
|
||||||
const bool isInteger = v.isSingleInteger();
|
const bool isInteger = v.isSingleInteger();
|
||||||
const std::string& uniformName = util::convertName(v.name, true);
|
const std::string& uniformName = util::convertName(v.name, true);
|
||||||
setters << "\tinline bool set" << uniformName << "(";
|
methods << "\tinline bool set" << uniformName << "(";
|
||||||
const Types& cType = util::resolveTypes(v.type);
|
const Types& cType = util::resolveTypes(v.type);
|
||||||
auto layoutIter = shaderStruct.layouts.find(v.name);
|
auto layoutIter = shaderStruct.layouts.find(v.name);
|
||||||
Layout layout;
|
Layout layout;
|
||||||
|
@ -110,126 +125,119 @@ bool generateSrc(const std::string& templateShader, const std::string& templateU
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.arraySize > 0 && isInteger) {
|
if (v.arraySize > 0 && isInteger) {
|
||||||
setters << "const ";
|
methods << "const ";
|
||||||
} else if (cType.passBy == PassBy::Reference) {
|
} else if (cType.passBy == PassBy::Reference) {
|
||||||
setters << "const ";
|
methods << "const ";
|
||||||
}
|
}
|
||||||
setters << cType.ctype;
|
methods << cType.ctype;
|
||||||
if (v.arraySize == -1 || cType.passBy == PassBy::Pointer) {
|
if (v.arraySize == -1 || cType.passBy == PassBy::Pointer) {
|
||||||
setters << "*";
|
methods << "*";
|
||||||
} else if (cType.passBy == PassBy::Reference) {
|
} else if (cType.passBy == PassBy::Reference) {
|
||||||
if (v.arraySize <= 0) {
|
if (v.arraySize <= 0) {
|
||||||
setters << "&";
|
methods << "&";
|
||||||
}
|
}
|
||||||
} else if (cType.passBy == PassBy::Value) {
|
} else if (cType.passBy == PassBy::Value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.arraySize > 0) {
|
if (v.arraySize > 0) {
|
||||||
setters << " (&" << v.name << ")[" << v.arraySize << "]";
|
methods << " (&" << v.name << ")[" << v.arraySize << "]";
|
||||||
} else {
|
} else {
|
||||||
setters << " " << v.name;
|
methods << " " << v.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.isSampler() && layout.binding != -1) {
|
if (v.isSampler() && layout.binding != -1) {
|
||||||
setters << " = video::TextureUnit::" << convertToTexUnit(layout.binding);
|
methods << " = video::TextureUnit::" << convertToTexUnit(layout.binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.arraySize == -1) {
|
if (v.arraySize == -1) {
|
||||||
setters << ", int amount";
|
methods << ", int amount";
|
||||||
}
|
}
|
||||||
setters << ") const {\n";
|
methods << ") const {\n";
|
||||||
|
|
||||||
setters << "\t\tconst int location = ";
|
methods << "\t\tconst int location = ";
|
||||||
if (layout.location != -1) {
|
if (layout.location != -1) {
|
||||||
setters << layout.location << ";\n";
|
methods << layout.location << ";\n";
|
||||||
} else {
|
} else {
|
||||||
setters << "getUniformLocation(\"" << v.name << "\");\n";
|
methods << "getUniformLocation(\"" << v.name << "\");\n";
|
||||||
setters << "\t\tif (location == -1) {\n";
|
methods << "\t\tif (location == -1) {\n";
|
||||||
setters << "\t\t\treturn false;\n";
|
methods << "\t\t\treturn false;\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
}
|
}
|
||||||
setters << "\t\tsetUniform" << util::uniformSetterPostfix(v.type, v.arraySize == -1 ? 2 : v.arraySize);
|
methods << "\t\tsetUniform" << util::uniformSetterPostfix(v.type, v.arraySize == -1 ? 2 : v.arraySize);
|
||||||
setters << "(location, " << v.name;
|
methods << "(location, " << v.name;
|
||||||
if (v.arraySize > 0) {
|
if (v.arraySize > 0) {
|
||||||
setters << ", " << v.arraySize;
|
methods << ", " << v.arraySize;
|
||||||
} else if (v.arraySize == -1) {
|
} else if (v.arraySize == -1) {
|
||||||
setters << ", amount";
|
methods << ", amount";
|
||||||
}
|
}
|
||||||
setters << ");\n";
|
methods << ");\n";
|
||||||
setters << "\t\treturn true;\n";
|
methods << "\t\treturn true;\n";
|
||||||
setters << "\t}\n";
|
methods << "\t}\n";
|
||||||
|
|
||||||
if (v.isSampler()) {
|
if (v.isSampler()) {
|
||||||
if (layout.binding != -1) {
|
if (layout.binding != -1) {
|
||||||
setters << "\n\tinline video::TextureUnit getBound" << uniformName << "TexUnit() const {\n";
|
methods << "\n\tinline video::TextureUnit getBound" << uniformName << "TexUnit() const {\n";
|
||||||
setters << "\t\treturn video::TextureUnit::" << convertToTexUnit(layout.binding) << ";\n\t}\n";
|
methods << "\t\treturn video::TextureUnit::" << convertToTexUnit(layout.binding) << ";\n\t}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (v.isSampler() || v.isImage()) {
|
if (v.isSampler() || v.isImage()) {
|
||||||
if (layout.imageFormat != video::ImageFormat::Max) {
|
if (layout.imageFormat != video::ImageFormat::Max) {
|
||||||
setters << "\n\tinline video::ImageFormat getImageFormat" << uniformName << "() const {\n";
|
methods << "\n\tinline video::ImageFormat getImageFormat" << uniformName << "() const {\n";
|
||||||
setters << "\t\treturn video::ImageFormat::" << util::getImageFormatTypeString(layout.imageFormat) << ";\n\t}\n";
|
methods << "\t\treturn video::ImageFormat::" << util::getImageFormatTypeString(layout.imageFormat) << ";\n\t}\n";
|
||||||
}
|
}
|
||||||
// TODO: generate texture with correct format and constraints.
|
|
||||||
}
|
|
||||||
if (layout.primitiveType != PrimitiveType::None) {
|
|
||||||
// TODO:
|
|
||||||
}
|
|
||||||
if (layout.blockLayout != BlockLayout::unknown) {
|
|
||||||
// TODO:
|
|
||||||
}
|
}
|
||||||
if (layout.localSize.x != -1) {
|
if (layout.localSize.x != -1) {
|
||||||
setters << "\n\tinline int getLocalSizeX() const {\n";
|
methods << "\n\tinline int getLocalSizeX() const {\n";
|
||||||
setters << "\t\treturn " << layout.localSize.x << ";\n\t}\n";
|
methods << "\t\treturn " << layout.localSize.x << ";\n\t}\n";
|
||||||
}
|
}
|
||||||
if (layout.localSize.y != -1) {
|
if (layout.localSize.y != -1) {
|
||||||
setters << "\n\tinline int getLocalSizeY() const {\n";
|
methods << "\n\tinline int getLocalSizeY() const {\n";
|
||||||
setters << "\t\treturn " << layout.localSize.y << ";\n\t}\n";
|
methods << "\t\treturn " << layout.localSize.y << ";\n\t}\n";
|
||||||
}
|
}
|
||||||
if (layout.localSize.z != -1) {
|
if (layout.localSize.z != -1) {
|
||||||
setters << "\n\tinline int getLocalSizeZ() const {\n";
|
methods << "\n\tinline int getLocalSizeZ() const {\n";
|
||||||
setters << "\t\treturn " << layout.localSize.z << ";\n\t}\n";
|
methods << "\t\treturn " << layout.localSize.z << ";\n\t}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.arraySize > 0) {
|
if (v.arraySize > 0) {
|
||||||
setters << "\n\tinline bool set" << uniformName << "(" << "const std::vector<" << cType.ctype << ">& var) const {\n";
|
methods << "\n\tinline bool set" << uniformName << "(" << "const std::vector<" << cType.ctype << ">& var) const {\n";
|
||||||
setters << "\t\tconst int location = getUniformLocation(\"" << v.name;
|
methods << "\t\tconst int location = getUniformLocation(\"" << v.name;
|
||||||
setters << "\");\n\t\tif (location == -1) {\n";
|
methods << "\");\n\t\tif (location == -1) {\n";
|
||||||
setters << "\t\t\treturn false;\n";
|
methods << "\t\t\treturn false;\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
setters << "\t\tcore_assert((int)var.size() == " << v.arraySize << ");\n";
|
methods << "\t\tcore_assert((int)var.size() == " << v.arraySize << ");\n";
|
||||||
setters << "\t\tsetUniform" << util::uniformSetterPostfix(v.type, v.arraySize) << "(location, &var.front(), var.size());\n";
|
methods << "\t\tsetUniform" << util::uniformSetterPostfix(v.type, v.arraySize) << "(location, &var.front(), var.size());\n";
|
||||||
setters << "\t\treturn true;\n";
|
methods << "\t\treturn true;\n";
|
||||||
setters << "\t}\n";
|
methods << "\t}\n";
|
||||||
} else if (cType.type == Variable::Type::VEC2 || cType.type == Variable::Type::VEC3 || cType.type == Variable::Type::VEC4) {
|
} else if (cType.type == Variable::Type::VEC2 || cType.type == Variable::Type::VEC3 || cType.type == Variable::Type::VEC4) {
|
||||||
setters << "\n\tinline bool set" << uniformName << "(" << "const std::vector<float>& var) const {\n";
|
methods << "\n\tinline bool set" << uniformName << "(" << "const std::vector<float>& var) const {\n";
|
||||||
setters << "\t\tconst int location = getUniformLocation(\"" << v.name;
|
methods << "\t\tconst int location = getUniformLocation(\"" << v.name;
|
||||||
setters << "\");\n\t\tif (location == -1) {\n";
|
methods << "\");\n\t\tif (location == -1) {\n";
|
||||||
setters << "\t\t\treturn false;\n";
|
methods << "\t\t\treturn false;\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
setters << "\t\tcore_assert(int(var.size()) % " << cType.components << " == 0);\n";
|
methods << "\t\tcore_assert(int(var.size()) % " << cType.components << " == 0);\n";
|
||||||
setters << "\t\tsetUniformfv(location, &var.front(), " << cType.components << ", " << cType.components << ");\n";
|
methods << "\t\tsetUniformfv(location, &var.front(), " << cType.components << ", " << cType.components << ");\n";
|
||||||
setters << "\t\treturn true;\n";
|
methods << "\t\treturn true;\n";
|
||||||
setters << "\t}\n";
|
methods << "\t}\n";
|
||||||
}
|
}
|
||||||
if (i < uniformSize- - 2) {
|
if (i < uniformSize- - 2) {
|
||||||
setters << "\n";
|
methods << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (v.arraySize == -1 || v.arraySize > 1) {
|
if (v.arraySize == -1 || v.arraySize > 1) {
|
||||||
setters << "\tinline bool set" << uniformName << "(";
|
methods << "\tinline bool set" << uniformName << "(";
|
||||||
const Types& cType = util::getTypes(v.type);
|
const Types& cType = util::getTypes(v.type);
|
||||||
setters << "const std::vector<" << cType.ctype << ">& " << v.name << ") const {\n";
|
methods << "const std::vector<" << cType.ctype << ">& " << v.name << ") const {\n";
|
||||||
setters << "\t\tif (!hasUniform(\"" << v.name << "[0]\")) {\n";
|
methods << "\t\tif (!hasUniform(\"" << v.name << "[0]\")) {\n";
|
||||||
setters << "\t\t\treturn false;\n";
|
methods << "\t\t\treturn false;\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
setters << "\t\tsetUniform" << util::uniformSetterPostfix(v.type, v.arraySize == -1 ? 2 : v.arraySize);
|
methods << "\t\tsetUniform" << util::uniformSetterPostfix(v.type, v.arraySize == -1 ? 2 : v.arraySize);
|
||||||
setters << "(\"" << v.name << "[0]\", &" << v.name << "[0], " << v.name << ".size());\n";
|
methods << "(\"" << v.name << "[0]\", &" << v.name << "[0], " << v.name << ".size());\n";
|
||||||
setters << "\t\treturn true;\n";
|
methods << "\t\treturn true;\n";
|
||||||
setters << "\t}\n";
|
methods << "\t}\n";
|
||||||
if (i < uniformSize- - 2) {
|
if (i < uniformSize- - 2) {
|
||||||
setters << "\n";
|
methods << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,70 +246,70 @@ bool generateSrc(const std::string& templateShader, const std::string& templateU
|
||||||
const Variable& v = shaderStruct.attributes[i];
|
const Variable& v = shaderStruct.attributes[i];
|
||||||
const std::string& attributeName = util::convertName(v.name, true);
|
const std::string& attributeName = util::convertName(v.name, true);
|
||||||
const bool isInt = v.isInteger();
|
const bool isInt = v.isInteger();
|
||||||
setters << "\tinline bool init" << attributeName << "Custom(size_t stride = ";
|
methods << "\tinline bool init" << attributeName << "Custom(size_t stride = ";
|
||||||
setters << "sizeof(" << util::resolveTypes(v.type).ctype << ")";
|
methods << "sizeof(" << util::resolveTypes(v.type).ctype << ")";
|
||||||
setters << ", const void* pointer = nullptr, video::DataType type = ";
|
methods << ", const void* pointer = nullptr, video::DataType type = ";
|
||||||
if (isInt) {
|
if (isInt) {
|
||||||
setters << "video::DataType::Int";
|
methods << "video::DataType::Int";
|
||||||
} else {
|
} else {
|
||||||
setters << "video::DataType::Float";
|
methods << "video::DataType::Float";
|
||||||
}
|
}
|
||||||
setters << ", int size = ";
|
methods << ", int size = ";
|
||||||
setters << util::resolveTypes(v.type).components << ", ";
|
methods << util::resolveTypes(v.type).components << ", ";
|
||||||
setters << "bool isInt = ";
|
methods << "bool isInt = ";
|
||||||
setters << (isInt ? "true" : "false");
|
methods << (isInt ? "true" : "false");
|
||||||
setters << ", bool normalize = false) const {\n";
|
methods << ", bool normalize = false) const {\n";
|
||||||
setters << "\t\tconst int loc = enableVertexAttributeArray(\"" << v.name << "\");\n";
|
methods << "\t\tconst int loc = enableVertexAttributeArray(\"" << v.name << "\");\n";
|
||||||
setters << "\t\tif (loc == -1) {\n";
|
methods << "\t\tif (loc == -1) {\n";
|
||||||
setters << "\t\t\treturn false;\n";
|
methods << "\t\t\treturn false;\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
setters << "\t\tif (isInt) {\n";
|
methods << "\t\tif (isInt) {\n";
|
||||||
setters << "\t\t\tsetVertexAttributeInt(loc, size, type, stride, pointer);\n";
|
methods << "\t\t\tsetVertexAttributeInt(loc, size, type, stride, pointer);\n";
|
||||||
setters << "\t\t} else {\n";
|
methods << "\t\t} else {\n";
|
||||||
setters << "\t\t\tsetVertexAttribute(loc, size, type, normalize, stride, pointer);\n";
|
methods << "\t\t\tsetVertexAttribute(loc, size, type, normalize, stride, pointer);\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
setters << "\t\treturn true;\n";
|
methods << "\t\treturn true;\n";
|
||||||
setters << "\t}\n\n";
|
methods << "\t}\n\n";
|
||||||
setters << "\tinline int getLocation" << attributeName << "() const {\n";
|
methods << "\tinline int getLocation" << attributeName << "() const {\n";
|
||||||
setters << "\t\treturn getAttributeLocation(\"" << v.name << "\");\n";
|
methods << "\t\treturn getAttributeLocation(\"" << v.name << "\");\n";
|
||||||
setters << "\t}\n\n";
|
methods << "\t}\n\n";
|
||||||
setters << "\tinline int getComponents" << attributeName << "() const {\n";
|
methods << "\tinline int getComponents" << attributeName << "() const {\n";
|
||||||
setters << "\t\treturn getAttributeComponents(\"" << v.name << "\");\n";
|
methods << "\t\treturn getAttributeComponents(\"" << v.name << "\");\n";
|
||||||
setters << "\t}\n\n";
|
methods << "\t}\n\n";
|
||||||
setters << "\tinline bool init" << attributeName << "() const {\n";
|
methods << "\tinline bool init" << attributeName << "() const {\n";
|
||||||
setters << "\t\tconst int loc = enableVertexAttributeArray(\"" << v.name << "\");\n";
|
methods << "\t\tconst int loc = enableVertexAttributeArray(\"" << v.name << "\");\n";
|
||||||
setters << "\t\tif (loc == -1) {\n";
|
methods << "\t\tif (loc == -1) {\n";
|
||||||
setters << "\t\t\treturn false;\n";
|
methods << "\t\t\treturn false;\n";
|
||||||
setters << "\t\t}\n";
|
methods << "\t\t}\n";
|
||||||
setters << "\t\tconst size_t stride = sizeof(" << util::resolveTypes(v.type).ctype << ");\n";
|
methods << "\t\tconst size_t stride = sizeof(" << util::resolveTypes(v.type).ctype << ");\n";
|
||||||
setters << "\t\tconst void* pointer = nullptr;\n";
|
methods << "\t\tconst void* pointer = nullptr;\n";
|
||||||
setters << "\t\tconst video::DataType type = ";
|
methods << "\t\tconst video::DataType type = ";
|
||||||
if (isInt) {
|
if (isInt) {
|
||||||
setters << "video::DataType::Int";
|
methods << "video::DataType::Int";
|
||||||
} else {
|
} else {
|
||||||
setters << "video::DataType::Float";
|
methods << "video::DataType::Float";
|
||||||
}
|
}
|
||||||
setters << ";\n";
|
methods << ";\n";
|
||||||
setters << "\t\tconst int size = getAttributeComponents(loc);\n";
|
methods << "\t\tconst int size = getAttributeComponents(loc);\n";
|
||||||
if (isInt) {
|
if (isInt) {
|
||||||
setters << "\t\tsetVertexAttributeInt(loc, size, type, stride, pointer);\n";
|
methods << "\t\tsetVertexAttributeInt(loc, size, type, stride, pointer);\n";
|
||||||
} else {
|
} else {
|
||||||
setters << "\t\tsetVertexAttribute(loc, size, type, false, stride, pointer);\n";
|
methods << "\t\tsetVertexAttribute(loc, size, type, false, stride, pointer);\n";
|
||||||
}
|
}
|
||||||
setters << "\t\treturn true;\n";
|
methods << "\t\treturn true;\n";
|
||||||
setters << "\t}\n\n";
|
methods << "\t}\n\n";
|
||||||
setters << "\tinline bool set" << attributeName << "Divisor(uint32_t divisor) const {\n";
|
methods << "\tinline bool set" << attributeName << "Divisor(uint32_t divisor) const {\n";
|
||||||
setters << "\t\tconst int location = getAttributeLocation(\"" << v.name << "\");\n";
|
methods << "\t\tconst int location = getAttributeLocation(\"" << v.name << "\");\n";
|
||||||
setters << "\t\treturn setDivisor(location, divisor);\n";
|
methods << "\t\treturn setDivisor(location, divisor);\n";
|
||||||
setters << "\t}\n";
|
methods << "\t}\n";
|
||||||
|
|
||||||
if (i < attributeSize - 1) {
|
if (i < attributeSize - 1) {
|
||||||
setters << "\n";
|
methods << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shaderStruct.uniformBlocks.empty()) {
|
if (!shaderStruct.uniformBlocks.empty()) {
|
||||||
setters << "\n";
|
methods << "\n";
|
||||||
}
|
}
|
||||||
std::stringstream ub;
|
std::stringstream ub;
|
||||||
std::stringstream shutdown;
|
std::stringstream shutdown;
|
||||||
|
@ -354,17 +362,17 @@ bool generateSrc(const std::string& templateShader, const std::string& templateU
|
||||||
ub << "\n\tinline operator const video::UniformBuffer&() const {\n";
|
ub << "\n\tinline operator const video::UniformBuffer&() const {\n";
|
||||||
ub << "\t\treturn _" << uniformBufferName << ";\n";
|
ub << "\t\treturn _" << uniformBufferName << ";\n";
|
||||||
ub << "\t}\n";
|
ub << "\t}\n";
|
||||||
setters << "\t/**\n";
|
methods << "\t/**\n";
|
||||||
setters << "\t * @brief The the uniform buffer for the uniform block " << ubuf.name << "\n";
|
methods << "\t * @brief The the uniform buffer for the uniform block " << ubuf.name << "\n";
|
||||||
setters << "\t */\n";
|
methods << "\t */\n";
|
||||||
setters << "\tinline bool set" << uniformBufferStructName << "(const video::UniformBuffer& buf) {\n";
|
methods << "\tinline bool set" << uniformBufferStructName << "(const video::UniformBuffer& buf) {\n";
|
||||||
setters << "\t\treturn setUniformBuffer(\"" << ubuf.name << "\", buf);\n";
|
methods << "\t\treturn setUniformBuffer(\"" << ubuf.name << "\", buf);\n";
|
||||||
setters << "\t}\n";
|
methods << "\t}\n";
|
||||||
|
|
||||||
std::string generatedUb = core::string::replaceAll(templateUniformBuffer, "$name$", uniformBufferStructName);
|
std::string generatedUb = core::string::replaceAll(templateUniformBuffer, "$name$", uniformBufferStructName);
|
||||||
generatedUb = core::string::replaceAll(generatedUb, "$namespace$", namespaceSrc);
|
generatedUb = core::string::replaceAll(generatedUb, "$namespace$", namespaceSrc);
|
||||||
generatedUb = core::string::replaceAll(generatedUb, "$uniformbuffers$", ub.str());
|
generatedUb = core::string::replaceAll(generatedUb, "$uniformbuffers$", ub.str());
|
||||||
generatedUb = core::string::replaceAll(generatedUb, "$setters$", "");
|
generatedUb = core::string::replaceAll(generatedUb, "$methods$", "");
|
||||||
generatedUb = core::string::replaceAll(generatedUb, "$shutdown$", shutdown.str());
|
generatedUb = core::string::replaceAll(generatedUb, "$shutdown$", shutdown.str());
|
||||||
|
|
||||||
const std::string targetFileUb = sourceDirectory + uniformBufferStructName + ".h";
|
const std::string targetFileUb = sourceDirectory + uniformBufferStructName + ".h";
|
||||||
|
@ -379,10 +387,10 @@ bool generateSrc(const std::string& templateShader, const std::string& templateU
|
||||||
}
|
}
|
||||||
|
|
||||||
src = core::string::replaceAll(src, "$attributes$", attributes.str());
|
src = core::string::replaceAll(src, "$attributes$", attributes.str());
|
||||||
src = core::string::replaceAll(src, "$setters$", setters.str());
|
src = core::string::replaceAll(src, "$methods$", methods.str());
|
||||||
src = core::string::replaceAll(src, "$includes$", includes.str());
|
src = core::string::replaceAll(src, "$includes$", includes.str());
|
||||||
|
|
||||||
const std::string targetFile = sourceDirectory + filename + ".h";
|
const std::string targetFile = sourceDirectory + filename + ".h" + postfix;
|
||||||
Log::debug("Generate shader bindings for %s at %s", shaderStruct.name.c_str(), targetFile.c_str());
|
Log::debug("Generate shader bindings for %s at %s", shaderStruct.name.c_str(), targetFile.c_str());
|
||||||
if (!filesystem->syswrite(targetFile, src)) {
|
if (!filesystem->syswrite(targetFile, src)) {
|
||||||
Log::error("Failed to write %s", targetFile.c_str());
|
Log::error("Failed to write %s", targetFile.c_str());
|
||||||
|
|
|
@ -11,6 +11,6 @@
|
||||||
namespace shadertool {
|
namespace shadertool {
|
||||||
|
|
||||||
extern bool generateSrc(const std::string& templateShader, const std::string& templateUniformBuffer, const ShaderStruct& shaderStruct,
|
extern bool generateSrc(const std::string& templateShader, const std::string& templateUniformBuffer, const ShaderStruct& shaderStruct,
|
||||||
const io::FilesystemPtr& filesystem, const std::string& namespaceSrc, const std::string& sourceDirectory, const std::string& shaderDirectory);
|
const io::FilesystemPtr& filesystem, const std::string& namespaceSrc, const std::string& sourceDirectory, const std::string& shaderDirectory, const std::string& postfix);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
|
|
||||||
namespace shadertool {
|
namespace shadertool {
|
||||||
|
|
||||||
static const char* PrimitiveTypeStr[] {
|
static const char* PrimitiveStr[] {
|
||||||
nullptr,
|
|
||||||
"points",
|
"points",
|
||||||
"lines",
|
"lines",
|
||||||
"lines_adjacency",
|
"lines_adjacency",
|
||||||
|
@ -27,18 +26,15 @@ static const char* PrimitiveTypeStr[] {
|
||||||
"line_strip",
|
"line_strip",
|
||||||
"triangle_strip"
|
"triangle_strip"
|
||||||
};
|
};
|
||||||
static_assert(lengthof(PrimitiveTypeStr) == std::enum_value(PrimitiveType::Max), "PrimitiveTypeStr doesn't match enum");
|
static_assert(lengthof(PrimitiveStr) == std::enum_value(video::Primitive::Max), "PrimitiveStr doesn't match enum");
|
||||||
|
|
||||||
static PrimitiveType layoutPrimitiveType(const std::string& token) {
|
static video::Primitive layoutPrimitiveType(const std::string& token) {
|
||||||
for (int i = 0; i < lengthof(PrimitiveTypeStr); ++i) {
|
for (int i = 0; i < lengthof(PrimitiveStr); ++i) {
|
||||||
if (PrimitiveTypeStr[i] == nullptr) {
|
if (token == PrimitiveStr[i]) {
|
||||||
continue;
|
return (video::Primitive)i;
|
||||||
}
|
|
||||||
if (token == PrimitiveTypeStr[i]) {
|
|
||||||
return (PrimitiveType)i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PrimitiveType::None;
|
return video::Primitive::Max;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseLayout(TokenIterator& tok, Layout& layout) {
|
bool parseLayout(TokenIterator& tok, Layout& layout) {
|
||||||
|
@ -156,7 +152,12 @@ bool parseLayout(TokenIterator& tok, Layout& layout) {
|
||||||
if (format != video::ImageFormat::Max) {
|
if (format != video::ImageFormat::Max) {
|
||||||
layout.imageFormat = format;
|
layout.imageFormat = format;
|
||||||
} else {
|
} else {
|
||||||
Log::warn("Unknown token given for layout: %s (line %i)", token.c_str(), tok.line());
|
video::Primitive primitiveType = layoutPrimitiveType(token);
|
||||||
|
if (primitiveType != video::Primitive::Max) {
|
||||||
|
layout.primitiveType = primitiveType;
|
||||||
|
} else {
|
||||||
|
Log::warn("Unknown token given for layout: %s (line %i)", token.c_str(), tok.line());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (token != ")");
|
} while (token != ")");
|
||||||
|
@ -216,6 +217,10 @@ bool parse(ShaderStruct& shaderStruct, const std::string& shaderFile, const std:
|
||||||
Log::warn("SSBO not supported");
|
Log::warn("SSBO not supported");
|
||||||
} else if (token == "uniform") {
|
} else if (token == "uniform") {
|
||||||
v = &shaderStruct.uniforms;
|
v = &shaderStruct.uniforms;
|
||||||
|
} else if (hasLayout && token == "in") {
|
||||||
|
shaderStruct.in.layout = layout;
|
||||||
|
} else if (hasLayout && token == "out") {
|
||||||
|
shaderStruct.out.layout = layout;
|
||||||
} else if (uniformBlock) {
|
} else if (uniformBlock) {
|
||||||
if (token == "}") {
|
if (token == "}") {
|
||||||
uniformBlock = false;
|
uniformBlock = false;
|
||||||
|
|
|
@ -62,7 +62,7 @@ $uniformarrayinfo$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$setters$
|
$methods$
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<$name$> $name$Ptr;
|
typedef std::shared_ptr<$name$> $name$Ptr;
|
||||||
|
|
|
@ -95,6 +95,7 @@ core::AppState ShaderTool::onRunning() {
|
||||||
_shaderDirectory = getArgVal("--shaderdir");
|
_shaderDirectory = getArgVal("--shaderdir");
|
||||||
_sourceDirectory = getArgVal("--sourcedir",
|
_sourceDirectory = getArgVal("--sourcedir",
|
||||||
_filesystem->basePath() + "src/modules/" + _namespaceSrc + "/");
|
_filesystem->basePath() + "src/modules/" + _namespaceSrc + "/");
|
||||||
|
_postfix = getArgVal("--postfix", "");
|
||||||
|
|
||||||
if (!core::string::endsWith(_shaderDirectory, "/")) {
|
if (!core::string::endsWith(_shaderDirectory, "/")) {
|
||||||
_shaderDirectory = _shaderDirectory + "/";
|
_shaderDirectory = _shaderDirectory + "/";
|
||||||
|
@ -138,7 +139,7 @@ core::AppState ShaderTool::onRunning() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shadertool::generateSrc(templateShader, templateUniformBuffer, _shaderStruct,
|
if (!shadertool::generateSrc(templateShader, templateUniformBuffer, _shaderStruct,
|
||||||
filesystem(), _namespaceSrc, _sourceDirectory, _shaderDirectory)) {
|
filesystem(), _namespaceSrc, _sourceDirectory, _shaderDirectory, _postfix)) {
|
||||||
Log::error("Failed to generate shader source for %s", _shaderfile.c_str());
|
Log::error("Failed to generate shader source for %s", _shaderfile.c_str());
|
||||||
_exitCode = 1;
|
_exitCode = 1;
|
||||||
return core::AppState::Cleanup;
|
return core::AppState::Cleanup;
|
||||||
|
@ -199,7 +200,7 @@ core::AppState ShaderTool::onRunning() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shadertool::generateSrc(templateShader, templateUniformBuffer, _shaderStruct,
|
if (!shadertool::generateSrc(templateShader, templateUniformBuffer, _shaderStruct,
|
||||||
filesystem(), _namespaceSrc, _sourceDirectory, _shaderDirectory)) {
|
filesystem(), _namespaceSrc, _sourceDirectory, _shaderDirectory, _postfix)) {
|
||||||
Log::error("Failed to generate shader source for %s", _shaderfile.c_str());
|
Log::error("Failed to generate shader source for %s", _shaderfile.c_str());
|
||||||
_exitCode = 1;
|
_exitCode = 1;
|
||||||
return core::AppState::Cleanup;
|
return core::AppState::Cleanup;
|
||||||
|
|
|
@ -19,6 +19,7 @@ protected:
|
||||||
ShaderStruct _shaderStruct;
|
ShaderStruct _shaderStruct;
|
||||||
std::string _namespaceSrc;
|
std::string _namespaceSrc;
|
||||||
std::string _sourceDirectory;
|
std::string _sourceDirectory;
|
||||||
|
std::string _postfix;
|
||||||
std::string _shaderDirectory;
|
std::string _shaderDirectory;
|
||||||
std::string _shaderTemplateFile;
|
std::string _shaderTemplateFile;
|
||||||
std::string _glslangValidatorBin;
|
std::string _glslangValidatorBin;
|
||||||
|
|
|
@ -23,18 +23,6 @@ enum class BlockLayout {
|
||||||
std430
|
std430
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PrimitiveType {
|
|
||||||
None,
|
|
||||||
Points,
|
|
||||||
Lines,
|
|
||||||
LinesAdjacency,
|
|
||||||
Triangles,
|
|
||||||
TrianglesAdjacency,
|
|
||||||
LineStrip,
|
|
||||||
TriangleStrip,
|
|
||||||
Max
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Variable {
|
struct Variable {
|
||||||
enum Type {
|
enum Type {
|
||||||
DOUBLE = 0, FLOAT, UNSIGNED_INT, INT, BOOL,
|
DOUBLE = 0, FLOAT, UNSIGNED_INT, INT, BOOL,
|
||||||
|
@ -93,7 +81,7 @@ struct Layout {
|
||||||
bool pixelCenterInteger = false; // 4.0
|
bool pixelCenterInteger = false; // 4.0
|
||||||
bool earlyFragmentTests = false; // 4.2
|
bool earlyFragmentTests = false; // 4.2
|
||||||
glm::ivec3 localSize { -1 };
|
glm::ivec3 localSize { -1 };
|
||||||
PrimitiveType primitiveType = PrimitiveType::None;
|
video::Primitive primitiveType = video::Primitive::Max;
|
||||||
BlockLayout blockLayout = BlockLayout::unknown;
|
BlockLayout blockLayout = BlockLayout::unknown;
|
||||||
video::ImageFormat imageFormat = video::ImageFormat::Max;
|
video::ImageFormat imageFormat = video::ImageFormat::Max;
|
||||||
|
|
||||||
|
@ -110,12 +98,21 @@ struct ImageFormatType {
|
||||||
const char* ctype;
|
const char* ctype;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PrimitiveType {
|
||||||
|
video::Primitive type;
|
||||||
|
const char* str;
|
||||||
|
};
|
||||||
|
|
||||||
struct UniformBlock {
|
struct UniformBlock {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<Variable> members;
|
std::vector<Variable> members;
|
||||||
Layout layout;
|
Layout layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InOut {
|
||||||
|
Layout layout;
|
||||||
|
};
|
||||||
|
|
||||||
struct ShaderStruct {
|
struct ShaderStruct {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
@ -129,4 +126,6 @@ struct ShaderStruct {
|
||||||
std::vector<Variable> varyings;
|
std::vector<Variable> varyings;
|
||||||
// fragment only
|
// fragment only
|
||||||
std::vector<Variable> outs;
|
std::vector<Variable> outs;
|
||||||
|
InOut in;
|
||||||
|
InOut out;
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,7 +21,7 @@ $uniformbuffers$
|
||||||
void shutdown() {
|
void shutdown() {
|
||||||
$shutdown$
|
$shutdown$
|
||||||
}
|
}
|
||||||
$setters$
|
$methods$
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -143,6 +143,29 @@ const char* getImageFormatTypeString(video::ImageFormat format) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PRIMITVEENTRY(x) {video::Primitive::x, #x}
|
||||||
|
static const PrimitiveType cPrimitiveType[] = {
|
||||||
|
PRIMITVEENTRY(Points),
|
||||||
|
PRIMITVEENTRY(Lines),
|
||||||
|
PRIMITVEENTRY(LinesAdjacency),
|
||||||
|
PRIMITVEENTRY(Triangles),
|
||||||
|
PRIMITVEENTRY(TrianglesAdjacency),
|
||||||
|
PRIMITVEENTRY(LineStrip),
|
||||||
|
PRIMITVEENTRY(TriangleStrip)
|
||||||
|
};
|
||||||
|
#undef PRIMITVEENTRY
|
||||||
|
static_assert((size_t)video::Primitive::Max == lengthof(cPrimitiveType), "mismatch in primitive types");
|
||||||
|
|
||||||
|
const char* getPrimitiveTypeString(video::Primitive primitive) {
|
||||||
|
const int max = std::enum_value(video::Primitive::Max);
|
||||||
|
for (int i = 0; i < max; ++i) {
|
||||||
|
if (primitive == cPrimitiveType[i].type) {
|
||||||
|
return cPrimitiveType[i].str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::string uniformSetterPostfix(const Variable::Type type, int amount) {
|
std::string uniformSetterPostfix(const Variable::Type type, int amount) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Variable::MAX:
|
case Variable::MAX:
|
||||||
|
|
|
@ -30,6 +30,8 @@ extern video::ImageFormat getImageFormat(const std::string& type, int line);
|
||||||
extern const char* getImageFormatGLType(video::ImageFormat format);
|
extern const char* getImageFormatGLType(video::ImageFormat format);
|
||||||
extern const char* getImageFormatTypeString(video::ImageFormat format);
|
extern const char* getImageFormatTypeString(video::ImageFormat format);
|
||||||
|
|
||||||
|
extern const char* getPrimitiveTypeString(video::Primitive primitive);
|
||||||
|
|
||||||
extern int getComponents(const Variable::Type type);
|
extern int getComponents(const Variable::Type type);
|
||||||
|
|
||||||
extern Variable::Type getType(const std::string& type, int line);
|
extern Variable::Type getType(const std::string& type, int line);
|
||||||
|
|
Loading…
Reference in New Issue