使用Webgl创建三角形的随机位置

如何解决使用Webgl创建三角形的随机位置

我刚刚开始学习webgl,我一直在尝试使用javascript生成具有随机大小和位置的三角形,就像这张图片一样。

Random triangles

我知道我需要在函数initScene()中使用for循环,但是我不确定如何将新位置放入数组中。请帮忙。

// Application info.
var app = app || {};
var nbTriangles=20;
function getContextGL(canvasElement)
{
    var can = document.getElementById(canvasElement);
    if(can == null)
    {
        return [null,null];
    }

    var gl = can.getContext("webgl");

    return [can,gl];
}


function createShaderFromElement(gl,id) 
{
    // Grab the script element.
    var scriptElt = document.getElementById(id);
    if (!scriptElt) 
    {
        return null;
    }

    // Retrieve the source.
    var scriptSource = scriptElt.textContent;

    // Identify shader type based on element type.
    var shaderObj;
    if (scriptElt.type == "x-shader/x-fragment") 
    {
        shaderObj = gl.createShader(gl.FRAGMENT_SHADER);
    } 
    else if (scriptElt.type == "x-shader/x-vertex") 
    {
        shaderObj = gl.createShader(gl.VERTEX_SHADER);
    } 
    else 
    {
        return null;
    }

    // Compile and check status.
    gl.shaderSource(shaderObj,scriptSource);
    gl.compileShader(shaderObj);

  var ok = gl.getShaderParameter(shaderObj,gl.COMPILE_STATUS);

    if (!ok)
    {
        var msgError = gl.getShaderInfoLog(shaderObj);
    alert(msgError);
        gl.deleteShader(shader);

        return null;
    }

    return shaderObj;
}

function buildProgram(gl,vertexShader,fragmentShader)
{
    if (!vertexShader || !fragmentShader)
    {
        return null;
    }

    var progObject = gl.createProgram();
  if(!progObject)
  {
    alert("Can't create program object.");
    return ;
  }

  gl.attachShader(progObject,vertexShader);
  gl.attachShader(progObject,fragmentShader);

  gl.linkProgram(progObject);

    var ok = gl.getProgramParameter(progObject,gl.LINK_STATUS);
  if(!ok)
  {
    var msgError = gl.getProgramInfoLog(progObject);
    alert(msgError);

    gl.deleteProgram(progObject);
    return null;
  }

    return progObject;
}

function initGL()
{
    app.gl.viewport(0,app.can.width,app.can.height);


    app.gl.clearColor(0.,0.,1.0);
    app.gl.clear(app.gl.COLOR_BUFFER_BIT);

    var vs = createShaderFromElement(app.gl,"vs");
    var fs = createShaderFromElement(app.gl,"fs");
    app.progObject = buildProgram(app.gl,vs,fs);

    app.gl.useProgram(app.progObject);
}

function initScene()
{
    var gl = app.gl;

    // Creer le buffer de geometrie (vertex)
    //
    
       /* Drawing one triangle:
    

        var positions = [
            // coordonnees normalisees.
            0.0,0.1,-0.1,-0.1
            
        
        ];*/

        for (var i=0; i<nbTriangles;++i)
        {
        
        
        var  orig = [0.0,1.0,-1.0,-1.0];
        var scale = Math.random() * 0.2;
        var Trans = [Math.random() * 1.6,Math.random * 1.6];
        P0 = orig[0] * scale + Trans[0];
        P1 = orig[1] * scale + Trans[1];
        P2 = orig[2] * scale + Trans[2];


        var positions= new Positions (P0,P1,P2)

        TRIANGLES.push(newPositions); 
        }


    // Creer un nouveau buffer vide.
    var posBuffer = gl.createBuffer();

    // Ref sur l'attribut "pos" dans le vertex shader.
    var posLocation = gl.getAttribLocation(app.progObject,"pos");

    // Activer le buffer. Toute operation sur buffer
    // sera appliquer a posBuffer (il est actif!).
    gl.bindBuffer(gl.ARRAY_BUFFER,posBuffer);
    gl.enableVertexAttribArray(posLocation);
    gl.vertexAttribPointer(posLocation,2,gl.FLOAT,false /*no normalization*/,0 /*stride*/,0 /*offset*/);
    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(positions),gl.STATIC_DRAW);

}

function render()
{
    var gl = app.gl;

    gl.clear( gl.COLOR_BUFFER_BIT)

    
        // Dessiner le buffer.
        gl.drawArrays(gl.TRIANGLES,3* nbTriangles);
}

