Skip to content

Commit 1ab111e

Browse files
authored
Re-add ProgramState setTextureArray feature and do improvement (#2649)
* Re-add ProgramState setTextureArray feature and do improvement * OMG, the d3d11 terrain rendering works as expected And previous revision does't work as expected due to texture binding slots incorrect * Restore `ProgramState::setTextureArray` * Improve Terrain rendering, use `uniform sampler2D u_details[4]` to store detailMap textures * Improve Terrain rendering, set alphaMap, lightMap dummy texture RHI independent when they are not used * Fix Terrain rendering doesn't work when use d3d11 * Fix vertex attribute binding cache incorrect * Use macos-14 for ios ci due to unexpected compile error * Upgrade MSL version: 1.2 => 2.0 (requires macos13 and ios 11+) for supporting texture array `sampler2D u_details[4]`
1 parent c50fc03 commit 1ab111e

File tree

14 files changed

+251
-131
lines changed

14 files changed

+251
-131
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ jobs:
144144
templates/**/*.apk
145145
tests/**/*.apk
146146
ios:
147-
runs-on: macos-latest
147+
runs-on: macos-14
148148
strategy:
149149
matrix:
150150
target_os:

1k/build.profiles

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# --- region platfom:common
77

88
# The axmol shader compiler, legacy name is 'glslcc' before axmol-2.3.0
9-
axslcc=1.12.0+
9+
axslcc=1.13.1
1010

1111
# The cmake, @gradle @axmol-cmdline
1212
# as latest as possible

axmol/3d/Terrain.cpp

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ using namespace ax;
4747

4848
namespace ax
4949
{
50-
51-
namespace
52-
{
53-
// It's used for creating a default texture when lightMap is nullpter
54-
static unsigned char ax_2x2_white_image[] = {
55-
// RGBA8888
56-
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
57-
} // namespace
58-
5950
Terrain* Terrain::create(TerrainData& parameter, CrackFixedType fixedType)
6051
{
6152
Terrain* terrain = new Terrain();
@@ -135,37 +126,36 @@ void Terrain::draw(ax::Renderer* renderer, const ax::Mat4& transform, uint32_t f
135126
_programState->setUniform(_lightDirLocation, &_lightDir, sizeof(_lightDir));
136127
if (!_alphaMap)
137128
{
138-
_programState->setTexture(_detailMapLocation[0], 0, _detailMapTextures[0]->getRHITexture());
129+
_programState->setTexture(_detailMapLocation, _detailMapBindings[0].slot, _detailMapBindings[0].tex);
139130
int hasAlphaMap = 0;
140131
_programState->setUniform(_alphaIsHasAlphaMapLocation, &hasAlphaMap, sizeof(hasAlphaMap));
132+
_programState->setTexture(_lightMapLocation, BINDING_SLOT_ALPHA_MAP, _dummyTexture->getRHITexture());
141133
}
142134
else
143135
{
144136
float detailMapSize[4] = {0.0f, 0.0f, 0.0f, 0.0f};
145137
for (int i = 0; i < _maxDetailMapValue; ++i)
146138
{
147-
_programState->setTexture(_detailMapLocation[i], i, _detailMapTextures[i]->getRHITexture());
148139
detailMapSize[i] = _terrainData._detailMaps[i]._detailMapSize;
149140
}
141+
_programState->setTextureArray(_detailMapLocation, _detailMapBindings);
150142
_programState->setUniform(_detailMapSizeLocation, detailMapSize, sizeof(detailMapSize));
151143

152144
int hasAlphaMap = 1;
153145
_programState->setUniform(_alphaIsHasAlphaMapLocation, &hasAlphaMap, sizeof(hasAlphaMap));
154-
_programState->setTexture(_alphaMapLocation, 4, _alphaMap->getRHITexture());
146+
_programState->setTexture(_alphaMapLocation, BINDING_SLOT_ALPHA_MAP, _alphaMap->getRHITexture());
155147
}
156148
if (_lightMap)
157149
{
158150
int hasLightMap = 1;
159151
_programState->setUniform(_lightMapCheckLocation, &hasLightMap, sizeof(hasLightMap));
160-
_programState->setTexture(_lightMapLocation, 5, _lightMap->getRHITexture());
152+
_programState->setTexture(_lightMapLocation, BINDING_SLOT_LIGHT_MAP, _lightMap->getRHITexture());
161153
}
162154
else
163155
{
164156
int hasLightMap = 0;
165157
_programState->setUniform(_lightMapCheckLocation, &hasLightMap, sizeof(hasLightMap));
166-
#if AX_RENDER_API == AX_RENDER_API_MTL || AX_RENDER_API == AX_RENDER_API_D3D
167-
_programState->setTexture(_lightMapLocation, 5, _detailMapTextures[0]->getRHITexture());
168-
#endif
158+
_programState->setTexture(_lightMapLocation, BINDING_SLOT_LIGHT_MAP, _dummyTexture->getRHITexture());
169159
}
170160
auto camera = Camera::getVisitingCamera();
171161

@@ -265,14 +255,8 @@ Terrain::Terrain()
265255
EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom*) { reload(); });
266256
_director->getEventDispatcher()->addEventListenerWithFixedPriority(_backToForegroundListener, 1);
267257
#endif
268-
#if AX_RENDER_API == AX_RENDER_API_MTL || AX_RENDER_API == AX_RENDER_API_D3D
269-
auto image = new Image();
270-
bool AX_UNUSED isOK = image->initWithRawData(ax_2x2_white_image, sizeof(ax_2x2_white_image), 2, 2, 8);
271-
AXASSERT(isOK, "The 2x2 empty texture was created unsuccessfully.");
272-
_dummyTexture = new Texture2D();
273-
_dummyTexture->initWithImage(image);
274-
AX_SAFE_RELEASE(image);
275-
#endif
258+
_dummyTexture = _director->getTextureCache()->getWhiteTexture();
259+
AX_SAFE_RETAIN(_dummyTexture);
276260
}
277261

278262
void Terrain::setChunksLOD(const Vec3& cameraPos)
@@ -477,6 +461,7 @@ Terrain::~Terrain()
477461
{
478462
_detailMapTextures[i]->release();
479463
}
464+
_detailMapBindings[i].reset();
480465
}
481466
for (int i = 0; i < MAX_CHUNKES; ++i)
482467
{
@@ -689,14 +674,16 @@ void Terrain::setDetailMap(unsigned int index, DetailMap detailMap)
689674
_terrainData._detailMaps[index] = detailMap;
690675
if (_detailMapTextures[index])
691676
{
692-
693677
_detailMapTextures[index]->release();
694678
}
695679
_detailMapTextures[index] = new Texture2D();
696680
auto textImage = new Image();
697681
textImage->initWithImageFile(detailMap._detailMapSrc);
698682
_detailMapTextures[index]->initWithImage(textImage);
699683
delete textImage;
684+
685+
_detailMapBindings[index].slot = BINDING_SLOT_DETAIL_BASE + index;
686+
_detailMapBindings[index].tex = _detailMapTextures[index]->getRHITexture();
700687
}
701688

702689
Terrain::ChunkIndices Terrain::lookForIndicesLOD(int neighborLod[4], int selfLod, bool* result)
@@ -799,26 +786,18 @@ void Terrain::onEnter()
799786
void Terrain::cacheUniformAttribLocation()
800787
{
801788
_alphaMapLocation.reset();
802-
for (int i = 0; i < 4; ++i)
803-
{
804-
_detailMapLocation[i].reset();
805-
}
789+
_detailMapLocation.reset();
806790
_detailMapSizeLocation.reset();
807791

808792
_alphaIsHasAlphaMapLocation = _programState->getUniformLocation("u_has_alpha");
809793
_lightMapCheckLocation = _programState->getUniformLocation("u_has_light_map");
810794
if (!_alphaMap)
811795
{
812-
_detailMapLocation[0] = _programState->getUniformLocation("u_tex0");
796+
_detailMapLocation = _programState->getUniformLocation("u_details");
813797
}
814798
else
815799
{
816-
char str[20];
817-
for (int i = 0; i < _maxDetailMapValue; ++i)
818-
{
819-
auto key = fmt::format_to_z(str, "u_tex{}", i);
820-
_detailMapLocation[i] = _programState->getUniformLocation(key);
821-
}
800+
_detailMapLocation = _programState->getUniformLocation("u_details");
822801

823802
_detailMapSizeLocation = _programState->getUniformLocation("u_detailSize"); // float[4]
824803

@@ -834,6 +813,7 @@ bool Terrain::initTextures()
834813
for (int i = 0; i < 4; ++i)
835814
{
836815
_detailMapTextures[i] = nullptr;
816+
_detailMapBindings[i].reset();
837817
}
838818

839819
rhi::TextureDesc texDesc;
@@ -855,6 +835,9 @@ bool Terrain::initTextures()
855835
texture->initWithSpec(texDesc, subDatas);
856836
_detailMapTextures[0] = texture;
857837
image->release();
838+
839+
_detailMapBindings[0].slot = BINDING_SLOT_DETAIL_BASE;
840+
_detailMapBindings[0].tex = texture->getRHITexture();
858841
}
859842
else
860843
{
@@ -887,6 +870,9 @@ bool Terrain::initTextures()
887870
texture->initWithSpec(texDesc, subDatas);
888871
_detailMapTextures[i] = texture;
889872

873+
_detailMapBindings[i].slot = BINDING_SLOT_DETAIL_BASE + i;
874+
_detailMapBindings[i].tex = texture->getRHITexture();
875+
890876
image->release();
891877
}
892878
}

axmol/3d/Terrain.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ class AX_DLL Terrain : public Node
100100
INCREASE_LOWER,
101101
};
102102

