Пт, 29 Мар 2024
Механоиды 3
Приветствую Вас Гость | RSS
Главная страница | Регистрация | Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум "Механоиды 3" » Рабочий раздел. » Программирование » Наши классы :)
Наши классы :)
YandersenДата: Вс, 26 Апр 2009, 20:21 | Сообщение # 1
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Предлагаю выкладывать тут написанные нами (или спёртые откуда-нить) библиотеки, классы, функции и т.п. кодовую байду, готовую к общему и совместному использованию. Не забудьте писать подробную документацию, чтобы Вашими трудами могли пользоваться другие люди без надобности копаться и разбираться в написанном Вами коде. wink

Обсуждение в другой, соответствующей классу теме.


[Беженец со Скаев]
 
YandersenДата: Вс, 26 Апр 2009, 21:22 | Сообщение # 2
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Написал класс, включающий в себя функции по инициализации OpenGL в виндусовом объекте - окне / панели / кнопке / ...; изменению размеров 3D-окна, установке настроек OpenGL и др.
Как пользоваться
Класс описан в заголовочном файле (см. в прикреплении) "Handler3D.h", так что сперва нужно подключить его:

#include "Handler3D.h"

Один (а больше и не нужно) экземпляр класса уже объявлен в заголовочном файле "Handler3D.h", и называется он "Window3D". Так что обращаться ко встроенным в него функциям нужно так: "Window3D.<И_название_функции>"
Затем нужно инициализировать OpenGL (но не раньше, чем инициализируется само окно приложения, в котором будет инициализирована OpenGLя!). Необходимая функция - "InitOpenGL". Она требует такие аргументы:
1) "void *DrawingObjectHandle" - это handler окна/панели/..., в котором будет рисоваться 3D. Я работаю в Borland Builder 6, и если, к примеру, название формы у меня Form1, то её handler находится прямо тут: "Form1->Handler". Аналогично находится и handler класса панели (TPanel).
2,3) "int ViewportWidth", "int ViewportHeight" - ширина и высота окна/панели/..., в котором будет рисоваться 3D.
К примеру:

Window3D.InitOpenGL(Form1->Handle, Form1->ClientWidth, Form1->ClientHeight);

Примечание: отметьте, что поскольку окно имеет бордюры толщиной в несколько пикселов, правильно будет использовать параметры "Form1->ClientWidth", "Form1->ClientHeight", а не "Form1->Width", "Form1->Height".
После того, как контекст OpenGL создан, можно пользоваться всеми её функциями. Так что время настраивания параметров OpenGL. Вы можете сделать это сами, либо довериться уже составленному мной списку необходимых настроек, запускаемых функцией "SetupMySettings":

Window3D.SetupMySettings();

В любом случае, полезно ознакомиться, что там происходит. Функция находится ближе к концу файла.
Если хотите установить параметры перспективной проекции, пользуйтесь "SetupPerspective". Требует 3 аргумента:
1) "float ViewAngle" - угол зрения (как "ширина обзора", что ли?..). По-умолчанию он выставлен: 45 градусов.
2,3) "float MinViewDistance", "float MaxViewDistance" определяют расстояния до ближней и до дальней плоскостей отсечения. По-умолчанию я выставил 0.1 и 1000.
Пример (установка тех же параметров, что и так стоят по-умолчанию):

Window3D.SetupPerspective(45, 0.1, 1000);

При изменении размеров объекта c 3D нужно вызывать ResizeViewport, чтобы соответствующим образом изменить размеры области, в которой выводится изображение:

Window3D.ResizeViewport(Form1->ClientWidth, Form1->ClientHeight);