function init()
{
    [app.can,app.gl] = getContextGL('can');
    if (app.can == null || app.gl == null)
    {
        alert("Can't init canvas or context");
        return;
    }

    app.can.width = app.can.height * (app.can.clientWidth / app.can.clientHeight);
    
    var rect = app.can.getBoundingClientRect();
  app.scaleX = app.can.width / rect.width;
  app.scaleY = app.can.height / rect.height; 

    initGL();
    initScene();
    render();
}
div 
{
}

#main-div
{
display:inline-block;
}

#viewport,#manager
{
    float: left;
    margin: auto;
}

.color
{
    width:100px;
    height:50px;
}

.blue{
    background:#0f0;
}

#viewport
{
    width: 600px;
    height:700px;
}

#can
{
    width: 600px;
    height: 500px;
    border:1px solid orange;
}

#manager
{
    width: 200px;
    height:300px;
    padding: 0 0 0 5px;

}

#obj-list
{
    width: 200px;
}
<!DOCTYPE html>
<html>

<head>
    <title>Colored Quad</title>
    <link rel="stylesheet" type="text/css" href="style.css">
    <script src="colored_quad.js"></script> 

    <script id="vs" type="x-shader/x-vertex">
  precision mediump float;
    attribute vec2 pos;

  void main() 
    {
        vec4 pt = vec4(pos,0.0,1.0);
        gl_Position = pt;
  }
 </script>

    <script id="fs" type="x-shader/x-fragment">
  precision mediump float;
  void main() 
    {
    gl_FragColor = vec4(1,1);
  }
  </script>

</head>

<body onload="init();">

    <div id="main-div">

            <div id="viewport">
                <canvas id="can" >Your browser doesn't seem to support canvas!</canvas>
            </div>

    </div>

</body>
</html>

解决方法

运行代码时,出现错误“位置未定义”

也许您应该在发布问题之前尝试解决这些错误?如果您只是在学习JavaScript,也许these lessons would help

无论如何,此代码

Positions

有很多基本的javascript问题。

TRIANGLES未定义(运行它时的第一个错误)。仅查看代码,我还可以看到对未定义的newPositions的引用,对未定义的P0的引用。我还看到P1P2orig被假定为点,但是它们在P2中仅引用一个值,而不是2个值( x和y)。并且Trans[2]引用的 var positions = []; for (var i = 0; i < nbTriangles; ++i) { var orig = [0.0,1.0,-1.0,-1.0]; var scale = Math.random() * 0.2; var Trans = [Math.random() * 1.6,Math.random() * 1.6]; var P0 = [ orig[0] * scale + Trans[0],orig[1] * scale + Trans[1],]; var P1 = [ orig[2] * scale + Trans[0],orig[3] * scale + Trans[1],]; var P2 = [ orig[4] * scale + Trans[0],orig[5] * scale + Trans[1],]; positions.push(...P0,...P1,...P2); } 不存在。

这是一个解决方法

orig

另一种解决方法是遍历 for (var i = 0; i < nbTriangles; ++i) { var orig = [0.0,Math.random() * 1.6]; for (var j = 0; j < orig.length; j += 2) { positions.push( orig[j ] * scale + Trans[0],orig[j + 1] * scale + Trans[1],); } } 中的点

      const addV = (v1,v2) => v1.map((v1Elem,i) => v1Elem + v2[i]);
      const scaleV = (v,scale) => v.map((elem) => elem * scale);

      for (var i = 0; i < nbTriangles; ++i) {

        var orig = [0.0,Math.random() * 1.6];
        for (var j = 0; j < orig.length; j += 2) {
          // pull out 2 values from orig
          let p = orig.slice(j,j + 2);
          p = scaleV(p,scale);
          p = addV(p,Trans); 
          positions.push(...p);
        }
      }

另一种方法是编写缩放和添加向量的函数

// Application info.
var app = app || {};
var nbTriangles = 20;

function getContextGL(canvasElement) {
  var can = document.getElementById(canvasElement);
  if (can == null) {
    return [null,null];
  }

  var gl = can.getContext("webgl");

  return [can,gl];
}


function createShaderFromElement(gl,id) {
  // Grab the script element.
  var scriptElt = document.getElementById(id);
  if (!scriptElt) {
    return null;
  }

  // Retrieve the source.
  var scriptSource = scriptElt.textContent;

  // Identify shader type based on element type.
  var shaderObj;
  if (scriptElt.type == "x-shader/x-fragment") {
    shaderObj = gl.createShader(gl.FRAGMENT_SHADER);
  } else if (scriptElt.type == "x-shader/x-vertex") {
    shaderObj = gl.createShader(gl.VERTEX_SHADER);
  } else {
    return null;
  }

  // Compile and check status.
  gl.shaderSource(shaderObj,scriptSource);
  gl.compileShader(shaderObj);

  var ok = gl.getShaderParameter(shaderObj,gl.COMPILE_STATUS);

  if (!ok) {
    var msgError = gl.getShaderInfoLog(shaderObj);
    alert(msgError);
    gl.deleteShader(shader);

    return null;
  }

  return shaderObj;
}

