Compilable WebGL program
This commit is contained in:
commit
92603d8faf
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/.idea/
|
||||
/gradle/
|
||||
/.gradle/
|
||||
/build/
|
||||
*.class
|
||||
*.jar
|
||||
/out/
|
||||
/gradlew*
|
||||
/.kotlin/
|
||||
*.js
|
28
build.gradle.kts
Normal file
28
build.gradle.kts
Normal file
@ -0,0 +1,28 @@
|
||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform") version "2.1.10"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
binaries.executable()
|
||||
browser {
|
||||
commonWebpackConfig {
|
||||
outputFileName = "computer-graphics-1.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
jsMain {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
gradle.properties
Normal file
1
gradle.properties
Normal file
@ -0,0 +1 @@
|
||||
kotlin.code.style=official
|
1
settings.gradle.kts
Normal file
1
settings.gradle.kts
Normal file
@ -0,0 +1 @@
|
||||
rootProject.name = "cg-js"
|
@ -0,0 +1,86 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.browser.window
|
||||
import org.khronos.webgl.Float32Array
|
||||
import org.khronos.webgl.Int32Array
|
||||
import org.khronos.webgl.WebGLRenderingContext
|
||||
import org.w3c.dom.HTMLCanvasElement
|
||||
|
||||
fun main() {
|
||||
val canvas = document.getElementById("canvas")!! as HTMLCanvasElement
|
||||
|
||||
val gl: dynamic = canvas.getContext("webgl2")!! /*as WebGLRenderingContext*/
|
||||
|
||||
val modelVertexesBuffer = gl.createBuffer()
|
||||
val textureVertexesBuffer = gl.createBuffer()
|
||||
val textureTypesBuffer = gl.createBuffer()
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, modelVertexesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Float32Array(model.modelVertexes.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 3 * 4, 0)
|
||||
gl.enableVertexAttribArray(0)
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, textureVertexesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Float32Array(model.textureVertexes.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 2 * 4, 0)
|
||||
gl.enableVertexAttribArray(1)
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, textureTypesBuffer)
|
||||
gl.bufferData(
|
||||
gl.ARRAY_BUFFER,
|
||||
Int32Array(model.textureTypes.map { t -> t.ordinal }.toTypedArray()),
|
||||
gl.STATIC_DRAW
|
||||
)
|
||||
gl.vertexAttribIPointer(2, 2, gl.INT, false, 1 * 4, 0)
|
||||
gl.enableVertexAttribArray(2)
|
||||
|
||||
val vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
||||
gl.shaderSource(vertexShader, vertexShaderSource)
|
||||
gl.compileShader(vertexShader)
|
||||
println("vertex shader compilation status: ${gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)}")
|
||||
println("vertex shader compilation log: ${gl.getShaderInfoLog(vertexShader)}")
|
||||
|
||||
val fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
|
||||
gl.shaderSource(fragmentShader, fragmentShaderSource)
|
||||
gl.compileShader(fragmentShader)
|
||||
println("fragment shader compilation status: ${gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)}")
|
||||
println("fragment shader compilation log: ${gl.getShaderInfoLog(fragmentShader)}")
|
||||
|
||||
|
||||
val shaderProgram = gl.createProgram()
|
||||
gl.attachShader(shaderProgram, vertexShader)
|
||||
gl.attachShader(shaderProgram, fragmentShader)
|
||||
gl.linkProgram(shaderProgram)
|
||||
println("program compilation log: ${gl.getProgramInfoLog(shaderProgram)}")
|
||||
|
||||
gl.useProgram(shaderProgram)
|
||||
gl.clearColor(0f, 0f, 0f, 1f);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, model.textureTypes.size / 3)
|
||||
|
||||
window.onkeydown = { keyEvent ->
|
||||
when (keyEvent.code) {
|
||||
"ArrowDown" -> {
|
||||
|
||||
gl.clearColor(0f, 0f, 0f, 1f);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, model.textureTypes.size / 3)
|
||||
}
|
||||
|
||||
"ArrowUp" -> {}
|
||||
"ArrowLeft" -> {}
|
||||
"ArrowRight" -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,130 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.ModelTriangles
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.Point2F
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.Polygon
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.TextureType
|
||||
|
||||
private fun rot_n(degrees: Int, length: Int): Point2F {
|
||||
val radians = degrees.toLong().toDouble() * PI / 180;
|
||||
return Point2F(
|
||||
x = cos(radians).times(length).toFloat(),
|
||||
y = sin(radians).times(length).toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
val model = ModelTriangles.fromPolygons(
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1)),
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, rot_n(60, 2)),
|
||||
Polygon.PolygonVertex(-1f, 1f, 1f, rot_n(0, 2)),
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, rot_n(60, 2)),
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1)),
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, rot_n(60, 2)),
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1)),
|
||||
Polygon.PolygonVertex(1f, -1f, 1f, rot_n(120, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, rot_n(180, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, -1f, rot_n(240, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, rot_n(180, 2)),
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, rot_n(180, 2)),
|
||||
Polygon.PolygonVertex(1f, 0f, 1f, rot_n(120, 1)),
|
||||
Polygon.PolygonVertex(1f, -1f, 1f, rot_n(120, 2))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, rot_n(300, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, -1f, rot_n(240, 2)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, rot_n(300, 2)),
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1)),
|
||||
Polygon.PolygonVertex(1f, 1f, 0f, rot_n(240, 1))
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.HSV,
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, rot_n(300, 2)),
|
||||
Polygon.PolygonVertex(0f, 1f, 1f, rot_n(0, 1)),
|
||||
Polygon.PolygonVertex(-1f, 1f, 1f, rot_n(0, 2))
|
||||
),
|
||||
Polygon(
|
||||
TextureType.WHITE_TRANSPARENCY,
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, 0f, 0f),
|
||||
Polygon.PolygonVertex(-1f, -1f, -1f, 0f, 1f),
|
||||
Polygon.PolygonVertex(-1f, 1f, 1f, 1f, 0f)
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.WHITE_TRANSPARENCY,
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, 1f, 1f),
|
||||
Polygon.PolygonVertex(-1f, -1f, -1f, 0f, 1f),
|
||||
Polygon.PolygonVertex(-1f, 1f, 1f, 1f, 0f)
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.WHITE_TRANSPARENCY,
|
||||
Polygon.PolygonVertex(-1f, -1f, -1f, 0f, 0f),
|
||||
Polygon.PolygonVertex(-1f, 1f, -1f, 0f, 1f),
|
||||
Polygon.PolygonVertex(1f, 1f, -1f, 1f, 1f)
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.WHITE_TRANSPARENCY,
|
||||
Polygon.PolygonVertex(-1f, -1f, -1f, 0f, 0f),
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, 1f, 0f),
|
||||
Polygon.PolygonVertex(1f, 1f, -1f, 1f, 1f)
|
||||
),
|
||||
|
||||
Polygon(
|
||||
TextureType.CHESS,
|
||||
Polygon.PolygonVertex(1f, -1f, 1f, 0f, 0f),
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, 0f, 1f),
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, 1f, 0f)
|
||||
),
|
||||
Polygon(
|
||||
TextureType.CHESS,
|
||||
Polygon.PolygonVertex(-1f, -1f, -1f, 1f, 1f),
|
||||
Polygon.PolygonVertex(-1f, -1f, 1f, 0f, 1f),
|
||||
Polygon.PolygonVertex(1f, -1f, -1f, 1f, 0f)
|
||||
),
|
||||
)
|
@ -0,0 +1,50 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
|
||||
class ModelTriangles(
|
||||
val modelVertexes: FloatArray,
|
||||
val textureVertexes: FloatArray,
|
||||
val textureTypes: Array<TextureType>
|
||||
) {
|
||||
companion object {
|
||||
private fun <T> MutableCollection<T>.addAll(vararg elems: T) {
|
||||
this.addAll(elems)
|
||||
}
|
||||
|
||||
fun fromPolygons(vararg polygons: Polygon): ModelTriangles {
|
||||
val modelVertexes = ArrayList<Float>()
|
||||
val textureVertexes = ArrayList<Float>()
|
||||
val textureTypes = ArrayList<TextureType>()
|
||||
|
||||
polygons@ for (polygon in polygons) {
|
||||
val it = polygon.vertexes.iterator()
|
||||
if (!it.hasNext()) continue@polygons
|
||||
val root = it.next()
|
||||
if (!it.hasNext()) continue@polygons
|
||||
var prev = it.next()
|
||||
for (curr in it) {
|
||||
modelVertexes.addAll(
|
||||
root.modelVertex.x, root.modelVertex.y, root.modelVertex.z,
|
||||
prev.modelVertex.x, prev.modelVertex.y, prev.modelVertex.z,
|
||||
curr.modelVertex.x, curr.modelVertex.y, curr.modelVertex.z,
|
||||
)
|
||||
textureVertexes.addAll(
|
||||
root.textureVertex.x, root.textureVertex.y,
|
||||
prev.textureVertex.x, prev.textureVertex.y,
|
||||
curr.textureVertex.x, curr.textureVertex.y,
|
||||
)
|
||||
textureTypes.addAll(
|
||||
polygon.textureType, polygon.textureType, polygon.textureType
|
||||
)
|
||||
|
||||
prev = curr
|
||||
}
|
||||
}
|
||||
return ModelTriangles(
|
||||
modelVertexes = modelVertexes.toTypedArray().toFloatArray(),
|
||||
textureVertexes = textureVertexes.toTypedArray().toFloatArray(),
|
||||
textureTypes = textureTypes.toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
class Point2F(
|
||||
val x: Float,
|
||||
val y: Float,
|
||||
) {
|
||||
operator fun component1(): Float = this.x
|
||||
operator fun component2(): Float = this.y
|
||||
|
||||
override fun toString(): String =
|
||||
"<point 2f x=${this.x} y=${this.y}>"
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
class Point3F(
|
||||
val x: Float,
|
||||
val y: Float,
|
||||
val z: Float,
|
||||
) {
|
||||
operator fun component1(): Float = this.x
|
||||
operator fun component2(): Float = this.y
|
||||
operator fun component3(): Float = this.z
|
||||
|
||||
override fun toString(): String =
|
||||
"<point 3f x=${this.x} y=${this.y} z=${this.z}>"
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
class Polygon(
|
||||
val textureType: TextureType,
|
||||
vararg val vertexes: PolygonVertex
|
||||
) {
|
||||
init {
|
||||
require(this.vertexes.size >= 3) { "Polygon should has at least 3 vertexes" }
|
||||
}
|
||||
|
||||
class PolygonVertex(
|
||||
val modelVertex: Point3F,
|
||||
val textureVertex: Point2F
|
||||
) {
|
||||
operator fun component1() = this.modelVertex
|
||||
operator fun component2() = this.textureVertex
|
||||
|
||||
constructor(mx: Float, my: Float, mz: Float, tx: Float, ty: Float) :
|
||||
this(Point3F(mx, my, mz), Point2F(tx, ty))
|
||||
|
||||
constructor(m: Point3F, tx: Float, ty: Float) :
|
||||
this(m, Point2F(tx, ty))
|
||||
|
||||
constructor(mx: Float, my: Float, mz: Float, t: Point2F) :
|
||||
this(Point3F(mx, my, mz), t)
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1.model_builder
|
||||
|
||||
enum class TextureType {
|
||||
CHESS,
|
||||
HSV,
|
||||
WHITE_TRANSPARENCY,
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package ru.landgrafhomyak.bgtu.computer_graphics1
|
||||
|
||||
import ru.landgrafhomyak.bgtu.computer_graphics1.model_builder.TextureType
|
||||
|
||||
internal val vertexShaderSource = """
|
||||
#version 300 es
|
||||
|
||||
uniform mat4 transform;
|
||||
layout(location = 0) in vec3 vertex_pos;
|
||||
layout(location = 1) in vec2 texture_pos;
|
||||
layout(location = 2) in int texture_type;
|
||||
out vec2 texture_pos_v2f;
|
||||
flat out int texture_type_v2f;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(vertex_pos.xyz, 1) * transform;
|
||||
texture_pos_v2f = texture_pos;
|
||||
texture_type_v2f = texture_type;
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
internal val fragmentShaderSource = """
|
||||
#version 300 es
|
||||
|
||||
precision mediump float;
|
||||
in vec2 texture_pos_v2f;
|
||||
flat in int texture_type_v2f;
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
switch (texture_type_v2f) {
|
||||
case ${TextureType.WHITE_TRANSPARENCY.ordinal}:
|
||||
color = vec4(255, 255, 255, 127);
|
||||
break;
|
||||
case ${TextureType.CHESS.ordinal}:
|
||||
if (int( round(floor(texture_pos_v2f.x / 0.1)) + round(floor(texture_pos_v2f.y / 0.1)) ) % 2 == 0) {
|
||||
color = vec4(0, 0, 0, 255);
|
||||
} else {
|
||||
color = vec4(255, 255, 255, 255);
|
||||
}
|
||||
break;
|
||||
case ${TextureType.HSV.ordinal}:
|
||||
default:
|
||||
color = vec4(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
12
src/jsMain/resources/index.html
Normal file
12
src/jsMain/resources/index.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<canvas style="left: 0; top: 0; right: 0; bottom:0; position: fixed" id="canvas"></canvas>
|
||||
<script src="computer-graphics-1.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user