Ну а при рисовке кадра удобно пользоваться FrameBegin (для очистки буфферов и обнуления матрицы модельной трансформации) и FrameFinish (переключает буффера кадра, так что отрисованная в скрытом буффере сцена выводится на экран).
К примеру:
void DrawScene()
{
Window3D.FrameBegin();

gluLookAt(0,0,1, 0,0,0, 0,1,0);

glBegin(GL_TRIANGLES);
glVertex3f(0,1,0);
glVertex3f(-1,-1,0);
glVertex3f(1,-1,0);
glEnd();

Window3D.FrameFinish();
}

Прикрепления: Handler3D.h (7.7 Kb)


[Беженец со Скаев]

Сообщение отредактировал Yandersen - Вс, 26 Апр 2009, 21:27
 
YandersenДата: Ср, 20 Май 2009, 14:23 | Сообщение # 3
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Класс вектора
Возможно, написание класса вектора - тревиальная задача, но я решил отличиться переописанием операторов С++, таких как "+", "-", "*" и т.д., что позволило производить сложение, вычитание, умножение, сравнения и множество других векторных операций используя привычный школьнику синтаксис. Типа, если a,b,c - векторы, то можно писать:
c=a*b;
c=a+b;
c=a-b;
bool eq = a==b;
И т.д. Полная документация (даже с картинками! biggrin ) по классу и сам заголовочный файл, содержащий описание класса - в прикреплении.
Прикрепления: Vector.doc (107.5 Kb) · Vector.h (21.2 Kb)


[Беженец со Скаев]

Сообщение отредактировал Yandersen - Ср, 20 Май 2009, 14:24
 
YandersenДата: Ср, 20 Май 2009, 14:28 | Сообщение # 4
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Класс секундомера TStopwatch (точнее, милисекундомера)
Простейший класс для отсчитывания милисекунд (базирующийся на системных тиках). Я к примеру, его юзаю для сравнения времени отработки функций (которые вызываю миллионы раз для теста). Экземпяр класса имеет размер в 4 байта и в интерфейсе имеет всего 2 функции - Start и Stop.
Как пользоваться:
1) Подключите заголовочный файл:

#include "Stopwatch.h"

2) Создайте экземпляр(ы) класса:

TStopwatch Stopwatch1;

3) Для запуска секундомера вызовите

Stopwatch1.Start();

4) Чтобы узнать количество милисекунд, прошедшее со времени запуска секундомера:

long ms = Stopwatch1.Stop();

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

Прикрепления: Stopwatch.h (0.7 Kb)


[Беженец со Скаев]

Сообщение отредактировал Yandersen - Ср, 20 Май 2009, 14:28
 
PA3UJIbДата: Пн, 22 Июн 2009, 16:29 | Сообщение # 5
1 Поколение
Группа: Основной состав
Сообщений: 105
Замечания: 0%
Статус: Offline
Ну, вот я и написал
Quote
функцию которая ищет файлы в требуемой директории с требуемым расширением и записывает пути файлов в массив.
. Бета версия этой функции Вам и предлагается.
Прикрепления: getFiles.h (2.0 Kb)
 
YandersenДата: Пн, 22 Июн 2009, 23:42 | Сообщение # 6
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Класс TArray (шаблон класса-контейнера)

Динамический массив с удобным интерфейсом.
Заголовочный файл и полная документация в прикреплении. Краткая памятка по пользованию:

//--------------------------------------------------
Поместите в папку проекта файл Arrays.h и подключите его:

#include "Arrays.h"

Создание требует указания класса элементов, из которых массив состоит (пускай это будет double):

TArray<double> MyArray; //Создать пустой массив
TArray<double> MyArray(3); //Создать массив, содержащий три элемента
TArray<double> MyArray = MyArray.ItemToRange(1.0) + 2.0 + 3.0 + 4.0; //Создать массив, перечисляя все его элементы

!!! Важно: если перечисление членов начинается с "голого" элемента, применяйте к нему функцию ItemToRange, как
показано выше.

Доступ к элементам массива:

MyArray[2] = 3.0; //Модифицировать элемент с индексом 2 (третий по счёту)
MyArray.LastItem() = 3.0; //Модифицировать последний элемент массива
double d3 = MyArray[2]; //Прочитать значение элемента под индексом 2

