Uploaded by meiseiRRR

Индивидуальное задание (1)

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
«ЛУГАНСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ
ИМЕНИ ВЛАДИМИРА ДАЛЯ»
Факультет компьютерных систем и информационных технологий
Кафедра информатики и программной инженерии
Индивидуальная работа
Прорисовка, текстурирование и анимация 3D модели «Молоток» на WebGL.
(название темы индивидуальной работы)
Студент-исполнитель
Озеров В.П.
(Ф.И.О., подпись)
2 курс ИТ-692____________________
(курс, группа)
Приняли:
Ромашова О. Н. __________________
(Ф.И.О., подпись)
Чигрина А. Н. ___________________
(Ф.И.О., подпись)
Оценка:
___________________
Луганск 2020
2
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛУГАНСКОЙ НАРОДНОЙ РЕСПУБЛИКИ
«ЛУГАНСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ
ИМЕНИ ВЛАДИМИРА ДАЛЯ»
Факультет компьютерных систем и информационных технологий
Кафедра информатики и программной инженерии
Направление подготовки: 09.03.04 – Программная инженерия
(шифр и название)
ЗАДАНИЕ
НА ИНДИВИДУАЛЬНУЮ РАБОТУ
студенту Озерову Вячеславу Павловичу
1. Тема работы: «Прорисовка, текстурирование и анимация 3D модели
«Молоток» на WebGL.»;
2. Руководитель работы: Чигрина Анастасия Николаевна, Ромашова
Ольга Николаевна, старший преподаватель;
3. Срок представления студентом работы: 28.12.2020;
4. Содержание индивидуальной работы:
а) Реферат
б) Введение
в) Ход работы
г) Вывод
д) Литература
5. Дата выдачи задания: 02.12.2020.
3
РЕФЕРАТ
Работа содержит: 8 страниц основного текста, 28 страниц приложений,
6 рисунков, 4 использованных источников.
Работа состоит из трех разделов, введения, выводов и приложений.
Объектом исследования данной работы является WebGl.
Предметом исследования является молоток.
Целью работы является создание 3D модели молотка на WebGl.
Результатом работы является 3D модель молотка.
Ключевые слова: WEBGL, молоток.
4
СОДЕРЖАНИЕ
ВВЕДЕНИЕ............................................................................................................. 5
РАЗДЕЛ 1 ................................................................................................................ 6
ДЕТАЛИ ДЛЯ ОБЪЕКТА ................................................................................... 6
БИБЛИОТЕКА GL.MATRIX.JS ..................................................................... 6
glMatrix предназначен для выполнения векторных и матричных
операций. Вручную настраивая каждую функцию для максимальной
производительности и поощряя эффективные шаблоны использования
с помощью соглашений API моделирование объекта ................................ 6
РАЗДЕЛ 2 ................................................................................................................ 7
ОСВЕЩЕНИЕ И АНИМАЦИЯ ......................................................................... 7
ОСВЕЩЕНИЕ .................................................................................................... 7
АНИМАЦИЯ ..................................................................................................... 10
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ ..................................... 13
ПРИЛОЖЕНИЯ .................................................................................................. 14
5
ВВЕДЕНИЕ
WebGL представляет собой технологию, базирующуюся на OpenGL ES
2.0 и предназначенную для рисования и отображения интерактивной 2D- и 3Dграфики в веб-браузерах. При этом для работы с данной технологией не
требуются сторонние плагины или библиотеки. Вся работа веб-приложений с
использованием WebGL основана на коде JavaScript, а некоторые элементы
кода - шейдеры могут выполняться непосредственно на графических
процессорах на видеокартах, благодаря чему разработчики могут получить
доступ к дополнительным ресурсам компьютера, увеличить быстродействие.
Таким образом, для создания приложений разработчики могу использовать
стандартные для веб-среды технологии HTML/CSS/JavaScript и при этом
также применять аппаратное ускорение графики.
В проекте будет рассмотрена задача по моделированию различных
объектов, а также добавление анимации и освещения.
6
РАЗДЕЛ 1
ДЕТАЛИ ДЛЯ ОБЪЕКТА
БИБЛИОТЕКА GL.MATRIX.JS
glMatrix предназначен для выполнения векторных и матричных
операций. Вручную настраивая каждую функцию для максимальной
производительности и поощряя эффективные шаблоны использования с
помощью соглашений API моделирование объекта
Объект «Молоток» можно создать, с использованием библиотеки
glMatrix, но чистый объект создается с помощью геометрии двух
перпендикулярно расположенных друг к другу параллелограмма. Полный
html - код написания модели изложен в Приложении.
Получаем готовый Объект «Молоток». (Рис 1.1)
Рис 1.1 – 3D модель молотка
7
РАЗДЕЛ 2
ОСВЕЩЕНИЕ И АНИМАЦИЯ
ОСВЕЩЕНИЕ
Освещение сделано с помощью библиотеки glMatrix;
Имеет такой вид в коде.
// получаем вектор направления света
vec3 lightDirection = normalize(uLightPosition - vertexPositionEye3);
// получаем нормаль
vec3 normal = normalize(uNMatrix * aVertexNormal);
// получаем скалярное произведение векторов нормали и направления
света
float diffuseLightDot = max(dot(normal, lightDirection), 0.0);
// получаем вектор отраженного луча и нормализуем его
vec3 reflectionVector = normalize(reflect(-lightDirection, normal));
float specularLightDot = max(dot(reflectionVector, viewVectorEye), 0.0);
float specularLightParam = pow(specularLightDot, shininess);
// отраженный свет равен сумме фонового, диффузного и зеркального
отражений света
vLightWeighting = (uAmbientMaterialColor * uAmbientLightColor +
uDiffuseMaterialColor
*
uDiffuseLightColor
*
uSpecularMaterialColor
*
uSpecularLightColor
*
diffuseLightDot +
specularLightParam);
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 21.0);
vTextureCoords = vec2(aVertexPosition.x+0.5,aVertexPosition.y+0.5);
8
Есть возможность менять положение источника света объекта вручную
с выбора значения осей x, y, z,(Рис 2.1)
Рис 2.1
Источник света можно расположить в любом месте модели по X Y Z. (Рис 2.2)
Рис 2.2 – источник света, расположенный с верху объекта
9
Либо поменять освещение с помощью готовых предустановок. Для этого
всего лишь требуется выбрать значение в меню intensive.
(Рис 2.3, 60% освещение)
Рис 2.3
10
АНИМАЦИЯ
Для того, чтобы анимировать наш объект, требуется создать функции,
которые будут управлять моделью. Управлять объектом мы будем с помощью
стрелочек клавиатуры. А с помощью клавиш w s изменять масштаб объекта.
Часть кода отвечающая за это:
function handleKeyDown(e){
switch(e.keyCode)
{
case 39: // стрелка вправо
yAngle+=0.1;
break;
case 37: // стрелка влево
yAngle-=0.1;
break;
case 40: // стрелка вниз
xAngle+=0.1;
break;
case 38: // стрелка вверх
xAngle-=0.1;
break;
case 87: // клавиша w
zTranslation+=step*scale;
break;
case 83: // клавиша s
zTranslation-=step;
break;
11
рис. 2.4(вид сверху)
рис. 2.4
рис. 2.5(вид сбоку)
рис. 2.5
12
рис. 2.6(приближённый объект)
Рис. 2.6
13
СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ
1. Лекции.
2. https://webglfundamentals.org/webgl/lessons/ru/webgl-3d-geometrylathe.html
3. https://developer.mozilla.org/enUS/docs/Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_W
ebGL
4. Онлайн книга по WebGL (https://metanit.com/web/webgl/)
14
ПРИЛОЖЕНИЯ
<!DOCTYPE html>
<html>
<head>
<title>3D in WebGL!</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<canvas id="canvas3D" width="1000" height="600">Ваш браузер не
поддерживает элемент canvas</canvas>
<div class="menu">
<label>setLightOX:<select id="setLightOX">
<option value="0">0</option>
<option value="1">1</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="30">30</option>
15
</select></label>
<label>setLightOY:<select id="setLightOY">
<option value="0">0</option>
<option value="1">1</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="30">30</option>
</select></label>
<label>setLightOZ:<select id="setLightOZ">
<option value="0">0</option>
<option value="1">1</option>
<option value="3">3</option>
<option value="5">5</option>
<option value="10">10</option>
16
<option value="30">30</option>
</select></label>
<label>intensive:<select id="intensive">
<option value="0.1">5%</option>
<option value="0.5">20%</option>
<option value="1">40%</option>
<option value="2">60%</option>
<option value="3">80%</option>
<option value="4">100%</option>
</select></label>
<label>scale:<select id="scale">
<option value="1">100%</option>
<option value="1.5">150%</option>
<option value="0.75">75%</option>
<option value="0.5">50%</option>
17
<option value="0.25">25%</option>
</select></label>
</div>
<script type="text/javascript" src="gl-matrix-min.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec3 aVertexNormal;
varying vec2 vTextureCoords;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
uniform mat3 uNMatrix;
uniform vec3 uLightPosition;
uniform vec3 uAmbientLightColor;
uniform vec3 uDiffuseLightColor;
uniform vec3 uSpecularLightColor;
uniform vec3 uAmbientMaterialColor;
uniform vec3 uDiffuseMaterialColor;
uniform vec3 uSpecularMaterialColor;
varying vec3 vLightWeighting;
const float shininess = 16.0;
18
void main() {
// установка позиции наблюдателя сцены
vec4 vertexPositionEye4 = uMVMatrix * vec4(aVertexPosition, 1.0);
vec3
vertexPositionEye3
=
vertexPositionEye4.xyz
/
vertexPositionEye4.w;
// получаем вектор направления света
vec3 lightDirection = normalize(uLightPosition - vertexPositionEye3);
// получаем нормаль
vec3 normal = normalize(uNMatrix * aVertexNormal);
// получаем скалярное произведение векторов нормали и
направления света
float diffuseLightDot = max(dot(normal, lightDirection), 0.0);
// получаем вектор отраженного луча и нормализуем его
vec3 reflectionVector = normalize(reflect(-lightDirection, normal));
// установка вектора камеры
vec3 viewVectorEye = -normalize(vertexPositionEye3);
float specularLightDot = max(dot(reflectionVector, viewVectorEye),
0.0);
float specularLightParam = pow(specularLightDot, shininess);
// отраженный свет равен сумме фонового, диффузного и
зеркального отражений света
vLightWeighting = (uAmbientMaterialColor * uAmbientLightColor +
19
uDiffuseMaterialColor
*
uDiffuseLightColor
*
uSpecularMaterialColor
*
uSpecularLightColor
*
diffuseLightDot +
specularLightParam);
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 21.0);
vTextureCoords
=
vec2(aVertexPosition.x+0.5,aVertexPosition.y+0.5);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
precision highp float;
uniform sampler2D uSampler;
varying vec2 vTextureCoords;
varying vec3 vLightWeighting;
void main() {
gl_FragColor
=
texture2D(uSampler,
vTextureCoords)
vec4(vLightWeighting.rgb, 1);
//gl_FragColor = vec4(vLightWeighting.rgb, 1);
// gl_FragColor = vec4(1.0, 0.5, 0.0, 1);
}
</script>
<script type="text/javascript">
+
20
var texture; // переменная для хранения текстуры
var gl;
var shaderProgram;
var wallVertexBuffer;
var wallIndexBuffer;
var roofVertexBuffer;
var vertexBuffer;
var roofIndexBuffer;
var vertexNormalBuffer;
var RoofvertexNormalBuffer
var yAngle = 2.0;//угол вращения в радианах вокруг оси Y
var zTranslation=-2.0; // смещение по оси Z
var xTranslation=0.0;
var yTranslation=0.0;
var xAngle = 0.1; // угол вращения в радианах вокруг оси Х
var zAngle = 0.1; // угол вращения в радианах вокруг оси Z
var step= 0.1;
var mvMatrix = mat4.create(); // матрица вида модели
var pMatrix = mat4.create(); // матрица проекции
var nMatrix = mat3.create(); // матрица нормалей
// установка шейдеров
function initShaders() {
var fragmentShader = getShader(gl.FRAGMENT_SHADER, 'shaderfs');
var vertexShader = getShader(gl.VERTEX_SHADER, 'shader-vs');
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
21
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Не удалсь установить шейдеры");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute
=
gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
// атрибут нормали
shaderProgram.vertexNormalAttribute
=
gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
// настройка параметров uniform матриц для передачи в шейдер
shaderProgram.MVMatrix = gl.getUniformLocation(shaderProgram,
"uMVMatrix");
shaderProgram.ProjMatrix = gl.getUniformLocation(shaderProgram,
"uPMatrix");
shaderProgram.NormalMatrix
=
gl.getUniformLocation(shaderProgram, "uNMatrix");
// настройка переменных uniform освещения для передачи в
шейдер
22
// позиция источника света
shaderProgram.uniformLightPosition
=
gl.getUniformLocation(shaderProgram, "uLightPosition");
// фоновое отражение света
shaderProgram.uniformAmbientLightColor
=
gl.getUniformLocation(shaderProgram, "uAmbientLightColor");
// диффузное отражение света
shaderProgram.uniformDiffuseLightColor
=
gl.getUniformLocation(shaderProgram, "uDiffuseLightColor");
// зеркальное отражение света
shaderProgram.uniformSpecularLightColor
=
gl.getUniformLocation(shaderProgram, "uSpecularLightColor");
shaderProgram.uniformAmbientMaterialColor
=
gl.getUniformLocation(shaderProgram, "uAmbientMaterialColor");
shaderProgram.uniformDiffuseMaterialColor
=
gl.getUniformLocation(shaderProgram, "uDiffuseMaterialColor");
shaderProgram.uniformSpecularMaterialColor
=
gl.getUniformLocation(shaderProgram, "uSpecularMaterialColor");
}
// настройка цветов освещения
function setupLights() {
var OX = document.getElementById("setLightOX").value;
var OY = document.getElementById("setLightOY").value;
var OZ = document.getElementById("setLightOZ").value;
var intensive= document.getElementById("intensive").value;
gl.uniform3fv(shaderProgram.uniformLightPosition, [OX, OY, OZ]);
gl.uniform3fv(shaderProgram.uniformAmbientLightColor, [0.0, 0.2,
0.5]);//wdtn vjltkb
23
gl.uniform3fv(shaderProgram.uniformDiffuseLightColor,
[intensive,
intensive, intensive]);
gl.uniform3fv(shaderProgram.uniformSpecularLightColor, [2.0, 1.0,
1.0]);
}
// настройка цветов освещения
function setupLights() {
var OX = document.getElementById("setLightOX").value;
var OY = document.getElementById("setLightOY").value;
var OZ = document.getElementById("setLightOZ").value;
var intensive= document.getElementById("intensive").value;
gl.uniform3fv(shaderProgram.uniformLightPosition, [OX, OY, OZ]);
gl.uniform3fv(shaderProgram.uniformAmbientLightColor, [0.0, 0.2,
0.5]);//wdtn vjltkb
gl.uniform3fv(shaderProgram.uniformDiffuseLightColor,
[intensive,
intensive, intensive]);
gl.uniform3fv(shaderProgram.uniformSpecularLightColor, [2.0, 1.0,
1.0]);
}
function setupScale() {
var OX = document.getElementById("setLightOX").value;
var OY = document.getElementById("setLightOY").value;
var OZ = document.getElementById("setLightOZ").value;
var intensive= document.getElementById("intensive").value;
gl.uniform3fv(shaderProgram.uniformLightPosition, [OX, OY, OZ]);
gl.uniform3fv(shaderProgram.uniformAmbientLightColor, [0.0, 0.2,
0.5]);//wdtn vjltkb
24
gl.uniform3fv(shaderProgram.uniformDiffuseLightColor,
[intensive,
intensive, intensive]);
gl.uniform3fv(shaderProgram.uniformSpecularLightColor, [2.0, 1.0,
1.0]);
}
// установка материалов
function setupMaterials() {
gl.uniform3fv(shaderProgram.uniformAmbientMaterialColor,
[0.0,
0.0, 0.0]);
gl.uniform3fv(shaderProgram.uniformDiffuseMaterialColor, [0.7, 0.7,
0.7]);
gl.uniform3fv(shaderProgram.uniformSpecularMaterialColor,
[1.0,
1.0, 1.0]);
}
function setMatrixUniforms(){
gl.uniformMatrix4fv(shaderProgram.ProjMatrix,false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.MVMatrix, false, mvMatrix);
gl.uniformMatrix3fv(shaderProgram.NormalMatrix, false, nMatrix);
}
// Функция создания шейдера
function getShader(type,id) {
var source = document.getElementById(id).innerHTML;
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
25
alert("Ошибка
компиляции
gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
function initWallBuffers() {
var vertices =[
// первая колонна
// лицевая часть
-0.1, -0.5, 0.2,
-0.1, 0.5, 0.2,
0.13, 0.5, 0.2,
0.13, -0.5, 0.2,
// задняя часть
-0.1, -0.5, 0.1,
-0.1, 0.5, 0.1,
0.13, 0.5, 0.1,
0.13, -0.5, 0.1,
// левая боковая часть
-0.1, -0.5, 0.2,
-0.1, 0.5, 0.2,
-0.1, 0.5, 0.1,
-0.1, -0.5, 0.1,
// правая боковая часть
шейдера:
"
+
26
0.13, -0.5, 0.2,
0.13, 0.5, 0.2,
0.13, 0.5, 0.1,
0.13, -0.5, 0.1,
];
var indices = [ // лицевая часть
0, 1, 2,
2, 3, 0,
// задняя часть
4, 5, 6,
6, 7, 4,
//левая боковая часть
8, 9, 10,
10, 11, 8,
// правая боковая часть
12, 13, 14,
14, 15, 12,
// вторая колонна
// лицевая часть
16, 17, 18,
18, 19, 16,
// задняя часть
20, 21 ,22,
22, 23, 20,
//левая боковая часть
24, 25, 26,
26, 27, 24,
// правая боковая часть
28, 29, 30,
27
30, 31, 28,
//третья колонна
// лицевая часть
32, 33, 34,
34, 35, 32,
// // задняя часть
36, 37, 38,
38, 39, 36,
// //левая боковая часть
40, 41, 42,
42, 43, 40,
// // правая боковая часть
44, 45, 46,
46, 47, 44,
// четвертая колонна
// лицевая часть
48, 49, 50,
50, 51, 48,
// задняя часть
52, 53, 54,
54, 55, 52,
//левая боковая часть
56, 57, 58,
58, 59, 56,
// правая боковая часть
60, 61, 62,
62, 63, 60
28
];
wallVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, wallVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new
Float32Array(vertices),
gl.STATIC_DRAW);
wallVertexBuffer.itemSize = 3;
wallIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, wallIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
Uint16Array(indices), gl.STATIC_DRAW);
wallIndexBuffer.numberOfItems = indices.length;
var normals = [
// Лицевая сторона
0.0, 0.0, 1.0, //v0
0.0, 0.0, 1.0, //v1
0.0, 0.0, 1.0, //v2
0.0, 0.0, 1.0, //v3
// Задняя сторона
0.0, 0.0, -1.0, //v4
0.0, 0.0, -1.0, //v5
0.0, 0.0, -1.0, //v6
0.0, 0.0, -1.0, //v7
// Левая боковая сторона
-1.0, 0.0, 0.0, //v8
-1.0, 0.0, 0.0, //v9
new
29
-1.0, 0.0, 0.0, //v10
-1.0, 0.0, 0.0, //v11
// Правая боковая сторона
1.0, 0.0, 0.0, //v12
1.0, 0.0, 0.0, //v13
1.0, 0.0, 0.0, //v14
1.0, 0.0, 0.0, //v15
// Лицевая сторона
0.0, 0.0, 1.0, //v0
0.0, 0.0, 1.0, //v1
0.0, 0.0, 1.0, //v2
0.0, 0.0, 1.0, //v3
// Задняя сторона
0.0, 0.0, -1.0, //v4
0.0, 0.0, -1.0, //v5
0.0, 0.0, -1.0, //v6
0.0, 0.0, -1.0, //v7
// Левая боковая сторона
-1.0, 0.0, 0.0, //v8
-1.0, 0.0, 0.0, //v9
-1.0, 0.0, 0.0, //v10
-1.0, 0.0, 0.0, //v11
// Правая боковая сторона
1.0, 0.0, 0.0, //v12
1.0, 0.0, 0.0, //v13
30
1.0, 0.0, 0.0, //v14
1.0, 0.0, 0.0, //v15
// Лицевая сторона
0.0, 0.0, 1.0, //v0
0.0, 0.0, 1.0, //v1
0.0, 0.0, 1.0, //v2
0.0, 0.0, 1.0, //v3
// Задняя сторона
0.0, 0.0, -1.0, //v4
0.0, 0.0, -1.0, //v5
0.0, 0.0, -1.0, //v6
0.0, 0.0, -1.0, //v7
// Левая боковая сторона
-1.0, 0.0, 0.0, //v8
-1.0, 0.0, 0.0, //v9
-1.0, 0.0, 0.0, //v10
-1.0, 0.0, 0.0, //v11
// Правая боковая сторона
1.0, 0.0, 0.0, //v12
1.0, 0.0, 0.0, //v13
1.0, 0.0, 0.0, //v14
1.0, 0.0, 0.0, //v15
// Лицевая сторона
0.0, 0.0, 1.0, //v0
0.0, 0.0, 1.0, //v1
31
0.0, 0.0, 1.0, //v2
0.0, 0.0, 1.0, //v3
// Задняя сторона
0.0, 0.0, -1.0, //v4
0.0, 0.0, -1.0, //v5
0.0, 0.0, -1.0, //v6
0.0, 0.0, -1.0, //v7
// Левая боковая сторона
-1.0, 0.0, 0.0, //v8
-1.0, 0.0, 0.0, //v9
-1.0, 0.0, 0.0, //v10
-1.0, 0.0, 0.0, //v11
// Правая боковая сторона
1.0, 0.0, 0.0, //v12
1.0, 0.0, 0.0, //v13
1.0, 0.0, 0.0, //v14
1.0, 0.0, 0.0, //v15
];
// Создаем буфер нормалей куба
vertexNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
gl.STATIC_DRAW);
vertexNormalBuffer.itemSize = 3;
}
new
Float32Array(normals),
32
function initRoofBuffers() {
var vertices =[
// лицевая часть
-0.3, 0.5, 0.3,
-0.3, 0.7, 0.3,
0.3, 0.7, 0.3,
0.3, 0.5, 0.3,
// задняя часть
-0.3, 0.5, 0.0,
-0.3, 0.7, 0.0,
0.3, 0.7, 0.0,
0.3, 0.5, 0.0,
// левая боковая часть
-0.3, 0.5, 0.3,
-0.3, 0.7, 0.3,
-0.3, 0.7, 0.0,
-0.3, 0.5, 0.0,
// правая боковая часть
0.3, 0.5, 0.3,
0.3, 0.7, 0.3,
0.3, 0.7, 0.0,
0.3, 0.5, 0.0,
// низ
-0.3, 0.5, 0.3,
-0.3, 0.5, 0.0,
0.3, 0.5, 0.0,
0.3, 0.5, 0.3,
// верх
-0.3, 0.7, 0.3,
33
-0.3, 0.7, 0.0,
0.3, 0.7, 0.0,
0.3, 0.7, 0.3,
];
var indices = [
0, 1, 2,
2, 3, 0,
// задняя часть
4, 5, 6,
6, 7, 4,
//левая боковая часть
8, 9, 10,
10, 11, 8,
// правая боковая часть
12, 13, 14,
14, 15, 12,
// низ
16, 17, 18,
18, 19, 16,
// верх
20, 21, 22,
22, 23, 20
];
roofVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, roofVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
gl.STATIC_DRAW);
roofVertexBuffer.itemSize = 3;
new
Float32Array(vertices),
34
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER,
new
Float32Array(vertices),
gl.STATIC_DRAW);
vertexBuffer.itemSize = 3;
roofIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, roofIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
new
Uint16Array(indices), gl.STATIC_DRAW);
roofIndexBuffer.numberOfItems = indices.length;
var Roofnormals = [];
for (var i=0; i<6; i++) {
Roofnormals.push(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0);
RoofvertexNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, RoofvertexNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(Roofnormals),
gl.STATIC_DRAW);
RoofvertexNormalBuffer.itemSize = 3;
var indices = [0, 1, 2, 2, 3, 0];
indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
Uint16Array(indices), gl.STATIC_DRAW);
indexBuffer.numberOfItems = indices.length;
}
}
new
35
function wallDraw() {
gl.bindBuffer(gl.ARRAY_BUFFER, wallVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
wallVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
vertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.enable(gl.DEPTH_TEST);
gl.drawElements(gl.TRIANGLES,
wallIndexBuffer.numberOfItems,
gl.UNSIGNED_SHORT,0);
}
function roofDraw() {
gl.bindBuffer(gl.ARRAY_BUFFER, roofVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
roofVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, RoofvertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,
RoofvertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.enable(gl.DEPTH_TEST);
36
gl.drawElements(gl.TRIANGLES,
roofIndexBuffer.numberOfItems,
gl.UNSIGNED_SHORT,0);
}
function draw() {
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.drawElements(gl.TRIANGLES,
indexBuffer.numberOfItems,
gl.UNSIGNED_SHORT,0);
}
function setupWebGL()
{
gl.clearColor(0.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT || gl.DEPTH_BUFFER_BIT);
scale = document.getElementById("scale").value;
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
mat4.perspective(pMatrix,
1.04,
gl.viewportWidth
/
gl.viewportHeight, 0.1, 100.0);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix,mvMatrix,[xTranslation,
zTranslation]);
mat4.rotateX(mvMatrix,mvMatrix, xAngle);
mat4.rotateY(mvMatrix,mvMatrix, yAngle);
mat4.rotateZ(mvMatrix,mvMatrix, zAngle);
yTranslation,
37
mat3.normalFromMat4(nMatrix, mvMatrix);
}
window.onload=function(){
var canvas = document.getElementById("canvas3D");
try {
gl
=
canvas.getContext("webgl")
canvas.getContext("experimental-webgl");
}
catch(e) {}
if (!gl) {
alert("Ваш браузер не поддерживает WebGL");
}
if(gl){
document.addEventListener('keydown', handleKeyDown, false);
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
initShaders();
initRoofBuffers();
initWallBuffers();
setupMaterials();
setupLights();
setTextures();
(function animloop(){
setupWebGL();
setMatrixUniforms();
||
38
setupLights();
wallDraw();
roofDraw();
requestAnimFrame(animloop, canvas);
})();
}
}
function setTextures() {
console.log("fff")
texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var image = new Image();
image.onload = function () {
handleTextureLoaded(image, texture);
setupWebGL();
draw();
}
image.src = "123.png";
shaderProgram.samplerUniform
gl.getUniformLocation(shaderProgram, "uSampler");
gl.uniform1i(shaderProgram.samplerUniform, 0);
}
function handleTextureLoaded(image, texture) {
=
39
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE, image);
gl.texParameteri(gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,
gl.TEXTURE_MIN_FILTER,
gl.NEAREST);
}
function handleTextureLoaded(image, texture) {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE, image);
gl.texParameteri(gl.TEXTURE_2D,
gl.TEXTURE_MAG_FILTER,
gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,
gl.NEAREST);
}
function handleKeyDown(e){
switch(e.keyCode)
{
case 39: // стрелка вправо
yAngle+=0.1;
break;
case 37: // стрелка влево
yAngle-=0.1;
gl.TEXTURE_MIN_FILTER,
40
break;
case 40: // стрелка вниз
xAngle+=0.1;
break;
case 38: // стрелка вверх
xAngle-=0.1;
break;
case 188: // клавиша <
zAngle+=0.1;
break;
case 190: // клавиша >
zAngle-=0.1;
break;
case 87: // клавиша w
zTranslation+=step*scale;
break;
case 83: // клавиша s
zTranslation-=step;
break;
case 65: // клавиша a
xTranslation+=step;
break;
case 68: // клавиша d
xTranslation-=step;
break;
case 81: // клавиша q
yTranslation+=step;
break;
case 69: // клавиша e
yTranslation-=step;
41
break;
}
}
window.requestAnimFrame = (function(){
return window.requestAnimationFrame
||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame
window.msRequestAnimationFrame
||
||
function(callback, element) {
return window.setTimeout(callback, 1000/60);
};
})();
</script>
</body>
</html>
42
Download