'공부/WebGL'에 해당되는 글 3건

반응형

 

<!DOCTYPE html>
<html>
<style type="text/css">
    canvas { background: blue; }
</style>

<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>


<select id = "SelectedImgae" onchange="change();">
    <option value="image1">image1</option>
    <option value="image2">image2</option>
    <option value="image3">image3</option>
</select>


<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
attribute  vec2 vTexCoord;

varying vec4 fColor;
varying vec2 fTexCoord;

uniform vec3 theta;

void main()
{
    // Compute the sines and cosines of theta for each of
    //   the three axes in one computation.
    vec3 angles = radians( theta );
    vec3 c = cos( angles );
    vec3 s = sin( angles );

    // Remeber: thse matrices are column-major
    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
		    0.0,  c.x,  s.x, 0.0,
		    0.0, -s.x,  c.x, 0.0,
		    0.0,  0.0,  0.0, 1.0 );

    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
		    0.0, 1.0,  0.0, 0.0,
		    s.y, 0.0,  c.y, 0.0,
		    0.0, 0.0,  0.0, 1.0 );

    mat4 rz = mat4( c.z, s.z, 0.0, 0.0,
		    -s.z,  c.z, 0.0, 0.0,
		    0.0,  0.0, 1.0, 0.0,
		    0.0,  0.0, 0.0, 1.0 );

    fColor = vColor;
    fTexCoord = vTexCoord;
    gl_Position = rz * ry * rx * vPosition;
    gl_Position.z = -gl_Position.z;
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;

varying vec4 fColor;
varying  vec2 fTexCoord;

//shader에서 텍스쳐 데이터에 접근
uniform sampler2D Tex0;


void
main()
{
    gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord)*texture2D(Tex2, fTexCoord));
}
</script>

<script type="text/javascript" src="./webgl-utils.js"></script>
<script type="text/javascript" src="./initShaders.js"></script>
<script type="text/javascript" src="./MV.js"></script>
<script type="text/javascript" src="./textureCube1.js"></script>


<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
<img id = "image1" src = "./image1.jpg" ></img>
<img id = "image2" src = "./image2.jpg" ></img>
<img id = "image3" src = "./image3.jpg" ></img>
</body>
</html>

 

"use strict";

var canvas;
var gl;
//삼각형 4개, 사각형 1개(삼각형2개) => 4*3 + 2*4 = 18 개 정점
var numVertices  = 18;

var texSize = 64;


var program;

var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];

var texture;

//텍스쳐 좌표계
var texCoord = [
    vec2(0, 0),
    vec2(0, 1),
    vec2(1, 1),
    vec2(1, 0)
];

/*
var texCoord2 = [
    vec2(0, 1),
    vec2(0.5, 1),
    vec2(1, 0)
];
*/
/*
    [위에서 쳐다봤을때]
    삼각형 4개 
  1 ㅡㅡㅡㅡㅡㅡ 2
    |*      * |
    |  *  *   |
    |   *4    |  
    | *     * |
   0ㅡㅡㅡㅡㅡㅡ 3
        
*/
var vertices = [
    vec4( -0.5, -0.5,  -0.5, 1.0 ),//0
        vec4( -0.5, -0.5,  0.5, 1.0 ),//1
        vec4(  0.5, -0.5,  0.5, 1.0 ),//2
        vec4(  0.5, -0.5,  -0.5, 1.0 ),//3
        vec4(    0,  0.5,    0, 1.0 )//4
];


var vertexColors = [
    vec4( 0.0, 0.0, 0.0, 1.0 ),  // black
    vec4( 1.0, 0.0, 0.0, 1.0 ),  // red
    vec4( 1.0, 1.0, 0.0, 1.0 ),  // yellow
    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green
    vec4( 0.0, 0.0, 1.0, 1.0 ),  // blue
    vec4( 1.0, 0.0, 1.0, 1.0 ),  // magenta
    vec4( 0.9, 0.9, 0.9, 1.0 ),  // white
    vec4( 0.0, 1.0, 1.0, 1.0 )   // cyan
];

var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];

var thetaLoc;

