Skip to content

Commit

Permalink
Add opacity support to Placemarks, Paths, Ellipses, Polygons, Surface…
Browse files Browse the repository at this point in the history
…Images and Labels.
  • Loading branch information
GuzulFromUkraine authored and EMaksymenko committed Sep 28, 2023
1 parent fe2d1d2 commit 988c0b4
Show file tree
Hide file tree
Showing 12 changed files with 52 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ open class DrawShapeState internal constructor() {
var enableDepthWrite = true
var depthOffset = 0.0
protected val color = Color()
protected var opacity: Float = 1.0f
protected var lineWidth = 1f
protected var texture: Texture? = null
protected val texCoordMatrix = Matrix3()
Expand All @@ -40,6 +41,7 @@ open class DrawShapeState internal constructor() {
enableDepthTest = true
depthOffset = 0.0
color.set(1f, 1f, 1f, 1f)
opacity = 1.0f
lineWidth = 1f
texture = null
texCoordMatrix.setToIdentity()
Expand All @@ -51,6 +53,8 @@ open class DrawShapeState internal constructor() {

fun color(color: Color) = apply { this.color.copy(color) }

fun opacity(opacity: Float) = apply { this.opacity = opacity }

fun lineWidth(width: Float) = apply { lineWidth = width }

fun texture(texture: Texture?) = apply { this.texture = texture }
Expand All @@ -69,6 +73,7 @@ open class DrawShapeState internal constructor() {
prim.type = type
prim.offset = offset
prim.color.copy(color)
prim.opacity = opacity
prim.lineWidth = lineWidth
prim.texture = texture
prim.texCoordMatrix.copy(texCoordMatrix)
Expand All @@ -82,6 +87,7 @@ open class DrawShapeState internal constructor() {
var type = 0
var offset = 0
val color = Color()
var opacity: Float = 1.0f
var lineWidth = 0f
var texture: Texture? = null
val texCoordMatrix = Matrix3()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import kotlin.jvm.JvmStatic
open class DrawableScreenTexture protected constructor(): Drawable {
val unitSquareTransform = Matrix4()
val color = Color()
var opacity: Float = 1.0f
var enableDepthTest = true
var program: BasicShaderProgram? = null
var texture: Texture? = null
Expand Down Expand Up @@ -76,6 +77,7 @@ open class DrawableScreenTexture protected constructor(): Drawable {

// Use the drawable's color.
program.loadColor(drawable.color)
program.loadOpacity(opacity)

// Attempt to bind the drawable's texture, configuring the shader program appropriately if there is no texture
// or if the texture failed to bind.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ open class DrawableShape protected constructor(): Drawable {
for (idx in 0 until drawState.primCount) {
val prim = drawState.prims[idx]
program.loadColor(prim.color)
program.loadOpacity(prim.opacity)
if (prim.texture?.bindTexture(dc) == true) {
program.loadTexCoordMatrix(prim.texCoordMatrix)
program.enableTexture(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import kotlin.jvm.JvmStatic
open class DrawableSurfaceTexture protected constructor(): Drawable {
val sector = Sector()
val color = Color()
var opacity: Float = 1.0f
val texCoordMatrix = Matrix3()
var texture: Texture? = null
var program: SurfaceTextureProgram? = null
Expand All @@ -30,6 +31,7 @@ open class DrawableSurfaceTexture protected constructor(): Drawable {
program: SurfaceTextureProgram?, sector: Sector?, texture: Texture?, texCoordMatrix: Matrix3?
) = apply {
if (sector != null) this.sector.copy(sector) else this.sector.setEmpty()
this.opacity = 1f
this.color.set(1f, 1f, 1f, 1f)
if (texCoordMatrix != null) this.texCoordMatrix.copy(texCoordMatrix) else this.texCoordMatrix.setToIdentity()
this.texture = texture
Expand Down Expand Up @@ -123,6 +125,8 @@ open class DrawableSurfaceTexture protected constructor(): Drawable {

// Use the surface texture's RGBA color.
program.loadColor(texture.color)
// Use the surface texture's opacity.
program.loadOpacity(texture.opacity)

// Draw the terrain as triangles.
terrain.drawTriangles(dc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ open class BasicShaderProgram : AbstractShaderProgram() {
uniform bool enablePickMode;
uniform bool enableTexture;
uniform vec4 color;
uniform float opacity;
uniform sampler2D texSampler;
varying vec2 texCoord;
Expand All @@ -47,10 +48,10 @@ open class BasicShaderProgram : AbstractShaderProgram() {
gl_FragColor = color * texMask;
} else if (!enablePickMode && enableTexture) {
/* Modulate the RGBA color with the 2D texture's RGBA color. */
gl_FragColor = color * texture2D(texSampler, texCoord);
gl_FragColor = color * texture2D(texSampler, texCoord) * opacity;
} else {
/* Return the RGBA color as-is. */
gl_FragColor = color;
gl_FragColor = color * opacity;
}
}
""".trimIndent()
Expand All @@ -62,12 +63,14 @@ open class BasicShaderProgram : AbstractShaderProgram() {
protected val mvpMatrix = Matrix4()
protected val texCoordMatrix = Matrix3()
protected val color = Color()
protected var opacity = 1.0f
protected var enablePickModeId = KglUniformLocation.NONE
protected var enableTextureId = KglUniformLocation.NONE
protected var mvpMatrixId = KglUniformLocation.NONE
protected var texCoordMatrixId = KglUniformLocation.NONE
protected var texSamplerId = KglUniformLocation.NONE
protected var colorId = KglUniformLocation.NONE
protected var opacityId = KglUniformLocation.NONE
private val array = FloatArray(16)

override fun initProgram(dc: DrawContext) {
Expand All @@ -85,6 +88,8 @@ open class BasicShaderProgram : AbstractShaderProgram() {
colorId = gl.getUniformLocation(program, "color")
val alpha = color.alpha
gl.uniform4f(colorId, color.red * alpha, color.green * alpha, color.blue * alpha, alpha)
opacityId = gl.getUniformLocation(program, "opacity")
gl.uniform1f(opacityId, opacity)
texSamplerId = gl.getUniformLocation(program, "texSampler")
gl.uniform1i(texSamplerId, 0) // GL_TEXTURE0
}
Expand Down Expand Up @@ -124,4 +129,10 @@ open class BasicShaderProgram : AbstractShaderProgram() {
gl.uniform4f(colorId, color.red * alpha, color.green * alpha, color.blue * alpha, alpha)
}
}
fun loadOpacity(opacity: Float) {
if (this.opacity != opacity) {
this.opacity = opacity
gl.uniform1f(opacityId, opacity)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ open class SurfaceTextureProgram : AbstractShaderProgram() {
uniform bool enablePickMode;
uniform bool enableTexture;
uniform vec4 color;
uniform float opacity;
uniform sampler2D texSampler;
varying vec2 texCoord;
Expand All @@ -65,10 +66,10 @@ open class SurfaceTextureProgram : AbstractShaderProgram() {
} else if (!enablePickMode && enableTexture) {
/* Using the first texture coordinate, modulate the RGBA color with the 2D texture's RGBA color. Finally,
modulate by the tile mask to suppress fragments outside the surface tile. */
gl_FragColor = color * texture2D(texSampler, texCoord) * tileMask;
gl_FragColor = color * texture2D(texSampler, texCoord) * opacity * tileMask;
} else {
/* Modulate the RGBA color by the tile mask to suppress fragments outside the surface tile. */
gl_FragColor = color * tileMask;
gl_FragColor = color * opacity * tileMask;
}
}
""".trimIndent()
Expand All @@ -83,9 +84,11 @@ open class SurfaceTextureProgram : AbstractShaderProgram() {
protected var texCoordMatrixId = KglUniformLocation.NONE
protected var texSamplerId = KglUniformLocation.NONE
protected var colorId = KglUniformLocation.NONE
protected var opacityId = KglUniformLocation.NONE
private val mvpMatrixArray = FloatArray(16)
private val texCoordMatrixArray = FloatArray(9 * 2)
private val color = Color()
protected var opacity = 1.0f

override fun initProgram(dc: DrawContext) {
super.initProgram(dc)
Expand All @@ -103,6 +106,8 @@ open class SurfaceTextureProgram : AbstractShaderProgram() {
colorId = gl.getUniformLocation(program, "color")
color.set(1f, 1f, 1f, 1f) // opaque white
gl.uniform4f(colorId, color.red, color.green, color.blue, color.alpha)
opacityId = gl.getUniformLocation(program, "opacity")
gl.uniform1f(opacityId, opacity)
texSamplerId = gl.getUniformLocation(program, "texSampler")
gl.uniform1i(texSamplerId, 0) // GL_TEXTURE0
}
Expand All @@ -129,4 +134,11 @@ open class SurfaceTextureProgram : AbstractShaderProgram() {
gl.uniform4f(colorId, color.red * a, color.green * a, color.blue * a, a)
}
}

fun loadOpacity(opacity: Float) {
if (this.opacity != opacity) {
this.opacity = opacity
gl.uniform1f(opacityId, opacity)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ open class Ellipse @JvmOverloads constructor(

// Configure the drawable to display the shape's interior.
drawState.color(if (rc.isPickMode) pickColor else activeAttributes.interiorColor)
drawState.opacity(rc.currentLayer.opacity)
drawState.texCoordAttrib(2 /*size*/, 12 /*offset in bytes*/)
val top = drawState.elementBuffer!!.ranges[TOP_RANGE]!!
drawState.drawElements(GL_TRIANGLE_STRIP, top.length, GL_UNSIGNED_SHORT, top.lower * 2 /*offset*/)
Expand All @@ -336,6 +337,7 @@ open class Ellipse @JvmOverloads constructor(

// Configure the drawable to display the shape's outline.
drawState.color(if (rc.isPickMode) pickColor else activeAttributes.outlineColor)
drawState.opacity(rc.currentLayer.opacity)
drawState.lineWidth(activeAttributes.outlineWidth)
drawState.texCoordAttrib(1 /*size*/, 20 /*offset in bytes*/)
val outline = drawState.elementBuffer!!.ranges[OUTLINE_RANGE]!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ open class Label @JvmOverloads constructor(
// Obtain a pooled drawable and configure it to draw the label's text.
val pool = rc.getDrawablePool<DrawableScreenTexture>()
val drawable = DrawableScreenTexture.obtain(pool)
drawable.opacity = rc.currentLayer.opacity

// Use the basic GLSL program to draw the text.
drawable.program = rc.getShaderProgram { BasicShaderProgram() }
Expand All @@ -200,6 +201,7 @@ open class Label @JvmOverloads constructor(
// in the texture's color.
if (rc.isPickMode) drawable.color.copy(renderData.pickColor)
else drawable.color.set(1f, 1f, 1f, 1f)
drawable.opacity = rc.currentLayer.opacity
drawable.texture = texture
drawable.enableDepthTest = activeAttributes.isDepthTest

Expand Down
2 changes: 2 additions & 0 deletions worldwind/src/commonMain/kotlin/earth/worldwind/shape/Path.kt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ open class Path @JvmOverloads constructor(
}
}

drawState.opacity(rc.currentLayer.opacity)

// Configure the drawable to display the shape's outline. Increase surface shape line widths by 1/2 pixel. Lines
// drawn indirectly offscreen framebuffer appear thinner when sampled as a texture.
if (activeAttributes.isDrawOutline) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,10 @@ open class Placemark @JvmOverloads constructor(
// the active attributes' image source and its associated tex coord transform. If the texture is not specified
// or not available, draw a simple colored square.
drawable.color.copy(if (rc.isPickMode) pickColor else activeAttributes.imageColor)
drawable.opacity = rc.currentLayer.opacity
drawable.texture = activeTexture
drawable.enableDepthTest = activeAttributes.isDepthTest
drawable.opacity = rc.currentLayer.opacity
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ open class Polygon @JvmOverloads constructor(

// Configure the drawable to display the shape's interior top.
drawState.color(if (rc.isPickMode) pickColor else activeAttributes.interiorColor)
drawState.opacity(rc.currentLayer.opacity)
drawState.texCoordAttrib(2 /*size*/, 12 /*offset in bytes*/)
drawState.drawElements(GL_TRIANGLES, topElements.size, GL_UNSIGNED_SHORT, 0 /*offset*/)

Expand All @@ -228,6 +229,7 @@ open class Polygon @JvmOverloads constructor(

// Configure the drawable to display the shape's outline.
drawState.color(if (rc.isPickMode) pickColor else activeAttributes.outlineColor)
drawState.opacity(rc.currentLayer.opacity)
drawState.lineWidth(activeAttributes.outlineWidth)
drawState.texCoordAttrib(1 /*size*/, 20 /*offset in bytes*/)
drawState.drawElements(
Expand All @@ -238,6 +240,7 @@ open class Polygon @JvmOverloads constructor(
// Configure the drawable to display the shape's extruded verticals.
if (activeAttributes.isDrawVerticals && isExtrude) {
drawState.color(if (rc.isPickMode) pickColor else activeAttributes.outlineColor)
drawState.opacity(rc.currentLayer.opacity)
drawState.lineWidth(activeAttributes.outlineWidth)
drawState.texture(null)
drawState.drawElements(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ open class SurfaceImage(sector: Sector, var imageSource: ImageSource): AbstractS
val program = getShaderProgram(rc)
val pool = rc.getDrawablePool<DrawableSurfaceTexture>()
val drawable = DrawableSurfaceTexture.obtain(pool).set(program, sector, texture, texture.coordTransform)
drawable.opacity = rc.currentLayer.opacity
rc.offerSurfaceDrawable(drawable, 0.0 /*z-order*/)

// Enqueue a picked object that associates the drawable surface texture with this surface image.
Expand Down

0 comments on commit 988c0b4

Please sign in to comment.