使2D对象围绕其中心和屏幕中心旋转

时间:2019-03-23 15:43:46

标签: javascript html webgl

我收到了显示房屋的代码。我尝试从我所拥有的书中输入代码,然后整个形状消失了。一次,我解决了房屋消失的问题,我不知道如何更改代码以进行所需的旋转

我尝试将顶点着色器更改为书中应有的功能,但这是房子消失的时候

HTML

<html>
  <head>
    <meta content="text/html; charset=utf-8" />
    <title> WebGL - Lab4 </title>
    <style>
      #canvas_gl {
        margin : auto;
        display: block;
      } 
    </style>
  </head>
  <body onload="main()">
    <canvas id="canvas_gl" width="480" height="480"> </canvas>

    <!-- load utility scripts -->
    <script src="webgl-utils.js"> </script>
    <script src="webgl-debug.js"> </script>
    <script src="cuon-matrix.js"> </script>
    <script src="cuon-utils.js"> </script>

    <!-- load program code -->
    <script src="lab4.js"> </script>
  </body>
</html>

JavaScript

// ------------------------------------------------------------
// WebGL Lab 4 - Transformations
// ------------------------------------------------------------

var VSHADER = 
`
precision highp float;
attribute vec2 a_Position;
uniform mat4 H;
attribute float a_Value;
varying float v_Value;
void main() {
  gl_Position =  vec4(a_Position, 0.0, 1.0);
  gl_PointSize = 4.0;
  v_Value = a_Value;
}
`

var FSHADER =
`
precision highp float;
uniform int u_Mode;
varying float v_Value;
void main() {
  if (u_Mode == 0) {
    gl_FragColor = vec4(0.5, 0.5, 1.0, 1.0);  
  } else if (u_Mode == 1) {
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
  }

}
`
var angle = 90.0;

function transpose_mat3(mat3) {
  // transpose matH3 to column major
  for (let i=1;i<3; ++i) {
    for (let j=0;j<i; ++j) {
      // use direct access (i*3+j)
      let h = mat3[i*3+j];
      mat3[i*3+j] = mat3[j*3+i];
      mat3[j*3+i] = h;
    }
  } 
}

// global context object to store everything 
// ( we basically just throw everything that we 
//  need into this object ... no need for software 
//  engineering at this point :) )
let context = { };
/*let H = new Float32Array([1.0,0.0,0.0,0.0,
0.0,1.0,0.0,0.0,
0.0,0.0,1.0,0.0,
0.0,0.0,0.0,1.0]);*/

/*
    mouse handler function 
      - gets mouse coordinates in browser client area coordinates
      - handler transforms from client area coordinates
           to WebGL normalized device coordinates
*/
function handle_mouse(ev, canvas, context) {
  let rect = ev.target.getBoundingClientRect();
  let mx = ev.clientX;    // x mouse
  let my = ev.clientY;    // y mouse
  let cx = rect.left;     // canvas position x
  let cy = rect.top;      // canvas position y
  let wx = canvas.width;  // canvas width x
  let wy = canvas.height; // canvas width y

  // transform in matrix-vector notation
  //
  // ┏ 1  0 ┓   ┏ 2/w_x       0 ┓ ┏ m_x - c_x ┓   ┏ - 1.0 ┓
  // ┗ 0 -1 ┛ ( ┗      0  2/w_y ┛ ┗ m_y - c_y ┛ + ┗ - 1.0 ┛ )
  //
  let x_premul =  2.0 / wx;
  let y_premul = -2.0 / wy;
  let screen_x = x_premul*(mx-cx) - 1.0;
  let screen_y = y_premul*(my-cy) + 1.0;

  context.mouse = { x : screen_x, y : screen_y };

  // currently, no explicite update calls
}

function init_mousehandler(context, canvas) {
  canvas.onmousedown = function(ev) {
      handle_mouse(ev, canvas, context);
  };
}

function init_buffers(context) {
  let ctx = context;    // shortcut alias
  let gl = context.gl;  // shortcut alias

  ctx.buffer_house = gl.createBuffer();
  ctx.buffer_wires = gl.createBuffer();
  ctx.vertices_house = new Float32Array([
      0.0, 0.0,  0.2, 0.0,  0.2, 0.2,
      0.0, 0.0,  0.2, 0.2,  0.0, 0.2,
      0.0, 0.2,  0.2, 0.2,  0.1, 0.3
  ]);
  ctx.vertices_wires = new Float32Array([
      0.0, 0.0,  0.2, 0.0,  0.2, 0.0,  0.2, 0.2,  0.2, 0.2, 0.0, 0.0,
      0.0, 0.0,  0.2, 0.2,  0.2, 0.2,  0.0, 0.2,  0.0, 0.2, 0.0, 0.0, 
      0.0, 0.2,  0.2, 0.2,  0.2, 0.2,  0.1, 0.3,  0.1, 0.3, 0.0, 0.2
  ]);

  // TODO initialize matrix
}

