Merging r6493 through r6517 from trunk to ogl-es branch

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6518 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
cutealien 2023-08-03 19:12:11 +00:00
parent 1de0ec5459
commit e9c494503d
16 changed files with 216 additions and 85 deletions

@ -11,6 +11,10 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
--------------------------
Changes in 1.9 (not yet released)
- Optimize quaternion::rotationFromTo. Thanks @Robert Eisele for patch and proof (https://raw.org/proof/quaternion-from-two-vectors)
- Shader material example shows now how to pass material values.
In 1.8 we could still use gl_FrontMaterial, but that is no longer supported in shaders
- Get IMeshBuffer::append functions working for a few more cases and adapt interface so one can prevent the BoundingBox update.
- Bugfix: SMaterialLayer::operator!= no longer returns true when comparing a layer without texture matrix with one with a set identity texture matrix. Those are the same.
- SMaterialLayer no longer releases allocated texture memory before destructor unless explicitly requested.
This can avoid constantly allocation/releasing memory in the active driver material when setting materials.
@ -404,6 +408,15 @@ Changes in 1.9 (not yet released)
--------------------------
Changes in 1.8.6
- Fix compiling on OSX with case-sensitive filesystems: IrrFramework-Info.plist now always starting with upper-case.
Thanks @Ryan Schmidt for bug report and patch.
- Fix: The build-in libpng now uses same zlib headers as rest of Irrlicht.
This fixes OSX compiling (which didn't have zlib in include path and used system header for this one instead).
Thanks @Ryan Schmidt for bug report.
- Backport parts of COpenGLCommon.h to ensure that COpenGLExtensionHandler, COpenGLShaderMaterialRenderer and COpenGLTexture all use identical GL extension settings
- Backport removing register keywords (deprecated by c++17)
- Backport bugfix from trunk to make CUserPointerAttribute::setString work on 64-bit systems.
- Remove unnecessary implemented assignment operator in quaternion, irrMap, SViewFrustum, line2d and IQ3Shader which cause warnings with -Wdeprecated in newer gcc
- Avoid warning about stringop-overflow in string<T>::subString when compiling in release with newer gcc
- Update library zlib to 1.2.11 (from 1.2.8)
- Update library bzip2 to 1.0.8 (from 1.0.6)

@ -48,8 +48,10 @@ class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
MyShaderCallBack() : WorldViewProjID(-1), TransWorldID(-1), InvWorldID(-1), PositionID(-1),
ColorID(-1), TextureID(-1)
ColorID(-1), TextureID(-1), EmissiveID(-1)
{
for ( int i=0; i<4; ++i )
Emissive[i] = 0.f;
}
virtual void OnCreate(video::IMaterialRendererServices* services, s32 userData)
@ -57,11 +59,15 @@ public:
if (UseHighLevelShaders)
{
// Get shader constants id.
// Constants are "uniforms" in other shading languages.
// And they are not constant at all but can be changed before every draw call
// (the naming probably comes from Direct3D where they are called constants)
WorldViewProjID = services->getVertexShaderConstantID("mWorldViewProj");
TransWorldID = services->getVertexShaderConstantID("mTransWorld");
InvWorldID = services->getVertexShaderConstantID("mInvWorld");
PositionID = services->getVertexShaderConstantID("mLightPos");
ColorID = services->getVertexShaderConstantID("mLightColor");
EmissiveID = services->getPixelShaderConstantID("mEmissive");
// Textures ID are important only for OpenGL interface.
video::IVideoDriver* driver = services->getVideoDriver();
@ -91,6 +97,21 @@ public:
services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1);
}
// Called when any SMaterial value changes
virtual void OnSetMaterial(const irr::video::SMaterial& material)
{
// Remember material values to pass them on to shader in OnSetConstants
Emissive[0] = material.EmissiveColor.getRed() / 255.0f;
Emissive[1] = material.EmissiveColor.getGreen() / 255.0f;
Emissive[2] = material.EmissiveColor.getBlue() / 255.0f;
Emissive[3] = material.EmissiveColor.getAlpha() / 255.0f;
// Note: Until Irrlicht 1.8 it was possible to use gl_FrontMaterial in glsl
// This is no longer supported since Irrlicht 1.9
// Reason: Passing always every material value is slow, harder to port
// and generally getting deprecated in newer shader systems.
}
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
@ -145,6 +166,12 @@ public:
}
else
services->setVertexShaderConstant(world.pointer(), 10, 4);
// Set material values
if (UseHighLevelShaders)
{
services->setPixelShaderConstant(EmissiveID, Emissive, 4);
}
}
private:
@ -154,6 +181,9 @@ private:
s32 PositionID;
s32 ColorID;
s32 TextureID;
s32 EmissiveID;
irr::f32 Emissive[4];
};
/*
@ -398,6 +428,7 @@ int main()
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialFlag(video::EMF_BLEND_OPERATION, true);
node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
node->getMaterial(0).EmissiveColor = irr::video::SColor(0,50,0,50);
smgr->addTextSceneNode(gui->getBuiltInFont(),
L"PS & VS & EMT_TRANSPARENT",

@ -108,17 +108,97 @@ namespace scene
\param numVertices Number of vertices in the array.
\param indices Pointer to index array.
\param numIndices Number of indices in array. */
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) IRR_OVERRIDE
{
// TODO
// We simply assume it has the same vertex and index type as this object. If other types are passed this will crash
append(getVertexType(), vertices, numVertices, getIndexType(), indices, numIndices, updateBoundingBox);
}
//! Append the meshbuffer to the current buffer
/** Only works for compatible vertex types
\param other Buffer to append to this one. */
virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE
/** \param other Buffer to append to this one. */
virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) IRR_OVERRIDE
{
// TODO
append(other->getVertexType(), other->getVertices(), other->getVertexCount(), other->getIndexType(), other->getIndices(), other->getIndexCount(), updateBoundingBox);
}
void append(video::E_VERTEX_TYPE vertexType, const void* const vertices, u32 numVertices, video::E_INDEX_TYPE indexType, const void* const indices, u32 numIndices, bool updateBoundingBox)
{
if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks
return;
const u32 vertexCount = getVertexCount();
VertexBuffer->reallocate(vertexCount+numVertices, false);
if ( vertexType == getVertexType() )
{
const irr::u32 typeSize = getVertexPitchFromType(vertexType);
VertexBuffer->set_used(vertexCount+numVertices);
irr::u8* target = &static_cast<irr::u8*>(VertexBuffer->pointer())[vertexCount*typeSize];
memcpy(target, vertices, numVertices*typeSize);
}
else
{
switch ( vertexType )
{
case video::EVT_STANDARD:
for (u32 i=0; i<numVertices; ++i)
{
VertexBuffer->push_back(static_cast<const video::S3DVertex*>(vertices)[i]);
}
break;
case video::EVT_2TCOORDS:
for (u32 i=0; i<numVertices; ++i)
{
VertexBuffer->push_back(static_cast<const video::S3DVertex2TCoords*>(vertices)[i]);
}
break;
case video::EVT_TANGENTS:
for (u32 i=0; i<numVertices; ++i)
{
VertexBuffer->push_back(static_cast<const video::S3DVertexTangents*>(vertices)[i]);
}
break;
}
}
if ( updateBoundingBox && numVertices > 0)
{
if ( vertexCount == 0 )
BoundingBox.reset( static_cast<const video::S3DVertex*>(vertices)[0].Pos );
const u32 typePitch = getVertexPitchFromType(vertexType);
const irr::u8* v8 = static_cast<const irr::u8*>(vertices);
for (u32 i=0; i<numVertices; ++i, v8 += typePitch)
{
BoundingBox.addInternalPoint(reinterpret_cast<const video::S3DVertex*>(v8)->Pos);
}
}
IndexBuffer->reallocate(getIndexCount()+numIndices, false);
switch ( indexType )
{
case video::EIT_16BIT:
{
const irr::u16* indices16 = reinterpret_cast<const irr::u16*>(indices);
for (u32 i=0; i<numIndices; ++i)
{
// Note: This can overflow, not checked. Will result in broken models, but no crashes.
IndexBuffer->push_back(indices16[i]+vertexCount);
}
break;
}
case video::EIT_32BIT:
{
const irr::u32* indices32 = reinterpret_cast<const irr::u32*>(indices);
for (u32 i=0; i<numIndices; ++i)
{
IndexBuffer->push_back(indices32[i]+vertexCount);
}
break;
}
}
setDirty();
}