function buildProgram(gl,vertexShader,fragmentShader) {
  if (!vertexShader || !fragmentShader) {
    return null;
  }

  var progObject = gl.createProgram();
  if (!progObject) {
    alert("Can't create program object.");
    return;
  }

  gl.attachShader(progObject,vertexShader);
  gl.attachShader(progObject,fragmentShader);

  gl.linkProgram(progObject);

  var ok = gl.getProgramParameter(progObject,gl.LINK_STATUS);
  if (!ok) {
    var msgError = gl.getProgramInfoLog(progObject);
    alert(msgError);

    gl.deleteProgram(progObject);
    return null;
  }

  return progObject;
}

function initGL() {
  app.gl.viewport(0,app.can.width,app.can.height);


  app.gl.clearColor(0.,0.,1.0);
  app.gl.clear(app.gl.COLOR_BUFFER_BIT);

  var vs = createShaderFromElement(app.gl,"vs");
  var fs = createShaderFromElement(app.gl,"fs");
  app.progObject = buildProgram(app.gl,vs,fs);

  app.gl.useProgram(app.progObject);
}

function initScene() {
  var gl = app.gl;

  // Creer le buffer de geometrie (vertex)
  //

  var positions = [];

  for (var i = 0; i < nbTriangles; ++i) {


    var orig = [0.0,-1.0];
    var scale = Math.random() * 0.2;
    var Trans = [Math.random() * 1.6,Math.random() * 1.6];
    var P0 = [
       orig[0] * scale + Trans[0],];
    var P1 = [
      orig[2] * scale + Trans[0],];
    var P2 = [
      orig[4] * scale + Trans[0],];
    positions.push(...P0,...P2);
  }


  // Creer un nouveau buffer vide.
  var posBuffer = gl.createBuffer();

  // Ref sur l'attribut "pos" dans le vertex shader.
  var posLocation = gl.getAttribLocation(app.progObject,"pos");

  // Activer le buffer. Toute operation sur buffer
  // sera appliquer a posBuffer (il est actif!).
  gl.bindBuffer(gl.ARRAY_BUFFER,posBuffer);
  gl.enableVertexAttribArray(posLocation);
  gl.vertexAttribPointer(posLocation,2,gl.FLOAT,false /*no normalization*/,0 /*stride*/,0 /*offset*/ );
  gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(positions),gl.STATIC_DRAW);

}

function render() {
  var gl = app.gl;

  gl.clear(gl.COLOR_BUFFER_BIT)


  // Dessiner le buffer.
  gl.drawArrays(gl.TRIANGLES,3 * nbTriangles);
}

function init() {
  [app.can,app.gl] = getContextGL('can');
  if (app.can == null || app.gl == null) {
    alert("Can't init canvas or context");
    return;
  }

  app.can.width = app.can.height * (app.can.clientWidth / app.can.clientHeight);

  var rect = app.can.getBoundingClientRect();
  app.scaleX = app.can.width / rect.width;
  app.scaleY = app.can.height / rect.height;

  initGL();
  initScene();
  render();
}

init();

关于为每个三角形添加不同的颜色,我建议您阅读一些other articles on WebGL

#main-div {
  display: inline-block;
}

#viewport,#manager {
  float: left;
  margin: auto;
}

.color {
  width: 100px;
  height: 50px;
}

.blue {
  background: #0f0;
}

#viewport {
  width: 600px;
  height: 700px;
}

#can {
  width: 600px;
  height: 500px;
  border: 1px solid orange;
}

#manager {
  width: 200px;
  height: 300px;
  padding: 0 0 0 5px;
}

#obj-list {
  width: 200px;
}
  <div id="main-div">

      <div id="viewport">
        <canvas id="can" >Your browser doesn't seem to support canvas!</canvas>
      </div>

  </div>
  <script id="vs" type="x-shader/x-vertex">
  precision mediump float;
  attribute vec2 pos;

  void main() 
  {
    vec4 pt = vec4(pos,0.0,1.0);
    gl_Position = pt;
  }
 </script>

  <script id="fs" type="x-shader/x-fragment">
  precision mediump float;
  void main() 
  {
    gl_FragColor = vec4(1,1);
  }
  </script>
{{1}}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-