Monday, February 18, 2013


Математика для программиста

Все мои идеи, касаемо вопроса "математика и программирование" очень ясно отображены в статье с хабра (ссылка внизу). Мне вообще было это очень приятно читать, т.к. многие люди вокруг меня с ума сошли и утверждают обратное. Просто этому есть хорошее объяснение: все те, кто утверждают, что для разработчика нужна математика в размере 5 университетских лет, остались на уровне старой школы и не способны мыслить не в контексте "математика тут главная, а вы вообще не понятно, кто такие". На самом деле все просто: математика и компьютерные науки идут рядом, где-то они очень тесно взаимодействуют, а где очень и очень слабо, что в среднем дает количественную оценку знания математики для разработчика на уровне первого, ну или может второго курса матфака.

Я лично отношусь к математике, как к набору инструментов для решения проблем. В частности наиболее используемые мной ветки математики: криптография, дискретка, теория графов, линейная алгебра, вычислительная математика (очень малая часть) и не очень часто, теория вероятностей. Может я что-то и упустил.

Ну и напоследок я скажу, что: лучше бы учили хорошо курсу "алгоритмы и структуры данных" вместо того, чтобы давать бакалаврам в области "информатика и вычислительная техника" на 4 курсе дисциплины: "математика в экономике" и "организация и планирование производства". Извините, но тех, кто составляют учебные планы не жалко за яйца или, что там у них повесить.


Ссылка на статью
http://habrahabr.ru/post/37217/

Всем спасибо

Friday, February 15, 2013

Shadows in OpenGL. GLSL implementation

Computer graphics has several techniques for creating shadows:
1) Shadow Mapping
2) Shadow Volumes

I'd like to talk about Shadow Mapping, because it's relatively easy to implement, and I have already made class for rendering scene or some part of the scene to the texture using FBO. Thats why Shadow Mapping algorithm will be based on FBO.

Shadow Mapping Algorithm (2pass algorithm, 1st pass - generating shadow map, 2nd pass - drawing the shadow):

1 st pass:
a) we assume the light source has a “view frustum” just like a camera
b) render scene from light source’s position
c) save depth values only
d) we end up with a shadow (depth-) map

2ndpass
a) render scene as usual, but transform vertices to light space, too
b) for each fragment, compare rasterized fragment depth to previously stored depth (read it from shadow map)
b1) zfragment > zfrom_shadow_map => fragment lies in shadow
c) both fragments must be in light space

It's an example of how you can do this. Implementation of shadow mapping I'm going to cover later with detailed review

First of all CREATE AN FBO! For this you should use Fixed Function Pipeline of OpenGL

Vertex Shader:


#version 140

uniform mat4 M;               // model matrix
uniform mat4 V_cam;       // view matrix for the camera
uniform mat4 P_cam;       // projection matrix for the camera
uniform mat4 texture_matrix;
in vec4 vertex;                 // from the application
out vec4 SM_tex_coord; // pass on to the FS

void main(void) {
      // standard transformation
      gl_Position = P_cam * V_cam * M * vertex;
      // shadow texture coords in projected light space
      SM_tex_coord = texture_matrix * V_cam * M * vertex;
}



Fragment Shader:


#version 140

uniform sampler2D shadow_map;
in vec4 SM_tex_coord;       // passed on from VS
out vec4 fragment_color;    // final fragment color destination

void main(void) {
      // note the perspective division!
      vec3 tex_coords = SM_tex_coord.xyz/SM_tex_coord.w;
     // read depth value from shadow map
     float depth = texture(shadow_map, tex_coords.xy).r;
     float inShadow = (depth < tex_coords.z) ? 1.0 : 0.0;
     // do something with that value ...
}

Wednesday, February 13, 2013

Future improvements
Возможно у кого то возникли сложности и не приятные ощущения от кода в скриншотах, но я поясню данную политику: статьи я пишу по уже довольно большому проекту, поэтому, мне гораздо удобнее просто снять скрин и запостить его с соответствующими обьяснениями. Но это не значит что Вам придется выковыривать программу из картинок, нет, просто я загружу все коды в репозиторий (Sourceforge, GitHub и т.п.) откуда скачать сможет кто угодно. 
Следующая статья / tutorial скоро появиться.

И еще, некоторые статьи я буду на английском писать. Но это будет редко

По всем вопросам пожалуйста пишите на astemireleev@gmail.com
Всем спасибо

Friday, February 8, 2013

Искусство программирования. Позитивные логические выражения.

Немного не про java и openGL, но тем не менее это фундаментальная вещь часто остающаяся без внимания. Не многие люди не имеют проблем с непониманием не коротких не положительных фраз, т.е. большинство людей имеют трудности с понимаем большого количества отрицаний. Старайтесь избегать подобного. 

Например:
if (!statusOk) {
   ...
   // делаем что то
   ...
} else {
   ...
   // делаем что то еще
   ...
}

Эту конструкцию можно заменить более читабельной, как:

if (statusOk) { // условие в этой строке было заменено на противоположное
   ...
   // делаем что то
   ...
   // код в этом блоке был поменян местами... ->
} else {
   // ->... с этим кодом
   ...
   // делаем что то еще
   ...
}

Данный пример не я придумал, я лишь хочу поделиться этим с разработчиками. 
Второй фрагмент кода логически эквивалентен с первым, но его читать легче, не приходиться думать от противного, как это было продемонстрировано ранее. Тут всего лишь отрицательное выражение было изменено на положительное, с заменой местами тел условий.

Так же, в похожих ситуациях применение теоремы Деморгана для упрощения логических проверок с отрицанием может оказаться эффективным решением для борьбы со сложностью. Теоремы Деморгана позволяют эксплуатировать логическую взаимосвязь между некоторыми выражениями и версией этого выражения , обозначающего то же самое, благодоря использованию двойного отрицания. 

Например:

if (!displayOk || !orinterOk) {
   ...
}

Данное логическое выражение после применения одной из теорем Деморгана будет выглядеть так:

if (!(displayOk && printerOk)) {
   ...
}



Данный пример взят из книги "Совершенный Код" автор Стив Макконнелл. Название книги говорит само за себя. 

Для многих данная оптимизация вероятно известна, тем не менее, если хоть кто то почерпнет для себя что то новое, то я буду считать, что моя миссия выполнена.

Всем спасибо

Thursday, February 7, 2013

И пришел OpenGL. 

Скажу сразу, я ориентируюсь не на новичка в программировании. Как минимум, что такое динамическая диспетчеризация вы должны знать. Шучу! :) Не стоит бояться делать, что то новое. Дорогу осилит только идущий.

Ну что же, погнали

Под Java существует несколько дистрибутивов OpenGL, в частности: jogl, gl4java и lwjgl. Насколько я знаю lwjgl имеет довольно большое сообщество. Да и сам факт того, что например minecraft, spiral knights и прочие довольно успешные проекты реализованы с использование данной технологии, например для меня говорит многое.

Light weight java game library или просто lwjgl http://www.lwjgl.org/ - библиотека для языка программирования java, которая по сути из себя представляет объектную оболочку над OpenGL. Плюс набор классов для работы с оконной системой, контролерами.

Перейдем к делу. Я не буду дублировать информацию о том, как же подключить lwjgl к какой либо ide. Это задача довольно проста и на мой взгляд тот, кто не смог это сделать, не сможет самостоятельно двигаться в мире программирования. Тем более, что в вышеуказанной ссылке есть туториалы о том, как подключить эту библиотеку ко множеству сред разработки. Я представлю, что вы подключили библиотеку и начину непосредственно с создания базового программного кода. Создав проект в одной из ide (Eclipse, NetBeans или IDEA) создайте интерфейс:



Я поясню суть каждого из методов.
Все очень просто. Давайте начнем с конца: метод getInformationAboutSysConfig при запуске нашей программы будет выводить в консоль информацию о текущей версии lwjgl, имени вашей платформы, поставщике видео аппаратуры,модели видео адаптера и текущей версии OpenGL. 
Вот как это выглядит на моей машинке:



- Метод cleanup будет "уничтожать" и высвобождать ресурсы  для отображения окна.
- Метод createWindow, как следует из названия будет средствами lwjgl создавать, инициализировать и параметризировать окно.
- Метод pollInput будет нашим handler"ом по "поимке" и обработке событий с клавиатуры, мыши и контроллеров.
- Метод initGL инициализирует конвейер состояний OpenGL (да, да, OpenGL это конечный автомат, ну об этом позже).
- Ну и метод run. Это то на чем следует сфокусироваться. Это то место, в котором, как в конвейере будут вызываться, создаваться и высвобождаться (я очень надеюсь, что сборщик мусора услышит меня) данные. Концепция в следующем: этот метод, вызывается каждый кадр, то есть это цикл который запускается с момента его вызова до того момента пока программа не будет завершена (ну или пока не вылетит exception :)). В англоязычной литературе OpenGL до версии 2.0 именуется как fixed function pipeline (фиксированный трубопровод). Да, до версии OpenGL 2.0 он был далеко не полностью программируемым мягко говоря, но с появлением шейдеров в этой самой версии 2.0, машина состояний OpenGL получила новое название - peogrammable pipeline (программируемый трубопровод). О шейдерах я начну чуть позже и скорее всего через пару десятков постов :) (нужен хороший background перед столь низко и одновременно высокоуровневым программированием комп графики). 
Давайте теперь реализуем наш интерфейс, и посмотрим что получиться на выходе:



Начнем с метода run. Пока что он ничего толком не делает. Просто крутиться себе трубопровод, пока вы не закроете программу и все. В инициализации окна (строчка 64) и машины состояний (строчка 65) вопросов возникнуть не должно, когда вы реализации всех методов увидите.

А теперь я вас попугаю чуть чуть:

Это метод initGL, инициализирующий машину состояний OpenGL. В моем проекте инициализация этой машины очень нехилая :). Содержание данного метода в данной статье концептуально не важно. Подробно каждая из функций будет рассмотрена позже. Данный пример я привел, для того, чтобы вы психологически подготовились к туче кода. 



На данном этапе нам интересней всего как же создать окно средствами lwjgl.
А все просто: для начала мы импортирует класс Display, который очень простой в использовании. Имея статическую сущность мы просто обращается через класс Display к методам.



Для высвобождения ресурсов я инкапсулировал метод destroy в свой метод.


Ну и последний метод, для получения статистической информации о системе. Пока что, просто примите на веру то, что написано тут. Позже, все станет шаг за шагом проясняться.

В следующей статье, я начну подробный рассказ о функциях и концепциях заложенных в OpenGL.

Всем спасибо.

Обо мне

Привет! Меня зовут Астемир, я инженер программист. Хотя, я больше программист чем инженер :). Мне нравиться ООП, компьютерная графика, разные алгоритмы ну и конечно структуры данных. Java как язык программирования я знаю лучше остальных, более 4х лет я программирую с использованием данной технологии. Но мои знания только этим не ограничиваются :). По ходу продвижения в java и openGL я включу в блог GLSL шейдеры. Ну и без математики ни куда не деться. Так что она тоже будет рассматриваться, но не с точки зрения математика я буду о ней рассказывать, а с точки зрения разработчика, т.е. нас будет в первую очередь волновать создание математических и по возможности обобщенных инструментов.