@ -191,59 +191,48 @@ namespace scene
//! Append the vertices and indices to the current buffer
/** Only works for compatible types, i.e. either the same type
or the main buffer is of standard type. Otherwise, behavior is
undefined.
undefined. Also can't append it's own vertices/indices to itself.
*/
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) IRR_OVERRIDE
{
if (vertices == getVertices())
if (vertices == getVertices() || indices == getIndices()) // can't do that because we're doing reallocations on those blocks
return;
const u32 vertexCount = getVertexCount();
u32 i;
Vertices.reallocate(vertexCount+numVertices);
Vertices.reallocate(vertexCount+numVertices, false);
for (i=0; i<numVertices; ++i)
{
Vertices.push_back(static_cast<const T*>(vertices)[i]);
}
if ( updateBoundingBox && numVertices > 0)
{
if ( vertexCount == 0 )
BoundingBox.reset(static_cast<const T*>(vertices)[0].Pos);
for (i=0; i<numVertices; ++i)
BoundingBox.addInternalPoint(static_cast<const T*>(vertices)[i].Pos);
}
Indices.reallocate(getIndexCount()+numIndices);
Indices.reallocate(getIndexCount()+numIndices, false);
for (i=0; i<numIndices; ++i)
{
Indices.push_back(indices[i]+vertexCount);
}
setDirty();
}
//! Append the meshbuffer to the current buffer
/** Only works for compatible types, i.e. either the same type
or the main buffer is of standard type. Otherwise, behavior is
undefined.
\param other Meshbuffer to be appended to this one.
*/
virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE
virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) IRR_OVERRIDE
{
/*
if (this==other)
if ( getVertexType() != other->getVertexType() )
return;
const u32 vertexCount = getVertexCount();
u32 i;
Vertices.reallocate(vertexCount+other->getVertexCount());
for (i=0; i<other->getVertexCount(); ++i)
{
Vertices.push_back(reinterpret_cast<const T*>(other->getVertices())[i]);
}
Indices.reallocate(getIndexCount()+other->getIndexCount());
for (i=0; i<other->getIndexCount(); ++i)
{
Indices.push_back(other->getIndices()[i]+vertexCount);
}
BoundingBox.addInternalBox(other->getBoundingBox());
*/
append(other->getVertices(), other->getVertexCount(), other->getIndices(), other->getIndexCount(), updateBoundingBox);
}

