В полку "хеллоуворлдов" прибыло. В этот раз на очереди WebGL. Захотелось приглядеться к этому "зверю" попристальней, потому как потенциал в нем видится не малый. Думаю, рано или поздно он потеснит на рынке все другие технологии в своей нише. Или появится что-то более удобное во всех отношениях. Пока же, по моим ощущениям, для Stage3D (Flash) писать гораздо приятней, что-ли. Но хватит разжигания межплатформенных розней.
Основа кода мной была взята отсюда. Я лишь немного её изменил для возможного дальнейшего препарирования, добавил чуток анимации и некоторых других утилитарных "плюшек".
Вкратце, можно сказать, что для простейшего приложения на WebGL необходим файл HTML, файл с кодом приложения на Javascript и утилитарный файл с Javascript для работы с матрицами. Впрочем, без последнего вполне себе можно обойтись, но тогда или придется много написать самому или приложение будет ну совсем уж простым.
Файл HTML нам нужен для представления сцены (HTML-элемент canvas с поддержкой OpenGL-контекста) и кода шейдеров на ESSL (подмножестве высокоуровнего языка GLSL для написания программ для графических процессоров). Я взял заготовку HTML из набора Boilerplate (кстати, очень рекомендую) и добавил следующий код из урока:
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}
</script>
Это код вершинного шейдера — программы отвечающей за обработку каждой вершины в графическом процессоре. Еще нам необходима программа обработки каждого пиксела в графическом процессоре:
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
Стоит отметить, что данные шейдеры можно заменить на другие (коих уже очень много) и можно получить совершенно другой эффект на экране.
Далее сам HTML-код, содержащий необходимые элементы:
<!--основной контейнер-->
<div role="main" id="content-holder">
<!--контейнер для отображения FPS (кадры в секунду)-->
<div>FPS: <span id="fps-holder">60</span></div>
<!--элемент canvas - где мы рисуем-->
<canvas id="scene-holder" width="640" height="480">HTML5 not supported!</canvas>
<!--контейнер для отображения ошибок или лога-->
<div id="error-holder"></div>
</div>
Дальше подключаем необходимые нам скрипты:
<script src="js/libs/underscore.js"></script>
<script src="js/libs/glMatrix-0.9.5.min.js"></script>
<script src="js/main.js"></script>
Первым в списке идет шикарная библиотека underscore, которая превращает Javascript в очень удобный язык. После того, как начинаешь ей пользоваться отвыкнуть уже сложно. Затем подключаем библиотеку работы с матрицами и, наконец, код со скриптом приложения.
Код приложения я решил построить на основе функции конструктора, чтобы максимально избежать наличия глобальных переменных. Основа:
/**
* Renderer application
*
* @module main
* @requires underscore, json, glMatrix
*/
var WEBGLEX = WEBGLEX || {};
WEBGLEX.Renderer = function (errorCallback) {
'use strict';
if (!(this instanceof WEBGLEX.Renderer)) {
return new WEBGLEX.Renderer();
}
};
// entry point
window.onload = function () { WEBGLEX.Renderer(); };
Здесь как бы создается пространство имен WEBGLEX и класс Renderer в нем. Класс инициируется после загрузки DOM. В классе мы вызываем последовательность методов, необходимых для работы приложения:
(function (self, callbacks) {
var success = callbacks.shift().call(self);
if (!success) return;
_.each(callbacks, function (callback) {
callback.call(self);
});
})(_self, [_initGL, _initHelpers, _initGLShaders,
_initGLBuffers, _initGLParams, _drawLoop]);
_initGL выбирает контекст рисования, в _initHelpers настраиваются различные утилитарные вещи, _initGLShaders компилиреут шейдеры, _initGLBuffers загружает и биндит VBO (буффер вершин), в _initGLParams настраиваются начальные параметры GL, _drawLoop — основной цикл прорисовки.
У получившегося приложения еще не мало мест для оптимизации и рефакторинга. Но целью было знакомство с технологией, а не создание своего движка.
Полный код доступен здесь.
Комментариев нет:
Отправить комментарий