Форум программистов, компьютерный форум, киберфорум
JavaScript: HTML5 Canvas
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
Эксперт JS
 Аватар для DrType
6553 / 3624 / 1075
Регистрация: 07.09.2019
Сообщений: 5,877
Записей в блоге: 1

WebGL: не происходит отрисовка фигуры.

31.10.2020, 15:40. Показов 1907. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Запустил следующий код, который был предназначен для того, чтобы нарисовать на холсте красную точку с использованием возможностей WebGL :
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html>
 
<head>
  <meta charset="utf-8">
  <title></title>
  <style>
    #canvas {
      width: 70%;
      margin: auto;
    }
  </style>
</head>
 
<body>
  <div id="canvas">
    <canvas width="300" height="300"></canvas>
  </div>
  <script src="webgl-utils.js"></script>
  <script src="webgl-debug.js"></script>
  <script src="cuon-utils.js"></script>
  <script>
    function draw() {
      const canvas = document.querySelector("canvas");
      //const gl = canvas.getContext("experimental-webgl") || canvas.getContext("webgl");
      const gl = getWebGLContext(canvas);
      const VSHADER_SOURCE = 'void main(){gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 10.0;}',
        FSHADER_SOURCE = 'void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}';
      if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        alert("failed");
        //return
      };
      gl.clearColor(0.0, 0.0, 0.4, 1);
      gl.clear(gl.COLOR_BUFFER_BIT);
      gl.drawArrays(gl.POINTS, 0, 1);
      alert("ready");
    }
    draw()
  </script>
</body>
 
</html>
Скрипты, подключаемые в строчках 19 — 21, взял отсюда: https://github.com/yukoba/WebG... master/lib (и, как видно по ссылкам, положил в одну папку с приведённым выше HTML-файлом), при этом функции инициализации шейдеров и создания программы в файле cuon-utils.js я (для удобства проверки в мобильных браузерах) переписал так:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function initShaders(gl, vshader, fshader) {
    var program = createProgram(gl, vshader, fshader);
    if (!program) {
        alert('Не удалось создать программу');
        return false;
    }
    gl.useProgram(program);
    gl.program = program;
    alert("Инициализация прошла успешно.");
    return true;
}
function createProgram(gl, vshader, fshader) {
    var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
    var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
    if (!vertexShader) {
        alert("Вершинный шейдер не найден.");
    }
    if (!fragmentShader) {
        alert("Фрагментный шейдер не найден.");
    }
    if (!vertexShader || !fragmentShader) {
        return null;
    }
    var program = gl.createProgram();
    if (!program) {
        alert("ошибка");
        return null;
    }
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!linked) {
        var error = gl.getProgramInfoLog(program);
        alert('failed to link program: ' + error);
        gl.deleteProgram(program);
        gl.deleteShader(fragmentShader);
        gl.deleteShader(vertexShader);
        return null;
    }
    return program;
}
Сообщений об ошибках я не получил, но и точки не появилось! Как быть, почему не удалось нарисовать точку?..
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.10.2020, 15:40
Ответы с готовыми решениями:

WebGL 2.0 OpenGL ES 3.0 отрисовка объектов одним вызовом с разными матрицами модели
Привет, интересуюсь таким вопросом у людей, кто пробовал реализовать подобное: У меня есть массив вершин, предположим 1000 обектов,...

Отрисовка фигуры
Доброго времени суток всем. Уже битый час пытаюсь выйти в эту фигуру. Есть код на отрисовку квадрата, думаю нужно поменять в Begin 100%, но...

Отрисовка и поворот 3D фигуры
Мне необходимо нарисовать параллелепипед и программно его покрутить (то есть, вычислять его новые координаты и перерисовывать) Застрял я...

5
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,969
Записей в блоге: 233
28.11.2020, 23:04
Давайте вместе попробуем найти. Я закомментировал часть вашего кода и добавил свой. Сейчас заработало. Я только добавил свой код для компиляции шейдеров и для создания объекта шейдерной программы.

Название: Point.png
Просмотров: 79

Размер: 984 байт

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<!DOCTYPE html>
<html>
 
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        #canvas {
            width: 70%;
            margin: auto;
        }
    </style>
</head>
 
