Skip to content

Commit 399dac7

Browse files
authored
[PROPOSAL] Add wireframe rendering and function classification improvements. (#778)
* Add wireframe rendering and function classification improvements. * Fix platform compilation. * Update CommandBufferGL.cpp GL_LINE and GL_FILL are no present in mobile devices, so the raw value has been used instead. * Update CommandBufferGL.cpp * Try fix IOS compilation * Update CommandBufferMTL.h [skip ci] * GLES & D3D11 wireframe Added crude but okay wireframe mode for GLES and D3D11 devices.
1 parent c21408c commit 399dac7

File tree

15 files changed

+122
-57
lines changed

15 files changed

+122
-57
lines changed

core/3d/CCMesh.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ static Texture2D* getDummyTexture()
111111
Mesh::Mesh()
112112
: _skin(nullptr)
113113
, _visible(true)
114-
, _isTransparent(false)
115-
, _force2DQueue(false)
116114
, meshIndexFormat(CustomCommand::IndexFormat::U_SHORT)
117115
, _meshIndexData(nullptr)
118116
, _blend(BlendFunc::ALPHA_NON_PREMULTIPLIED)
@@ -390,12 +388,13 @@ void Mesh::draw(Renderer* renderer,
390388
uint32_t flags,
391389
unsigned int lightMask,
392390
const Vec4& color,
393-
bool forceDepthWrite)
391+
bool forceDepthWrite,
392+
bool wireframe)
394393
{
395394
if (!isVisible())
396395
return;
397396

398-
bool isTransparent = (_isTransparent || color.w < 1.f);
397+
bool isTransparent = (_material->isTransparent() || color.w < 1.f);
399398
float globalZ = isTransparent ? 0 : globalZOrder;
400399
if (isTransparent)
401400
flags |= Node::FLAGS_RENDER_AS_3D;
@@ -416,8 +415,6 @@ void Mesh::draw(Renderer* renderer,
416415
else
417416
_material->getStateBlock().setDepthWrite(true);
418417

419-
_material->getStateBlock().setBlend(_force2DQueue || isTransparent);
420-
421418
// set default uniforms for Mesh
422419
// 'u_color' and others
423420
const auto scene = Director::getInstance()->getRunningScene();
@@ -441,7 +438,8 @@ void Mesh::draw(Renderer* renderer,
441438
command.init(globalZ, transform);
442439
command.setSkipBatching(isTransparent);
443440
command.setTransparent(isTransparent);
444-
command.set3D(!_force2DQueue);
441+
command.set3D(!_material->isForce2DQueue());
442+
command.setWireframe(wireframe);
445443
}
446444

447445
_meshIndexData->setPrimitiveType(_material->_drawPrimitive);

core/3d/CCMesh.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ class AX_DLL Mesh : public Ref
224224
uint32_t flags,
225225
unsigned int lightMask,
226226
const Vec4& color,
227-
bool forceDepthWrite);
227+
bool forceDepthWrite,
228+
bool wireframe);
228229

229230
/**skin setter*/
230231
void setSkin(MeshSkin* skin);
@@ -239,11 +240,6 @@ class AX_DLL Mesh : public Ref
239240
*/
240241
void calculateAABB();
241242

242-
/**
243-
* force set this Mesh renderer to 2D render queue
244-
*/
245-
void setForce2DQueue(bool force2D) { _force2DQueue = force2D; }
246-
247243
std::string getTextureFileName() { return _texFile; }
248244

249245
Mesh();
@@ -257,8 +253,7 @@ class AX_DLL Mesh : public Ref
257253
std::map<NTextureData::Usage, Texture2D*> _textures; // textures that submesh is using
258254
MeshSkin* _skin; // skin
259255
bool _visible; // is the submesh visible
260-
bool _isTransparent; // is this mesh transparent, it is a property of material in fact
261-
bool _force2DQueue; // add this mesh to 2D render queue
256+
262257
CustomCommand::IndexFormat meshIndexFormat;
263258

264259
std::string _name;

core/3d/CCMeshRenderer.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ MeshRenderer::MeshRenderer()
276276
, _lightMask(-1)
277277
, _shaderUsingLight(false)
278278
, _forceDepthWrite(false)
279+
, _wireframe(false)
279280
, _usingAutogeneratedGLProgram(true)
281+
, _transparentMaterialHint(false)
280282
{}
281283

282284
MeshRenderer::~MeshRenderer()
@@ -408,7 +410,7 @@ MeshRenderer* MeshRenderer::createMeshRendererNode(NodeData* nodedata, ModelData
408410
texParams.sAddressMode = textureData->wrapS;
409411
texParams.tAddressMode = textureData->wrapT;
410412
tex->setTexParameters(texParams);
411-
mesh->_isTransparent = (materialData->getTextureData(NTextureData::Usage::Transparency) != nullptr);
413+
_transparentMaterialHint = materialData->getTextureData(NTextureData::Usage::Transparency) != nullptr;
412414
}
413415
}
414416
textureData = materialData->getTextureData(NTextureData::Usage::Normal);
@@ -512,6 +514,7 @@ void MeshRenderer::genMaterial(bool useLight)
512514
for (auto&& mesh : _meshes)
513515
{
514516
auto material = materials[mesh->getMeshIndexData()->getMeshVertexData()];
517+
material->setTransparent(_transparentMaterialHint);
515518
// keep original state block if exist
516519
auto oldmaterial = mesh->getMaterial();
517520
if (oldmaterial)
@@ -573,8 +576,7 @@ void MeshRenderer::createNode(NodeData* nodedata, Node* root, const MaterialData
573576
texParams.sAddressMode = textureData->wrapS;
574577
texParams.tAddressMode = textureData->wrapT;
575578
tex->setTexParameters(texParams);
576-
mesh->_isTransparent =
577-
(materialData->getTextureData(NTextureData::Usage::Transparency) != nullptr);
579+
_transparentMaterialHint = materialData->getTextureData(NTextureData::Usage::Transparency) != nullptr;
578580
}
579581
}
580582
textureData = materialData->getTextureData(NTextureData::Usage::Normal);
@@ -811,7 +813,7 @@ void MeshRenderer::draw(Renderer* renderer, const Mat4& transform, uint32_t flag
811813
for (auto&& mesh : _meshes)
812814
{
813815
mesh->draw(renderer, _globalZOrder, transform, flags, _lightMask, Vec4(color.r, color.g, color.b, color.a),
814-
_forceDepthWrite);
816+
_forceDepthWrite, _wireframe);
815817
}
816818
}
817819

@@ -946,14 +948,6 @@ Mesh* MeshRenderer::getMesh() const
946948
return _meshes.at(0);
947949
}
948950

949-
void MeshRenderer::setForce2DQueue(bool force2D)
950-
{
951-
for (const auto& mesh : _meshes)
952-
{
953-
mesh->setForce2DQueue(force2D);
954-
}
955-
}
956-
957951
///////////////////////////////////////////////////////////////////////////////////
958952
MeshRendererCache* MeshRendererCache::_cacheInstance = nullptr;
959953
MeshRendererCache* MeshRendererCache::getInstance()

core/3d/CCMeshRenderer.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ class AX_DLL MeshRenderer : public Node, public BlendProtocol
178178
void setLightMask(unsigned int mask) { _lightMask = mask; }
179179
unsigned int getLightMask() const { return _lightMask; }
180180

181+
/** enables wireframe rendering mode for this mesh renderer only, this can be very useful for debugging and
182+
understanding generated meshes. */
183+
void setWireframe(bool value) { _wireframe = value; }
184+
bool isWireframe() const { return _wireframe; }
185+
181186
/** render all meshes within this mesh renderer */
182187
virtual void draw(Renderer* renderer, const Mat4& transform, uint32_t flags) override;
183188

@@ -194,15 +199,11 @@ class AX_DLL MeshRenderer : public Node, public BlendProtocol
194199
*/
195200
void setMaterial(Material* material, int meshIndex);
196201

