Урок Инициализация в Windows я начинаю это пособие непосредственного с кода, разбитого на секции, каждая из которых будет подробно комментироваться. Первое, что вы должны сделать это создать проект в Visual C++



страница11/27
Дата17.11.2018
Размер7.85 Mb.
ТипУрок
1   ...   7   8   9   10   11   12   13   14   ...   27
glPrint() изменился не значительно. Единственное отличие от урока об текстурных шрифтах то, что я добавил возможность печатать значение переменных. Единственная причина, по которой я привожу этот раздел кода это та, что Вы можете при этом увидеть изменения. Вызов функции печати позиционирует текст в позиции x и y, которые Вы задаете. Вы можете выбрать один из 2 наборов символов, и значение переменных будет выведено на экран. Это позволит нам отображать текущий уровень и стадию.

 

Заметьте, что я разрешаю наложение текстуры, сбрасываю матрицу вид, и затем уставливаю в необходимую x / y позицию. Также заметьте, что, если выбран набор символов 0, шрифт укрупнен по ширине в полтора раз, и в два раза по высоте от первоначального размера. Я сделал это для того чтобы написать заголовок игры большими буквами. После того, как текст выведен, я отключаю наложение текстуры.

 

GLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...) // Печать



{

  char    text[256];          // Место для строки

  va_list    ap;              // Ссылка на список аргументов

 

  if (fmt == NULL)            // Если нет текста



    return;                   // то выходим

 

  va_start(ap, fmt);          // Разбор строки из значений



      vsprintf(text, fmt, ap);// и конвертирование символов в фактические числа

  va_end(ap);                 // Результат в текст

 

  if (set>1)                  // Если выбран не верный набор символов?



  {

    set=1;                    // Если так, то выбрать набор 1 (Курсив)

  }

  glEnable(GL_TEXTURE_2D);    // Разрешить наложение текстуры



  glLoadIdentity();           // Сбросить матрицу просмотра вида

  glTranslated(x,y,0);        // Позиция текста (0,0 – Низ Лево)

  glListBase(base-32+(128*set)); // Выбор набора символов (0 или 1)

 

  if (set==0)                 // Если 0 используем укрупненный фонт



  {

    glScalef(1.5f,2.0f,1.0f); // Ширина и Высота укрупненного шрифта

  }

 

  glCallLists(strlen(text),GL_UNSIGNED_BYTE, text); // Вывод текста на экран



  glDisable(GL_TEXTURE_2D);   // Запрет наложения текстуры

}

 



Код изменения размеров НОВЫЙ :). Вместо использования перспективной проекции я использую ортографическую проекцию для этого урока. Это означает, что объекты не уменьшаются, когда они удаляются от наблюдателя. Ось Z не используется в этом уроке.

 

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



 

Затем мы выбираем матрицу проецирования и сбросим ее.

 

Сразу же после того, как мы сбрасываем матрицу проецирования, мы устанавливаем ортогональное проецирование. Я объясню эту команду подробнее.



 

Первый параметр (0.0f) - значение, которое мы хотим иметь на крайней левой стороне экрана. Вы хотели бы узнать, как использовать реальные значения пикселей, а не трехмерные координаты. Поэтому вместо использования отрицательного числа для левого края, я задал значение 0. Второй параметр - значение для крайней правой стороны экрана. Если наше окно - 640x480, значение по ширине будет 640. Поэтому крайняя правая сторона экрана равна 640. Поэтому наш экран по оси X изменяется от 0 до 640.

 

Третий параметр (высота) обычно был равен отрицательному числу, задающему нижний край экрана по оси Y. Но так как мы хотим использовать реальные значения пикселей, мы, не хотим иметь отрицательное число. Вместо этого мы сделаем низ экрана, равным высоте нашего окна. Если наше окно - 640x480, высота будет равна 480. Поэтому низ нашего экрана будет 480. Четвертый параметр обычно был равен положительному числу, задающему верхний край нашего экрана. Мы хотим, чтобы верхний край экрана был равным 0 (добрые старые координаты экрана), поэтому мы задаем четвертый параметр равным 0. При этом мы получим изменение от 0 до 480 по оси Y.



 

