#javascript #webgl
#javascript #webgl
Вопрос:
Привет, я пытался одновременно рисовать разные фигуры в WebGL, однако он рисует только первую. Я действительно новичок в WebGL. Я не знаю, проблема в том, что я не использую буферы, поскольку я должен это делать, или шейдеры.
Но я думаю, что я использую разные буферы для каждой фигуры, потому что я передаю функцию «модель», а затем делаю модель.Idbuffer… Поэтому я думаю, что создаю буфер для каждого из них.
Любая помощь приветствуется, спасибо.
Это мой код.
var gl = null;
var program;
var x = 0;
var y = 0;
var z = 0;
var radi = 0;
var nombre_costats = 100;
var figura = {
"vertices" : [-0.2, -0.2 , 0.0,
-0.2, -0.1, 0.0,
-0.4, -0.1, 0.0,
-0.4, -0.2, 0.0,
-0.5, -0.2, 0.0,
-0.5, 0.0, 0.0,
-0.2, 0.0, 0.0,
-0.2, 0.2, 0.0,
0.3, 0.2, 0.0,
0.3, 0.0, 0.0,
0.4, 0.0, 0.0,
0.4, -0.2, 0.0,
0.3, -0.2, 0.0,
0.3, -0.1, 0.0,
0.1, -0.1, 0.0,
0.1, -0.2, 0.0,],
"indices" : [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 0]
};
var poligon = {
"vertices" : [],
"indices" : []
};
function dibuixar_cercle(x, y, z, radi, nombre_costats, poligon){
var nombre_vertex = nombre_costats 2;
poligon.vertices.push(0);
poligon.vertices.push(0);
poligon.vertices.push(0);
for (var i = 1; i<nombre_vertex; i ){
poligon.vertices.push(x radi * Math.cos( i * (2 * Math.PI) / nombre_costats));
poligon.vertices.push(y radi * Math.sin( i * (2 * Math.PI) / nombre_costats));
poligon.vertices.push(0);
if (i>=2){
poligon.indices.push(0);
poligon.indices.push(i-1);
poligon.indices.push(i);
}
}
}
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
try {
return canvas.getContext("webgl2");
}
catch(e) {
}
return null;
}
function initShaders() {
// paso 1
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById('myVertexShader').text);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById('myFragmentShader').text);
gl.compileShader(fragmentShader);
// paso 2
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// paso 3
gl.linkProgram(program);
gl.useProgram(program);
program.vertexPositionAttribute = gl.getAttribLocation( program, "VertexPosition");
gl.enableVertexAttribArray(program.vertexPositionAttribute);
}
function initRendering() {
gl.clearColor(0.0,0.0,1.0,1.0);
}
function initBuffers(model) {
model.idBufferVertices = gl.createBuffer ();
gl.bindBuffer (gl.ARRAY_BUFFER, model.idBufferVertices);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(model.vertices), gl.STATIC_DRAW);
model.idBufferIndices = gl.createBuffer ();
gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW);
}
function draw(model) {
gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.drawElements(gl.LINE_LOOP, 32, gl.UNSIGNED_SHORT, 0);
}
function draw2(model) {
gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.drawElements(gl.TRIANGLE, nombre_costats*3 , gl.UNSIGNED_SHORT, 0);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT);
draw(figura);
draw2(poligon);
}
function initWebGL() {
var costats = 100;
var radi = 0.1;
var x_centre = 0;
var y_centre = 0;
var z_centre = 0;
gl = getWebGLContext();
if (!gl) {
alert("WebGL 2.0 no está disponible");
return;
}
initShaders();
dibuixar_cercle(x_centre, y_centre, z_centre, radi, costats, poligon);
console.log(figura);
initBuffers(figura);
initBuffers(poligon);
console.log(poligon);
initRendering();
requestAnimationFrame(drawScene);
}
initWebGL();
```
Ответ №1:
В общем, вы должны включить свои шейдеры для вопросов WebGL. Но в любом случае проблема в том, что это gl.TRIANGLES
не gl.TRIANGLE
var gl = null;
var program;
var x = 0;
var y = 0;
var z = 0;
var radi = 0;
var nombre_costats = 100;
var figura = {
"vertices" : [-0.2, -0.2 , 0.0,
-0.2, -0.1, 0.0,
-0.4, -0.1, 0.0,
-0.4, -0.2, 0.0,
-0.5, -0.2, 0.0,
-0.5, 0.0, 0.0,
-0.2, 0.0, 0.0,
-0.2, 0.2, 0.0,
0.3, 0.2, 0.0,
0.3, 0.0, 0.0,
0.4, 0.0, 0.0,
0.4, -0.2, 0.0,
0.3, -0.2, 0.0,
0.3, -0.1, 0.0,
0.1, -0.1, 0.0,
0.1, -0.2, 0.0,],
"indices" : [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 0]
};
var poligon = {
"vertices" : [],
"indices" : []
};
function dibuixar_cercle(x, y, z, radi, nombre_costats, poligon){
var nombre_vertex = nombre_costats 2;
poligon.vertices.push(0);
poligon.vertices.push(0);
poligon.vertices.push(0);
for (var i = 1; i<nombre_vertex; i ){
poligon.vertices.push(x radi * Math.cos( i * (2 * Math.PI) / nombre_costats));
poligon.vertices.push(y radi * Math.sin( i * (2 * Math.PI) / nombre_costats));
poligon.vertices.push(0);
if (i>=2){
poligon.indices.push(0);
poligon.indices.push(i-1);
poligon.indices.push(i);
}
}
}
function getWebGLContext() {
var canvas = document.getElementById("myCanvas");
try {
return canvas.getContext("webgl2");
}
catch(e) {
}
return null;
}
function initShaders() {
// paso 1
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById('myVertexShader').text);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById('myFragmentShader').text);
gl.compileShader(fragmentShader);
// paso 2
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// paso 3
gl.linkProgram(program);
gl.useProgram(program);
program.vertexPositionAttribute = gl.getAttribLocation( program, "VertexPosition");
gl.enableVertexAttribArray(program.vertexPositionAttribute);
}
function initRendering() {
gl.clearColor(0.0,0.0,1.0,1.0);
}
function initBuffers(model) {
model.idBufferVertices = gl.createBuffer ();
gl.bindBuffer (gl.ARRAY_BUFFER, model.idBufferVertices);
gl.bufferData (gl.ARRAY_BUFFER, new Float32Array(model.vertices), gl.STATIC_DRAW);
model.idBufferIndices = gl.createBuffer ();
gl.bindBuffer (gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW);
}
function draw(model) {
gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.drawElements(gl.LINE_LOOP, 32, gl.UNSIGNED_SHORT, 0);
}
function draw2(model) {
gl.bindBuffer(gl.ARRAY_BUFFER, model.idBufferVertices);
gl.vertexAttribPointer(program.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, model.idBufferIndices);
gl.drawElements(gl.TRIANGLES, nombre_costats*3 , gl.UNSIGNED_SHORT, 0);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT);
draw(figura);
draw2(poligon);
}
function initWebGL() {
var costats = 100;
var radi = 0.1;
var x_centre = 0;
var y_centre = 0;
var z_centre = 0;
gl = getWebGLContext();
if (!gl) {
alert("WebGL 2.0 no está disponible");
return;
}
initShaders();
dibuixar_cercle(x_centre, y_centre, z_centre, radi, costats, poligon);
//console.log(figura);
initBuffers(figura);
initBuffers(poligon);
//console.log(poligon);
initRendering();
requestAnimationFrame(drawScene);
}
initWebGL();
<canvas id="myCanvas"></canvas>
<script id="myVertexShader" type="whatever">
attribute vec4 VertexPosition;
void main() {
gl_Position = VertexPosition;
}
</script>
<script id="myFragmentShader" type="whatever">
precision highp float;
void main() {
gl_FragColor = vec4(1, 1, 0, 1);
}
</script>
Несколько заметок:
-
Нет причин использовать
try
/catch
aroundcanvas.getContext
. Эта функция не будет генерировать исключение. Он вернется толькоnull
при сбое -
не принято включать атрибуты вершин во время инициализации.
-
в следующий раз попробуйте опубликовать рабочий фрагмент
-
этот скрипт может помочь найти ошибки. Он бы нашел эту.
ошибка в drawElements(/UNKNOWN WebGL ENUM/ undefined, 300, UNSIGNED_SHORT, 0): аргумент 0 не определен
Причина отсутствия ошибок заключается в том, что
gl.TRIANGLE
не существует, поэтому он заканчивается передачейundefined
gl.drawElements
.undefined
автоматически преобразуется в .0
0
это то же значение,gl.POINTS
что и допустимое значение. Причина, по которой вы ничего не видите, заключается в том, что вам нужно установитьgl_PointSize
вершинный шейдер, чтобы видеть точки.Это приводит к подсказке, которой я часто следую. Никогда не выбирайте 0 в качестве допустимого значения enum. Для чего-то слишком легко случайно передать 0, поэтому, если 0 является допустимым значением, то случайность будет трудно найти. К сожалению, OpenGL выбирает 0 для
gl.POINTS
и точная проблема потратила впустую время 10 тысяч программистов. -
Вы можете найти эти статьи полезными.