103+
/* must match in shader terrain.frag
104+
layout(binding = 0) uniform sampler2D u_details[4]; // will take slot 0~3
105+
layout(binding = 4) uniform sampler2D u_alphaMap;
106+
layout(binding = 5) uniform sampler2D u_lightMap;
107+
*/
108+
enum TextureBindingSlot {
109+
BINDING_SLOT_DETAIL_BASE = 0,
110+
BINDING_SLOT_ALPHA_MAP = 4,
111+
BINDING_SLOT_LIGHT_MAP = 5
112+
};
113+
103114
/**
104115
*DetailMap
105116
*this struct maintain a detail map data ,including source file ,detail size.
@@ -524,6 +535,7 @@ class AX_DLL Terrain : public Node
524535
unsigned char* _data;
525536
float _lodDistance[3];
526537
Texture2D* _detailMapTextures[4];
538+
rhi::TextureBinding _detailMapBindings[4]; // weak ref
527539
Texture2D* _alphaMap;
528540
Texture2D* _lightMap;
529541
Texture2D* _dummyTexture = nullptr;
@@ -561,7 +573,7 @@ class AX_DLL Terrain : public Node
561573

562574
private:
563575
// uniform locations
564-
rhi::UniformLocation _detailMapLocation[4];
576+
rhi::UniformLocation _detailMapLocation;
565577
rhi::UniformLocation _alphaMapLocation;
566578
rhi::UniformLocation _alphaIsHasAlphaMapLocation;
567579
rhi::UniformLocation _lightMapCheckLocation;

axmol/3d/VertexInputBinding.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ namespace ax
3333
{
3434

3535
/**
36-
* axmol-3.0: we use meshIndexData+instancing as key to ensure cache hit
36+
* axmol-3.0: we use meshIndexData+program+instancing as key to ensure cache hit
3737
* older version: cache miss always due to programState always changes when switch
3838
* render objects
3939
*/
@@ -67,12 +67,14 @@ VertexInputBinding* VertexInputBinding::spawn(MeshIndexData* meshIndexData,
6767
struct HashMe
6868
{
6969
MeshIndexData* meshData;
70+
Program* shaderProg;
7071
bool instancing;
7172
};
7273

7374
HashMe hashMe;
7475
memset(&hashMe, 0, sizeof(hashMe));
7576
hashMe.meshData = meshIndexData;
77+
hashMe.shaderProg = pass->getProgramState()->getProgram();
7678
hashMe.instancing = instancing;
7779

7880
auto hash = XXH32(&hashMe, sizeof(hashMe), 0);
@@ -166,7 +168,7 @@ void VertexInputBinding::setVertexInputPointer(VertexLayoutDesc& desc,
166168
}
167169
else
168170
{
169-
AXLOGD("VertexInputBinding: warning: attribute: '{}' not present in shader", name);
171+
AXLOGI("VertexInputBinding: attribute: '{}' not present in shader", name);
170172
}
171173
}
172174