function configureTexture( image ) {
//1--------------------------------------------------------------------
	//텍스쳐 생성
    texture = gl.createTexture();
	//사용하기전에 바인딩
    gl.bindTexture( gl.TEXTURE_2D, texture );
	//webGL 애플리케이션은 Y축기준으로 텍스쳐 로딩
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
	//바인딩 후 이미지 데이터 생성 => 이미지를 textImage2D 함수로 넘김
    gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB,
         gl.RGB, gl.UNSIGNED_BYTE, image );
       //밉맵 생성
    gl.generateMipmap( gl.TEXTURE_2D );
	//텍스쳐 필터 지정
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
                      gl.NEAREST_MIPMAP_LINEAR );
    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
    gl.uniform1i(gl.getUniformLocation(program, "texture"), 0);
   
//--------------------------------------------------------------------
}

function quad(a, b, c, d) {

     pointsArray.push(vertices[a]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[0]);

     pointsArray.push(vertices[b]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[1]);

     pointsArray.push(vertices[c]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[2]);

     pointsArray.push(vertices[a]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[0]);

     pointsArray.push(vertices[c]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[2]);

     pointsArray.push(vertices[d]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[3]);
}

function triple(a, b, c) {
     pointsArray.push(vertices[a]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[0]);

     pointsArray.push(vertices[b]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[1]);

     pointsArray.push(vertices[c]);
     colorsArray.push(vertexColors[6]);
     texCoordsArray.push(texCoord[2]);

} 

function colorCube()
{
   triple( 0, 4, 1);
   triple( 3, 4, 0 );
   triple( 2, 4, 3);
   triple( 1, 4, 2 );
   quad( 0, 1, 2,3 );
}

function chageSelectedValue(){
    var SelectedImg = document.getElementById("Selected Imgae");
    var selectedValue = SelectedImg.options[SelectedImg.selectedIndex].value;
  
}


window.onload = function init() {

    canvas = document.getElementById( "gl-canvas" );

    gl = WebGLUtils.setupWebGL( canvas );
    if ( !gl ) { alert( "WebGL isn't available" ); }

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );

    gl.enable(gl.DEPTH_TEST);

    //
    //  Load shaders and initialize attribute buffers
    //
    program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );

    colorCube();


    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );

    var vColor = gl.getAttribLocation( program, "vColor" );
    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vColor );

    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );

    var vPosition = gl.getAttribLocation( program, "vPosition" );
    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );

    var tBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );

    var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
    gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vTexCoord );






    change();

    thetaLoc = gl.getUniformLocation(program, "theta");

    document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
    document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
    document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};

    render();

}

function change(){

    var SelectedImg = document.getElementById("SelectedImgae");
    var id = SelectedImg.options[SelectedImg.selectedIndex].value;

    var image = document.getElementById(id);
    configureTexture( image );
}



var render = function(){
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    theta[axis] += 2.0;
    gl.uniform3fv(thetaLoc, flatten(theta));
    gl.drawArrays( gl.TRIANGLES, 0, numVertices );
    requestAnimFrame(render);
}

참고: 만약 로컬에서 이걸 실행하는 경우 WebGL에서 이미지를 로드할 수 있도록 하기 위해 간단한 웹 서버가 필요합니다 => 가장 간단하게 만들 수 있는 웹 서버인 “Web Server for Chrome”

728x90
반응형

'공부 > WebGL' 카테고리의 다른 글

WebGL 피라미드  (0) 2020.07.17
WebGL sierpinski carpet  (0) 2020.07.17
블로그 이미지

아상관없어

,

WebGL 피라미드

공부/WebGL 2020. 7. 17. 02:33
반응형

<html>

<html>

<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
varying vec4 fColor;

uniform vec3 theta;

void main() 
{
    // Compute the sines and cosines of theta for each of
    //   the three axes in one computation.
    vec3 angles = radians( theta );//각도입력
    vec3 c = cos( angles );//cos
    vec3 s = sin( angles );//sin

    // Remeber: thse matrices are column-major
    //x축 회전인데, column major로 표현
    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
		    0.0,  c.x,  s.x, 0.0,
		    0.0, -s.x,  c.x, 0.0,
		    0.0,  0.0,  0.0, 1.0 );
    //y축 회전인데, column major로 표현
    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
		    0.0, 1.0,  0.0, 0.0,
		    s.y, 0.0,  c.y, 0.0,
		    0.0, 0.0,  0.0, 1.0 );

    //z축 회전인데, column major로 표현
    mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
		    s.z,  c.z, 0.0, 0.0,
		    0.0,  0.0, 1.0, 0.0,
		    0.0,  0.0, 0.0, 1.0 );

    fColor = vColor;
    gl_Position = rz * ry * rx * vPosition;
    //x, y, z순으로 곱해져야
    //새로운 vPosition
} 
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;
   
varying vec4 fColor;

void
main()
{
    gl_FragColor = fColor;
}
</script>

<script type="text/javascript" src="webgl-utils.js"></script>
<script type="text/javascript" src="initShaders.js"></script>
<script type="text/javascript" src="MV.js"></script>
<script type="text/javascript" src="cube.js"></script>

<body>
<canvas id="gl-canvas" width="512"" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
   
<br/>

<button id= "xButton">Rotate X</button>
<button id= "yButton">Rotate Y</button>
<button id= "zButton">Rotate Z</button>

</body>
</html>

 

js

//=====================================================================
//변수들 선언
//=====================================================================
var canvas;
var gl;

//삼각형 4개, 사각형 1개(삼각형2개) => 4*3 + 2*4 = 18 개 정점
var NumVertices  = 18;

//정점을 저장하는 배열
var points = [];

//색상을 저장하는 배열
var colors = [];

//x, y, z축
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;

//기본축
var axis = 0;

//x, y, z만큼 각도
var theta = [ 0, 0, 0 ];

var thetaLoc;
//=====================================================================
window.onload = function init()// 콜백함수, onload = 모든코드가 로드된 후 시작할 위치를 지정
//모든 action은 init()과 render()같은 함수 안에 잇는데, 
//onload 이벤트가 발생할때, init()함수를 실행하게함.
{
    canvas = document.getElementById( "gl-canvas" );
    // 캔버스를 읽어옴, getElementById 함수로 "gl-canvas"를 불러옴

    gl = WebGLUtils.setupWebGL( canvas );
    // 불러온 canvas를 인자로 넘겨, WebGL코드를 설정해줌
    if ( !gl ) { alert( "WebGL isn't available" ); }

    //함수 실행
    colorCube();
    //=====================================================================
    gl.viewport( 0, 0, canvas.width, canvas.height );//크기
    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );//배경색
    //depth buffer의 내용에 따라 fragment의 깊이 값을 테스트합니다.
    //OpenGL은 depth test를 수행하고 이 테스트가 통과되면 이 depth buffer는 새로운 깊이 값으로 수정됩니다. 
    //이 테스트가 실패한다면 해당 fragment는 폐기됩니다.
    gl.enable(gl.DEPTH_TEST);
    //=====================================================================


    //=====================================================================
    //  Load shaders and initialize attribute buffers
    //=====================================================================
    //GPU에 넘겨줄 Program 객체
    //initShaders사용하여 shader 로드, 컴파일, 링크하여 Program객체 생성
    var program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );
    
    //-------------------------------------------------------------------
    //color 버퍼를 만들고 컬러를 넣음
    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );

    var vColor = gl.getAttribLocation( program, "vColor" );
    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vColor );
    //-------------------------------------------------------------------

    //-------------------------------------------------------------------
    //data를 넣을 버펄르 만들고 데이터를 줌
    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
    

    var vPosition = gl.getAttribLocation( program, "vPosition" );
    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );
    //------------------------------------------------------------------- 

    //getUniformLocation함수로 theta값 가져옴.
    thetaLoc = gl.getUniformLocation(program, "theta");
     
    //=====================================================================


    //=====================================================================
    //버튼 이벤트 리스너 (축에 버튼에 해당하는 축을 넣음)
    //=====================================================================
    document.getElementById( "xButton" ).onclick = function () {
        axis = xAxis;
    };
    document.getElementById( "yButton" ).onclick = function () {
        axis = yAxis;
    };
    document.getElementById( "zButton" ).onclick = function () {
        axis = zAxis;
    };
    //=====================================================================   


    render();
}

//=====================================================================   
function colorCube()
{
    //피라미드는 삼각형 4개, 정육면체 1개
   triple( 1, 0, 4 );
   triple( 0, 3, 4 );
   triple( 3, 2, 4 );
   triple( 1, 4, 2 );
   quad( 0, 4, 7, 3 );
}
//=====================================================================   



//=====================================================================   
//삼각형을 그려줌, abc인자로
//=====================================================================   
/*
    [위에서 쳐다봤을때]
    삼각형 4개 
  1 ㅡㅡㅡㅡㅡㅡ 2
    |*      * |
    |  *  *   |
    |   *4    |  
    | *     * |
   0ㅡㅡㅡㅡㅡㅡ 3
        
*/
//사각뿔의 꼭지 위 점과, 밑 사각형의 점로 삼각형을 그림
function triple(a, b, c){
    //삼각형 4개 정점
    var vertices = [
        vec4( -0.5, -0.5,  -0.5, 1.0 ),//0
        vec4( -0.5, -0.5,  0.5, 1.0 ),//1
        vec4(  0.5, -0.5,  0.5, 1.0 ),//2
        vec4(  0.5, -0.5,  -0.5, 1.0 ),//3
        vec4(    0,  0.5,    0, 1.0 )//4
    ];
    var vertexColors = [
        [ 0.0, 0.0, 0.0, 1.0 ],  // black
        [ 1.0, 0.0, 0.0, 1.0 ],  // red
        [ 1.0, 1.0, 0.0, 1.0 ],  // yellow
        [ 0.0, 1.0, 0.0, 1.0 ],  // green
        [ 0.0, 0.0, 1.0, 1.0 ],  // blue
        [ 1.0, 0.0, 1.0, 1.0 ],  // magenta
        [ 0.0, 1.0, 1.0, 1.0 ],  // cyan
        [ 1.0, 1.0, 1.0, 1.0 ]   // white
    ];

    
    //삼각형이므로 인자를 3개 받음
    var indices = [ a, b, c ];

    for ( var i = 0; i < indices.length; ++i ) {
        //vertices[a], vertices[b], vertices[c]를 넣음
        points.push( vertices[indices[i]] );
            //평면의 색을 그라데이션효과 처럼 해줌        
        //colors.push( vertexColors[indices[i]] );
    
        //평면이 모두 같은 색(vertexColors[b]으로 되게 해줌 => 2번째 인자를 안겹치게 했음
        colors.push(vertexColors[b]);
        
    }
}
//=====================================================================   







//=====================================================================   
//4개의 인자로, abc, acd 사각형을 그려줌
//=====================================================================   
/*
[밑에서 쳐다봤을때] 
정육면체1개(삼각형 2개) 
        
   4ㅡㅡㅡㅡㅡㅡ7
    |         |
    |         |
    |         |  
    |         |
   0ㅡㅡㅡㅡㅡㅡ3
 =>예제 cube코드를 가져와 사용.       
*/
function quad(a, b, c, d) 
{
    //=> ppt그림 참고함
    var vertices = [
        vec4( -0.5, -0.5,  0.5, 1.0 ),//0
        vec4( -0.5,  0.5,  0.5, 1.0 ),//1
        vec4(  0.5,  0.5,  0.5, 1.0 ),//2
        vec4(  0.5, -0.5,  0.5, 1.0 ),//3
        vec4( -0.5, -0.5, -0.5, 1.0 ),//4
        vec4( -0.5,  0.5, -0.5, 1.0 ),//5
        vec4(  0.5,  0.5, -0.5, 1.0 ),//6
        vec4(  0.5, -0.5, -0.5, 1.0 )//7
    ];

    var vertexColors = [
        [ 0.0, 0.0, 0.0, 1.0 ],  // black
        [ 1.0, 0.0, 0.0, 1.0 ],  // red
        [ 1.0, 1.0, 0.0, 1.0 ],  // yellow
        [ 0.0, 1.0, 0.0, 1.0 ],  // green
        [ 0.0, 0.0, 1.0, 1.0 ],  // blue
        [ 1.0, 0.0, 1.0, 1.0 ],  // magenta
        [ 0.0, 1.0, 1.0, 1.0 ],  // cyan
        [ 1.0, 1.0, 1.0, 1.0 ]   // white
    ];

    
    var indices = [ a, b, c, a, c, d ];

    for ( var i = 0; i < indices.length; ++i ) {
        //vertices[a] ~ [b] ~ [c] ~ [a] ~ [c] ~[d]를 넣음
        points.push( vertices[indices[i]] );
        //colors.push( vertexColors[indices[i]] );
    
        // 위 삼각형들의 색상과 겹치지 않게 하기위해 6번째 색 사용 
        colors.push(vertexColors[5]);
        
    }
}
//=====================================================================   








//=====================================================================   
function render()
{
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

    //aixs축 기준으로 각도 2도 만큼
    theta[axis] += 2.0;
    //uniform 변수로 theta 전달, vertex shader가 그릴수 있게 해줌.
    gl.uniform3fv(thetaLoc, theta);
    
    /* 밑의 코드와 동일 코드
    for(i = 0; i< points.length; i = i+3){ 
        gl.drawArrays( gl.TRIANGLES, i, 3);
    }*/
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );

    requestAnimFrame( render );
    //render 함수를 애니메이션으로 실행
}
//=====================================================================   

 

 

옆면의 삼각형 4개와 밑면의 사각형 하나가 필요하다. 밑면의 사각형은 2개의 삼각형으로 만들어지므로, 결국 6개의 삼각형으로 구성된다. 따라서 Numvertex18개가 된다.

 

 

꼭지점을 위 그림처럼 잡아주었고 그리고 순서를 0,1,2,3,4로주어 그림을 그렸다.

colorCube함수에 삼각형을 그려주는 triple함수를 구현하여, 삼각형과 사각형을 따로 구분 지어 그렸다.

728x90
반응형

'공부 > WebGL' 카테고리의 다른 글

WebGL 피라미드 텍스쳐  (0) 2020.07.17
WebGL sierpinski carpet  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형

 

carpet.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>2D Sierpinski carpet LAST</title>

<!--Vertex Shader에 전송하는 변수 'v'Position-->
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;

void
main()
{
    gl_Position = vPosition;
}
</script>

<!--fragment shader-->
<!--정밀도는 medium으로-->
<!--X => (배경색을 빨강으로 하고 안의 네모를 힌색으로 구현)-->
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;

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


<script type="text/javascript" src="webgl-utils.js"></script>
<script type="text/javascript" src="initShaders.js"></script>
<!--
gasket2.js 에서 사용할 라이브러리, Web GL구동을 위한 기본적인 라이브러리
webgl-utils.js = 웹사이트의 Common 디렉토리에 있는 WebGL context를 설정하는 표준 유틸리티
initShaders.js = shader를 읽고, 컴파일하고, 링크하는 JS와 WebGL 코드
-->
<script type="text/javascript" src="MV.js"></script>
<!--수학함수 벡터관리 함수, 자체 행렬 벡터 패키지(책의 저자가 제공)-->
<script type="text/javascript" src="carpet.js"></script>
<!-- 실행 하려는 프로그램, 응용 프로그램 파일-->
</head>   

<body>
	<!-- 캔버스 정의-->
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

carpet.js

"use strict";

var canvas;
var gl;
var i;
var points = [];

var NumTimesToSubdivide = 7;



//onload함수로 시작함
window.onload = function init()// 콜백함수, onload = 모든코드가 로드된 후 시작할 위치를 지정
{
    canvas = document.getElementById( "gl-canvas" );
    // 캔버스를 읽어옴, getElementById 함수로 "gl-canvas"를 불러옴

    gl = WebGLUtils.setupWebGL( canvas );
    // 불러온 canvas를 인자로 넘겨, WebGL코드를 설정해줌

    if ( !gl ) { alert( "WebGL isn't available" ); }
    //예외처리

    //
    //  Initialize our data 
    //

    // 네 점 초기ㅗ하

    var vertices = [
        vec2(-1,-1),//a
        vec2(-1, 1),//b
        vec2(1, 1),//c
        vec2(1, -1)//d
    ];
    /*
     b     c
     *-----* 
     |   * |
     | *   |
     *-----*
     a     d

    */
    divideTriangle(vertices[0], vertices[1], vertices[2], vertices[3], NumTimesToSubdivide);
    

    /*==========================================================*/
    //WebGL 기본 코드 
    //
    //  Configure WebGL
    //
    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 1.0, 1.0, 1.0, 1.0  ); // X => (//색상 흰색으로)
    /*==========================================================*/


    /*====================================================================*/
    //  Load shaders and initialize attribute buffers
    //GPU에 넘겨줄 Program 객체
    //initShaders사용하여 shader 로드, 컴파일, 링크하여 Program객체 생성
    var program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );
    /*====================================================================*/


    /*========================================================================================*/
    // Load the data into the GPU
    //Vertex buffer 객체를 GPU에 로드함
    //버퍼를 만들어서 data를 줌성
    var bufferId = gl.createBuffer();//버퍼 생성
    gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );//bufferId에 binding
    gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );//데이터를 버퍼에
    //flatten() => js배열을 float32 배열로 변환 (OpenGL - JS간 배열 해석이 다르므로 row -> column)
    /*========================================================================================*/


    /*========================================================================================*/
    // Associate out shader variables with our data buffer
    //프로그램 내 변수와 shader변수를 연결해야함 => 버퍼내 이름, 타입, 위치가 필요
    //vPosition 변수에 실어 보냄, vPosition => 그 변수의 위치를 받아오겠다
    var vPosition = gl.getAttribLocation( program, "vPosition" );//getAttributeLocation = 위치
    gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );//vertex 속성, 2차원
    gl.enableVertexAttribArray( vPosition );
    /*========================================================================================*/


    //랜더링 = 그림을 그려줌
    render();
};

/*==========================*/
//WebGL은 삼각형만 디스플레이함/
/*==========================*/

//스택에 4개 넣고
//기본요소 TRIANGLE_FAN를 사용, 인자 4개
function triangle( a, b, c, d )
{
    points.push( a, b, c, d );
}


// X => (/* 배경을 빨간색으로 지정하고 안의 사각형을 힌색으로 지정해 안의 사각형만 그려주면됌*/)
//사각형을 그려줌, 중간 공간은 안그림
function divideTriangle( a, b, c, d, count )
{

    // check for end of recursion
    //더이상 쪼갤 필요가 없을때 
   if ( count === 0 ) {
        triangle( a, b, c, d);
    }

   else {
        //위
        var bc1 = mix( b, c, 1/3);
        var bc2 = mix( b, c, 2/3);

        //왼쪽
        var ab1 = mix( a, b, 1/3);
        var ab2 = mix( a, b, 2/3);

        //오른쪽
        var cd1 = mix( c, d, 1/3);
        var cd2 = mix( c, d, 2/3);

        //밑
        var ad1 = mix( a, d, 1/3);
        var ad2 = mix( a, d, 2/3);

        //중간 사각형 vertex
        var ma = mix( ab1, cd2, 1/3);
        var mb = mix( ab2, cd1, 1/3);
        var mc = mix( ab2, cd1, 2/3);
        var md = mix( ab1, cd2, 2/3);
        //=> 중간에 있는 4개 vertex를 사용해서 삼각형 두개로 사각형 만듬  
        //최종적 실행은 triangle(ma, mb, mc, md) => 각 사각형 마다 해주면됌      


        /*

            b  bc1 bc2  c
            *---*---*---*
            | 1 | 2 | 3 |
         ab2*---*---*---*cd1
            | 4 | 5 | 6 |
         ab1*---*---*---*cd2
            | 7 | 8 | 9 |
            *---*---*---* 
            a  ad1 ad2  d

        */
         --count;


        divideTriangle(ab2, b, bc1, mb, count);  //1번사각형
        divideTriangle(mb, bc1, bc2, mc, count); //2번사각형
        divideTriangle(mc, bc2, c, cd1, count);  //3번사각형
        divideTriangle(ab1, ab2, mb, ma, count); //4번사각형

        //중간 사각형은그리지 않으므로
        //divideTriangle(ma, mb, mc, md, count); //5번사각형 

        divideTriangle(md, mc, cd1, cd2, count); //6번사각형
        divideTriangle(a, ab1, ma, ad1, count);  //7번사각형
        divideTriangle(ad1, ma, md, ad2, count); //8번사각형
        divideTriangle(ad2, md, cd2, d, count);  //9번사각형
    }
}

function render()
{
    gl.clear( gl.COLOR_BUFFER_BIT );
    for(i = 0; i< points.length; i = i+4){ 
        gl.drawArrays( gl.TRIANGLE_FAN, i, 4);
    }
    //삼각형 두개 로 나눠서 위 삼각형 아래 삼각형 따로 함수 구현하지 않기 위해 Triganles 대신 Triangles_fan 사용
}

 

728x90
반응형

'공부 > WebGL' 카테고리의 다른 글

WebGL 피라미드 텍스쳐  (0) 2020.07.17
WebGL 피라미드  (0) 2020.07.17
블로그 이미지

아상관없어

,