Узнать текущее количество элементов в массиве:

unsigned int Quantity = MyArray.TotalItems();

Узнать текущий адрес массива элементов (при изменении длины массива он всегда меняется):

double* d = MyArray.ItemsAddress();
или
double* d = &MyArray[0]; //Менее предпочтительно в плане быстродействия

Посчитать количество байт, занимаемое всеми элементами массива (размер массива):

unsigned int SizeInBytes = MyArray.ByteSize();

Изменить количество элементов массива:

MyArray.ResizeTo(4); //Теперь массив MyArray содержит 4 элемента
MyArray.ResizeBy(2); //Массив MyArray расширен на 2 элемента
MyArray.ResizeBy(-3); //Массив MyArray урезан на 3 элемента

Нюанс: конструкторы объектов не вызываются (используется функция malloc, а не оператор new), поэтому свежесозданные элементы содержат беспорядочные данные.

Взять несколько (пускай, 3) подряд идущих элементов, начинающихся с элемента с указанным индексом (1, к примеру):

TArray<double> MyArray = MyArray.ItemToRange(1.0) + 2.0 + 3.0 + 4.0 + 5.0;
TArray<double> NewArray = MyArray(1,3); //NewArray будет выглядеть как: {2.0, 3.0, 4.0}

Если не давать второй аргумент (не указывать количество элементов), будут взяты все элементы, идущие после указанного (включая его):

NewArray = MyArray(1); //NewArray теперь будет выглядеть как: {2.0, 3.0, 4.0, 5.0}

Копирование отрезков массивов:

TArray<double> a1 = a1.ItemToRange(1.0) + 2.0 + 3.0 + 4.0 + 5.0 + 6,0;
TArray<double> a2 = a2.ItemToRange(7.0) + 8.0 + 9.0 + 10.0 + 11.0;
a2(1,3) = a1(2,3); //Теперь a2 выглядит так: {7.0, 3.0, 4.0, 5.0, 11.0}

Копирование собственных отрезков допустимо только если они не имеют общих элементов:

a1(0,3) = a1(3,3); //ОК
a1(0,3) = a1(2,3); //Результат операции непредсказуем - отрезки имеют общий элемент (индекс которого 2)

Добавление в массив новых элементов, массивов или отрезков массивов выполняется с помощью оператора "+=":

TArray<double> MyArray = MyArray.ItemToRange(1.0) + 2.0 + 3.0;
TArray<double> AddArray1 = AddArray1.ItemToRange(4.0) + 5.0 + 6.0 + 7.0 + 8.0 + 9.0;
TArray<double> AddArray2 = AddArray2.ItemToRange(8.0) + 9.0 + 10.0;
MyArray += 4.0; //Результат: {1.0, 2.0, 3.0, 4.0}
MyArray += AddArray1(1,3); //Результат: {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}
MyArray += AddArray2; //Результат: {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0}
три строки кода выше могли бы легко быть заменены таким выражением:
MyArray += MyArray1.ItemToRange(4.0) + AddArray1(1,3) + AddArray2;
или
MyArray = MyArray + 4.0 + AddArray1(1,3) + AddArray2;

Дополнительно ещё введены функции Cut (вырезать) и Insert (вставить):

TArray<double> MyArray1 = MyArray1.ItemToRange(1.0) + 2.0 + 3.0 + 4.0 + 5.0;
TArray<double> MyArray2 = MyArray1;
MyArray1.Cut(2); //Вырезать третий элемент массива (результат: { 1.0, 2.0, 4.0, 5.0 })
MyArray2.Cut(1,3); //Вырезать три элемента начиная со второго (результат: { 1.0, 5.0 })

TArray<double> MyArray3 = MyArray3.ItemToRange(1.0) + 2.0 + 3.0;
TArray<double> MyArray4 = MyArray3;
TArray<double> MyArray5 = MyArray3;

TArray<double> InsArr = InsArr.ItemToRange(4.0) + 5.0 + 6.0 + 7.0 + 8.0;
double d = 9.0;

MyArray3.Insert(2, d); //Результат: { 1.0, 2.0, 9.0, 3.0 }
//Аналогичный результат: MyArray3 = MyArray3(0,2) + d + MyArray3(3)
MyArray4.Insert(2, InsArr); //Результат: { 1.0, 2.0, 4.0, 5.0, 6.0, 7.0, 8.0, 3.0 }
//Аналогичный результат: MyArray4 = MyArray4(0,2) + InsArr + MyArray4(3)
MyArray3.Insert(2, MyArray3.ItemToRange(d) + MyArray3 + MyArray3(1,2)); //...
//...вставка собственных фрагментов допускается

Прикрепления: 9967406.h (27.5 Kb) · 6535037.doc (87.5 Kb)


[Беженец со Скаев]
 
YandersenДата: Чт, 02 Июл 2009, 14:37 | Сообщение # 7
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Класс TTexture

Написал класс для загрузки текстуры из *.bmp файлов, использующий лишь gl.h, glu.h, stlib.h, stdio.h заголовки (библиотека glut не нужна).
Поскольку формат .bmp я счёл убогим, то ввёл в класс TTexture дополнительные функции по работе с простым и, ИМХО, универсальным .tex форматом (конвертирование *.bmp в *.tex, загрузка из *.tex). Вот его описание:
4 byte: ширина картики (unsigned int), "width"
4 byte: высота картики (unsigned int), "height"
(n * 4) bytes: пикселы в формате RGBA, по 4 байта на каждый пиксел (unsigned char[4]); картинка записана ряд за рядом. Размер каждого ряда, соответственно, width*4 bytes, а всей картинки - width*height*4 bytes.

Как пользоваться:

0) Подключите заголовок:

#include "Textures.h"

1) Создайте экземпляр класса (его размер - всего 4 байта, определяемый одной переменной, в него входящей - символическое имя текстуры (unsigned int):

TTexture MyTex;

2) Переконвертировать *.bmp в *.tex можно когда угодно, при этом *.tex файл появится в той же папке и будет иметь то же имя, что и *.bmp файл:

MyTex.BMPtoTEX("image.bmp");

3) Загрузить картинку в видеопамять можно, по понятным причинам, лишь после инициализации окна OpenGL. Поддерживаемые форматы - стандартный 24-битный bitmap (*.bmp) и файл текстуры (*.tex):

MyTex.LoadFromBMP("image.bmp");
или
MyTex.LoadFromTEX("image.tex");

4) Текстуру можно загрузить и из смешанного файла, содержащего другие данные (к примеру, данные формы модели). Часть файла, содержащего текстуру, должна быть структурирована так же, как содержимое *.tex файла (тоже 4 байта - ширина картинки, затем 4 байта - высота, и потом требуемое количество пикселов, 4 байта на каждый, ряд за рядом). К примеру, если в файл images.tex последовательно записать 2 текстуры, то загрузить их можно будет так:

TTexture Tex1, Tex2;
FILE* FileHandler = fopen("images.tex","rb");
Tex1.LoadFromChunk(FileHandler);
Tex2.LoadFromChunk(FileHandler);
fclose(FileHandler);

5) Загруженная только что тестура будет активной. Загружается она как двумерная (GL_TEXTURE_2D).
Чтобы выбрать данную текстуру в качестве текущей в любой момент времени, используйте Bind():

MyTex.Bind(); //Аналогично glBindTexture(GL_TEXTURE_2D, ...);

6) Чтобы освободить текстуру в видеопамяти, можно явно вызвать деструктор класса:

~MyTex();

Усё. smile

А как ты вообще это делаешь? Я намекну:
glBindTexture(GL_TEXTURE_2D);
glTexParameter или как там.......
Ну так вот, мой класс просто не делает настройку текстуры за тебя - его задача лишь прочитать текстуру и загрузить в видеопамять (юзается gluBuild2DMipmaps). Учти, настраивается же текстура загруженная, а не в файле! Так что пиши так:

TTexture MyTex; //Создай экземпляр класса
MyTex.LoadFromBMP("image.bmp"); //Выбери файл для загрузки
MyTex.Bind(); //Выбери данную текстуру текущей
...и настраивай её на здоровье!

Прикрепления: Textures.h (7.8 Kb)


[Беженец со Скаев]
 
YandersenДата: Сб, 25 Июл 2009, 01:17 | Сообщение # 8
1 Поколение
Группа: Доверенные
Сообщений: 196
Замечания: 0%
Статус: Offline
Класс TTexture (v.1.2)

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

Конструктор класса по-умолчанию присваивает имя текстуры "0", но можно явно задать указанное (например, ранее загруженной текстуры или созданной вручную):
inline TTexture(unsigned int TextureName=0):Name(TextureName){}

//Деструктор. Будьте осторожны: при уничтожении класса автоматически-вызываемый деструктор ещё и удаляет соответствующую текстуру из видеопамяти. Если это необходимо предотвратить, перед уничтожением класса присваивайте нулевое имя текстуры.
inline ~TTexture(){if(Name)glDeleteTextures(1,&Name);}

Конвертирует *.bmp файл в *.tex файл:
bool BMPtoTEX(const char* FilePath);

Выдирает картинку из *.bmp файла и добавляет её в указанный файл (в виде TEX-отрезка):
bool BMPtoChunk(const char* BMPFilePath, FILE* CurrentlyOpenedFile);

Выдирает картинку из *.tex файла и добавляет её в указанный файл (в виде TEX-отрезка):
bool TEXtoChunk(const char* TEXFilePath, FILE* CurrentlyOpenedFile);

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

Загружает в видеопамять текстуру из *.bmp файла:
bool LoadFromBMP(const char* FilePath);

Загружает в видеопамять текстуру из *.tex файла:
bool LoadFromTEX(const char* FilePath);

Выдирает из видеопамяти картинку текстуры и сохраняет её в *.tex файл:
bool SaveToTEX(const char* FilePath);

Загружает в видеопамять текстуру из TEX-отрезка файла:
void LoadFromChunk(FILE* CurrentlyOpenedFile);

Выдирает из видеопамяти картинку текстуры и добавляет её в указанный файл (в виде TEX-отрезка):
void SaveToChunk(FILE* CurrentlyOpenedFile);

Просто пропускает TEX-отрезок файла, не загружая текстуру из него:
void PassChunk(FILE* CurrentlyOpenedFile);

Макрос для выбора данной текстуры в качестве текущей 2D-текстуры (в фигурных скобках тут же для наглядности - тело макроса (то, чем заменится при компилляции)):
inline void Bind(){ glBindTexture(GL_TEXTURE_2D,Name); }

Оператор "=" описан для явного присвоения текстуре другого имени (имя текстуры в OpenGL в формате unsigned int):
inline void operator = (unsigned int TextureName){ Name=TextureName; }

Оператор "==" для проверки (сравнения на эквивалентность) номерного имени текстуры:
inline bool operator == (unsigned int TextureName){ return Name==TextureName; }

З.Ы.: номерное имя текстуры (unsigned int Name) хранится в классе и недоступно для прямого чтения-записи.
Пока что всё.

Прикрепления: 3887884.h (15.1 Kb)


[Беженец со Скаев]

Сообщение отредактировал Yandersen - Сб, 25 Июл 2009, 01:19
 
Форум "Механоиды 3" » Рабочий раздел. » Программирование » Наши классы :)
  • Страница 1 из 1
  • 1
Поиск:


Хостинг от uCoz