axmol/renderer/shaders/terrain.frag

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,8 @@ precision highp int;
66

77
layout(location = TEXCOORD0) in vec2 v_texCoord;
88
layout(location = NORMAL) in vec3 v_normal;
9-
layout(binding = 0) uniform sampler2D u_alphaMap;
10-
layout(binding = 1) uniform sampler2D u_tex0;
11-
layout(binding = 2) uniform sampler2D u_tex1;
12-
layout(binding = 3) uniform sampler2D u_tex2;
13-
layout(binding = 4) uniform sampler2D u_tex3;
9+
layout(binding = 0) uniform sampler2D u_details[4]; // will take slot 0~3
10+
layout(binding = 4) uniform sampler2D u_alphaMap;
1411
layout(binding = 5) uniform sampler2D u_lightMap;
1512
layout(std140) uniform fs_ub {
1613
int u_has_alpha;
@@ -35,15 +32,15 @@ void main()
3532
float lightFactor = dot(-u_lightDir,v_normal);
3633
if(u_has_alpha<=0)
3734
{
38-
FragColor = texture(u_tex0, v_texCoord)*lightColor*lightFactor;
35+
FragColor = texture(u_details[0], v_texCoord)*lightColor*lightFactor;
3936
}
4037
else
4138
{
4239
vec4 blendFactor =texture(u_alphaMap,v_texCoord);
4340
vec4 color = vec4(0.0,0.0,0.0,0.0);
44-
color = texture(u_tex0, v_texCoord*vfloat_at(u_detailSize, 0))*blendFactor.r +
45-
texture(u_tex1, v_texCoord*vfloat_at(u_detailSize, 1))*blendFactor.g + texture(u_tex2, v_texCoord*vfloat_at(u_detailSize, 2))*blendFactor.b
46-
+ texture(u_tex3, v_texCoord*vfloat_at(u_detailSize, 3))*(1.0 - blendFactor.a);
41+
color = texture(u_details[0], v_texCoord*vfloat_at(u_detailSize, 0))*blendFactor.r +
42+
texture(u_details[1], v_texCoord*vfloat_at(u_detailSize, 1))*blendFactor.g + texture(u_details[2], v_texCoord*vfloat_at(u_detailSize, 2))*blendFactor.b
43+
+ texture(u_details[3], v_texCoord*vfloat_at(u_detailSize, 3))*(1.0 - blendFactor.a);
4744
FragColor = vec4(color.rgb*lightColor.rgb*lightFactor, 1.0);
4845
}
4946
}

0 commit comments

Comments
 (0)