Scalajs WebGL“Hello World!”

时间:2015-12-18 11:16:42

标签: scala scala.js

好吧,这不是文字“Hello World!”程序,但相当于:它使用WebGL渲染上下文向画布输出几个三角形。

该程序可以正常工作,但有没有办法摆脱那些令人讨厌的动态演员阵容和程序后半部分中不优雅的scalajs Arrays初始化。显然我可以创建自己的实用程序函数/类(我使用自己的实用程序生成着色器源代码),但我更愿意尽可能使用scalajs标准方法。

package pClient
import org.scalajs._
import dom._
import pUtil._

object ClientApp extends scalajs.js.JSApp
  {
    def main(): Unit =  
    {
      var can: html.Canvas =    document.createElement("canvas").asInstanceOf[html.Canvas]
      document.body.appendChild(can)
      can.width = window.innerWidth
      can.height = window.innerHeight - 60

      import raw.WebGLRenderingContext._
      var gl: raw.WebGLRenderingContext = can.getContext("webgl").asInstanceOf[raw.WebGLRenderingContext]     
      gl.clearColor(0.4, 0.0, 0.5, 0.8)
      gl.clear(COLOR_BUFFER_BIT)     

      var vShader = gl.createShader(VERTEX_SHADER)     
      var vertText = "attribute vec2 position;" -+ VMain(Seq("gl_Position = vec4(position, 0, 1);")).out(0)     
      gl.shaderSource(vShader, vertText)     
      gl.compileShader(vShader)     

      var fShader = gl.createShader(FRAGMENT_SHADER)
      var fragText = "precision highp float;" -+ "uniform vec4 color;" -+ VMain(Seq("gl_FragColor = vec4(0, 1, 0, 1);")).out(0)
      gl.shaderSource(fShader, fragText)
      gl.compileShader(fShader)

      var program = gl.createProgram()
      gl.attachShader(program, vShader)
      gl.attachShader(program, fShader)
      gl.linkProgram(program)     

      var tempVertices: scalajs.js.Array[Float] = scalajs.js.Array[Float]()
      tempVertices.push(-0.3f,-0.3f,   0.3f,-0.3f,  0.0f,0.3f,  0.2f,0.2f,   0.6f, 0.6f,   0.4f, -0.4f)     
      import scalajs.js.typedarray.Float32Array
      var vertices: Float32Array = new Float32Array(tempVertices)

      var buffer = gl.createBuffer()
      gl.bindBuffer(ARRAY_BUFFER, buffer)
      gl.bufferData(ARRAY_BUFFER, vertices, STATIC_DRAW)

      gl.useProgram(program)
      var progDyn = program.asInstanceOf[scalajs.js.Dynamic]
      progDyn.color = gl.getUniformLocation(program, "color")
      var temp2 = scalajs.js.Array[Double]()
      temp2.push(0f, 1f, 0.5f, 1.0f)
      gl.uniform4fv(progDyn.color.asInstanceOf[raw.WebGLUniformLocation], temp2)

      progDyn.position = gl.getAttribLocation(program, "position")
      gl.enableVertexAttribArray(progDyn.position.asInstanceOf[Int])
      gl.vertexAttribPointer(progDyn.position.asInstanceOf[Int], 2, FLOAT, false, 0, 0)
      gl.drawArrays(TRIANGLES, 0, vertices.length / 2)     
    } 
}

我在Eclipse中使用该程序。它在路径上有以下罐子:

scalajs-cli-assembly_2.11-0.6.5.jar
scalajs-compiler_2.11.7-0.6.5.jar
scalajs-dom_sjs0.6_2.11-0.9.0-SNAPSHOT.jar
scalajs-library_2.11-0.6.5.jar

我正在和sbt一起建设。 build.sbt:

enablePlugins(ScalaJSPlugin)
name := "ScalaClient"
scalaVersion := "2.11.7"
libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.8.0"
scalaSource in Compile := baseDirectory.value / "src"
scalacOptions := Seq("-feature", "-language:implicitConversions", "-deprecation", "-target:jvm-1.8")
unmanagedSourceDirectories in Compile += file("/sdat/scalaPackages/pUtil")

2 个答案:

答案 0 :(得分:2)

您可以显着改善数组初始化,如下所示:

import scala.scalajs.js // common import in Scala.js
import scala.scalajs.js.typedarray._

val vertices = new Float32Array(js.Array(
    -0.3f,-0.3f,  0.3f,-0.3f,  0.0f,0.3f,  0.2f,0.2f,
    0.6f,0.6f,  0.4f,-0.4f))

对于js.Dynamic的强制转型,这主要是因为WebGL的类型不尽如人意。此时WebGLProgram为空。随意为这些打字做出改进!

答案 1 :(得分:1)

以下是您在ScalaFiddle中的示例:https://scalafiddle.io/sf/Rb13PUG/8

import fiddle.Fiddle, Fiddle.println
import scalajs.js
import scala.scalajs.js.typedarray._
import org.scalajs.dom
import dom.raw.WebGLRenderingContext._

object ScalaFiddle extends js.JSApp{
  def main(): Unit = {
    var can: dom.html.Canvas = dom.document.createElement("canvas").asInstanceOf[dom.html.Canvas]
    dom.document.body.appendChild(can)
    can.width = Fiddle.canvas.width
    can.height = Fiddle.canvas.height

    var gl: dom.raw.WebGLRenderingContext = can.getContext("webgl").asInstanceOf[dom.raw.WebGLRenderingContext]     
    gl.clearColor(0.4, 0.0, 0.5, 0.8)
    gl.clear(COLOR_BUFFER_BIT)

    var vShader = gl.createShader(VERTEX_SHADER)     
    var vertText = "attribute vec2 position; void main() {gl_Position = vec4(position, 0, 1);}"
    gl.shaderSource(vShader, vertText)     
    gl.compileShader(vShader)     

    var fShader = gl.createShader(FRAGMENT_SHADER)
    var fragText = "precision highp float; uniform vec4 color; void main() {gl_FragColor = vec4(0, 1, 0, 1);}"
    gl.shaderSource(fShader, fragText)
    gl.compileShader(fShader)

    var program = gl.createProgram()
    gl.attachShader(program, vShader)
    gl.attachShader(program, fShader)
    gl.linkProgram(program)     

    val vertices = new Float32Array(js.Array(
    -0.3f,-0.3f,  0.3f,-0.3f,  0.0f,0.3f,  0.2f,0.2f,
    0.6f,0.6f,  0.4f,-0.4f))

    var buffer = gl.createBuffer()
    gl.bindBuffer(ARRAY_BUFFER, buffer)
    gl.bufferData(ARRAY_BUFFER, vertices, STATIC_DRAW)

    gl.useProgram(program)
    var progDyn = program.asInstanceOf[scalajs.js.Dynamic]
    progDyn.color = gl.getUniformLocation(program, "color")
    var temp2 = scalajs.js.Array[Double]()
    temp2.push(0f, 1f, 0.5f, 1.0f)
    gl.uniform4fv(progDyn.color.asInstanceOf[dom.raw.WebGLUniformLocation], temp2)

    progDyn.position = gl.getAttribLocation(program, "position")
    gl.enableVertexAttribArray(progDyn.position.asInstanceOf[Int])
    gl.vertexAttribPointer(progDyn.position.asInstanceOf[Int], 2, FLOAT, false, 0, 0)
    gl.drawArrays(TRIANGLES, 0, vertices.length / 2)     
  }
}