@ -24,7 +24,7 @@ public:
//! Destructor
virtual ~IMaterialRendererServices() {}
//! Return an index constant for the vertex shader based on a name.
//! Return an index constant for the vertex shader based on a uniform variable name.
virtual s32 getVertexShaderConstantID(const c8* name) = 0;
//! Call when you set shader constants outside of IShaderConstantSetCallBack
@ -41,27 +41,8 @@ public:
//! Call this when you are done setting shader constants outside of OnCreate or OnSetConstants
virtual void stopUseProgram() {}
//! Sets a constant for the vertex shader based on a name.
/** This can be used if you used a high level shader language like GLSL
or HLSL to create a shader. Example: If you created a shader which has
variables named 'mWorldViewProj' (containing the WorldViewProjection
matrix) and another one named 'fTime' containing one float, you can set
them in your IShaderConstantSetCallBack derived class like this:
\code
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
f32 time = (f32)os::Timer::getTime()/100000.0f;
services->setVertexShaderConstant("fTime", &time, 1);
core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);
}
\endcode
\param index Index of the variable
//! Sets a value for a vertex shader uniform variable.
/**\param index Index of the variable (as received from getVertexShaderConstantID)
\param floats Pointer to array of floats
\param count Amount of floats in array.
\return True if successful.
@ -77,7 +58,7 @@ public:
*/
virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) = 0;
//! Sets a vertex shader constant.
//! Sets a vertex shader constant (or "uniform" in more modern terms)
/** Can be used if you created a shader using pixel/vertex shader
assembler or ARB_fragment_program or ARB_vertex_program.
\param data: Data to be set in the constants
@ -85,14 +66,14 @@ public:
\param constantAmount: Amount of registers to be set. One register consists of 4 floats. */
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0;
//! Return an index constant for the pixel shader based on a name.
//! Return an index constant for the pixel shader for the given uniform variable name
virtual s32 getPixelShaderConstantID(const c8* name) = 0;
//! Sets a constant for the pixel shader based on a name.
//! Sets a value for the given pixel shader uniform variable
/** This can be used if you used a high level shader language like GLSL
or HLSL to create a shader. See setVertexShaderConstant() for an
example on how to use this.
\param index Index of the variable
\param index Index of the variable (as received from getPixelShaderConstantID)
\param floats Pointer to array of floats
\param count Amount of floats in array.
\return True if successful. */
@ -116,6 +97,26 @@ public:
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount=1) = 0;
//! \deprecated. This method may be removed by Irrlicht 2.0
/** This can be used if you use a high level shader language like GLSL
or HLSL to create a shader. Example: If you created a shader which has
variables named 'mWorldViewProj' (containing the WorldViewProjection
matrix) and another one named 'fTime' containing one float, you can set
them in your IShaderConstantSetCallBack derived class like this:
\code
virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
f32 time = (f32)os::Timer::getTime()/100000.0f;
services->setVertexShaderConstant("fTime", &time, 1);
core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);
}
\endcode
**/
IRR_DEPRECATED bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);