Последние два параметра - для оси Z. Мы не заботимся об оси Z, поэтому мы зададим диапазон от -1.0f до 1.0f. Нам будет достаточно того, что мы можем увидеть в 0.0f по оси Z.

 

После того, как мы задали ортографическую проекцию, мы выбираем матрицу просмотра вида (информация об объектах... расположение, и т.д) и сбрасываем ее.



 

GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Масштабирование и инициализация окна GL

{

  if (height==0)                 // Предотвращение деления на ноль



  {

    height=1;                    // Сделать высоту равной 1

  }

 

  glViewport(0,0,width,height);  // Сброс текущей области просмотра



 

  glMatrixMode(GL_PROJECTION);   // Выбор матрицы проектирования

  glLoadIdentity();              // Сброс матрицы проектирования

 

  glOrtho(0.0f,width,height,0.0f,-1.0f,1.0f); // Создание ортог. вида 640x480 (0,0 – верх лево)



 

  glMatrixMode(GL_MODELVIEW);    // Выбор матрицы просмотра вида

  glLoadIdentity();              // Сброс матрицы просмотра вида

}

 



Код инициализации содержит несколько новых команд. Вначале загружаем наши текстуры. Если они не загрузились, программа прекратит работу с сообщением об ошибке. После того, как мы создали текстуры, мы создаем наш шрифт. Я не делаю проверок на ошибки, если Вам надо вставьте его самостоятельно.

После того, как шрифт создан, мы задаем настройки. Мы разрешаем плавное сглаживание, задаем черный цвет очистки экрана и значение 1.0f для очистки буфера глубины. После этого, следует новая строка кода.

Функция glHint() сообщает OpenGL о настройках вывода. В этом случае мы сообщаем OpenGL, что мы хотим, чтобы сглаживание линии было наилучшим (самым хорошим), насколько это возможно под OpenGL. Эта команда разрешает сглаживание (anti-aliasing).

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

Важно отметить, что иногда кажется, что сглаживание не работает. Объекты в этой игре небольшие, поэтому Вы можете и не заметить сглаживание вначале. Посмотрите по внимательнее. Заметьте, как зазубренные линии на противниках сглаживаются, когда сглаживание включено. Игрок и песочные часы также должны смотреться лучше.

 

int InitGL(GLvoid)            // Все настройки для OpenGL делаются здесь



{

  if (!LoadGLTextures())      // Переход на процедуру загрузки текстур

  {

    return FALSE;             // Если текстура не загружена, вернем ЛОЖЬ



  }

 

  BuildFont();                // Построение шрифта



 

  glShadeModel(GL_SMOOTH);    // Разрешить плавное сглаживание

  glClearColor(0.0f, 0.0f, 0.0f, 0.5f);   // Черный фон

  glClearDepth(1.0f);         // Настройка буфера глубины

  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // Сглаживание линий

  glEnable(GL_BLEND);         // Разрешить смешивание

  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Тип смешивания

  return TRUE;                // Инициализация окончена успешна

}

 

Теперь кода рисования. Это именно то место, где творится волшебство :).



Мы очищаем экран (черным) вместе с буфером глубины. Затем мы выбираем текстуру шрифта (texture[0]). Мы хотим вывести фиолетовым цветом слова "GRID CRAZY" (сумасшедшая сетка), поэтому мы задаем красный и синий полной интенсивности, а зеленый половиной интенсивности. После того, как мы выбрали цвет, мы вызываем glPrint(). Мы помещаем слова "GRID CRAZY" с 207 по оси X (в центре экрана) и с 24 по оси Y (вверху экрана). Мы используем наш увеличенный шрифт, при помощи выбора шрифта 0.

После того, как мы вывели "GRID CRAZY" на экран, мы изменяем цвет на желтый (полная интенсивность красного, полная интенсивность зеленого). Мы пишем на экране "Level:" (уровень) и значение переменной level2. Помните, чтоlevel2 может быть больше чем 3. level2 хранит значение уровня, которое игрок видит на экране. Выражение %2i означает, что мы не хотим больше чем двух цифр на экране для представления уровня. Спецификатор “i” означает, что значение - целое число.

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

 

int DrawGLScene(GLvoid)                 //Здесь мы будем рисовать



{

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Очистка экрана и буфера глубины

  glBindTexture(GL_TEXTURE_2D, texture[0]); // Выбор текстуры нашего шрифта

  glColor3f(1.0f,0.5f,1.0f);            // Установить фиолетовый цвет

  glPrint(207,24,0,"GRID CRAZY");       // Написать GRID CRAZY на экране

  glColor3f(1.0f,1.0f,0.0f);            // Установить желтый цвет

  glPrint(20,20,1,"Level:%2i",level2);  // Вывод состояние текущего уровня

  glPrint(20,40,1,"Stage:%2i",stage);   // Вывод состояние стадии

 

Теперь мы проверим, закончена ли игра. Если игра закончена, переменная gameover будет равна ИСТИНА. Если игра закончена, мы используем glColor3ub(r, г, b) чтобы выбрать случайный цвет. Отмечу, что мы использует 3ub вместо 3f. Используя 3ub, мы можем использовать целочисленные значения от 0 до 255 для задания цветов. Плюс в том, что при этом проще получить случайное значение от 0 до 255, чем получить случайное значение от 0.0f до 1.0f.



Как только случайный цвет был выбран, мы пишем слова "GAME OVER" (игра окончена) справа от заголовка игры. Справа под "GAME OVER" мы пишем "PRESS SPACE" (нажмите пробел). Это визуальное сообщение игроку, которое позволит ему узнать, что жизней больше нет и нажать пробел для перезапуска игры.

 

  if (gameover)                      // Игра окончена?



  {

    glColor3ub(rand()%255,rand()%255,rand()%255); // Выбор случайного цвета

    glPrint(472,20,1,"GAME OVER");   // Вывод GAME OVER на экран

    glPrint(456,40,1,"PRESS SPACE"); // Вывод PRESS SPACE на экран

  }

 

Если игрока еще имеются жизни, мы выводим анимированные изображения символа игрока справа от заголовка игры. Чтобы сделать это, мы создаем цикл, который начинается от 0 до текущего количества жизней игрока минус один. Я вычитаю один, потому что текущая жизнь это то изображение, которым Вы управляете.



Внутри цикла, мы сбрасываем область просмотра. После того, как область просмотра была сброшена, мы передвигаемся на 490 пикселей вправо плюс значение loop1 умноженное 40.0f. Это позволит, выводить каждую из анимированных жизней игрока сдвинутую друг относительно друга на 40 пикселей. Первое анимированное изображение будет выведено в 490 + (0*40) (= 490), второе анимированное изображение будет выведено в 490 + (1*40) (= 530), и т.д.

После того, как мы сдвинули точку, мы выводим анимированное изображение и вращаем его против часовой стрелки в зависимости от значения в player.spin. Это заставляет анимированные изображения жизней вращаться в другую сторону относительно изображения активного игрока.

Затем выбираем зеленый цвет, и рисуем изображение. Способ вывода линий очень похож на рисование четырехугольника или многоугольника. Вы начинаете с glBegin(GL_LINES), сообщая OpenGL, что мы хотим вывести линию. Линии имеют 2 вершины. Мы используем glVertex2d, чтобы задать нашу первую точку. Функции glVertex2dне требуется указывать значение z. Эта функция хорошо нам подходит, так как мы не заботимся о значении z. Первая точка нарисована на 5 пикселей слева от текущего значения x и на 5 пикселей выше от текущего значения y. Это даст нам левую верхнюю точку. Вторая точка нашей первой линии рисуется на 5 пикселей справа от нашего текущего положения по x, и на 5 пикселей вниз. Это даст нам правую нижнюю точку. При этом будет нарисована линия от  левой верхней точки до правой нижней точки. Наша вторая линия будет нарисована от правой верхней точки до левой нижней точки. При этом будет нарисован зеленый символ "X" на экране.

 

После того, как мы вывели зеленый символ “X”, мы делаем вращение против часовой стрелки (по оси z) еще больше, но на этот раз с половиной скорости. Затем мы выбираем более темный оттенок зеленого (0.75f) и рисуем другой символ “X” размером 7 вместо 5. При этом будет выведен большой / темный символ “X” сверху первого зеленного символа “X”. Поскольку более темный символ “X” вращается медленнее, то возникнет иллюзия наличия сверху яркого символа “X” вращающихся усиков (смешок).



 

  for (loop1=0; loop1

  {

    glLoadIdentity();             // Сброс вида



    glTranslatef(490+(loop1*40.0f),40.0f,0.0f);  // Перенос вправо от нашего заголовка

    glRotatef(-player.spin,0.0f,0.0f,1.0f);      // Вращение против часовой стрелки

    glColor3f(0.0f,1.0f,0.0f);    // Цвет игрока зеленный

    glBegin(GL_LINES);            // Рисуем игрока с помощью линий

      glVertex2d(-5,-5);          // Лево верх игрока

      glVertex2d( 5, 5);          // Низ право

      glVertex2d( 5,-5);          // Верх право

      glVertex2d(-5, 5);          // Низ лево

    glEnd();                      // Закончили рисовать игрока

    glRotatef(-player.spin*0.5f,0.0f,0.0f,1.0f); // Вращение против часовой стрелки

    glColor3f(0.0f,0.75f,0.0f);   // Установка темно-зеленного

    glBegin(GL_LINES);            // Рисуем игрока с помощью линий

      glVertex2d(-7, 0);          // Влево от центра игрока

      glVertex2d( 7, 0);          // Вправо от центра

      glVertex2d( 0,-7);          // Вверх от центра

      glVertex2d( 0, 7);          // Вниз от центра

    glEnd();                      // Закончили рисовать игрока

  }


 

Теперь мы выводим сетку. Мы задаем значение переменной filled равной ИСТИНА. Это сообщит нашей программе, что сетка была полностью выведена (Вы увидите позже, зачем мы это делаем).

Затем мы устанавливаем ширину линии равной 2.0f. Это делает линии более толстыми, делая визуализацию сетки более четкой.

Затем мы отключаем сглаживание. Причина, по которой мы отключаем сглаживание, состоит в том, что это великолепная функция, но она съедает центральный процессор на завтрак. Если Вы не имеете убийственную быструю графическую карту, то Вы заметите значительное падение производительности, если Вы оставите включенным сглаживание. Пробуйте это, если Вы хотите :).

Вид сброшен, и мы начинаем два цикла. Переменная loop1 будет путешествовать слева направо. Переменная loop2будет путешествовать сверху донизу.

Мы задаем синий цвет линии, затем мы проверяем, пройдена ли игроком эта горизонтальная линия, если это так, то мы задаем белый цвет. Значение hline[loop1][loop2] было бы равно ИСТИННА, если линия была пройдена, и ЛОЖЬ, если игрок не пробегал через нее.

После того, как мы задали синий или белый цвета, мы выводим линию. Первое что надо проверить это то, что мы не ушли далеко вправо. Нам не надо выводить линии или делать проверки о прохождении линии, когда loop1 больше, чем 9.

Если переменная loop1 имеет правильное значение, мы проверяем, пройдена ли горизонтальная линия. Если это не так, то переменная filled установлена в ЛОЖЬ, сообщая, что есть, по крайней мере, одна линия, которая не была пройдена.

Затем линия рисуется. Мы выводим нашу первую горизонтальную линию (слева направо), начиная от 20+(0*60) (= 20). Эта линия выводится до 80 + (0*60) (= 80). Заметьте, что линия выведена слева направо. Именно поэтому мы не хотим вывести 11 (0-10) линий. Потому что последняя линия началась бы с правого края экрана и кончилась бы на 80 пикселей за экраном.

 

  filled=TRUE;                       // Задать True до начала тестирования



  glLineWidth(2.0f);                 // Задать ширину линий для ячеек 2.0f

  glDisable(GL_LINE_SMOOTH);         // Запретить сглаживание

  glLoadIdentity();                  // Сброс текущей матрицы вида и модели

  for (loop1=0; loop1<11; loop1++)   // Цикл слева направо

  {

    for (loop2=0; loop2<11; loop2++) // Цикл сверху вниз



    {

      glColor3f(0.0f,0.5f,1.0f);     // Задать синий цвет линии

      if (hline[loop1][loop2])       // Прошли горизонтальную линию?

      {


        glColor3f(1.0f,1.0f,1.0f);   // Если да, цвет линии белый

      }


      if (loop1<10)                  // Не рисовать на правом краю

      {


        if (!hline[loop1][loop2])    // Если горизонтальную линию не прошли

        {

          filled=FALSE;              // filled равно False

        }

        glBegin(GL_LINES);           // Начало рисования горизонтального бордюра ячейки

          glVertex2d(20+(loop1*60),70+(loop2*40)); // Левая сторона горизонтальной линии

          glVertex2d(80+(loop1*60),70+(loop2*40)); // Правая сторона горизонтальной линии

        glEnd();                     // Конец рисования горизонтального бордюра ячейки

      }

 

Код ниже делает то же самое, но при этом проверяется, что линия не выводится за нижний край экрана также как за правый край. Этот код ответствен за рисование вертикальных линий.



 

      glColor3f(0.0f,0.5f,1.0f);     // Задать синий цвет линии

      if (vline[loop1][loop2])       // Прошли вертикальную линию?

      {


        glColor3f(1.0f,1.0f,1.0f);   // Если да, цвет линии белый

      }


      if (loop2<10)                  // Не рисовать на нижнем краю

      {


        if (!vline[loop1][loop2])    // Если вертикальную линию не прошли

        {

          filled=FALSE;              // filled равно False

        }

        glBegin(GL_LINES);           // Начало рисования вертикального бордюра ячейки

          glVertex2d(20+(loop1*60),70+(loop2*40));  // Верхняя сторона вертикальной линии

          glVertex2d(20+(loop1*60),110+(loop2*40)); // Нижняя сторона вертикальной линии

        glEnd();                     // Конец рисования вертикального бордюра ячейки

      }

 

Теперь мы проверим, пройдены ли все 4 стороны ячейки. Каждая ячейка на экране занимает 1/100-ая часть картинки полноэкранного экрана. Поскольку каждая ячейка часть большой текстуры, мы должны вначале разрешить отображение текстуры. Мы не хотим, чтобы текстура была подкрашена в красный, зеленый или синий, поэтому мы устанавливаем ярко белый цвет. После того, как цвет задан, мы выбираем нашу текстуру сетки (texture[1]).



Затем мы проверяем наличие ячейки на экране. Вспомните, что наш цикл рисует 11 линий справа и налево, и 11 линий сверху и вниз. Но мы не имеем 11 ячеек по одной линии. Мы имеем 10 ячеек. Поэтому мы не должны проверять 11-ую позицию. Для этого надо проверить, что и loop1 и loop2, меньше чем 10. Это даст 10 ячеек от 0 - 9.

После того, как мы будем уверены, что мы не выходим за диапазон, мы можем начинать проверять границы.hline[loop1][loop2] - верх ячейки. hline[loop1][loop2+1] - низ ячейки. vline[loop1][loop2] - левая сторона ячейки, и vline[loop1+1][loop2] - правая сторона ячейки. Я надеюсь, что следующий рисунок вам поможет:

 

http://www.opengl.org.ru/lesson/nehe21-1.jpg

 

Все горизонтальные линии получаются от loop1 до loop1+1. Как Вы можете видеть, первая горизонтальная линия создается при loop2. Вторая горизонтальная линия создается при loop2+1. Вертикальные линии получаются отloop2 до loop2+1. Первая вертикальная линия создается при loop1, и вторая вертикальная линия создается приloop1+1.



Когда переменная loop1 увеличивается, правая сторона нашей старой ячейки становится левой стороной новой ячейки. Когда переменная loop2 увеличивается, низ старой ячейки становится вершиной новой ячейки.

Если все 4 бордюра ИСТИННЫ (это означает, что мы прошли через все) мы можем наложить текстуру на блок. Мы сделаем это тем же самым способом, с помощью которого мы разделили текстуру шрифта на отдельные символы. Мы делим, и loop1 и loop2 на 10, потому что мы хотим наложить текстуру на 10 ячеек слева направо, и на 10 ячеек сверху и вниз. Координаты текстуры меняются от 0.0f до 1.0f, и 1/10-ый от 1.0f будет 0.1f.

Поэтому для вычисления координат правого верхнего угла нашего блока мы делим значения цикла на 10 и добавляем 0.1f к x координате текстуры. Чтобы получить координаты левого верхнего угла блока, мы делим наше значение цикла на 10. Чтобы получить координаты левого нижнего угла блока, мы делим наше значение цикла на 10 и добавляем 0.1f к y координате текстуры. Наконец, чтобы получить координаты правого нижнего угла текстуры, мы делим значение цикла на 10 и добавляем 0.1f, и к x и к y координатам текстуры.

Небольшой пример: loop1=0 и loop2=0

· Правая X координата текстуры = loop1/10+0.1f = 0/10+0.1f = 0+0.1f = 0.1f

· Левая X координата текстуры = loop1/10 = 0/10 = 0.0f

· Верх Y координата текстуры = loop2/10 = 0/10 = 0.0f;

· Низ Y координата текстуры = loop2/10+0.1f = 0/10+0.1f = 0+0.1f = 0.1f; 

loop1=1 и loop2=1

· Правая X координата текстуры = loop1/10+0.1f = 1/10+0.1f = 0.1f+0.1f = 0.2f

· Левая X координата текстуры = loop1/10 = 1/10 = 0.1f

· Верх Y координата текстуры = loop2/10 = 1/10 = 0.1f;

· Низ Y координата текстуры = loop2/10+0.1f = 1/10+0.1f = 0.1f+0.1f = 0.2f; 

Буду надеяться, что это все имеет смысл. Если бы loop1 и loop2 были бы равны 9, мы закончили бы со значениями 0.9f и 1.0f. Поэтому, как вы можете видеть, наши координаты текстуры наложенной на 10 блоков меняются от наименьшего значения 0.0f до наибольшего значения 1.0f. Т.е. наложение всей текстуры на экран. После того, как мы наложили часть текстуры на экран, мы отключаем наложение текстуры. После того, как мы нарисовали все линии и заполнили все блоки, мы задаем ширину линий равной 1.0f.

 

      glEnable(GL_TEXTURE_2D);      // Разрешение наложение текстуры



      glColor3f(1.0f,1.0f,1.0f);    // Ярко белый свет

      glBindTexture(GL_TEXTURE_2D, texture[1]); // Выбор мозаичного изображения

      if ((loop1<10) && (loop2<10)) // Если в диапазоне, заполнить пройденные ячейки

      {


        // Все ли стороны ячейки пройдены?

        if (hline[loop1][loop2] && hline[loop1][loop2+1] &&

            vline[loop1][loop2] && vline[loop1+1][loop2])

        {

          glBegin(GL_QUADS);       // Нарисовать текстурированный четырехугольник

            glTexCoord2f(float(loop1/10.0f)+0.1f,1.0f-(float(loop2/10.0f)));

            glVertex2d(20+(loop1*60)+59,(70+loop2*40+1));  // Право верх

            glTexCoord2f(float(loop1/10.0f),1.0f-(float(loop2/10.0f)));

            glVertex2d(20+(loop1*60)+1,(70+loop2*40+1));   // Лево верх

            glTexCoord2f(float(loop1/10.0f),1.0f-(float(loop2/10.0f)+0.1f));

            glVertex2d(20+(loop1*60)+1,(70+loop2*40)+39);  // Лево низ

            glTexCoord2f(float(loop1/10.0f)+0.1f,1.0f-(float(loop2/10.0f)+0.1f));

            glVertex2d(20+(loop1*60)+59,(70+loop2*40)+39); // Право низ

          glEnd();                 // Закончить текстурирование ячейки

        }

      }


      glDisable(GL_TEXTURE_2D);    // Запрет наложения текстуры

    }


  }

  glLineWidth(1.0f);               // Ширина линий 1.0f

 

Код ниже проверяет, равно ли значение переменной 


Каталог: forum
forum -> Лечение гепатозов
forum -> Система ведения овцеводства в крестьянско-фермерских и личных хозяйствах населения
forum -> Yaesuft-857 (ft-897) – переходник для подключения cat интерфейса к микрофонному разъему трансивера
forum -> Васильев Владимир Юрьевич
forum -> tl-wr1043ND Беспроводной гигабитный маршрутизатор серии n copyright & trademarks
forum -> Цели и задачи Контакта rtf docx
forum -> Назовите не менее трех результатов революции 1905- 1907гг. Приведите не менее трех положений, отражающих значение революции для отечественной истории начала 20 века


Поделитесь с Вашими друзьями:
1   ...   7   8   9   10   11   12   13   14   ...   27


База данных защищена авторским правом ©vossta.ru 2019
обратиться к администрации

    Главная страница