mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-07-25 04:12:21 +00:00
Uses vertex streams to get attribute locations reducing duplication in XML.
Also adds missing streams. This was SVN commit r26792.
This commit is contained in:
@@ -297,7 +297,7 @@ void InstancingModelRenderer::UpdateModelData(CModel* UNUSED(model), CModelRData
|
||||
// Setup one rendering pass.
|
||||
void InstancingModelRenderer::BeginPass(int streamflags)
|
||||
{
|
||||
ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0|STREAM_UV1)));
|
||||
ENSURE(streamflags == (streamflags & (STREAM_POS|STREAM_NORMAL|STREAM_UV0|STREAM_UV1|STREAM_UV2|STREAM_UV3|STREAM_UV4)));
|
||||
}
|
||||
|
||||
// Cleanup rendering pass.
|
||||
@@ -345,8 +345,7 @@ void InstancingModelRenderer::PrepareModelDef(
|
||||
GL_FALSE, stride, base + m->imodeldef->m_Tangent.offset);
|
||||
}
|
||||
|
||||
// The last UV set is STREAM_UV3
|
||||
for (size_t uv = 0; uv < 4; ++uv)
|
||||
for (size_t uv = 0; uv < 2; ++uv)
|
||||
if (streamflags & (STREAM_UV0 << uv))
|
||||
{
|
||||
if (def.GetNumUVsPerVertex() >= uv + 1)
|
||||
|
||||
@@ -100,41 +100,47 @@ GLenum GLTypeFromFormat(const Renderer::Backend::Format format)
|
||||
return type;
|
||||
}
|
||||
|
||||
int ParseAttribSemantics(Renderer::Backend::GL::CDevice* device, const CStr& str)
|
||||
int GetAttributeLocationFromStream(Renderer::Backend::GL::CDevice* device, const int stream)
|
||||
{
|
||||
// Old mapping makes sense only if we have an old/low-end hardware. Else we
|
||||
// need to use sequential numbering to fix #3054. We use presence of
|
||||
// compute shaders as a check that the hardware has universal CUs.
|
||||
if (device->GetCapabilities().computeShaders)
|
||||
{
|
||||
if (str == "gl_Vertex") return 0;
|
||||
if (str == "gl_Normal") return 1;
|
||||
if (str == "gl_Color") return 2;
|
||||
if (str == "gl_MultiTexCoord0") return 3;
|
||||
if (str == "gl_MultiTexCoord1") return 4;
|
||||
if (str == "gl_MultiTexCoord2") return 5;
|
||||
if (str == "gl_MultiTexCoord3") return 6;
|
||||
if (str == "gl_MultiTexCoord4") return 7;
|
||||
if (str == "gl_MultiTexCoord5") return 8;
|
||||
if (str == "gl_MultiTexCoord6") return 9;
|
||||
if (str == "gl_MultiTexCoord7") return 10;
|
||||
switch (stream)
|
||||
{
|
||||
case STREAM_POS: return 0;
|
||||
case STREAM_NORMAL: return 1;
|
||||
case STREAM_COLOR: return 2;
|
||||
case STREAM_UV0: return 3;
|
||||
case STREAM_UV1: return 4;
|
||||
case STREAM_UV2: return 5;
|
||||
case STREAM_UV3: return 6;
|
||||
case STREAM_UV4: return 7;
|
||||
case STREAM_UV5: return 8;
|
||||
case STREAM_UV6: return 9;
|
||||
case STREAM_UV7: return 10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Map known semantics onto the attribute locations documented by NVIDIA:
|
||||
// https://download.nvidia.com/developer/Papers/2005/OpenGL_2.0/NVIDIA_OpenGL_2.0_Support.pdf
|
||||
// https://developer.download.nvidia.com/opengl/glsl/glsl_release_notes.pdf
|
||||
if (str == "gl_Vertex") return 0;
|
||||
if (str == "gl_Normal") return 2;
|
||||
if (str == "gl_Color") return 3;
|
||||
if (str == "gl_MultiTexCoord0") return 8;
|
||||
if (str == "gl_MultiTexCoord1") return 9;
|
||||
if (str == "gl_MultiTexCoord2") return 10;
|
||||
if (str == "gl_MultiTexCoord3") return 11;
|
||||
if (str == "gl_MultiTexCoord4") return 12;
|
||||
if (str == "gl_MultiTexCoord5") return 13;
|
||||
if (str == "gl_MultiTexCoord6") return 14;
|
||||
if (str == "gl_MultiTexCoord7") return 15;
|
||||
switch (stream)
|
||||
{
|
||||
case STREAM_POS: return 0;
|
||||
case STREAM_NORMAL: return 2;
|
||||
case STREAM_COLOR: return 3;
|
||||
case STREAM_UV0: return 8;
|
||||
case STREAM_UV1: return 9;
|
||||
case STREAM_UV2: return 10;
|
||||
case STREAM_UV3: return 11;
|
||||
case STREAM_UV4: return 12;
|
||||
case STREAM_UV5: return 13;
|
||||
case STREAM_UV6: return 14;
|
||||
case STREAM_UV7: return 15;
|
||||
}
|
||||
}
|
||||
|
||||
debug_warn("Invalid attribute semantics");
|
||||
@@ -815,6 +821,7 @@ public:
|
||||
const GLint size = GLSizeFromFormat(format);
|
||||
const GLenum type = GLTypeFromFormat(format);
|
||||
glVertexAttribPointer(it->second, size, type, normalized, stride, pointer);
|
||||
m_ValidStreams |= STREAM_UV0 << (it->second - (m_Device->GetCapabilities().computeShaders ? 3 : 8));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,17 +882,16 @@ std::unique_ptr<CShaderProgram> CShaderProgram::Create(CDevice* device, const CS
|
||||
// Define all the elements and attributes used in the XML file
|
||||
#define EL(x) int el_##x = XeroFile.GetElementID(#x)
|
||||
#define AT(x) int at_##x = XeroFile.GetAttributeID(#x)
|
||||
EL(attrib);
|
||||
EL(define);
|
||||
EL(fragment);
|
||||
EL(stream);
|
||||
EL(uniform);
|
||||
EL(vertex);
|
||||
AT(attribute);
|
||||
AT(file);
|
||||
AT(if);
|
||||
AT(loc);
|
||||
AT(name);
|
||||
AT(semantics);
|
||||
AT(type);
|
||||
AT(value);
|
||||
#undef AT
|
||||
@@ -904,72 +910,86 @@ std::unique_ptr<CShaderProgram> CShaderProgram::Create(CDevice* device, const CS
|
||||
std::map<CStrIntern, int> vertexAttribs;
|
||||
int streamFlags = 0;
|
||||
|
||||
XERO_ITER_EL(root, Child)
|
||||
XERO_ITER_EL(root, child)
|
||||
{
|
||||
if (Child.GetNodeName() == el_define)
|
||||
if (child.GetNodeName() == el_define)
|
||||
{
|
||||
defines.Add(CStrIntern(Child.GetAttributes().GetNamedItem(at_name)), CStrIntern(Child.GetAttributes().GetNamedItem(at_value)));
|
||||
defines.Add(CStrIntern(child.GetAttributes().GetNamedItem(at_name)), CStrIntern(child.GetAttributes().GetNamedItem(at_value)));
|
||||
}
|
||||
else if (Child.GetNodeName() == el_vertex)
|
||||
else if (child.GetNodeName() == el_vertex)
|
||||
{
|
||||
vertexFile = L"shaders/" + Child.GetAttributes().GetNamedItem(at_file).FromUTF8();
|
||||
vertexFile = L"shaders/" + child.GetAttributes().GetNamedItem(at_file).FromUTF8();
|
||||
|
||||
XERO_ITER_EL(Child, Param)
|
||||
XERO_ITER_EL(child, param)
|
||||
{
|
||||
XMBAttributeList Attrs = Param.GetAttributes();
|
||||
XMBAttributeList attributes = param.GetAttributes();
|
||||
|
||||
CStr cond = Attrs.GetNamedItem(at_if);
|
||||
CStr cond = attributes.GetNamedItem(at_if);
|
||||
if (!cond.empty() && !preprocessor.TestConditional(cond))
|
||||
continue;
|
||||
|
||||
if (Param.GetNodeName() == el_uniform)
|
||||
if (param.GetNodeName() == el_uniform)
|
||||
{
|
||||
vertexUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] = Attrs.GetNamedItem(at_loc).ToInt();
|
||||
vertexUniforms[CStrIntern(attributes.GetNamedItem(at_name))] = attributes.GetNamedItem(at_loc).ToInt();
|
||||
}
|
||||
else if (Param.GetNodeName() == el_stream)
|
||||
else if (param.GetNodeName() == el_stream)
|
||||
{
|
||||
CStr StreamName = Attrs.GetNamedItem(at_name);
|
||||
if (StreamName == "pos")
|
||||
streamFlags |= STREAM_POS;
|
||||
else if (StreamName == "normal")
|
||||
streamFlags |= STREAM_NORMAL;
|
||||
else if (StreamName == "color")
|
||||
streamFlags |= STREAM_COLOR;
|
||||
else if (StreamName == "uv0")
|
||||
streamFlags |= STREAM_UV0;
|
||||
else if (StreamName == "uv1")
|
||||
streamFlags |= STREAM_UV1;
|
||||
else if (StreamName == "uv2")
|
||||
streamFlags |= STREAM_UV2;
|
||||
else if (StreamName == "uv3")
|
||||
streamFlags |= STREAM_UV3;
|
||||
}
|
||||
else if (Param.GetNodeName() == el_attrib)
|
||||
{
|
||||
const int attribLoc = ParseAttribSemantics(device, Attrs.GetNamedItem(at_semantics));
|
||||
vertexAttribs[CStrIntern(Attrs.GetNamedItem(at_name))] = attribLoc;
|
||||
const CStr streamName = attributes.GetNamedItem(at_name);
|
||||
const CStr attributeName = attributes.GetNamedItem(at_attribute);
|
||||
if (attributeName.empty())
|
||||
LOGERROR("Empty attribute name in vertex shader description '%s'", vertexFile.string8().c_str());
|
||||
|
||||
int stream = 0;
|
||||
if (streamName == "pos")
|
||||
stream = STREAM_POS;
|
||||
else if (streamName == "normal")
|
||||
stream = STREAM_NORMAL;
|
||||
else if (streamName == "color")
|
||||
stream = STREAM_COLOR;
|
||||
else if (streamName == "uv0")
|
||||
stream = STREAM_UV0;
|
||||
else if (streamName == "uv1")
|
||||
stream = STREAM_UV1;
|
||||
else if (streamName == "uv2")
|
||||
stream = STREAM_UV2;
|
||||
else if (streamName == "uv3")
|
||||
stream = STREAM_UV3;
|
||||
else if (streamName == "uv4")
|
||||
stream = STREAM_UV4;
|
||||
else if (streamName == "uv5")
|
||||
stream = STREAM_UV5;
|
||||
else if (streamName == "uv6")
|
||||
stream = STREAM_UV6;
|
||||
else if (streamName == "uv7")
|
||||
stream = STREAM_UV7;
|
||||
else
|
||||
LOGERROR("Unknown stream '%s' in vertex shader description '%s'", streamName.c_str(), vertexFile.string8().c_str());
|
||||
|
||||
const int attributeLocation = GetAttributeLocationFromStream(device, stream);
|
||||
vertexAttribs[CStrIntern(attributeName)] = attributeLocation;
|
||||
streamFlags |= stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Child.GetNodeName() == el_fragment)
|
||||
else if (child.GetNodeName() == el_fragment)
|
||||
{
|
||||
fragmentFile = L"shaders/" + Child.GetAttributes().GetNamedItem(at_file).FromUTF8();
|
||||
fragmentFile = L"shaders/" + child.GetAttributes().GetNamedItem(at_file).FromUTF8();
|
||||
|
||||
XERO_ITER_EL(Child, Param)
|
||||
XERO_ITER_EL(child, param)
|
||||
{
|
||||
XMBAttributeList Attrs = Param.GetAttributes();
|
||||
XMBAttributeList attributes = param.GetAttributes();
|
||||
|
||||
CStr cond = Attrs.GetNamedItem(at_if);
|
||||
CStr cond = attributes.GetNamedItem(at_if);
|
||||
if (!cond.empty() && !preprocessor.TestConditional(cond))
|
||||
continue;
|
||||
|
||||
if (Param.GetNodeName() == el_uniform)
|
||||
if (param.GetNodeName() == el_uniform)
|
||||
{
|
||||
// A somewhat incomplete listing, missing "shadow" and "rect" versions
|
||||
// which are interpreted as 2D (NB: our shadowmaps may change
|
||||
// type based on user config).
|
||||
GLenum type = GL_TEXTURE_2D;
|
||||
CStr t = Attrs.GetNamedItem(at_type);
|
||||
const CStr t = attributes.GetNamedItem(at_type);
|
||||
if (t == "sampler1D")
|
||||
#if CONFIG2_GLES
|
||||
debug_warn(L"sampler1D not implemented on GLES");
|
||||
@@ -987,8 +1007,8 @@ std::unique_ptr<CShaderProgram> CShaderProgram::Create(CDevice* device, const CS
|
||||
else if (t == "samplerCube")
|
||||
type = GL_TEXTURE_CUBE_MAP;
|
||||
|
||||
fragmentUniforms[CStrIntern(Attrs.GetNamedItem(at_name))] =
|
||||
std::make_pair(Attrs.GetNamedItem(at_loc).ToInt(), type);
|
||||
fragmentUniforms[CStrIntern(attributes.GetNamedItem(at_name))] =
|
||||
std::make_pair(attributes.GetNamedItem(at_loc).ToInt(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,11 @@ enum
|
||||
STREAM_UV0 = (1 << 3),
|
||||
STREAM_UV1 = (1 << 4),
|
||||
STREAM_UV2 = (1 << 5),
|
||||
STREAM_UV3 = (1 << 6)
|
||||
STREAM_UV3 = (1 << 6),
|
||||
STREAM_UV4 = (1 << 7),
|
||||
STREAM_UV5 = (1 << 8),
|
||||
STREAM_UV6 = (1 << 9),
|
||||
STREAM_UV7 = (1 << 10),
|
||||
};
|
||||
|
||||
namespace Renderer
|
||||
|
||||
Reference in New Issue
Block a user