197-
/** Adds a new material to a particular mesh in this mesh renderer.
198-
* if meshIndex == -1, then it will be applied to all the meshes that belong to this mesh renderer.
202+
/** Gets the material of a specific mesh in this mesh renderer.
199203
*
200-
* @param meshIndex Index of the mesh to apply the material to.
204+
* @param meshIndex Index of the mesh to get the material from. 0 is the default index.
201205
*/
202-
Material* getMaterial(int meshIndex) const;
203-
204-
/** force render this mesh renderer in 2D queue. */
205-
void setForce2DQueue(bool force2D);
206+
Material* getMaterial(int meshIndex = 0) const;
206207

207208
/** Get list of meshes used in this mesh renderer. */
208209
const Vector<Mesh*>& getMeshes() const { return _meshes; }
@@ -265,7 +266,9 @@ class AX_DLL MeshRenderer : public Node, public BlendProtocol
265266
unsigned int _lightMask;
266267
bool _shaderUsingLight; // Is the current shader using lighting?
267268
bool _forceDepthWrite; // Always write to depth buffer
269+
bool _wireframe; // render in wireframe mode
268270
bool _usingAutogeneratedGLProgram;
271+
bool _transparentMaterialHint; // Generate transparent materials when building from files
269272

270273
struct AsyncLoadParam
271274
{

core/renderer/CCMaterial.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,18 @@ std::string Material::getName() const
506506
return _name;
507507
}
508508

509+
void Material::setTransparent(bool value)
510+
{
511+
_isTransparent = value;
512+
getStateBlock().setBlend(_force2DQueue || _isTransparent);
513+
}
514+
515+
void Material::setForce2DQueue(bool value)
516+
{
517+
_force2DQueue = value;
518+
getStateBlock().setBlend(_force2DQueue || _isTransparent);
519+
}
520+
509521
Material::Material() : _name(""), _currentTechnique(nullptr), _target(nullptr) {}
510522

511523
Material::~Material() {}

core/renderer/CCMaterial.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,27 @@ class AX_DLL Material : public Ref
155155
*/
156156
axis::backend::PrimitiveType getPrimitiveType() const { return _drawPrimitive; }
157157

158+
/**
159+
* Enable material transparent rendering.
160+
* WARNING: depth testing will not work.
161+
*/
162+
void setTransparent(bool value);
163+
164+
/**
165+
* Is material transparent?
166+
*/
167+
bool isTransparent() const { return _isTransparent; }
168+
169+
/**
170+
* Enable material 2D queue rendering.
171+
*/
172+
void setForce2DQueue(bool value);
173+
174+
/**
175+
* Is material in 2D render queue?
176+
*/
177+
bool isForce2DQueue() const { return _force2DQueue; }
178+
158179
protected:
159180
Material();
160181
~Material();
@@ -189,6 +210,9 @@ class AX_DLL Material : public Ref
189210
std::unordered_map<std::string, int> _textureSlots;
190211
int _textureSlotIndex = 0;
191212

213+
bool _isTransparent = false; // is this mesh transparent.
214+
bool _force2DQueue = false; // render meshes using this material in 2D render queue.
215+
192216
axis::backend::PrimitiveType _drawPrimitive =
193217
axis::backend::PrimitiveType::TRIANGLE; // primitive draw type for meshes
194218
};

core/renderer/CCRenderCommand.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ class AX_DLL RenderCommand
9292
void set3D(bool value) { _is3D = value; }
9393
/**Get the depth by current model view matrix.*/
9494
float getDepth() const { return _depth; }
95+
/**Whether the command should be rendered in wireframe mode.*/
96+
bool isWireframe() const { return _isWireframe; }
97+
/**Set wireframe render mode for this command.*/
98+
void setWireframe(bool value) { _isWireframe = value; }
9599
/// Can use the result to change the descriptor content.
96100
inline PipelineDescriptor& getPipelineDescriptor() { return _pipelineDescriptor; }
97101

@@ -123,9 +127,12 @@ class AX_DLL RenderCommand
123127
/** Is the command been rendered on 3D pass. */
124128
bool _is3D = false;
125129

126-
/** Depth from the model view matrix.*/
130+
/** Depth from the model view matrix. */
127131
float _depth = 0.f;
128132

133+
/** Polygon render mode set to LINE, which represents wireframe mode. */
134+
bool _isWireframe = false;
135+
129136
Mat4 _mv;
130137

131138
PipelineDescriptor _pipelineDescriptor;

core/renderer/CCRenderer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,12 +731,13 @@ void Renderer::drawCustomCommand(RenderCommand* command)
731731
{
732732
_commandBuffer->setIndexBuffer(cmd->getIndexBuffer());
733733
_commandBuffer->drawElements(cmd->getPrimitiveType(), cmd->getIndexFormat(), cmd->getIndexDrawCount(),
734-
cmd->getIndexDrawOffset());
734+
cmd->getIndexDrawOffset(), cmd->isWireframe());
735735
_drawnVertices += cmd->getIndexDrawCount();
736736
}
737737
else
738738
{
739-
_commandBuffer->drawArrays(cmd->getPrimitiveType(), cmd->getVertexDrawStart(), cmd->getVertexDrawCount());
739+
_commandBuffer->drawArrays(cmd->getPrimitiveType(), cmd->getVertexDrawStart(), cmd->getVertexDrawCount(),
740+
cmd->isWireframe());
740741
_drawnVertices += cmd->getVertexDrawCount();
741742
}
742743
_drawnBatches++;

core/renderer/backend/CommandBuffer.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ class CommandBuffer : public axis::Ref
153153
* @param count For each instance, the number of indexes to draw
154154
* @see `drawElements(PrimitiveType primitiveType, IndexFormat indexType, unsigned int count, unsigned int offset)`
155155
*/
156-
virtual void drawArrays(PrimitiveType primitiveType, std::size_t start, std::size_t count) = 0;
156+
virtual void drawArrays(PrimitiveType primitiveType,
157+
std::size_t start,
158+
std::size_t count,
159+
bool wireframe = false) = 0;
157160

158161
/**
159162
* Draw primitives with an index list.
@@ -167,7 +170,8 @@ class CommandBuffer : public axis::Ref
167170
virtual void drawElements(PrimitiveType primitiveType,
168171
IndexFormat indexType,
169172
std::size_t count,
170-
std::size_t offset) = 0;
173+
std::size_t offset,
174+
bool wireframe = false) = 0;
171175

172176
/**
173177
* Do some resources release.

core/renderer/backend/metal/CommandBufferMTL.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ class CommandBufferMTL : public CommandBuffer
143143
* @param start For each instance, the first index to draw
144144
* @param count For each instance, the number of indexes to draw
145145
* @see `drawElements(PrimitiveType primitiveType, IndexFormat indexType, unsigned int count, unsigned int offset)`
146+
*
147+
* TODO: Implement a wireframe mode for METAL devices. Refer to: https://forums.ogre3d.org/viewtopic.php?t=95089
146148
*/
147-
virtual void drawArrays(PrimitiveType primitiveType, std::size_t start, std::size_t count) override;
149+
virtual void drawArrays(PrimitiveType primitiveType, std::size_t start, std::size_t count, bool wireframe) override;
148150

149151
/**
150152
* Draw primitives with an index list.
@@ -154,11 +156,14 @@ class CommandBufferMTL : public CommandBuffer
154156
* @param offset Byte offset within indexBuffer to start reading indexes from.
155157
* @see `setIndexBuffer(Buffer* buffer)`
156158
* @see `drawArrays(PrimitiveType primitiveType, unsigned int start, unsigned int count)`
159+
*
160+
* TODO: Implement a wireframe mode for METAL devices. Refer to: https://forums.ogre3d.org/viewtopic.php?t=95089
157161
*/
158162
virtual void drawElements(PrimitiveType primitiveType,
159163
IndexFormat indexType,
160164
std::size_t count,
161-
std::size_t offset) override;
165+
std::size_t offset,
166+
bool wireframe) override;
162167

163168
/**
164169
* Do some resources release.

0 commit comments

Comments
 (0)