/*
    initialization function
      - gets WebGL context from canvas object
      - initializes shaders via external library function
      - gets attribute location
      - stores WebGL context and additional information
          in global context object
      - registers mouse handler
      - clears framebuffer
*/
function canvas_init3D() {
  let canvas = document.querySelector("#canvas_gl");

  let gl = canvas.getContext("webgl");
  if (!gl) {
    console.log("Failed to get rendering context for WebGL");
    return;
  }

  if (!initShaders(gl, VSHADER, FSHADER)) {
    console.log("Failed to initialize shaders.");
    return;
  }

  let a_Position = gl.getAttribLocation(gl.program, "a_Position");
  if (a_Position < 0) {
    console.log("Failed to get storage location of a_Position.");
    return;
  }

  let a_Value = gl.getAttribLocation(gl.program, "a_Value");
  if (a_Value < 0) {
    console.log("Failed to get storage location of a_Value.");
    return;
  }  

  let u_Mode = gl.getUniformLocation(gl.program, "u_Mode");
  if (u_Mode < 0) {
    console.log("Failed to get storage location of u_Mode.");
    return;
  }

  // get matrix location in shader program

  // store information in context
  context.gl = gl;
  context.a_Position = a_Position;
  context.a_Value = a_Value;
  context.u_Mode = u_Mode;

  // initialize buffers
  init_buffers(context);

  // register mouse handler
  init_mousehandler(context, canvas);

  // clear framebuffer
  gl.clearColor(0.9,0.9,1.0,1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);
}

/* 
 * The update() function updates the model
 * that you want to render; it changes the
 * state of the model.
 */
function update(context, timestamp) {
  let ctx = context;    // shortcut alias
  let gl = context.gl;  // shortcut alias

  if (!ctx.timestamp_last) {
    console.log("no last time stamp");
    ctx.timestamp_last = timestamp;
    ctx.angle = 4.0;
    ctx.speed = 20.0; // degree per second
    return;
  }

  // get timestamp last and update in context
  let timestamp_last = ctx.timestamp_last
  ctx.timestamp_last = timestamp;

  // update transformation
}

/* 
 * The render function issues the draw calls
 * based on the current state of the model.
 */
function render(context, timestamp) {
  let ctx = context;    // shortcut alias
  let gl = context.gl;  // shortcut alias

  // clear framebuffer
  gl.clearColor(0.9,0.9,1.0,1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);

  // use vertices from buffer
  gl.bindBuffer(gl.ARRAY_BUFFER, ctx.buffer_house);
  gl.bufferData(gl.ARRAY_BUFFER, ctx.vertices_house, gl.STATIC_DRAW);
  gl.bindBuffer(gl.ARRAY_BUFFER, ctx.buffer_wires);
  gl.bufferData(gl.ARRAY_BUFFER, ctx.vertices_wires, gl.STATIC_DRAW);

  // set matrix data
  // TODO 

  // draw triangles
  gl.uniform1i(ctx.u_Mode, 0);
  gl.bindBuffer(gl.ARRAY_BUFFER, ctx.buffer_house);
  gl.vertexAttribPointer(ctx.a_Position, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(ctx.a_Position);
  gl.vertexAttrib1f(ctx.a_Value, 1.0);
  gl.drawArrays(gl.TRIANGLES, 0, 9);

  // draw wireframe mesh
  gl.uniform1i(ctx.u_Mode, 1);
  gl.bindBuffer(gl.ARRAY_BUFFER, ctx.buffer_wires);
  gl.vertexAttribPointer(ctx.a_Position, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(ctx.a_Position);
  gl.vertexAttrib1f(ctx.a_Value, 0.0);
  gl.drawArrays(gl.LINES, 0, ctx.vertices_wires.length/2);
}

/* 
 * The step() function is called for each animation
 * step. Note that the time points are not necessarily
 * equidistant.
 */
function step(timestamp) {
  update(context, timestamp);
  render(context);
  window.requestAnimationFrame(step);
}

function main() {
  console.log("WebGL - Lab4");

  window.requestAnimationFrame(step);
  canvas_init3D();
}

用我在这里的代码,房子确实显示了。但是,我无法弄清楚需要执行某些代码才能实现所需的旋转。

0 个答案:

没有答案