Последние записи
- Windows 10 сменить администратора
- Рандомное слайдшоу
- Событие для произвольной области внутри TImage
- Удаление папки с файлами
- Распечатка файла
- Преобразовать массив байт в вещественное число (single)
- TChromium (CEF3), сохранение изображений
- Как в Delphi XE обнулить таймер?
- Изменить цвет шрифта TextBox на форме
- Ресайз PNG без потери прозрачности
Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке - https://slurm.club/3MeqNEk
Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе
И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка - ttps://clck.ru/fCrQw
25th
Авг
РАСКРУТКА САЙТОВ Продвижение, раскрутка и улучшение сайтов
Наша слава лишь
мнением народным создается.
Шекспир
Рад, что вы решили прочитать именно мою статью, т.к. подобной информации уже так много, что просто «глаза разбегаются». В данном материале я буду, в большинстве случаев, опираться на личный опыт, не оставляя без внимания, и эксперименты других, возможно даже, более бывалых людей.
25th
ИЗ ВВЕДЕННОЙ С КЛАВИАТУРЫ СИМВОЛЬНОЙ СТРОКИ ВСЕ ТОЧКИ И ПОДСЧИТАТЬ ДЛИНУ ОТРЕДАКТИРОВАННОЙ СТРОКИ
Programming articles
Создание сайтов на шаблонах
Множество вариантов работы с графикой на канве
Шифруем файл с помощью другого файла
Перехват API функций — Основы
Как сделать действительно хороший сайт
Создание почтового клиента в Delphi 7
Применение паскаля для
решения геометрических задач
Управление windows с помощью Delphi
Создание wap сайта
Операционная система unix, термины и понятия
SQL враг или друг
Возникновение и первая редакция ОС UNIX
Оптимизация проекта в Delphi
Ресурсы, зачем нужны ресурсы
Термины программистов 20 века
Советы по созданию собственного сайта с нуля
Шифруем файл с помощью пароля
Фракталы — геометрия природы
Crypt — Delphi программа для шифрования
Рассылка, зачем она нужна и как ее организовать?
Учебник по C++ для начинающих программистов
Уроки для изучения ассемблера
Загадочный тип PCHAR
Средства по созданию сайтов
Операторы преобразования
классов is и as
Borland Developer studio 2006. Всё в одном
Создание базы данных в Delphi, без сторонних БД
Software engineering articles
25th
ExitCode- переменная
ExitCode
Содержит код возврата при завершении приложения
var ExitCode : Integer;
Описание:
Значение ExitCode будет показано в диалоговом окне, если переменная ErrorAddr не равна 0 при завершении приложения.
Пример кода:
i : Integer;
begin
// Set up an error address so that halt shows a termination dialog
ErrorAddr := Addr(i);
// Set the program exit code
ExitCode := 8;
end;
Результат выполнения:
Runtime error 8 at 0069FC94
Programming articles
Создание сайтов на шаблонах
Множество вариантов работы с графикой на канве
Шифруем файл с помощью другого файла
Перехват API функций — Основы
Как сделать действительно хороший сайт
Создание почтового клиента в Delphi 7
Применение паскаля для
решения геометрических задач
Управление windows с помощью Delphi
Создание wap сайта
Операционная система unix, термины и понятия
SQL враг или друг
Возникновение и первая редакция ОС UNIX
Оптимизация проекта в Delphi
Ресурсы, зачем нужны ресурсы
Термины программистов 20 века
Советы по созданию собственного сайта с нуля
Шифруем файл с помощью пароля
Фракталы — геометрия природы
Crypt — Delphi программа для шифрования
Рассылка, зачем она нужна и как ее организовать?
Учебник по C++ для начинающих программистов
Уроки для изучения ассемблера
Загадочный тип PCHAR
Средства по созданию сайтов
Операторы преобразования
классов is и as
Borland Developer studio 2006. Всё в одном
Создание базы данных в Delphi, без сторонних БД
Software engineering articles
25th
ТЕОРЕМА ШЕННОНА
Programming articles
Создание сайтов на шаблонах
Множество вариантов работы с графикой на канве
Шифруем файл с помощью другого файла
Перехват API функций — Основы
Как сделать действительно хороший сайт
Создание почтового клиента в Delphi 7
Применение паскаля для
решения геометрических задач
Управление windows с помощью Delphi
Создание wap сайта
Операционная система unix, термины и понятия
SQL враг или друг
Возникновение и первая редакция ОС UNIX
Оптимизация проекта в Delphi
Ресурсы, зачем нужны ресурсы
Термины программистов 20 века
Советы по созданию собственного сайта с нуля
Шифруем файл с помощью пароля
Фракталы — геометрия природы
Crypt — Delphi программа для шифрования
Рассылка, зачем она нужна и как ее организовать?
Учебник по C++ для начинающих программистов
Уроки для изучения ассемблера
Загадочный тип PCHAR
Средства по созданию сайтов
Операторы преобразования
классов is и as
Borland Developer studio 2006. Всё в одном
Создание базы данных в Delphi, без сторонних БД
Software engineering articles
25th
МОЩНЫЙ ИНСТАЛЯТОР
Install Creation System — программа для создания инсталляционных программ средней мощности, включает в себя все возможности для создания инсталляционных программ:
Установка различных версий установки.
Изменение реестра.
Удаление проделанной установки.
Программа удаления будет присутствовать в списке установки и удаления программ в Панели управления.
Установка рисунков на страницы диалога максимально упрощена.
Создание различных версий установки тоже элементарно просто.
Полный набор страниц диалога.
Возможность устанавливать некоторые файлы по абсолютному пути независимо от папки которую выбрал пользователь.
Создание ярлыков возможно везде где вы только захотите.
Присутствуют почти все системные константы, также можно создавать свои константы.
Автор статьи Ahilles
Programming articles
Создание сайтов на шаблонах
Множество вариантов работы с графикой на канве
Шифруем файл с помощью другого файла
Перехват API функций — Основы
Как сделать действительно хороший сайт
Создание почтового клиента в Delphi 7
Применение паскаля для
решения геометрических задач
Управление windows с помощью Delphi
Создание wap сайта
Операционная система unix, термины и понятия
SQL враг или друг
Возникновение и первая редакция ОС UNIX
Оптимизация проекта в Delphi
Ресурсы, зачем нужны ресурсы
Термины программистов 20 века
Советы по созданию собственного сайта с нуля
Шифруем файл с помощью пароля
Фракталы — геометрия природы
Crypt — Delphi программа для шифрования
Рассылка, зачем она нужна и как ее организовать?
Учебник по C++ для начинающих программистов
Уроки для изучения ассемблера
Загадочный тип PCHAR
Средства по созданию сайтов
Операторы преобразования
классов is и as
Borland Developer studio 2006. Всё в одном
Создание базы данных в Delphi, без сторонних БД
Software engineering articles
25th
Операционная система unix, термины и понятия
ОСНОВНЫЕ ПОНЯТИЯ
На первый взгляд UNIX выглядит неоправданно сложной операционной системой. Но под кажущейся сложностью скрывается очень простая и элегантная операционная система. Отдельные детали могут быть сложными, но общие принципы — просты.
Одним из достоинств ОС UNIX является то, что система базируется на небольшом числе интуитивно ясных понятий. Однако, несмотря на простоту этих понятий, к ним нужно привыкнуть. Без этого невозможно понять существо UNIX.
25th
УРОК 14 ИСПОЛЬЗОВАНИЕ ССЫЛОК В C++
Из урока 10 вы узнали, как изменять параметры внутри функции с помощью указателей. Для использования указателей вы должны предварять имена переменных-указателей звездочкой. Использование указателей досталось в «наследство» от языка С. Чтобы упростить процесс изменения параметров, С++ вводит такое понятие как ссылка. Как вы узнаете из этого урока, ссылка представляет собой псевдоним (или второе имя), который ваши программы могут использовать для обращения к переменной. К концу данного урока вы освоите следующие основные концепции:
• Для объявления и инициализации ссылки внутри программы объявите переменную, размещая амперсанд (&) сразу же после типа переменной, и затем используйте оператор присваивания для назначения псевдонима, например int& alias_name = variable’,.
• Ваши программы могут передавать ссылки в функцию в качестве параметров, а функция, в свою очередь, может изменять соответствующее значение параметра, не используя указателей.
• Внутри функции вам следует объявить параметр как ссылку, размещая амперсанд (&) после типа параметра, затем можно изменять значение параметра внутри функции без помощи указателей.Как вы узнаете, использование указателей очень упрощает изменение значений параметров внутри функции.
ССЫЛКА ЯВЛЯЕТСЯ ПСЕВДОНИМОМ
Ссылка C++ позволяет создать псевдоним (или второе имя) для переменных в вашей программе. Для объявления ссылки внутри программы укажите знак амперсанда (&) непосредственно после типа параметра. Объявляя ссылку, вы должны сразу же присвоить ей переменную, для которой эта ссылка будет псевдонимом, как показано ниже:
int& alias_name = variable; //—> Объявление ссылки
После объявления ссылки ваша программа может использовать или переменную , или ссылку:
alias_name = 1001;
variable = 1001;
Следующая программа SHOW_REF.CPP создает ссылку с именемalias_name и присваивает псевдониму переменную number. Далее программа использует как ссылку, так и переменную:
#include <iostream.h>
void main(void)
{
int number = 501;
int& alias_name = number; // Создать ссылку
cout << «Переменная number содержит » << number << endl;
cout << «Псевдоним для number содержит » << alias_name << endl;
alias_name = alias_name + 500;
cout << «Переменная number содержит » << number << endl;
cout << «Псевдоним для number содержит » << alias_name << endl;
}
Как видите, программа прибавляет 500 к ссылке alias_name. В итоге программа прибавляет 500 также и к соответствующей переменнойnumber, для которой ссылка служит псевдонимом или вторым именем. Когда вы откомпилируете и запустите эту программу, на вашем экране появится следующий вывод:
С:\> SHOW_REF <ENTER>
Переменная number содержит 501
Псевдоним для number содержит 501
Переменная number содержит 1001
Псевдоним для number содержит 1001
В общем случае использование ссылки таким образом, как только что было показано, создает трудности для понимания. Однако вы увидите, что использование ссылок значительно упрощает процесс изменения параметров внутри функции.
Объявление ссылкиСсылка C++ представляет собой псевдоним (второе имя), которое ваши программы могут использовать для обращения к переменной. Для объявления ссылки поставьте амперсанд (&) сразу же после типа переменной, а затем укажите имя ссылки, за которым следует знак равенства и имя переменной, для которой ссылка является псевдонимом:
float& salary_alias = salary;
ИСПОЛЬЗОВАНИЕ ССЫЛОК В КАЧЕСТВЕ ПАРАМЕТРОВ
Основное назначение ссылки заключается в упрощении процесса изменения параметров внутри функции. Следующая программа REFERENC.CPP присваивает ссылку с именем number_alias переменнойnumber. Программа передает ссылку на переменную в функциюchange_value, которая присваивает переменной значение 1001:
#include <iostream.h>
void change_value(int &alias)
{
alias = 1001;
}
void main(void)
{
int number;
int& number_alias = number;
change_value(number_alias);
out << «Переменная number содержит » << number << endl;
}
Как вы видите, программа передает ссылку в функцию change_value. Если вы рассмотрите объявление функции, вы обнаружите, что change_valueобъявляет параметр alias как ссылку на значение типа int.
void change_value(int& alias)
Внутри функции change_value можете изменять значение параметра без помощи указателя. В результате звездочка (*) не используется и операция внутри функции становится легче для понимания.
Использование комментариев для объяснения ссылок внутри ваших программБольшинство программистов C++ знакомы с языком программирования С, и они привыкли использовать указатели внутри функции, если необходимо изменить значение параметра. В результате, если такие программисты не видят указатели внутри функций, которые используют ссылки, они могут предположить, что значения параметров не изменяются. Для предотвращения подобных промахов не забывайте размещать несколько комментариев до и внутри функций, которые изменяют параметры с помощью ссылок. В таком случае программисты С лучше поймут работу ваших функций.
Рассмотрим второй пример
В уроке 10 вы использовали следующую функцию для перестановки двух значений с плавающей точкой:
void swap_values(float *a, float *b)
{
float temp;
temp = *a;
*a = *b;
*b = temp;
}
Как видите, функция комбинирует переменные-указатели с переменными-неуказателями. Следующая программа SWAP_REF.CPP использует ссылки на значения с плавающей точкой для упрощения функции:
#include <iostream.h>
void swap_values(float& a, float& b)
{ float temp;
temp = a;
a = b;
b = temp;
}
void main(void)
{ float big = 10000.0;
float small = 0.00001;
float& big_alias = big;
float& small_alias = small;
swap_values(big_alias, small_alias);
cout << «Big содержит » << big << endl;
cout << «Small содержит » << small << endl;
}
Как видите, функцию swap_values сейчас легче понять, однако ваша программа имеет теперь два дополнительных имени (ссылки big_alias и small_alias), за которыми вы должны следить.
ПРАВИЛА РАБОТЫ СО ССЫЛКАМИ
Ссылка не является переменной. Один раз присвоив значение ссылке, вы уже не можете ее изменить. Кроме того в отличие от указателей вы не можете выполнить следующие операции над ссылками:
• Вы не можете получить адрес ссылки, используя оператор адреса C++.
• Вы не можете присвоить ссылке указатель.
• Вы не можете сравнить значения ссылок, используя операторы сравнения C++.• Вы не можете выполнить арифметические операции над ссылкой, например добавить смещение.•Вы не можете изменить ссылку.По мере использования объектно-ориентированного программирования на C++ вы вернетесь к ссылкам.Использование ссылок для изменения параметров функцииИз урока 10 вы узнали, что ваши программы с помощью указателей могут изменять значение параметров внутри функции. Для изменения параметра вы должны передать его адрес в функцию. Чтобы получить адрес параметра, используйте оператор адреса C++ (&). В свою очередь функция использует переменные-указатели (которые хранят адрес памяти). Для объявления переменной-указателя внутри функции предваряйте имя параметра звездочкой (*). Чтобы изменить или использовать значение параметра внутри функции, предваряйте каждое обращение к имени этого параметра оператором разыменования C++ (*). К сожалению, многие операции внутри функции комбинируют переменные-указатели и переменные-неуказатели.
Ссылки C++ упрощают процесс изменения параметров функции, избавляя от операторов, которые смешивают переменные-указатели и переменные-неуказатели.
ЧТ0 ВАМ НЕОБХОДИМО ЗНАТЬ
Из этого урока вы узнали, как использовать ссылки C++ для создания псевдонима или второго имени переменной. Использование ссылок может упростить функции, изменяющие значения параметров. Из урока 15 вы узнаете, что C++ позволяет вам задавать значения по умолчанию для параметров функции. При вызове функции программа может опускать значения одного или нескольких параметров и функция будет использовать значения по умолчанию. До изучения урока 15 убедитесь, что вы освоили следующие основные концепции:
-
- Ссылка C++ является псевдонимом (или вторым именем) переменной.
- Для объявления ссылки поместите знак амперсанда (&) непосредственно после типа переменной, а затем укажите имя ссылки, за которым следует знак равенства и имя переменной, для которой ссылка является псевдонимом.
- Если вы однажды присвоили ссылке значение, вы не можете его изменить.
- Вам следует помещать несколько комментариев до и внутри функций, которые используют ссылки для изменения значений параметра, чтобы другие программисты, читающие ваш код, сразу обратили, на это внимание.
- Чрезмерное использование ссылок может привести к слишком трудному для понимания программному коду.
Предыдущий урок | Следующий урок
Programming articles
Создание сайтов на шаблонах
Множество вариантов работы с графикой на канве
Шифруем файл с помощью другого файла
Перехват API функций — Основы
Как сделать действительно хороший сайт
Создание почтового клиента в Delphi 7
Применение паскаля для
решения геометрических задач
Управление windows с помощью Delphi
Создание wap сайта
Операционная система unix, термины и понятия
SQL враг или друг
Возникновение и первая редакция ОС UNIX
Оптимизация проекта в Delphi
Ресурсы, зачем нужны ресурсы
Термины программистов 20 века
Советы по созданию собственного сайта с нуля
Шифруем файл с помощью пароля
Фракталы — геометрия природы
Crypt — Delphi программа для шифрования
Рассылка, зачем она нужна и как ее организовать?
Учебник по C++ для начинающих программистов
Уроки для изучения ассемблера
Загадочный тип PCHAR
Средства по созданию сайтов
Операторы преобразования
классов is и as
Borland Developer studio 2006. Всё в одном
Создание базы данных в Delphi, без сторонних БД
Software engineering articles
25th
УРОК 10 ИЗМЕНЕНИЕ ЗНАЧЕНИЙ ПАРАМЕТРОВ
Из урока 9 вы узнали, как разделить ваши программы на небольшие легко управляемые части, называемые функциями. Как вы уже знаете, программы могут передавать информацию (параметры) функциям. Представленные в уроке 9 программы использовали или выводили значения параметров, но не меняли их. Из этого урока вы узнаете, как изменить значение параметра в функции. Вы обнаружите, что для изменения параметров в функции фактически требуется больше шагов, чем можно предположить. Однако этот урок обучит вас всем шагам, которые необходимо знать. К концу данного урока вы освоите следующие основные концепции:
• Если функция не использует указатели или ссылки, она не может изменить значение параметра.
• Для изменения значения параметра функция должна знать адрес параметра в памяти.
• Оператор адреса C++ (&) позволяет вашей программе определить адрес переменной в памяти.
• Когда ваша программа узнает адрес памяти, она сможет использовать операцию разыменования C++ (*) для определения значения, хранимого по данному адресу.
• Если программе нужно изменить значение параметров функции, программа передает в функцию адрес параметра.
Изменение значения параметра функции представляет собой обычную операцию. Экспериментируйте с программами, представленными в этом уроке, чтобы убедиться, что вы полностью освоили этот процесс.
25th
Делаем динамические тени на OPENGL. Часть 1
Здравствуйте. В этой статье я хочу рассмотреть создание движка динамического освещения с помощью графической библиотеки OpenGL. Писаться движок будет на Delphi, но это не мешает переписать его на любой другой язык, так как главное, рассматриваемое в статье, это алгоритмы…
Вадим Буренков
vadim_burenkov@mail.ru
Чтобы не тратить время на инициализацию OpenGL и избежать других проблем (например, с настройкой таймеров и рендера в текстуру) я буду использовать движок ZenGL [1]. Впрочем, от него нам многого не понадобится. Итак, приступим…
Инициализация OpenGL в ZenGL
Первым делом качаем ZenGL и создаем в нем простейшее приложение (вы можете найти его в папке LightEngine ресурсов статьи, там же вы найдете ZenGL):
код:
uses
zgl_main,
zgl_screen,
zgl_window,
zgl_timers,
zgl_textures,
zgl_textures_jpg,
zgl_sprite_2d,
zgl_mouse,
zgl_keyboard,
zgl_utils;
var
BackTex:zglPTexture; // текстура фона
bTiles:zglTTiles2D; // параметры тайлинга
procedure Init;
var n,j:integer;
begin
// отключаем очищение буфера
zgl_disable(COLOR_BUFFER_CLEAR );
// Тут можно выполнять загрузку основных ресурсов
// загрузка текстуры и настройка тайлинга
BackTex:=tex_LoadFromFile( ‘Back.jpg’,0,TEX_DEFAULT_2D);
// параметры тайлов фона
bTiles.Count.X:=7;
bTiles.Count.Y:=5;
bTiles.Size.W:=128;
bTiles.Size.H:=128;
SetLength(bTiles.Tiles,7,5);
&nfor fto=0 to 4 do
&nbsforbsp;&ntob>for j:=0 to 6 do bTiles.Tiles[j,n]:=1;
end;
procedure Draw;
begin
// Тут «рисуем» что угодно 🙂
tiles2d_Draw(BackTex,0,0,BTiles); // отрисовка фона
end;
procedure Update;
begin
// Тут выполняется обработка данных
if key_Press( K_ESCAPE ) then zgl_Exit;
// обновление клавиш
key_ClearState;
Mouse_ClearState;
end;
procedure Timer;
begin
// Будем в заголовке показывать количество кадров в секунду
wnd_SetCaption( ‘LightEngine [ FPS: ‘ + u_IntToStr( zgl_Get(
SYS_FPS ) ) + ‘ ]’ );
end;
procedure Quit;
begin
// Тут выполняется очищение данных
end;
Begin
// Создаем таймер с интервалом 1000мс.
timer_Add( @Timer, 1000 );
// Создаем таймер с интервалом 10мс.
timer_Add( @Update, 10 );
// Регистрируем процедуру, что выполнится сразу после
// инициализации ZenGL
zgl_Reg( SYS_LOAD, @Init );
// Регистрируем процедуру, где будет происходить рендер
zgl_Reg( SYS_DRAW, @Draw );
// Регистрируем процедуру, которая выполнится после завершения
// работы ZenGL
zgl_Reg( SYS_EXIT, @Quit );
// Устанавливаем заголовок окна
// Разрешаем курсор мыши
wnd_ShowCursor( TRUE );
// Указываем первоначальные настройки
scr_SetOptions( 800, 600, REFRESH_MAXIMUM, FALSE, FALSE );
// Инициализируем ZenGL
zgl_Init;
End.
При инициализации мы указываем процедуры в которых будут производится различные действия (инициализация/обработка/очищение) а также параметры окна.
В инициализации загружается текстура и настраивается тайлинг (количество и размер настроен так, чтобы текстура закрывала весь экран). В обработке обновляются состояния мыши и клавиатуры, а также стоит проверка на нажатие ESC. Процедура очищения пока пуста, так как ресурсы движка очищаются самостоятельно.
Другие непонятные процедуры можно посмотреть в справке, которая находится в папке doc движка. Чтобы при компиляции не возникло проблем необходимо указать расположение модулей движка в Project->Options- >Directories/Conditionals->SearchPath, а именно папки zengl/src и zengl/src/PasZLib (см. рис.1). Можно скомпилировать проект, увидеть вы должны следующее (см. рис.2).
Рис. 1. Пути
Рис. 2. Тайлинг
Немного теории
Теперь перейдем к теории вопроса. В движке мы должны реализовать два типа – источники света и объекты, которые отбрасывают тени (см. рис.3):
Рис. 3. Тень от объекта
Источник света обладает параметрами:
- положение
- радиус
- цвет
- интенсивность
Все объекты являются невыпуклыми многоугольниками. Они имеют:
- локальные координаты вершин
- мировые координаты вершин
- количество вершин
- положение
- угол поворота
Локальные координаты нужны, так как через положение и угол поворота объекта его можно разворачивать.
Для хранения данных об освещенности нам понадобятся два буфера размером в экран. Первый – альфа буфер. В него выводится круглый источник света (см. рис.4):
Рис. 4. Источник света
После этого альфа буфер рисуется во второй буфер – буфер аккумуляции. При этом используется аддитивный режим блендинга, то есть цвета смешиваются. В буфере мы получаем такую картинку (см. рис.5):
Рис. 5. Смешивание источников света
В нем светлые участки – там где свет, а темные – там где тьма. А теперь мы выводим буфер аккамуляции на экран с блендингом MULT. Получается так, что чем светлее цвет, тем он прозрачнее (см. рис.6):
Рис. 6. Рисование с блендингом MULT
Как же делаются тени от объектов? При выводе источника света в альфа буфер на него рисуется форма тени черным цветом. Получается что от круга света «отрезают» кусок (см. рис.7):
Рис. 7. Форма тени на свете
С помощью такого алгоритма получаются тени любой сложности, причем их количество, как и источников света с объектами неограниченно (см.рис.8).
Да будет свет!
Под следующий код сделаем модуль, который и будет отвечать за тени. Назовем его ZGLShadows.
Рис. 8. Сцена с большим количеством теней
Напишем тип света:
код:
PLightSource=^TLightSource;
TLightSource=record
position:leVect; // положение
radius:single; // радиус
color:TColorRGB; // цвет
intensivity:single; // интенсивность cвета
prev,next:PLightSource;
end;
Все данные будут храниться в “prev-next” (двухсвязных) списках (см. рис.9):
Рис. 9. Списки
Каждый элемент является звеном цепи и имеет указатели на предыдущее и следующее звено. Нам же нужно иметь первый элемент и длину цепи для управления списком:
код:
// Источники света
le_Lights:PLightSource; // список
le_NumLights:integer; // количество
Более подробно о такой системе хранения данных можно почитать в Интернете. Как мы видим, у нас появились новые типы данных:
код:
TColorRGB=record
r,g,b:single;
end;
Данный тип нужен для хранения цвета в формате rgb, так как его использует OpenGL. ZenGL использует integer для хранения цветов (например $FFFFFF соответствует 1,1,1 в RGB), поэтому нам может понадобится процедура для перевода цвета в RGB:
код:
begin
Result.r := ((Color and $FF0000) shr 16) / 255;
Result.g := ((Color and $FF00) shr 8) / 255;
Result.b := (Color and $FF) / 255;
end;
Все координаты будут храниться в типе:
код:
leVect=record
x,y:single;
end;
Подробнее о нем будет написано позже, пока нам понадобится только формирование вектора по x и y:
код:
begin
result.x:=x;
result.y:=y;
end;
Перейдем к процедурам управления источниками света:
код:
color:TColorRGB):PLightSource;
var t: PLightSource;
begin
new(t);
t.Next:= nil;
t.Prev:= nil;
t.position:=p;
t.radius:=radius;
t.intensivity:=intensivity;
t.color:=color;
t.Next:= le_Lights;
if le_Lights <> nil then le_Lights.Prev:= t;
le_Lights:= t;
Result:= le_Lights;
inc(le_NumLights);
end;
Функция создает источник света в памяти и возвращает указатель на него. Большую часть кода занимает работа со списками.
В следующей процедуре происходит рисование круга света как на рисунке 4. Он рисуется через GL_TRIANGLE_FAN. Первая точка в центре имеет цвет и интенсивность света, далее идут точки по радиусу окружности с нулевым цветом, благодаря чему мы имеем плавный переход цвета:
код:
var angle:single;
begin
angle:=0;
glBegin(GL_TRIANGLE_FAN);
glColor4f(t.color.r, t.color.g, t.color.b, t.intensivity);
glVertex2f(t.position.x,t.position.y);
glColor4f(0, 0, 0, 0 );
while angle<=Pi*2 do begin
glVertex2f( t.radius*cos(angle) + t.position.x,
t.radius*sin(angle) + t.position.y);
angle:=angle+((PI*2)/le_numSubdivisions);
end;
glVertex2f(t.position.x+t.radius, t.position.y);
glEnd();
end;
Количество треугольников, из которого рисуется круг, задается константой:
код:
le_numSubdivisions = 32;
Следующая процедура рассчитывает и рисует тень для объектов, но о ней я напишу позже:
код:
Далее напишем процедуру, которая освобождает память, занятую источником света:
код:
var DelT: PLightSource;
begin
DelT:= t;
if t.Prev <> nil then t.Prev.Next := t.Next
else le_Lights:= t.Next;
if t.Next <> nil then t.Next.Prev := t.Prev;
Dispose(DelT);
dec(le_NumLights);
t:=nil
end;
Следующая процедура вспомогательная, она обрабатывает каждый источник света передаваемой в нее процедурой:
код:
var t, tNext: PLightSource;
begin
t:= le_Lights;
while t <> nil do
begin
tNext:= t.Next;
p(t);
t:= tNext;
end;
end;
le_proc – тип процедуры:
код:
le_proc=procedure(d:Pointer);
Например, данная строчка нарисует все источники света:
код:
Хочу заметить, что при попытке передать в le_EachLightSource процедуру очищения возникнет ошибка, связанная с памятью, поэтому для очищения всех источников света напишем отдельную процедуру:
код:
var t, tNext: PLightSource;
begin
t:= le_Lights;
while t <> nil do begin
tNext:= t.Next;
le_FreeLightSource(t);
t:= tNext;
end;
end;
Заставим это работать
С типом света мы управились, теперь надо заставить его работать. Объявим следующие переменные:
код:
le_AlphaBuffer: zglPRenderTarget; // буфер для света
le_AccBuffer: zglPRenderTarget; // буфер для сложения
// изображений света
le_DarkColor: integer; // цвет тени
В этой процедуре инициализируются буферы для рендеринга. К проекту нужно также подключить модули:
- zgl_textures – создание текстуры-буфера
- zgl_render_target – управление рендерингом
- zgl_primitives_2d – очищение рендер target. Хотя можно было бы просто рисовать QUAD на OpenGL.
- zgl_fx – процедуры управления блендингом
- zgl_sprite_2d – рисование текстур
Напишем процедуру инициализации буферов:
код:
begin
le_DarkColor:=DarkColor;
// инициализация буферов
le_AlphaBuffer:=rtarget_Add( RT_TYPE_FBO, tex_CreateZero(
800,600, 0, TEX_DEFAULT_2D ) , RT_FULL_SCREEN );
le_AccBuffer :=rtarget_Add( RT_TYPE_FBO, tex_CreateZero(
800,600, 0, TEX_DEFAULT_2D ) , RT_FULL_SCREEN );
end;
le_DarkColor – переменная, которая отвечает за освещенность. К ее смыслу и принципу работы я еще вернусь. Обобщающая процедура полной обработки света:
код:
begin
rtarget_Set( le_AlphaBuffer ); // начинаем рендер в буфер
pr2d_Rect(0,0,800,600, 0,255,PR2D_FILL); // очищаем черным
// цветом
le_DrawLightSource(t); // отрисовка источника света
rtarget_Set( nil );
rtarget_Set( le_AccBuffer ); // отрисовка полученного
// изобр-я в буфер аккамуляции
fx_SetBlendMode(FX_BLEND_ADD); // при отрисовке используем
// блендинг для сложения
// интенсивностей источ-в света
ssprite2d_Draw( le_AlphaBuffer.Surface, 0,0,800,600,0);
fx_SetBlendMode(FX_BLEND_NORMAL);
rtarget_Set( nil );
end;
И завершающая процедура – вывод буфера с использованием MULT блендинга:
код:
begin
// выводим полученные тени и свет на экран с использованием
// блендинга mult (чем светлее изображение тем прозрачней)
fx_SetBlendMode(FX_BLEND_MULT);
ssprite2d_Draw( le_AccBuffer.Surface, 0,0,800,600,0);
fx_SetBlendMode(FX_BLEND_NORMAL);
// очищаем буфер для следующего кадра (цветом le_DarkColor!)
rtarget_Set( le_AccBuffer );
pr2d_Rect(0,0,800,600, le_DarkColor,255,PR2D_FILL);
rtarget_Set( nil );
end;
Хочу заметить, что очищение le_AccBuffer проводится цветом le_DarkColor. Следовательно, чем светлее этот цвет тем прозрачнее тени (см. рис.10). На изображении видно, что справа фон просвечивается даже там, где света нет, так как le_DarkColor не черный, а серый ($1f1f1f).
Рис. 10. Различный DarkColor
Все, система света написана. Правда, пока без теней от объектов. Теперь проверим ее в действии.
Добавим переменную под управляемый свет:
код:
UserLight:PLightSource; // указатель на управляемый свет
Создадим его, и еще 4 света в Init:
код:
// загружаем источники света
le_CreateLightSource
(le_v(520,550),400,0.3,IntToRGB($FF00FF));
le_CreateLightSource
(le_v(470,50),250,0.5,IntToRGB($FF0000));
le_CreateLightSource
(le_v(200,300),270,1,IntToRGB($00FF00));
le_CreateLightSource
(le_v(640,270),300,0.8,IntToRGB($FFFFFF));
UserLight:=le_CreateLightSource(le_v(0 ,
0),100,0.8,IntToRGB($FFFFFF));
Теперь в Draw напишем рисование теней:
код:
le_EachLightSource(@le_RenderLight);
// отрисовка теней
le_FinishRender;
В Update привяжем UserLight к мышке, сделаем изменение размера при нажатии на кнопки мыши и цвета при нажатии на колесико:
код:
UserLight.radius:=UserLight.radius+3;
if mouse_Down( M_BRIGHT ) then
if UserLight.radius>0 then
UserLight.radius:=UserLight.radius-3;
if mouse_Click( M_BMIDLE ) then begin
UserLight.color.r:=random(100)/100;
UserLight.color.g:=random(100)/100;
UserLight.color.b:=random(100)/100;
end;
И наконец, в Quit очищаем источники света:
код:
Запускаем, любуемся результатом (см. рис.11).
Рис. 11. Результат
Заключение
В следующей части статьи я рассмотрю создание теней от объектов, а также оптимизирую код, чтобы добиться большей производительности. Весь исходный код проекта приложен к журналу «ПРОграммист. Пятый выпуск».
Продолжение следует…
Ресурсы
- Страница разработчика ZenGL http://andrukun.inf.ua/zengl.html
- Михалкович С.С. Основы программирования.
Второй семестр 08-09, 2 часть
Обсудить на форуме – Делаем динамические тени на OPENGL. Часть 1
22nd
Авг
Беспроводная сеть масштаба микрорайона. Часть 1
Общаясь с друзьями и знакомыми, работающими в области ИТ, не раз приходилось слышать заявление, что Wi-Fi подходит только для сетей масштаба квартиры или небольшого офиса. В качестве аргументов приводились малая дальность, зависимость от погодных условий, ненадежность оборудования. Примерно такое же мнение бытует о том, что для провайдерских сетей не подходит платформа Windows. Аргументы: высокая ресурсоемкость, ненадежность и вообще неспособность работать в качестве системы биллинга.
Александр
by WildHunter http://airnet.sytes.net
А так ли это? Этот вопрос нас всерьез заинтересовал и подтолкнул к попытке создания беспроводной сети как раз на базе Wi-Fi и Windows. Оговорюсь, что некоторый опыт создания беспроводных сетей у нас уже был, правда, немного другого назначения – корпоративных.
Начали мы естественно с постановки самим себе техзадания:
- Сетевая технология WiFi IEEE 802.11b/g, возможно в будущем 802.11a и 802.11n википедия
- Серверы на базе Windows Server. В качестве основной ОС был выбран Windows Server 2003, как достаточно надежная и неприхотливая система, при этом обеспечивающая нужный функционал википедия
- Максимальная простота развертывания, эксплуатации и администрирования сети.
- Минимальные затраты, поскольку проект некоммерческий и финансирования со стороны не будет, придется обходиться собственными силами и средствами.
- Надежность, производительность и пропускная способность, достаточные для обслуживания городского микрорайона.
Выбор оборудования
Основательно изучив рынок предложений недорогого Wi-Fi оборудования, мы остановили свой выбор на нескольких моделях точек доступа (ТД) от D-Link: DWL-2100AP, DAP-1150 и DAP-1160 http://www.d-link.ru. Основными причинами выбора именно этих точек стали их приемлемая цена, накопленный в России и на Украине большой опыт их эксплуатации, а также наличие большого количества альтернативных прошивок, как от различных производителей оборудования, так и open-source.
Для тестирования было закуплено несколько экземпляров указанных выше точек доступа, а также различных антенн к ним. Началось тестирование в различных режимах, на разных расстояниях, с различными антеннами и прошивками. От «родных» прошивок мы отказались практически сразу, поскольку они рассчитаны как раз на применение в домашних или условиях небольшого офиса, не позволяют менять многие важные параметры (ACK timeout, мощность передатчика, чувствительность приемника и т.д.), а также практически не обеспечивают возможности мониторинга беспроводных соединений.
Точки DWL-2100AP оказались хороши для построения мостов на большие расстояния (до 50 км), но капризными в эксплуатации и несовместимыми со многими другими моделями Wi-Fi устройств. Также у них обнаружилась неприятная проблема: довольно часто при большой нагрузке «слетали» прошивки, а их восстановление оказалось довольно непростой процедурой. В итоге DWL-2100AP была признана нами годной к применению только для организации мостов. Хотя вполне возможно, что нам просто достались неудачные экземпляры.
DAP-1150 – очень простое и надежное устройство, тем не менее отвечающее всем основным критериям хотспота. А с немного доработанной прошивкой от Conceptronic http://www.conceptronic.net эта точка стала практически полностью соответствовать нашим требованиям.
Рис. 1. Точка доступа DAP-1150
Основные характеристики DAP-1150 с прошивкой Conceptronic:
- Стандарты: 802.11b/g, 802.3/802.3u 10Base- T/100Base-TX Ethernet, ANSI/IEEE 802.3 NWay auto-negotiation.
- Интерфейсы: 802.11b/g беспроводная LAN, 1 порт 10/100Base-TX Ethernet LAN
- Диапазон частот: 2.4 – 2.4835 ГГц
- Количество каналов: 13 (ETSI)
- Схемы модуляции:
802.11b: DQPSK, DBPSK, DSSS, CCK
802.11g: BPSK, QPSK, 16QAM, 64QAM, OFDM - Режимы работы: Station – Ad Hoc, Station – Infrastructure, AP, AP Bridge – Point to Point, AP Bridge – Point to MultiPoint, AP Bridge – WDS, Universal Repeater.
- Скорость передачи данных:
802.11g: 6, 9, 12, 18, 24, 36, 48, 54 Мбит/с
802.11b: 1, 2, 5.5, 11 Мбит/с - Чувствительность приемника: до -100dBm
- Выходная мощность передатчика: 20dBm
- Безопасность: WEP, WPA/WPA2, фильтрация МАС-адресов, SSID broadcast disable.
- Дополнительные возможности: IAPP, встроенный Radius-сервер.
DAP-1160 с прошивкой AProuter http://aprouter.com.br превратилась в довольно серьезное устройство с широким функционалом, включающим в себя массу полезных возможностей, от контроля качества WDS- соединений википедия до многофункционального шейпера википедия.
Рис. 2. Точка доступа DAP-1160
Основные характеристики DAP-1160 с прошивкой AProuter:
- Стандарты: 802.11b/g, 802.3/802.3u 10Base- T/100Base-TX Ethernet, ANSI/IEEE 802.3 NWay auto-negotiation.
- Интерфейсы: 802.11b/g беспроводная LAN, 2 порта 10/100Base-TX Ethernet LAN
- Диапазон частот: 2.4 – 2.4835 ГГц
- Количество каналов: 13 (ETSI)
- Схемы модуляции:
802.11b: DQPSK, DBPSK, DSSS, CCK
802.11g: BPSK, QPSK, 16QAM, 64QAM, OFDM - Режимы работы роутера: WISP Client, Bridge, Gateway, Router (WAN Ethernet), Router (WAN Wireless).
- Режимы работы Wireless: Wireless Client, AP, WDS+AP, WDS-Bridge.
- Скорость передачи данных:
802.11g: 6, 9, 12, 18, 24, 36, 48, 54 Мбит/с
802.11b: 1, 2, 5.5, 11 Мбит/с - Чувствительность приемника: до -100dBm
- Выходная мощность передатчика: 20dBm
- Безопасность: WEP, WPA/WPA2, фильтрация МАС-адресов, SSID broadcast disable.
- Дополнительные возможности: IP Aliases, IAPP, Block Relay, Firewall, Traffic Control (шейпер), DDNS, Watchdog.
Антенны ANT24-0700C производства D-Link были выбраны по наилучшему показателю цена/качество в своем классе и из-за небольших размеров:
Рис. 3. Антенна ANT24-0700C
Основные характеристики ANT24-0700C:
- Диапазон частот: 2,4-2,5ГГц
- Сопротивление: 50 Ом
- VSWR: 1.92 (макс.)
- Максимальное усиление: 7dBi
- Допустимая мощность: 1 Вт
- Диаграмма направленности в вертикальной плоскости (Вектор Е): 24 градуса.
- Диаграмма направленности в горизонтальной плоскости (Вектор Н): 360 градусов.
- Разъем: Reverse SMA «мама» (встроенный в антенну), переходник с RP-SMA на RP-TNC (внешний).
- Материал корпуса: ABS, ABS+PC
- Рабочая температура: От -20 до 65 градусов.
Построение сети
После завершения тестирования мы приступили к созданию собственно сети. В качестве базовой была выбрана классическая топология «звезда», центральной точкой которой стала DAP-1160 в режиме Bridge WDS, а «лучами» DAP-1150 в режиме WDS + AP. Использование технологии WDS позволяет получить на каждой точке доступа скорость передачи данных на уровне 1.2-1.4 Мбайт/с, максимальная скорость у клиентов составляет порядка 550-600 кБайт/с. Реальная скорость передачи данных зависит от типа клиентского оборудования и качества беспроводного соединения клиент-ТД, а также от количества клиентов и общей загрузки сети.
Рис. 4. Общая схема сегмента сети
Покрытие каждой ТД составляет (в радиусе, значения указаны при наличии прямой видимости или незначительных препятствий, например деревьев):
- Мобильные устройства (смартфоны, КПК, PSP и т.п.) – до 200м
- Ноутбуки, нетбуки, USB-устройства со встроенными антеннами – до 300м
- Ноутбуки, USB-устройства с внешними (или внутренними дипольными) антеннами – до 1500м
- ТД в режиме клиента с направленными антеннами – до 10км
Установка точек доступа
Естественно, что мы старались устанавливать ТД как можно выше, но не всегда это удается. Кроме того, при установке ТД на самую высокую мачту в округе, есть риск получить прямое попадание в нее молнии, от которого не спасет никакая грозозащита. Поэтому второй фактор, который мы старались учитывать – наличие поблизости громоотводов или более высоких мачт.
Все наши хотспоты стоят на мачтах высотой 4-6 метров, которые расположены на крышах зданий высотой в 5-6 этажей. Рядом есть небольшой массив из 9-этажных зданий, но нам не удалось договориться с местным ОСМД*.
Питание на точки подается по витой паре, обычно из квартир наших клиентов (чтобы избежать бюрократии с ЖЕКами и ОСМД), по этому же кабелю клиенты входят в сеть. Взаимовыгодное сотрудничество: мы получаем место для установки и запитки точки, а клиенты получают VIP-доступ к сети
* Комментарий автора. Объединение совладельцев многоквартирного дома (ОСМД). Юридическое лицо, созданное владельцами для содействия использованию их собственного имущества и управления, содержания и использования неделимого и общего имущества.
Качество
На следующем скриншоте показаны характеристики соединения с ТД на расстоянии ~1000 метров при прямой видимости (см. рисунок 5):
Рис. 5. Качественные характеристики соединения в Atheros Client Utility
ТД: DAP-1150, мощность 20dBm, антенна штыревая 7dBi. Клиент: ноутбук Asus X51RL, WiFi-плата Atheros AR2425, антенна встроенная дипольная 4dBi.
Линк стабильный, текущая скорость линка «гуляет» в пределах 18-36 Мбит/с, это нормально. Скорость загрузки файла с сервера сети держится в пределах 400-500 Кбайт/с. Может показаться, что при средней скорости линка в 24 мегабита это немного, но нужно учитывать особенности технологии Wi-Fi, в которой мегабиты совсем другие, чем в кабельных сетях. Кроме того, режим WDS также вносит свои коррективы, и не в большую сторону. Если вы ожидаете от Wi-Fi волоконно-оптических скоростей, то вам действительно лучше посмотреть в сторону оптики. А Wi-Fi это простая, недорогая, удобная и достаточно качественная связь для всех.
Как это ни странно, но на качество связи почти не влияют погодные условия. Если линк стабилен в хорошую погоду, то он таким и останется в дождь, снег или туман. Возможно, немного снизится скорость, но связь будет. Наш опыт практической эксплуатации показывает следующие результаты: в дождь (даже сильный) или снег уровень сигнала между ТД снижается в среднем всего на 1-4 dBm, туман никакого заметного влияния вообще не оказывает. Замечу, что все точки стоят на примерно одинаковом расстоянии от центральной, которое составляет 800-1200 метров. Для Wi-Fi при прямой видимости это расстояние несерьезное. Так что мнение о влиянии погоды на Wi-Fi сильно преувеличено. Влияние погодных условий становится заметным только на больших расстояниях, от 5 км и более. А вот что действительно отрицательно влияет**: преграды, помехи в эфире, избыточная мощность радиоустройств. Данные факторы обсуждались и не раз, например на http://www.lan23.ru, поэтому подробно мы их здесь рассматривать не будем.
** Комментарий автора. В последнее время технология Wi-Fi в наших краях сделала явный рывок, но непонятно, вперед, назад или «налево». В эфире полный бардак, огромное количество различных устройств, большинство из которых настроены как попало или вообще не настроены. Все это снижает качество связи, а если так и будет продолжаться дальше – связь вообще станет невозможной… Вот какая картина открывается с некоторых наших хотспотов:
Каждая ТД нормально выдерживает до 20 одновременно работающих клиентов, если нет «тяжелого» трафика, в первую очередь P2P. Если есть, то даже один клиент в состоянии через минуту сделать для всех остальных вход в сеть недоступным, а минуты через 3-5 отправить точку на перезагрузку. ТД почти не критичны к скорости или общему объему трафика, но очень критичны к количеству подключений. Это не значит, что использовать «тяжелый» трафик невозможно. Вполне возможно, если предпринять определенные меры для защиты сети от перегрузок. К таким методам защиты, например, относятся ограничение количества подключений на хост, работа по VPN, а также использование адаптивных шейперов и QoS. Но об этом поговорим в другой раз, так как это более относится к серверным технологиям, а не к Wi- Fi.
Несколько слов о клиентских устройствах
Сейчас на рынке представлена масса самых разнообразных устройств 802.11b/g/n. Из них довольно трудно, но возможно выбрать оптимальный*** вариант. Некоторые устройства, например USB-брелки со встроенной антенной, рассчитаны на работу только внутри помещения и обладают очень ограниченным радиусом действия. Даже одна стена или дерево под окном, для них уже неодолимая преграда.
Другой класс – это устройства с внешними антеннами. Даже со штатными антеннами они показывают неплохую дальность при прямой видимости, а при установке хорошей антенны вполне могут работать на расстояниях, измеряемых километрами. Поэтому при выборе Wi-Fi устройства стоит обратить внимание не только на дизайн, размеры и цену, но в первую очередь – на технические характеристики.
При покупке ноутбука, КПК или любого другого устройства, оснащенного встроенным Wi-Fi, также обязательно интересуйтесь характеристиками Wi- Fi платы, типом и характеристиками встроенной антенны. Зачастую, встроенные платы подходят только для связи внутри комнаты или на расстояниях до 100 метров на открытой местности. Хотя есть и большое количество устройств, оснащенных качественным Wi-Fi и вполне способных поддерживать связь на приличных расстояниях.
Основные характеристики Wi-Fi устройств
- Стандарты, поддерживаемые устройством. От этого зависит универсальность и максимальная скорость передачи данных. В настоящее время в Европе поддерживаются следующие стандарты:
- 802.11b (максимальная скорость 11 Мбит/с)
- 802.11g (максимальная скорость 54 Мбит/с)
- 802.11n (максимальная скорость 150/300 Мбит/с)
- Мощность передатчика и чувствительность приемника. Не стоит чрезмерно увлекаться мощностью, слишком мощный сигнал в городских условиях скорее вреден, так как вызывает многократные отражения и наложения, а также создает массу помех. Да и для здоровья он не очень полезен. На наш взгляд оптимальные значения составляют до 100 мВт (20 dBm) мощности и -95 dBm чувствительности.
- Возможность подключения внешней антенны и характеристики штатной. «Главная часть любого радиоустройства – антенна», это вам скажет любой специалист по любому виду радиосвязи. К Wi-Fi это тоже относится в полной мере. Для нормальной работы (приличной дальности и скорости) любого Wi-Fi-устройства необходима антенна с коэффициентом усиления не менее 4dBi.
- Функционал устройства. К этому относится все, что устройство умеет делать и насколько удобно его использовать. По этому критерию выбор огромный, от самых простых до сложнейших устройств, которые «умнее» вашего компьютера. Главное – достаточно четко представлять, чего вы хотите и сколько вы согласны за это заплатить.
*** Комментарий редакции. Многие задаются вопросом: «Как увеличить дальность связи?». Перво-наперво, при выборе WLAN-аппарата, обратите внимание на то, чтобы выходная мощность была как можно ближе к разрешенной 20 dB. Следующим решающим фактором является чувствительность. У лучших современых аппаратов она находится на уровне -97 dB. Чем выше чувствительность к слабым сигналам, тем выше дальность. Но это палка о двух концах, так как мы не учитываем при этом помеховую обстановку вокруг.
Как влияют эти величины на дальность связи? К примеру, аппарат с мощностью в 20 dB сможет обеспечить в два раза большую дальность приема по сравнению с 14 dB, т.е. разница в 6 dB дает двойной выигрыш. Если к этому прибавить, что аппарат с чувствительностью -97 dB, позволяет получить выигрыш в 4 раза по сравнению с аппаратом, у которого чувствительность равна -76 dB, то общий выигрыш будет 8-ми кратным.
Заключение
Это основные характеристики, но существует еще масса различных тонкостей, специфических моментов и технических особенностей. Рассказать здесь обо всех нереально, поэтому выбор оборудования – совсем непростое дело, в котором не помешает консультация специалиста. Если вы, конечно, сами не являетесь таковым
Продолжение следует…
Ресурсы
- Сетевая аутентификация на практике http://www.citforum.ru/nets/articles/authentication
- Крупнейший и самый активный сайт рунета по Wi-Fi http://www.lan23.ru/index.html
- Антенны, много антен… хороших и разных http://radiowolna.narod.ru
Статья из пятого выпуска журнала “ПРОграммист”.
Скачать этот номер можно по ссылке.
Ознакомиться со всеми номерами журнала.
Обсудить на форуме — Беспроводная сеть масштаба микрорайона. Часть 1
Облако меток
css реестр ассемблер timer SaveToFile ShellExecute программы массив советы word MySQL SQL ListView pos random компоненты дата LoadFromFile form база данных сеть html php RichEdit indy строки Win Api tstringlist Image мысли макросы Edit ListBox office C/C++ memo графика StringGrid canvas поиск файл Pascal форма Файлы интернет Microsoft Office Excel excel winapi журнал ПРОграммист DelphiКупить рекламу на сайте за 1000 руб
пишите сюда - alarforum@yandex.ru
Да и по любым другим вопросам пишите на почту
пеллетные котлы
Пеллетный котел Emtas
Наши форумы по программированию:
- Форум Web программирование (веб)
- Delphi форумы
- Форумы C (Си)
- Форум .NET Frameworks (точка нет фреймворки)
- Форум Java (джава)
- Форум низкоуровневое программирование
- Форум VBA (вба)
- Форум OpenGL
- Форум DirectX
- Форум CAD проектирование
- Форум по операционным системам
- Форум Software (Софт)
- Форум Hardware (Компьютерное железо)