@ -126,19 +126,21 @@ namespace scene
virtual const video::SColor& getColor(u32 i) const = 0;
//! Append the vertices and indices to the current buffer
/** Only works for compatible vertex types
and not implemented for most buffers for now.
/** Only works for compatible vertex and index types
and not implemented for some buffers for now.
\param vertices Pointer to a vertex array.
\param numVertices Number of vertices in the array.
\param indices Pointer to index array.
\param numIndices Number of indices in array. */
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) = 0;
\param numIndices Number of indices in array.
\param updateBoundingBox When true update boundingbox by the added vertices */
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox=true) = 0;
//! Not supported right now by any meshbuffer
//! Not supported right now by all meshbuffer
//! In theory: Append the meshbuffer to the current buffer
/** Only works for compatible vertex types
\param other Buffer to append to this one. */
virtual void append(const IMeshBuffer* const other) = 0;
/** Only works for compatible vertex and index types
\param other Buffer to append to this one.
s \param updateBoundingBox When true update boundingbox by the added vertices */
virtual void append(const IMeshBuffer* const other, bool updateBoundingBox=true) = 0;
//! get the current hardware mapping hint
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const = 0;

@ -392,8 +392,7 @@ namespace video
const io::path& name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) =0;
//! Adds a new render target texture with 6 sides for a cubemap map to the texture cache.
/** NOTE: Only supported on D3D9 so far.
\param sideLen Length of one cubemap side.
/** \param sideLen Length of one cubemap side.
\param name A name for the texture. Later calls of getTexture() with this name will return this texture.
The name can _not_ be empty.
\param format The color format of the render target. Floating point formats are supported.

@ -187,13 +187,13 @@ namespace scene
//! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox) IRR_OVERRIDE
{
// can't do that as it doesn't own the vertex memory
}
//! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE
virtual void append(const IMeshBuffer* const other, bool updateBoundingBox) IRR_OVERRIDE
{
// can't do that as it doesn't own the vertex memory
}

@ -355,10 +355,10 @@ struct SSkinMeshBuffer : public IMeshBuffer
}
//! append the vertices and indices to the current buffer
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) IRR_OVERRIDE {}
virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices, bool updateBoundingBox) IRR_OVERRIDE {}
//! append the meshbuffer to the current buffer
virtual void append(const IMeshBuffer* const other) IRR_OVERRIDE {}
virtual void append(const IMeshBuffer* const other, bool updateBoundingBox) IRR_OVERRIDE {}
//! get the current hardware mapping hint for vertex buffers
virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const IRR_OVERRIDE

@ -721,6 +721,8 @@ inline core::quaternion& quaternion::makeIdentity()
inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const vector3df& to)
{
// Based on Stan Melax's article in Game Programming Gems
// Optimized by Robert Eisele: https://raw.org/proof/quaternion-from-two-vectors
// Copy, since cannot modify local
vector3df v0 = from;
vector3df v1 = to;
@ -745,10 +747,8 @@ inline core::quaternion& quaternion::rotationFromTo(const vector3df& from, const
return set(axis.X, axis.Y, axis.Z, 0).normalize();
}
const f32 s = sqrtf( (1+d)*2 ); // optimize inv_sqrt
const f32 invs = 1.f / s;
const vector3df c = v0.crossProduct(v1)*invs;
return set(c.X, c.Y, c.Z, s * 0.5f).normalize();
const vector3df c = v0.crossProduct(v1);
return set(c.X, c.Y, c.Z, 1 + d).normalize();
}

@ -11,6 +11,7 @@ float4x4 mInvWorld; // Inverted world matrix
float4x4 mTransWorld; // Transposed world matrix
float3 mLightPos; // Light position (actually just camera-pos in this case)
float4 mLightColor; // Light color
float4 mEmissive; // Emissive material color
// Vertex shader output structure
@ -83,6 +84,7 @@ PS_OUTPUT pixelMain(float2 TexCoord : TEXCOORD0,
// multiply with diffuse and do other senseless operations
Output.RGBColor = Diffuse * col;
Output.RGBColor *= 4.0;
Output.RGBColor += mEmissive;
return Output;
}

@ -1,9 +1,11 @@
uniform sampler2D myTexture;
uniform vec4 mEmissive;
void main (void)
{
vec4 col = texture2D(myTexture, vec2(gl_TexCoord[0]));
col *= gl_Color;
gl_FragColor = col * 4.0;
gl_FragColor += mEmissive;
}

@ -864,6 +864,7 @@
<Unit filename="COpenGLCoreFeature.h" />
<Unit filename="COpenGLCoreRenderTarget.h" />
<Unit filename="COpenGLCoreTexture.h" />
<Unit filename="COpenGLCommon.h" />
<Unit filename="COpenGLDriver.cpp" />
<Unit filename="COpenGLDriver.h" />
<Unit filename="COpenGLExtensionHandler.cpp" />

@ -1164,7 +1164,6 @@
<ClInclude Include="CZBuffer.h" />
<ClInclude Include="ITriangleRenderer.h" />
<ClInclude Include="IZBuffer.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="S2DVertex.h" />
<ClInclude Include="SB3DStructs.h" />
<ClInclude Include="CColorConverter.h" />

@ -1269,7 +1269,6 @@
<ClInclude Include="..\..\include\IAnimatedMeshMD3.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="CSceneLoaderIrr.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>

@ -27,7 +27,20 @@
/* We must ensure that zlib uses 'const' in declarations. */
# define ZLIB_CONST
#endif
#include "zlib.h"
/* Irrlicht change:
Avoid that build-in png uses a different zlib than the rest of Irrlicht.
Note: This also would allow removing zlib from the include paths, which
probably was done just to hide this bug. Anyway, it's less broken now
than it was and the rest is up to Irrlicht 1.9.
*/
#include "IrrCompileConfig.h"
#ifndef _IRR_USE_NON_SYSTEM_ZLIB_
#include <zlib.h> // use system lib
#else
#include "../zlib/zlib.h"
#endif
#ifdef const
/* zlib.h sometimes #defines const to nothing, undo this. */
# undef const