<body>
    <div id="canvas">
        <canvas width="300" height="300"></canvas>
    </div>
    <!-- <script src="webgl-utils.js"></script>
    <script src="webgl-debug.js"></script>
    <script src="cuon-utils.js"></script> -->
    <script>
        function initShaders(gl, vertShaderSrc, fragShaderSrc) {
            const vShader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(vShader, vertShaderSrc);
            gl.compileShader(vShader);
            let message = gl.getShaderInfoLog(vShader);
            if (message.length > 0)
            {
                console.log("Failed to compile a vertex shader");
                console.log(gl.getShaderInfoLog(fShader))
                return false;
            }
 
            const fShader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(fShader, fragShaderSrc);
            gl.compileShader(fShader);
            message = gl.getShaderInfoLog(fShader);
            if (message.length > 0)
            {
                console.log("Failed to compile a fragment shader");
                console.log(gl.getShaderInfoLog(fShader))
                return false;
            }
 
            const program = gl.createProgram();
            gl.attachShader(program, vShader);
            gl.attachShader(program, fShader);
            gl.linkProgram(program);
            gl.useProgram(program);
 
            gl.program = program;
            return true;
        }
 
        function draw() {
            const canvas = document.querySelector("canvas");
            //const gl = canvas.getContext("experimental-webgl") || canvas.getContext("webgl");
            const gl = canvas.getContext("webgl");
            const VSHADER_SOURCE = 'void main(){gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 10.0;}',
                FSHADER_SOURCE = 'void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}';
            if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE))
            {
                alert("failed");
                //return
            };
            gl.clearColor(0.0, 0.0, 0.4, 1);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.POINTS, 0, 1);
            alert("ready");
        }
        draw()
 
        // function initShaders(gl, vshader, fshader) {
        //     var program = createProgram(gl, vshader, fshader);
        //     if (!program)
        //     {
        //         alert('Не удалось создать программу');
        //         return false;
        //     }
        //     gl.useProgram(program);
        //     gl.program = program;
        //     alert("Инициализация прошла успешно.");
        //     return true;
        // }
        // function createProgram(gl, vshader, fshader) {
        //     var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
        //     var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
        //     if (!vertexShader)
        //     {
        //         alert("Вершинный шейдер не найден.");
        //     }
        //     if (!fragmentShader)
        //     {
        //         alert("Фрагментный шейдер не найден.");
        //     }
        //     if (!vertexShader || !fragmentShader)
        //     {
        //         return null;
        //     }
        //     var program = gl.createProgram();
        //     if (!program)
        //     {
        //         alert("ошибка");
        //         return null;
        //     }
        //     gl.attachShader(program, vertexShader);
        //     gl.attachShader(program, fragmentShader);
        //     gl.linkProgram(program);
        //     var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
        //     if (!linked)
        //     {
        //         var error = gl.getProgramInfoLog(program);
        //         alert('failed to link program: ' + error);
        //         gl.deleteProgram(program);
        //         gl.deleteShader(fragmentShader);
        //         gl.deleteShader(vertexShader);
        //         return null;
        //     }
        //     return program;
        // }
    </script>
</body>
 
</html>
1
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,969
Записей в блоге: 233
28.11.2020, 23:21
Лучший ответ Сообщение было отмечено DrType как решение

Решение

Я закомментировал свою функцию initShaders() и раскомментировал ваш код. Добавил свою функцию для загрузки шейдера:

JavaScript
1
2
3
4
5
6
        function loadShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            return shader;
        }
Работает:

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<!DOCTYPE html>
<html>
 
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        #canvas {
            width: 70%;
            margin: auto;
        }
    </style>
</head>
 
