Skip to content

[axmol-2.0] Support GLES3/OpenGL3 #1279

Closed
@halx99

Description

@halx99

Released

UPDATE

GLES3/OpenGL3 support was moved to milestone 2.0, and still support GLES2.0 for old android device and android simulator marketplace of china

workflow

  1. Write shader language by ESSL 310 or GLSL 450
  2. Add all shader files into project_root/Source/shaders, default shader file extensions: vertex(.vert, .vsh), fragment(.frag, .fsh)
  3. Engine will auto add shader files as glscc compiling files
  4. glscc compile source shaders to target platforms: Desktop GL(GLSL330), GLES3(ESSL300), GLES2(GLSL100), Apple Metal(MSL)
  5. Engine auto sync compiled runtime shader folder(${CMAKE_BINARY_DIR}/runtime/axslc) to target app app_res_root/axslc, and app_res_root/axslc will be added to search path by engine FileUtils implementation.
  6. Start app, load compiled shaders from app_res_root/axslc by shader name.

checklist

  • Mesh instancing draw, implemented by @DelinWorks and adpte metal backend by @halx99
  • axmolengine/glslcc 1.9.0 by @halx99
  • AXGLSLCC.cmake cmake tool by @halx99
  • Migrate engine shaders to ESSL 310 for glslcc spirv happy to compile them to target platforms: ESSL 300, GLES 330, MSL
  • Shader migrate tool: amol-migrate-1.1 by @delin and @halx99, because glslcc(spirv-cross) only accept ESSL310 or GLSL450 as input shader.
  • Android: switch GLES loader to glad for auto loading GLES3 APIs , i.e. glDrawElementsInstanced
  • OpenGL UBO support by @delin @halx99
  • Metal load compiled binary shader files (sgs format specified by glslcc) by @halx99
  • Since use glslcc, the thirdparty glsl-optimizer can be removed, and it's not support compile essl 3.1 to msl, not compatible with new shader workflow.
  • Auto sync compiled shaders ${CMAKE_BINARY_DIR}/runtime/axslc to apps by @halx99
    • win32/linux, use symlink
    • winuwp
    • android
    • macos/ios/tvos, draft works, waiting cmake patch by @halx99 to be merge by kitware
  • Migrate all tests shaders for making cpp_tests works on new shaders
  • Engine Material load needs reimplement due to shader load flow changed
  • Refactor shader load managment: ProgramManager support load cusom shader program immediately and improve register mechanism
  • Text rendering, SDF outline support
  • Remove mat3->mat4 convert, instead, provide math::Mat3 to initialize a GPU layout compatible mat3, both GL3/GLES3/Metal have same mat3 layout, identical to mat3x4
  • Check cpp-tests
  • GLESv2 compatible

Compatibility

  • Since shaders needs compiled by glslcc offline, no longer support embed c++ shaders
  • Don't worry, all changes are in dev branch, and will take long time, the main is the lts for 1.0.x currently. even through, we want merge dev in to main in the future, but before that, we will create a lts branch 1.0.x

New shader looks like

vertex shader:

#version 310 es

layout(location = 0) in vec4 a_position;
layout(location = 1) in vec2 a_texCoord;

layout(location = 0) out vec2 v_texCoord;

layout(std140) uniform vs_ub {
    mat4 u_MVPMatrix;
};

void main()
{
    gl_Position = u_MVPMatrix * a_position;
    v_texCoord = a_texCoord;
}

fragment shader:

#version 310 es
precision highp float;
precision highp int;

layout(location = 0) in vec2 v_texCoord;
layout(binding = 0) uniform sampler2D u_tex0;
layout(location = 0) out vec4 FragColor;

void main()
{
    FragColor =  texture(u_tex0, v_texCoord);
}

Notes

  • all non-sampler uniforms must in uniform block, because glslcc(spirv) limits
  • recommanded use macro for layout location to ensure them are same between vert and frag shader, oterwise, metal render will crash due to layout location between vert and frag shader mismatch
layout(location = POSITION) in vec4 a_position;
layout(location = TEXCOORD0) in vec2 a_texCoord;

layout(location = TEXCOORD0) out vec2 v_texCoord;

layout(std140) uniform vs_ub {
    mat4 u_MVPMatrix;
};

void main()
{
    gl_Position = u_MVPMatrix * a_position;
    v_texCoord = a_texCoord;
}
#version 310 es
precision highp float;
precision highp int;

layout(location = TEXCOORD0) in vec2 v_texCoord;
uniform sampler2D u_tex0;
layout(location = SV_Target0) out vec4 FragColor;

void main()
{
    FragColor =  texture(u_tex0, v_texCoord);
}

Shader syntax migrate summary

  • both vertex & fragment shader should insert version decl #version 310 es in header
  • fragment shader needs precision decls for float & int
  • the quailfier attribute in vertex shader change to in
  • the qualifier varying in vertex shader change to out
  • the quaifier varying in fragment shader change to in
  • the gl_FragColor need replaced by a defined out vec4 variable in fragment shader

Shader restrict or recommands

  • please only write 1 uniform block per shader stage, multi uniform blocks not implemented in metal backend

performance preview (release build)

axmol-dev:
image

axmol-main:
image

cocos2dx-3.17.1
image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions