2017-11-10 6 views
1

그리고 미리 감사드립니다.gl.drawElements가 해당 정점 배열 버퍼를 "찾는"방법은 무엇입니까?

저는 Webgl에서 매우 새롭습니다. drawElements 메소드와 현재 그리드하려는 버텍스 버퍼 사이의 링크를 실제로 이해하지 못합니다. drawArray 메소드의 상황을 대략적으로 이해합니다 (예 : 버퍼 작성, 컨텍스트에 바인딩, 데이터로 채우기, 해당 속성을 가리킴, 그리기).

[.Offscreen-For-WebGL-0x7fae2b940800]GL ERROR :GL_INVALID_OPERATION : glDrawElements: bound to target 0x8893 : no buffer 

어쩌면 내 코드의 힌트는 도움이 : 나는 인덱스 배열 적은 정점 데이터와 동일 할 때, 나는 이러한 유형의 오류가 발생.

const cube = new Program(renderer.gl, vertex3d, fragment); // my webgl program 
    const cubeData = new Cube(); // Only array of vertices/indices 
    const cubeVertexPosition = new ArrayBuffer(renderer.gl, cubeData.vertices, 'STATIC_DRAW'); // ARRAY_BUFFER 
    const cubeVertexIndices = new IndexBuffer(renderer.gl, renderer.gl.UNSIGNED_SHORT, cubeData.indices, 'STATIC_DRAW'); // ELEMENT_ARRAY_BUFFER 
cubeVertexPosition.attribute('aPosition', 3, 'FLOAT', false); // define attribute corresponding in vertex shader 
    cubeVertexPosition.attributePointer(cube); // enableVertexAttribArray + vertexAttribPointer 
    [...] 
    cubeVertexIndices.draw('TRIANGLES', 0, 36); // drawElements with gl.UNSIGNED_SHORT type 

제가

drawArray :)

((가) [...] 만 유니폼 변환 행렬된다)와 도면에서 성공적이다;

은 아마 당신은,

고마워 날이 마술을 이해하는 데 도움이 수를 염두에 빠른 조언을!

답변

1

drawArray 사용 하나 또는 그들이 버퍼에있는 순서대로 정점 count 매개 변수에 대한 first 매개 변수에서 그려진 곳에서 ARRAY_BUFFER 여러.

drawElements 사용 하나 또는 여러 ARRAY_BUFFER 그릴 ARRAY_BUFFER 정점을 가리키는 인덱스를 포함하고 있는지를 ELEMENT_ARRAY_BUFFER. drawElements에서 count 파라미터는 ELEMENT_ARRAY_BUFFER (데는 보통 FirstIndex*sizeof(type)type 될 수 UNSIGNED_BYTE (1 바이트를 판독하기 시작하는 곳 offset가)는 바이트 오프셋 UNSIGNED_SHORT (2 바이트를 지정하면서 ELEMENT_ARRAY_BUFFER 읽혀질 인덱스의 개수를 지정) 또는 UNSIGNED_INT (4 바이트)

ELEMENT_ARRAY_BUFFER :.

[0][1][2][1][2][0][1][2][3][3][1][2][3][4][5][... 

ARRAY_BUFFER :

| 0 | 1 | 2 | 3 | 4 | ... 
[x][y][z][x][y][z][x][y][z][x][y][z][x][y][z][... 
01,

제대로 작동하려면 offset + count*sizeof(type)ELEMENT_ARRAY_BUFFER 바이트보다 커야합니다. 또한 ELEMENT_ARRAY_BUFFER의 요소 인덱스는 ARRAY_BUFFER에 포함 된 정점 수보다 작아야합니다.

drawArray과 마찬가지로 drawElements은 현재 바인딩 된 버퍼 (특성 포인터가 구성된 상태)를 데이터 원본으로 사용합니다.

gl.bindBuffer(gl.ARRAY_BUFFER, myVerticesA); 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, myIndicesA); 
// configure attributes pointers here 
gl.drawElements(gl.TRIANGLES, 12345, gl.UNSIGNED_SHORT, 0); 

은 "어떻게"drawElementsARRAY_BUFFER 버퍼 (들)의 속성을 취할 것 인덱스가 저장있어서 : drawElements와의 차이는 당신이처럼 ELEMENT_ARRAY_BUFFER 대상을 사용하여, additionnal 요소 (인덱스) 버퍼를 지정해야한다는 것입니다 ELEMENT_ARRAY_BUFFER에서 속성 포인터 구성 방법에 따라 다릅니다.

인터리빙 위치, 법선과 질감 다음 정점 버퍼를 가정하면 좌표

| p0 || n0 || t0 || p1 || n1 || t1 | 
[px][py][pz][nx][ny][nz][tu][tv][px][py][pz][nx][ny][nz][tu][tv][... 

우리는 다음과 같은 속성 포인터를 정의

let stride = 8*4; // 8*float (8 * 4 bytes) 
let offp = 0; // positions at beginning 
let offn = 3*4; // normals after 3*float position. 
let offt = 6*4; // tex coords after 3*float position + 3*float normal 
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, stride, offp); 
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, stride, offn); 
gl.vertexAttribPointer(2, 2, gl.FLOAT, false, stride, offt); 

사용 요소 (인덱스) 버퍼 GL하겠습니다 ELEMENT_ARRAY_BUFFER 버퍼에 저장된 인덱스에 따라 간단히 포인터 위치를 이동하십시오.

// pseudo-code 
for(let i = start_elem; i < start_elem+count_elem; i++) { 

    let index = ELEMENT_ARRAY_BUFFER[i]; 

    attrib[0] = ARRAY_BUFFER[(index*stride)+offp]; 
    attrib[1] = ARRAY_BUFFER[(index*stride)+offn]; 
    attrib[2] = ARRAY_BUFFER[(index*stride)+offt]; 

} 
+0

빠른 답장을 보내 주셔서 감사합니다. 저를 위해 좀 더 명백합니다. 두 배열의 스키마는 사물이 어떻게 연결되어 있는지 설명하지만 링크가 명확하게 명확하지 않습니다. 어떤 ARRAY_BUFFER이 (가) ELEMENT_ARRAY_BUFFER에 "링크"되어 있는지 지정할 수있는 방법이 있습니까? –

+0

"링크"는 당신이'drawElements'를 호출 할 때 어느 버퍼에 묶여 있는지에 달려 있습니다.당신은'ELEMENT_ARRAY_BUFFER'를'target'으로'bindBuffer'를 호출하면 요소 (인덱스) 버퍼가 바인드되고 속성 (정점) 버퍼가 바인드 된'ARRAY_BUFFER'와 함께'bindBuffer'를 호출합니다. 이것은 그처럼 간단합니다. 이 부분을 지정하려면 내 대답을 편집하십시오. – dest1

0

게시 한 코드가 WebGL이 아닙니다. 코드에서 명확한 라이브러리를 사용 중입니다. Program, IndexBuffer, ArrayBuffer과 같은 것들은 사용중인 일부 라이브러리의 일부입니다. 그 라이브러리가하는 일은 그 라이브러리에 달렸습니다. 일반적 WebGL에있어서

쉐이더, 그 각 정점과 각 픽셀의 색 gl_FragColor을 설정하는 작업의 단편 쉐이더 좌표 클립 공간 gl_Position을 설정하는 작업의 버텍스 쉐이더있다.

버텍스 쉐이더는 일반적으로 속성에서 위치에 관한 데이터를 얻습니다. 속성은 일반적으로 버퍼에서 데이터를 가져옵니다. 먼저 버퍼를 ARRAY_BUFFER 바인드 포인트 인 gl.bindBuffer(gl.ARRAY_BUFFER, someBuffer)에 바인드 한 다음 gl.vertexAttribPointer을 호출하여 WebGL에 버퍼에서 데이터를 가져 오는 방법 (데이터의 유형, 데이터의 개수, 값의 수)을 알려주고 데이터를 가져올 버퍼의 속성을 지정합니다 정점 당 건너 뛸 바이트 수, 버퍼가 시작될 거리). gl.vertexAttribPointer은 주어진 속성에 대한 모든 정보와 ARRAY_BUFFER 바인드 포인트에 바인드 된 현재 버퍼에 대한 참조를 저장하므로 다른 버퍼를 바인드하여 다른 속성을 설정할 수 있습니다.

당신 셰이더의 속성으로 지정된 데이터 셰이더의 각 반복에 대해, 버퍼에서 한 세트의 값을 인출한다 gl.drawArrays 호출

은 하나 이상의 버퍼를 취 gl.drawElements 대해서는, 경계 ELEMENT_ARRAY_BUFFER으로 변경하고 gl.drawElements을 cll하면 버퍼의 데이터 유형 (gl.UNSIGNED_BYTE 또는 gl.UNSIGNED_SHORT)을 알 수 있습니다. 그런 다음 해당 버퍼 값을 사용하여 특성 버퍼에서 값을 가져옵니다.

gl.drawElements은 버퍼에 단순한 증가 값을 넣으면 정확히 gl.drawArrays과 같습니다. 예

const offset = 0; 
const numVerts = 100; 

// process 100 vertices from the buffers pointed to by the attributes 
// in order 0 to 99 
gl.drawArrays(gl.POINTS, offset, numVerts) 

당신이 INDEXDATA가 연속 될 필요가 없습니다 공급이 두 번째 경우 이후 효과적으로

// fill a buffer with numbers 0 to 99 (0 to numVerts) 
const numVerts = 100; 
const indexData = new Uint16Array(numVerts); 
for (let i = 0; i < numVerts; ++i) { 
    indexData[i] = i; 
} 
const indexBuffer = gl.createBuffer(); 
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW); 

// process 100 vertices from the buffers pointed to by the attributes 
// in order 0 to 99 
const offset = 0; 
gl.drawElements(gl.POINTS, numVerts, gl.UNSIGNED_SHORT, offset); 

그러나 물론 동일합니다.

다른 것을 읽을 것을 권합니다. webgl tutorials

+0

답장을 보내 주셔서 감사합니다. 죄송합니다 도서관 유사하게 보이는 코드. 그것은 반복적으로 다시 쓰지 않고도 나와 연결된 동일한 자습서를 작성하는 것입니다. 요점은 내가 drawArray 메서드를 이해하고 전에 성공적으로 적용했습니다. 이제 배열 버퍼를 인덱스 버퍼에 바인딩하는 프로그래밍 방식을 찾지 못하는 drawElements 메소드에 중점을 둡니다. –