diff --git a/client/shaders/Irrlicht/Renderer2D.vsh b/client/shaders/Irrlicht/Renderer2D.vsh index 914214895..c0916562b 100644 --- a/client/shaders/Irrlicht/Renderer2D.vsh +++ b/client/shaders/Irrlicht/Renderer2D.vsh @@ -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; diff --git a/irr/src/OpenGL/Driver.cpp b/irr/src/OpenGL/Driver.cpp index 150b80e7c..c1154e11b 100644 --- a/irr/src/OpenGL/Driver.cpp +++ b/irr/src/OpenGL/Driver.cpp @@ -689,58 +689,32 @@ void COpenGL3DriverBase::drawVertexPrimitiveList(const void *vertices, u32 verte setRenderStates3DMode(); - auto &vTypeDesc = getVertexTypeDescription(vType); - beginDraw(vTypeDesc, reinterpret_cast(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 &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 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 &position, const core::rect *clip) { - chooseMaterial2D(); - setMaterialTexture(0, 0); - - setRenderStates2DMode(color.getAlpha() < 255, false, false); - - core::rect pos = position; - - if (clip) - pos.clipAgainst(*clip); - - if (!pos.isValid()) - return; - - const core::dimension2d &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 &position, colorRightDown.getAlpha() < 255, false, false); - const core::dimension2d &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 &start, setRenderStates2DMode(color.getAlpha() < 255, false, false); - const core::dimension2d &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(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) { diff --git a/irr/src/OpenGL/Driver.h b/irr/src/OpenGL/Driver.h index d5ce7eab6..36dd02219 100644 --- a/irr/src/OpenGL/Driver.h +++ b/irr/src/OpenGL/Driver.h @@ -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); diff --git a/irr/src/OpenGL/Renderer2D.cpp b/irr/src/OpenGL/Renderer2D.cpp index 1dd717aa8..b7b8edf1b 100644 --- a/irr/src/OpenGL/Renderer2D.cpp +++ b/irr/src/OpenGL/Renderer2D.cpp @@ -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 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); diff --git a/irr/src/OpenGL/Renderer2D.h b/irr/src/OpenGL/Renderer2D.h index 6cfc7029d..8cc8fe6ca 100644 --- a/irr/src/OpenGL/Renderer2D.h +++ b/irr/src/OpenGL/Renderer2D.h @@ -24,6 +24,7 @@ public: protected: bool WithTexture; + s32 ProjectionID; s32 ThicknessID; s32 TextureUsageID; };