mirror of
https://github.com/minetest/minetest.git
synced 2025-01-06 21:37:30 +01:00
IrrlichtMt: Move OpenGL 3+ transformation matrix to shaders (#15591)
This replaces annoying calculations on C++-side and eases the implementation of 2D geometry batch rendering a lot.
This commit is contained in:
parent
412cc96bc9
commit
35bc217ba8
@ -9,6 +9,7 @@ attribute vec2 inTexCoord0;
|
||||
/* Uniforms */
|
||||
|
||||
uniform float uThickness;
|
||||
uniform mat4 uProjection;
|
||||
|
||||
/* Varyings */
|
||||
|
||||
@ -17,7 +18,7 @@ varying vec4 vVertexColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = inVertexPosition;
|
||||
gl_Position = uProjection * inVertexPosition;
|
||||
gl_PointSize = uThickness;
|
||||
vTextureCoord = inTexCoord0;
|
||||
vVertexColor = inVertexColor.bgra;
|
||||
|
@ -689,58 +689,32 @@ void COpenGL3DriverBase::drawVertexPrimitiveList(const void *vertices, u32 verte
|
||||
|
||||
setRenderStates3DMode();
|
||||
|
||||
auto &vTypeDesc = getVertexTypeDescription(vType);
|
||||
beginDraw(vTypeDesc, reinterpret_cast<uintptr_t>(vertices));
|
||||
GLenum indexSize = 0;
|
||||
|
||||
switch (iType) {
|
||||
case (EIT_16BIT): {
|
||||
indexSize = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
}
|
||||
case (EIT_32BIT): {
|
||||
indexSize = GL_UNSIGNED_INT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (pType) {
|
||||
case scene::EPT_POINTS:
|
||||
case scene::EPT_POINT_SPRITES:
|
||||
GL.DrawArrays(GL_POINTS, 0, primitiveCount);
|
||||
break;
|
||||
case scene::EPT_LINE_STRIP:
|
||||
GL.DrawElements(GL_LINE_STRIP, primitiveCount + 1, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_LINE_LOOP:
|
||||
GL.DrawElements(GL_LINE_LOOP, primitiveCount, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_LINES:
|
||||
GL.DrawElements(GL_LINES, primitiveCount * 2, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_TRIANGLE_STRIP:
|
||||
GL.DrawElements(GL_TRIANGLE_STRIP, primitiveCount + 2, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_TRIANGLE_FAN:
|
||||
GL.DrawElements(GL_TRIANGLE_FAN, primitiveCount + 2, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_TRIANGLES:
|
||||
GL.DrawElements((LastMaterial.Wireframe) ? GL_LINES : (LastMaterial.PointCloud) ? GL_POINTS
|
||||
: GL_TRIANGLES,
|
||||
primitiveCount * 3, indexSize, indexList);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
endDraw(vTypeDesc);
|
||||
drawGeneric(vertices, indexList, primitiveCount, vType, pType, iType);
|
||||
}
|
||||
|
||||
//! draws a vertex primitive list in 2d
|
||||
void COpenGL3DriverBase::draw2DVertexPrimitiveList(const void *vertices, u32 vertexCount,
|
||||
const void *indexList, u32 primitiveCount,
|
||||
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
|
||||
{
|
||||
os::Printer::log("draw2DVertexPrimitiveList unimplemented", ELL_ERROR);
|
||||
if (!primitiveCount || !vertexCount)
|
||||
return;
|
||||
|
||||
if (!vertices)
|
||||
return;
|
||||
|
||||
if (!checkPrimitiveCount(primitiveCount))
|
||||
return;
|
||||
|
||||
CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);
|
||||
|
||||
setRenderStates2DMode(
|
||||
Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA,
|
||||
Material.getTexture(0),
|
||||
Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL
|
||||
);
|
||||
|
||||
drawGeneric(vertices, indexList, primitiveCount, vType, pType, iType);
|
||||
}
|
||||
|
||||
void COpenGL3DriverBase::draw2DImage(const video::ITexture *texture, const core::position2d<s32> &destPos,
|
||||
@ -803,10 +777,10 @@ void COpenGL3DriverBase::draw2DImage(const video::ITexture *texture, const core:
|
||||
clipRect->getWidth(), clipRect->getHeight());
|
||||
}
|
||||
|
||||
f32 left = (f32)destRect.UpperLeftCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 right = (f32)destRect.LowerRightCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 down = 2.f - (f32)destRect.LowerRightCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 top = 2.f - (f32)destRect.UpperLeftCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 left = (f32)destRect.UpperLeftCorner.X;
|
||||
f32 right = (f32)destRect.LowerRightCorner.X;
|
||||
f32 down = (f32)destRect.LowerRightCorner.Y;
|
||||
f32 top = (f32)destRect.UpperLeftCorner.Y;
|
||||
|
||||
S3DVertex vertices[4];
|
||||
vertices[0] = S3DVertex(left, top, 0, 0, 0, 1, useColor[0], tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
|
||||
@ -903,10 +877,10 @@ void COpenGL3DriverBase::draw2DImageBatch(const video::ITexture *texture,
|
||||
|
||||
const core::rect<s32> poss(targetPos, sourceSize);
|
||||
|
||||
f32 left = (f32)poss.UpperLeftCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 right = (f32)poss.LowerRightCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 down = 2.f - (f32)poss.LowerRightCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 top = 2.f - (f32)poss.UpperLeftCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 left = (f32)poss.UpperLeftCorner.X;
|
||||
f32 right = (f32)poss.LowerRightCorner.X;
|
||||
f32 down = (f32)poss.LowerRightCorner.Y;
|
||||
f32 top = (f32)poss.UpperLeftCorner.Y;
|
||||
|
||||
vtx.emplace_back(left, top, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, color,
|
||||
@ -935,33 +909,7 @@ void COpenGL3DriverBase::draw2DRectangle(SColor color,
|
||||
const core::rect<s32> &position,
|
||||
const core::rect<s32> *clip)
|
||||
{
|
||||
chooseMaterial2D();
|
||||
setMaterialTexture(0, 0);
|
||||
|
||||
setRenderStates2DMode(color.getAlpha() < 255, false, false);
|
||||
|
||||
core::rect<s32> pos = position;
|
||||
|
||||
if (clip)
|
||||
pos.clipAgainst(*clip);
|
||||
|
||||
if (!pos.isValid())
|
||||
return;
|
||||
|
||||
const core::dimension2d<u32> &renderTargetSize = getCurrentRenderTargetSize();
|
||||
|
||||
f32 left = (f32)pos.UpperLeftCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 right = (f32)pos.LowerRightCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 down = 2.f - (f32)pos.LowerRightCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 top = 2.f - (f32)pos.UpperLeftCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
|
||||
S3DVertex vertices[4];
|
||||
vertices[0] = S3DVertex(left, top, 0, 0, 0, 1, color, 0, 0);
|
||||
vertices[1] = S3DVertex(right, top, 0, 0, 0, 1, color, 0, 0);
|
||||
vertices[2] = S3DVertex(right, down, 0, 0, 0, 1, color, 0, 0);
|
||||
vertices[3] = S3DVertex(left, down, 0, 0, 0, 1, color, 0, 0);
|
||||
|
||||
drawQuad(vtPrimitive, vertices);
|
||||
draw2DRectangle(position, color, color, color, color, clip);
|
||||
}
|
||||
|
||||
//! draw an 2d rectangle
|
||||
@ -987,18 +935,16 @@ void COpenGL3DriverBase::draw2DRectangle(const core::rect<s32> &position,
|
||||
colorRightDown.getAlpha() < 255,
|
||||
false, false);
|
||||
|
||||
const core::dimension2d<u32> &renderTargetSize = getCurrentRenderTargetSize();
|
||||
|
||||
f32 left = (f32)pos.UpperLeftCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 right = (f32)pos.LowerRightCorner.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 down = 2.f - (f32)pos.LowerRightCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 top = 2.f - (f32)pos.UpperLeftCorner.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 left = (f32)pos.UpperLeftCorner.X;
|
||||
f32 right = (f32)pos.LowerRightCorner.X;
|
||||
f32 down = (f32)pos.LowerRightCorner.Y;
|
||||
f32 top = (f32)pos.UpperLeftCorner.Y;
|
||||
|
||||
S3DVertex vertices[4];
|
||||
vertices[0] = S3DVertex(left, top, 0, 0, 0, 1, colorLeftUp, 0, 0);
|
||||
vertices[1] = S3DVertex(right, top, 0, 0, 0, 1, colorRightUp, 0, 0);
|
||||
vertices[0] = S3DVertex(left, top, 0, 0, 0, 1, colorLeftUp, 0, 0);
|
||||
vertices[1] = S3DVertex(right, top, 0, 0, 0, 1, colorRightUp, 0, 0);
|
||||
vertices[2] = S3DVertex(right, down, 0, 0, 0, 1, colorRightDown, 0, 0);
|
||||
vertices[3] = S3DVertex(left, down, 0, 0, 0, 1, colorLeftDown, 0, 0);
|
||||
vertices[3] = S3DVertex(left, down, 0, 0, 0, 1, colorLeftDown, 0, 0);
|
||||
|
||||
drawQuad(vtPrimitive, vertices);
|
||||
}
|
||||
@ -1013,12 +959,10 @@ void COpenGL3DriverBase::draw2DLine(const core::position2d<s32> &start,
|
||||
|
||||
setRenderStates2DMode(color.getAlpha() < 255, false, false);
|
||||
|
||||
const core::dimension2d<u32> &renderTargetSize = getCurrentRenderTargetSize();
|
||||
|
||||
f32 startX = (f32)start.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 endX = (f32)end.X / (f32)renderTargetSize.Width * 2.f - 1.f;
|
||||
f32 startY = 2.f - (f32)start.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 endY = 2.f - (f32)end.Y / (f32)renderTargetSize.Height * 2.f - 1.f;
|
||||
f32 startX = (f32)start.X;
|
||||
f32 endX = (f32)end.X;
|
||||
f32 startY = (f32)start.Y;
|
||||
f32 endY = (f32)end.Y;
|
||||
|
||||
S3DVertex vertices[2];
|
||||
vertices[0] = S3DVertex(startX, startY, 0, 0, 0, 1, color, 0, 0);
|
||||
@ -1047,6 +991,55 @@ void COpenGL3DriverBase::drawElements(GLenum primitiveType, const VertexType &ve
|
||||
endDraw(vertexType);
|
||||
}
|
||||
|
||||
void COpenGL3DriverBase::drawGeneric(const void *vertices, const void *indexList,
|
||||
u32 primitiveCount,
|
||||
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
|
||||
{
|
||||
auto &vTypeDesc = getVertexTypeDescription(vType);
|
||||
beginDraw(vTypeDesc, reinterpret_cast<uintptr_t>(vertices));
|
||||
GLenum indexSize = 0;
|
||||
|
||||
switch (iType) {
|
||||
case EIT_16BIT:
|
||||
indexSize = GL_UNSIGNED_SHORT;
|
||||
break;
|
||||
case EIT_32BIT:
|
||||
indexSize = GL_UNSIGNED_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (pType) {
|
||||
case scene::EPT_POINTS:
|
||||
case scene::EPT_POINT_SPRITES:
|
||||
GL.DrawArrays(GL_POINTS, 0, primitiveCount);
|
||||
break;
|
||||
case scene::EPT_LINE_STRIP:
|
||||
GL.DrawElements(GL_LINE_STRIP, primitiveCount + 1, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_LINE_LOOP:
|
||||
GL.DrawElements(GL_LINE_LOOP, primitiveCount, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_LINES:
|
||||
GL.DrawElements(GL_LINES, primitiveCount * 2, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_TRIANGLE_STRIP:
|
||||
GL.DrawElements(GL_TRIANGLE_STRIP, primitiveCount + 2, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_TRIANGLE_FAN:
|
||||
GL.DrawElements(GL_TRIANGLE_FAN, primitiveCount + 2, indexSize, indexList);
|
||||
break;
|
||||
case scene::EPT_TRIANGLES:
|
||||
GL.DrawElements((LastMaterial.Wireframe) ? GL_LINES : (LastMaterial.PointCloud) ? GL_POINTS
|
||||
: GL_TRIANGLES,
|
||||
primitiveCount * 3, indexSize, indexList);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
endDraw(vTypeDesc);
|
||||
}
|
||||
|
||||
void COpenGL3DriverBase::beginDraw(const VertexType &vertexType, uintptr_t verticesBase)
|
||||
{
|
||||
for (auto &attr : vertexType) {
|
||||
|
@ -316,6 +316,9 @@ protected:
|
||||
void drawElements(GLenum primitiveType, const VertexType &vertexType, const void *vertices, int vertexCount, const u16 *indices, int indexCount);
|
||||
void drawElements(GLenum primitiveType, const VertexType &vertexType, uintptr_t vertices, uintptr_t indices, int indexCount);
|
||||
|
||||
void drawGeneric(const void *vertices, const void *indexList, u32 primitiveCount,
|
||||
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType);
|
||||
|
||||
void beginDraw(const VertexType &vertexType, uintptr_t verticesBase);
|
||||
void endDraw(const VertexType &vertexType);
|
||||
|
||||
|
@ -32,6 +32,7 @@ COpenGL3Renderer2D::COpenGL3Renderer2D(const c8 *vertexShaderProgram, const c8 *
|
||||
|
||||
// These states don't change later.
|
||||
|
||||
ProjectionID = getPixelShaderConstantID("uProjection");
|
||||
ThicknessID = getPixelShaderConstantID("uThickness");
|
||||
if (WithTexture) {
|
||||
TextureUsageID = getPixelShaderConstantID("uTextureUsage");
|
||||
@ -62,6 +63,17 @@ void COpenGL3Renderer2D::OnSetMaterial(const video::SMaterial &material,
|
||||
f32 Thickness = (material.Thickness > 0.f) ? material.Thickness : 1.f;
|
||||
setPixelShaderConstant(ThicknessID, &Thickness, 1);
|
||||
|
||||
{
|
||||
// Update projection matrix
|
||||
const core::dimension2d<u32> renderTargetSize = Driver->getCurrentRenderTargetSize();
|
||||
core::matrix4 proj;
|
||||
float xInv2 = 2.0f / renderTargetSize.Width;
|
||||
float yInv2 = 2.0f / renderTargetSize.Height;
|
||||
proj.setScale({ xInv2, -yInv2, 0.0f });
|
||||
proj.setTranslation({ -1.0f, 1.0f, 0.0f });
|
||||
setPixelShaderConstant(ProjectionID, proj.pointer(), 4 * 4);
|
||||
}
|
||||
|
||||
if (WithTexture) {
|
||||
s32 TextureUsage = material.TextureLayers[0].Texture ? 1 : 0;
|
||||
setPixelShaderConstant(TextureUsageID, &TextureUsage, 1);
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool WithTexture;
|
||||
s32 ProjectionID;
|
||||
s32 ThicknessID;
|
||||
s32 TextureUsageID;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user