<body>
    <div id="canvas">
        <canvas width="300" height="300"></canvas>
    </div>
    <!-- <script src="webgl-utils.js"></script>
    <script src="webgl-debug.js"></script>
    <script src="cuon-utils.js"></script> -->
    <script>
        // function initShaders(gl, vertShaderSrc, fragShaderSrc) {
        //     const vShader = gl.createShader(gl.VERTEX_SHADER);
        //     gl.shaderSource(vShader, vertShaderSrc);
        //     gl.compileShader(vShader);
        //     let message = gl.getShaderInfoLog(vShader);
        //     if (message.length > 0)
        //     {
        //         console.log("Failed to compile a vertex shader");
        //         console.log(gl.getShaderInfoLog(fShader))
        //         return false;
        //     }
 
        //     const fShader = gl.createShader(gl.FRAGMENT_SHADER);
        //     gl.shaderSource(fShader, fragShaderSrc);
        //     gl.compileShader(fShader);
        //     message = gl.getShaderInfoLog(fShader);
        //     if (message.length > 0)
        //     {
        //         console.log("Failed to compile a fragment shader");
        //         console.log(gl.getShaderInfoLog(fShader))
        //         return false;
        //     }
 
        //     const program = gl.createProgram();
        //     gl.attachShader(program, vShader);
        //     gl.attachShader(program, fShader);
        //     gl.linkProgram(program);
        //     gl.useProgram(program);
 
        //     gl.program = program;
        //     return true;
        // }
 
        function draw() {
            const canvas = document.querySelector("canvas");
            //const gl = canvas.getContext("experimental-webgl") || canvas.getContext("webgl");
            const gl = canvas.getContext("webgl");
            const VSHADER_SOURCE = 'void main(){gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 10.0;}',
                FSHADER_SOURCE = 'void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}';
            if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE))
            {
                alert("failed");
                //return
            };
            gl.clearColor(0.0, 0.0, 0.4, 1);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.POINTS, 0, 1);
            alert("ready");
        }
        draw()
 
        function initShaders(gl, vshader, fshader) {
            var program = createProgram(gl, vshader, fshader);
            if (!program)
            {
                alert('Не удалось создать программу');
                return false;
            }
            gl.useProgram(program);
            gl.program = program;
            alert("Инициализация прошла успешно.");
            return true;
        }
        function loadShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            return shader;
        }
        function createProgram(gl, vshader, fshader) {
            var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
            var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
            if (!vertexShader)
            {
                alert("Вершинный шейдер не найден.");
            }
            if (!fragmentShader)
            {
                alert("Фрагментный шейдер не найден.");
            }
            if (!vertexShader || !fragmentShader)
            {
                return null;
            }
            var program = gl.createProgram();
            if (!program)
            {
                alert("ошибка");
                return null;
            }
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (!linked)
            {
                var error = gl.getProgramInfoLog(program);
                alert('failed to link program: ' + error);
                gl.deleteProgram(program);
                gl.deleteShader(fragmentShader);
                gl.deleteShader(vertexShader);
                return null;
            }
            return program;
        }
    </script>
</body>
 
</html>
Добавлено через 8 минут
Удобнее писать шейдеры в массиве, а массив объединить с помощью функции join("\n"), тогда, если при компиляции шейдера будет ошибка, то будет выведено в какой строке ошибка.

Лучше заменить это:
JavaScript
1
2
            const VSHADER_SOURCE = 'void main(){gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 10.0;}',
            const FSHADER_SOURCE = 'void main(){gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}';
На это:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
            const VSHADER_SOURCE = [
                'void main()',
                '{',
                '    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);',
                '    gl_PointSize = 10.0;',
                '}'].join('\n');
 
            const FSHADER_SOURCE = [
                'void main()',
                '{',
                '    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);',
                '}'].join('\n');
Так читать код удобнее.
1
Эксперт JS
 Аватар для DrType
6553 / 3624 / 1075
Регистрация: 07.09.2019
Сообщений: 5,877
Записей в блоге: 1
29.11.2020, 02:17  [ТС]
Спасибо за работающий код и комментарии.
Да, шейдеры записал в одну строчку, так как не ожидал ошибок в этой части. Действительно, через массив очень удобно.
1
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,969
Записей в блоге: 233
02.12.2020, 20:57
Этот способ записи можно сократить:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
            const vertShaderSrc = [
                'void main()',
                '{',
                '    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);',
                '    gl_PointSize = 10.0;',
                '}'].join('\n');
 
            const fragShaderSrc = [
                'void main()',
                '{',
                '    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);',
                '}'].join('\n');
Вот так:

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
        const vertShaderSrc =
            `attribute vec3 aPosition;
            void main()
            {
                gl_Position = vec4(aPosition, 1.0);
            }`;
 
        const fragShaderSrc =
            `void main()
            {
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }`
Самый удобный вариант - это хранить шейдеры в отдельных файлах, а в редакторе кода установить плагин для подсветки языка шейдеров - GLSL. Пример загрузки шейдеров из файлов: https://jsfiddle.net/8Observer8/wdn9ubhj/

Исходники

HTML5
1
2
3
4
5
6
7
8
    <canvas id="webgl" width="400" height="400">
        Please use a browser that supports "canvas"
    </canvas>
 
    <script src="https://dl.dropboxusercontent.com/s/ylw7v7a44xtrwv0/webgl-utils.js"></script>
    <script src="https://dl.dropboxusercontent.com/s/iz1n21c8xafd76n/webgl-debug.js"></script>
    <script src="https://dl.dropboxusercontent.com/s/subm1yzylxuao8v/cuon-utils.js"></script>
    <script src="https://dl.dropboxusercontent.com/s/jw3p82lq1cjwekg/cuon-matrix.js"></script>
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// LoadShaderFromFiles.js based on ColoredTriangle.js (c) 2012 matsuda
// This is an example from the book "WebGL Programming Guide"
// by Kouichi Matsuda and Rodger Lea
 
// Vertex shader program
var VSHADER_SOURCE = null;
// Fragment shader program
var FSHADER_SOURCE = null;
 
main();
//window.onload = main;
 
function main()
{
    // Retrieve <canvas> element
    var canvas = document.getElementById('webgl');
 
    // Get the rendering context for WebGL
    var gl = getWebGLContext(canvas);
    if (!gl)
    {
        console.log('Failed to get the rendering context for WebGL');
        return;
    }
    // Read shader from file
    //readShaderFile(gl, './ColoredTriangle.vert', 'v');
    //readShaderFile(gl, './ColoredTriangle.frag', 'f');
    // Read shader from file
    readShaderFile(gl, 'https://dl.dropboxusercontent.com/s/p9yihxes14zx6gk/ColoredTriangle.vert', 'v');
    readShaderFile(gl, 'https://dl.dropboxusercontent.com/s/xdd99o3xo69g6vu/ColoredTriangle.frag', 'f');
}
 
function start(gl)
{
    // Initialize shaders
    if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE))
    {
        console.log('Failed to intialize shaders.');
        return;
    }
 
    // Set vertex information
    var n = initVertexBuffers(gl);
    if (n < 0)
    {
        console.log('Failed to set the vertex information');
        return;
    }
 
    // Specify the color for clearing <canvas>
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
 
    // Clear <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);
 
    // Draw the rectangle
    gl.drawArrays(gl.TRIANGLES, 0, n);
}
 
function initVertexBuffers(gl)
{
    var verticesColors = new Float32Array([
      // Vertex coordinates and color
       0.0, 0.5, 1.0, 0.0, 0.0,
      -0.5, -0.5, 0.0, 1.0, 0.0,
       0.5, -0.5, 0.0, 0.0, 1.0,
    ]);
    var n = 3;
 
    // Create a buffer object
    var vertexColorBuffer = gl.createBuffer();
    if (!vertexColorBuffer)
    {
        console.log('Failed to create the buffer object');
        return false;
    }
 
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
 
    var FSIZE = verticesColors.BYTES_PER_ELEMENT;
    //Get the storage location of a_Position, assign and enable buffer
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_Position < 0)
    {
        console.log('Failed to get the storage location of a_Position');
        return -1;
    }
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);
    gl.enableVertexAttribArray(a_Position);  // Enable the assignment of the buffer object
 
    // Get the storage location of a_Position, assign buffer and enable
    var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
    if (a_Color < 0)
    {
        console.log('Failed to get the storage location of a_Color');
        return -1;
    }
    gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);
    gl.enableVertexAttribArray(a_Color);  // Enable the assignment of the buffer object
 
    return n;
}
 
// Read shader from file
function readShaderFile(gl, fileName, shader)
{
    var request = new XMLHttpRequest();
 
    request.onreadystatechange = function ()
    {
        if (request.readyState === 4 && request.status !== 404)
        {
            onReadShader(gl, request.responseText, shader);
        }
    }
    request.open('GET', fileName, true); // Create a request to acquire the file
    request.send();                      // Send the request
}
 
// The shader is loaded from file
function onReadShader(gl, fileString, shader)
{
    if (shader == 'v')  // Vertex shader
    {
        VSHADER_SOURCE = fileString;
    } else
        if (shader == 'f')  // Fragment shader
        {
            FSHADER_SOURCE = fileString;
        }
    // When both are available, call start().
    if (VSHADER_SOURCE && FSHADER_SOURCE) start(gl);
}
1
9933 / 2936 / 494
Регистрация: 05.10.2013
Сообщений: 7,969
Записей в блоге: 233
13.12.2020, 14:14
Шейдеры ещё можно хранить в теге скрипт:

HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    <script type="x-shader/x-vertex" id="vertexShader">
        attribute vec3 aPosition;
        uniform mat4 uMpMatrix;
        void main()
        {
            gl_Position = uMpMatrix * vec4(aPosition, 1.0);
        }
    </script>
 
    <script type="x-shader/x-fragment" id="fragmentShader">
        void main()
        {
            gl_FragColor = vec4(0.5, 0.5, 1.0, 1.0);
        }
    </script>
Получить исходники шейдеров можно так:

JavaScript
1
2
const vShaderSource = document.getElementById("vertexShader").firstChild.textContent;
const fShaderSource = document.getElementById("fragmentShader").firstChild.textContent;
Я сделали пример, где задаётся система координат в диапазоне [0, 100] с центром в левом верхнем углу (ось Y направлена вниз). Рисуется синий квадрат, который имеет размер 30x30 и расположен по координатам (50, 20). Координаты квадрата отсчитываются относительно его левого верхнего угла. Используются матрицы трансформаций из библиотеки glMatrix (http://glmatrix.net/)

Название: 45a0b8dad34a48b1cee07812b4fb1435e7dba56a.png
Просмотров: 189

Размер: 118 байт

Песочница: https://plnkr.co/edit/Jb6HpjIVDwRWqtbR?preview

index.html

PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rectangle with transforms. WebGL 1.0, JavaScript</title>
    <script src="https://cdn.jsdelivr.net/npm/gl-matrix@3.3.0/gl-matrix-min.js"></script>
</head>
 
<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>
 
    <script type="x-shader/x-vertex" id="vertexShader">
        attribute vec3 aPosition;
        uniform mat4 uMpMatrix;
        void main()
        {
            gl_Position = uMpMatrix * vec4(aPosition, 1.0);
        }
    </script>
 
    <script type="x-shader/x-fragment" id="fragmentShader">
        void main()
        {
            gl_FragColor = vec4(0.5, 0.5, 1.0, 1.0);
        }
    </script>
 
    <script>
        const gl = document.getElementById("renderCanvas").getContext("webgl");
        const program = createProgram();
        const n = initVertexBuffers(program);
        const mpMatrix = glMatrix.mat4.create();
        const projMatrix = glMatrix.mat4.create();
        const modelMatrix = glMatrix.mat4.create();
 
        glMatrix.mat4.ortho(projMatrix, 0, 100, 100, 0, -100, 100);
        glMatrix.mat4.translate(modelMatrix, modelMatrix, glMatrix.vec3.fromValues(50, 20, 0));
        glMatrix.mat4.scale(modelMatrix, modelMatrix, glMatrix.vec3.fromValues(30, 30, 1));
        glMatrix.mat4.mul(mpMatrix, projMatrix, modelMatrix);
        const uMpMatrixLocation = gl.getUniformLocation(program, "uMpMatrix");
        gl.uniformMatrix4fv(uMpMatrixLocation, false, mpMatrix);
 
        gl.clearColor(0.2, 0.2, 0.2, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
 
        function initVertexBuffers(program)
        {
            const vertPositions = new Float32Array([
                0, 0, 0,
                0, 1, 0,
                1, 1, 0,
                1, 0, 0
            ]);
            const vertPosBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, vertPosBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, vertPositions, gl.STATIC_DRAW);
            gl.bindAttribLocation(program, 0, "aPosition");
            gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(0);
            const indices = new Uint8Array([
                0, 1, 2,
                2, 3, 0
            ])
            const indexBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
 
            return indices.length;
        }
        
        function createProgram()
        {
            const vShaderSource = document.getElementById("vertexShader").firstChild.textContent;
            const vShader = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(vShader, vShaderSource);
            gl.compileShader(vShader);
            const fShaderSource = document.getElementById("fragmentShader").firstChild.textContent;
            const fShader = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(fShader, fShaderSource);
            gl.compileShader(fShader);
            const program = gl.createProgram();
            gl.attachShader(program, vShader);
            gl.attachShader(program, fShader);
            gl.linkProgram(program);
            gl.useProgram(program);
            return program;
        }
    </script>
</body>
 
</html>
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
13.12.2020, 14:14
Помогаю со студенческими работами здесь

Отрисовка ListBox: при нажатии на элемент не происходит выделение
почему при нажатии на элемент ListBox'a не происходит выделение? procedure TForm1.pl1DrawItem(Control: TWinControl; Index: Integer;...

Не происходит отрисовка пользовательского контрола при загрузке формы
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using...

Игра пинг-понг: отрисовка происходит там, где не должна
Написал отрисовку кадра в консоль и управление объектами. Начал тестировать многопоточность и в консоли стали появляться символы там где их...

Отрисовка фигуры в форме Windows по координатам из исходного файла
Кто может детально объяснить код и предложить варианты улучшения/оптимизации? Задачи: • Отрисовка фигуры в форме Windows по координатам...

Отрисовка изображения на canvas происходит только при повторном нажатии клавиши
В программе по нажатию клавиши происходит, точнее должна происходить отрисовка изображения на canvas, но происходит это только при...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru