2

How can I draw simple square using BufferGeometry? For example BufferGeometry draws 120000 triangles and I want to knock it down to two that form a simple square.

<html>
<head>
    <title>test app</title>
    <style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
    <script src="three.min.js"></script>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        //var geometry = new THREE.CubeGeometry(1,1,1);
        var triangles = 2;

        var geometry = new THREE.BufferGeometry();
        geometry.attributes = {
            index: {
                itemSize: 1,
                array: new Uint16Array( triangles * 3 ),
                numItems: triangles * 3
            },
            position: {
                itemSize: 3,
                array: new Float32Array( triangles * 3 * 3 ),
                numItems: triangles * 3 * 3
            },
            normal: {
                itemSize: 3,
                array: new Float32Array( triangles * 3 * 3 ),
                numItems: triangles * 3 * 3
            },
            color: {
                itemSize: 3,
                array: new Float32Array( triangles * 3 * 3 ),
                numItems: triangles * 3 * 3
            }
        }

        var color = new THREE.Color();

        var indices = geometry.attributes.index.array;
        var positions = geometry.attributes.position.array;
        var normals = geometry.attributes.normal.array; //not setting normals - is it relevant if there is no light defined?
        var colors = geometry.attributes.color.array;

        for ( var i = 0; i < indices.length; i ++ ) {

                indices[ i ] = i % ( 3 * 1 ); // How to set indices????

        }

        for ( var i = 0; i < positions.length; i += 9 ) {

            //I know these will make two triangles at same position, but i want to see them appear first..
            positions[ i ]     = 0;
            positions[ i + 1 ] = 0;
            positions[ i + 2 ] = 0;

            positions[ i + 3 ] = 0;
            positions[ i + 4 ] = 1;
            positions[ i + 5 ] = 0;

            positions[ i + 6 ] = 1;
            positions[ i + 7 ] = 0;
            positions[ i + 8 ] = 0;

            color.setRGB( 55, 202, 55 );

            colors[ i ]     = color.r;
            colors[ i + 1 ] = color.g;
            colors[ i + 2 ] = color.b;

            colors[ i + 3 ] = color.r;
            colors[ i + 4 ] = color.g;
            colors[ i + 5 ] = color.b;

            colors[ i + 6 ] = color.r;
            colors[ i + 7 ] = color.g;
            colors[ i + 8 ] = color.b;
        }           

        var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
        var square = new THREE.Mesh(geometry, material);
        scene.add(square);

        camera.position.z = -5;

        var render = function () {
            requestAnimationFrame(render);

            square.rotation.x += 0.1;
            square.rotation.y += 0.1;

            renderer.render(scene, camera);
        };

        render();
    </script>
</body>

Wilt
  • 41,477
  • 12
  • 152
  • 203
pera
  • 882
  • 11
  • 21
  • Can you please show us your code and what you have tried so far? It will be much easier for us to help you if you do so, and we will be more likely to put in the time to help you, as we will be able to see that you have put in the time to try to solve the problem yourself. – Zachary Kniebel Jul 11 '13 at 17:39
  • Thank you for reply, I added complete code to my question, it shows nothing. – pera Jul 12 '13 at 15:43

2 Answers2

3

In the newest three js version you cannot set index as how @calvin-sydney wrote in his answer. You will have to use the setIndex method from the THREE.BufferGeometry.

geometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), 2));
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(positions), 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3));
geometry.addAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3));

geometry.setIndex( new THREE.BufferAttribute( new Uint32Array( indices ), 1 ) );
Wilt
  • 41,477
  • 12
  • 152
  • 203
2

Here are the solution for your problems: Since your camera near and far view is between 0.1 and 1000

var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

Then your vertices z position must be in between that range. Therefore, please change your code from

positions[ i + 2 ] = 0; 

to

positions[ i + 2 ] = 1;

Also, your code seem to be missing these parts:

geometry.addAttribute( 'index', new THREE.BufferAttribute( indices, 3 ) );
geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );

for the full fixed code, please refer it here: http://learn-daily.com/three-js-drawing-flying-triangle-using-buffergeometry/

Nic
  • 12,220
  • 20
  • 77
  • 105
  • you technically still have one triangle there, not square but I get it from here :) – pera May 22 '15 at 12:16
  • In the latest versions of three.js the index attribute must be set using `setIndex` method. See my answer for more details. – Wilt Mar 03 '16 at 10:06