F2A9o


0. Вместо введения
------------------

    -- ..
    -- Подтверждаю. Дополнительные настройки.
    -- Юмор: 75%.
    -- Подтверждаю. Самоуничтожение произойдет через 10, 9..
    -- Пусть будет 60%.

    Интерстеллар, 2014, 2:38:36

Древняя мечта сразу начать изучение с языка, которого хватит на всю жизнь*, с трудом выдерживает критику хотя-бы потому, что существует по крайней мере три типа языков программирования, заточенных под различные виды задач (классификация в стиле "Летели два крокодила -- один зеленый а другой направо", в скобках -- наиболее частая область применения):

  -- декларативные языки программирования
     (web/HTML, базы данных/SQL, компиляторы LEX/YACC)

  -- функциональные языки программирования (CS, AI..)

  -- императивные языки программирования
     (как песня у чукчи, "Что вижу о том и пою")

Вот еще несколько реальных причин не застрять в единственном языке программирования.

  -- Существуют разные операционные системы и разные "оболочки" (IDE). например начинаю с C# под Windows 8.1 в Visual Studio 2012 Pro, продолжаю для IOS 8 под Xamarin Studio, снова C#. Тогда почему опять C#, если столько всего изменилось?

  -- Познакомившись обстоятельно с выбранным решением (скажем gcc, Linux, vi) начинаешь видеть его недостатки. Переход.

  -- Занимаешься кем-то начатым проектом.

  -- Хочешь починить исходники, созданные в устаревшей среде (скажем Windows XP, Visual Studio 2005, C++ [4]).

  -- Нашелся заработок в команде, работающей не там, где привычно..

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

Попробуем найти рациональное зерно в следующем источнике:

1. Видеокурс: Teaching Kids Programming with C# by Falco, Langit

  http://www.pluralsight.com/courses/teaching-kids-programming

На мой взгляд, наиболее ценным является следующее высказывание (7:18):

.. now, we know this is a little bit but a hack, but again.. this courseware is designed to be used by professional programmers..

..нет, не детей-профессионалов, а нужен помощник-профессионал.

Итак, учимся на своем коде вписанном в профессионально созданный шаблон. Насколько легко внести ошибку в чужой код? В старинных IDE (VB, Турбо..) старались отделить собственноручно написанное от чужого. Например:

  файл mi archivo

    hablar "¡¿Hola mundo?!" basta

  отделен от alien.cpp

    #include <iostream>

    #define hablar cout <<
    #define basta << endl;

    using namespace std;

    int main() {
      #include "mi archivo"
      return 0;
    }

Обучающийся _не_должен_ видеть C++ файл alien.cpp и пребывая в счастливом неведении, программировать на испанском. Впрочем, нынче это не модно (потому что ходить по тротуару тоже опасно).

Основная проблема при таком подходе это не незащищенность чужого кода (его можно легко восстановить с источника, с доступом для обучающегося "только для чтения", а в проверке корректности создаваемого файла (hablar "¡¿Hola mundo?!" basta). Для этого обучающему нужно найти/написать некоторое подобие программы lint, либо самому поработать за нее.

---

*) "Книга перемен" 200 стр, согласно Конфуцию изучать нужно 100 лет, Bjarne Stroustrup. The C++ Programming Language (4th Edition) 1366 pp.


1. Пример "development board" на основе простого контроллера
------------------------------------------------------------

Устройство представляет собой коробку с 16 выводами "под отвертку" и тремя кнопками: "1", "0", "OK". ASCII рисунок поможет работать с устройством в режиме симуляции на консоль компьютера. Oбычно первые программы пишут для консоли (например, "Hello, World!").

   -----------------------------------------------------------------
  |       7     6     5     4     3     2     1     0               |
  |  ---------------------------------------------------            |
  | |     ---   ---   ---   ---   ---   ---   ---   --- |           |
  | |   /   / /   / /   / /   / /   / /   / /   / /   / |           |
  | |   ---   ---   ---   ---   ---   ---   ---   ---   | [0 ] [ 1] |
  | | /   / /   / /   / /   / /   / /   / /   / /   /   |           |
  | | --- . --- . --- . --- . --- . --- . --- . --- .   |   [OK]    |
  |  ---------------------------------------------------            |
  |       F  E  D  C  B  A  9  8  7  6  5  4  3  2  1  0            |
  |      (+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)           |
   -----------------------------------------------------------------

и вариант "игра":

   -----------------------------------------------------------------
  |       7     6     5     4     3     2     1     0               |
  |  ---------------------------------------------------            |
  | |   ---   ---   ---   ---   ---   ---   ---   ---   |   [ ^ ]   |
  | |  |   | |   | |   | |   | |   | |   | |   | |   |  |           |
  | |   ---   ---   ---   ---   ---   ---   ---   ---   | [< ] [ >] |
  | |  |   | |   | |   | |   | |   | |   | |   | |   |  |           |
  | |   --- . --- . --- . --- . --- . --- . --- . --- . |   [ v ]   |
  |  ---------------------------------------------------            |
  |       F  E  D  C  B  A  9  8  7  6  5  4  3  2  1  0            |
  |      (+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)(+)           |
   -----------------------------------------------------------------

Кнопки без фиксации и дребезга,

            |   ---
  +V >--+--o|o--R Q-->
        |  ---  | |
         --o o--S |
                ---

Восемь семисегментных индикаторов адресуются цифрой в верхнем ряду, стандартная нумерация сегментов.

         a
        ---      7 6 5 4 3 2 1 0
     f/   /b     h g f e d c b a
    g --- g
   e/   /c
    --- .
     d h

Программа контроллера имеет две фазы "настройка" (setup) и "цикл" (loop)

    Настройка
  o----->-----o
             / \
            /   \
            \   /
             -<-
             Цикл

Настройка: 1. Задать роль внешних выводов:
                аналоговый или цифровой,
                вход или выход.
           2. Частоту опроса.
           3. Задать значения внутренних параметров
              (константы и переменные, об этом позже).

Цикл:      1. Измерить и запомнить сигналы на входах.
           2. На основе имеющихся данных принять решение.
           3. Установить выходные сигналы, согласно решению в п.2


Литература
----------

  1. https://www.youtube.com/watch?v=YFJzHKHRc48
  2. http://lazyfoo.net/SDL_tutorials/
  3. Боярское программирование
       http://habrahabr.ru/post/41303/
       https://yadi.sk/d/_U976GBRTqNVf
     Простой калькулятор на " боярском" диалекте MSVС++
       http://habrahabr.ru/post/41561/
  4. http://www.codeproject.com/Articles/42678/Irrlicht-car-simulation
  5. http://www.ishodniki.ru/list/info.php?id=3598
  6. http://stackoverflow.com/questions/1989431/opengl-mesa-3d-mingw
  7. https://wiki.libsdl.org/FrontPage
  8. http://content.gpwiki.org/index.php
       /SDL:Tutorials:Drawing_and_Filling_Circles
  9. http://catethysis.ru/7-segment/


Приложение А. C++: простая программа на SDL 2.0 + OpenGL
--------------------------------------------------------

  http://ivan4b.ru/simple-sdl-opengl-program-tutorial

..Для того чтобы скомпилировать программу воспользуйтесь своей IDE, либо g++.

  Linux:
    sudo apt-get install libsdl2-dev
    g++ cube.cpp -o cube -lSDL2 -lGL -lGLU
  Windows (MinGW):
    g++ cube.cpp -o cube.exe -lSDL2main -lSDL2 -lGL -lGLU

У вас должен получиться разноцветный вращающийся куб*

*) Должен, да не получился..

  > g++ cube.cpp -lmingw32 -lSDL2main -lSDL2 -lopenGL32 -lglu32 -o cube

Исходный файл (Changed: text formatting, SDL_Delay(10)):

  #include <SDL2/SDL.h>   // Библиотека SDL 2
  #include <GL/gl.h>      // Библиотека OpenGL
  #include <GL/glu.h>     // Библиотека GLU

  #include <iostream>     // стандартная библиотека ввода-вывода в C++

  using namespace std;

  SDL_Window *window;     // задаем окно для SDL

  const int width = 640;  // ширина окна
  const int height = 480; // высота окна

  void drawCube(float xrf, float yrf, float zrf);

  void init(){

    // Инициализация SDL

    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ){
      cout << "Unable to init SDL, error: " << SDL_GetError() << endl;
      exit(1);
    }

    // Включаем двойной буфер, настраиваем цвета

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);

    // Создаем окно с заголовком "Cube", размером 640х480 и
    // расположенным по центру экрана.

    window =
      SDL_CreateWindow(
        "Cube",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        width,
        height,
        SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

    // создаем контекст OpenGL
    // если не получилось создать окно, то выходим

    SDL_GLContext glcontext = SDL_GL_CreateContext(window);
    if ( window == NULL) {
      exit(1);
    }

    // Инициализация OpenGL
    // устанавливаем фоновый цвет на черный

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    // включаем тест глубины

    glClearDepth(1.0);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);

    glShadeModel(GL_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // настраиваем трехмерную перспективу

    gluPerspective(45.0f, (float) width / (float) height, 0.1f, 100.0f);

    // переходим в трехмерный режим

    glMatrixMode( GL_MODELVIEW);
  }

  int main(int argc, char *argv[]){
    init();                          // инициализация

    bool running = true;

    float xrf = 0, yrf = 0, zrf = 0; // углы поворота

    while (running) {
      SDL_Event event;               // события SDL

      // начинаем обработку событий
      while ( SDL_PollEvent(&event) ) {

        switch ( event.type) {
          // смотрим: если произошло событие закрытия окна,
          // то завершаем работу программы
          case SDL_QUIT:
            running = false;
          break;

          // если нажата клавиша смотрим какая
          case SDL_KEYDOWN:
            switch(event.key.keysym.sym) {
              case SDLK_ESCAPE:  // клавиша ESC
                running = false; // завершаем работу программы
              break;
            }
          break;
        }
      }

      // пока программа запущена изменяем углы поворота,
      // тем самым вращая куб

      xrf -= 0.5;
      yrf -= 0.5;
      zrf -= 0.5;

      // рисуем сам куб с текущими углами поворота
      drawCube(xrf, yrf, zrf);
      SDL_Delay(10);

      // обновляем экран
      glFlush();
      SDL_GL_SwapWindow(window);
    }

    SDL_Quit(); // завершаем работу SDL и выходим
    return 0;
  }

  void drawCube(float xrf, float yrf, float zrf){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -7.0f);  // Сдвинуть вглубь экрана

    glRotatef(xrf, 1.0f, 0.0f, 0.0f); // Вращение куба по X, Y, Z
    glRotatef(yrf, 0.0f, 1.0f, 0.0f); // Вращение куба по X, Y, Z
    glRotatef(zrf, 0.0f, 0.0f, 1.0f); // Вращение куба по X, Y, Z

    glBegin(GL_QUADS);                // Рисуем куб

    glColor3f(0.0f, 1.0f, 0.0f);      // Синяя сторона (Верхняя)
    glVertex3f( 1.0f, 1.0f, -1.0f);   // Верхний правый угол квадрата
    glVertex3f(-1.0f, 1.0f, -1.0f);   // Верхний левый
    glVertex3f(-1.0f, 1.0f,  1.0f);   // Нижний левый
    glVertex3f( 1.0f, 1.0f,  1.0f);   // Нижний правый

    glColor3f(1.0f, 0.5f, 0.0f);      // Оранжевая сторона (Нижняя)
    glVertex3f( 1.0f, -1.0f,  1.0f);  // Верхний правый угол квадрата
    glVertex3f(-1.0f, -1.0f,  1.0f);  // Верхний левый
    glVertex3f(-1.0f, -1.0f, -1.0f);  // Нижний левый
    glVertex3f( 1.0f, -1.0f, -1.0f);  // Нижний правый

    glColor3f(1.0f, 0.0f, 0.0f);      // Красная сторона (Передняя)
    glVertex3f( 1.0f,  1.0f, 1.0f);   // Верхний правый угол квадрата
    glVertex3f(-1.0f,  1.0f, 1.0f);   // Верхний левый
    glVertex3f(-1.0f, -1.0f, 1.0f);   // Нижний левый
    glVertex3f( 1.0f, -1.0f, 1.0f);   // Нижний правый

    glColor3f(1.0f,1.0f,0.0f);        // Желтая сторона (Задняя)
    glVertex3f( 1.0f, -1.0f, -1.0f);  // Верхний правый угол квадрата
    glVertex3f(-1.0f, -1.0f, -1.0f);  // Верхний левый
    glVertex3f(-1.0f,  1.0f, -1.0f);  // Нижний левый
    glVertex3f( 1.0f,  1.0f, -1.0f);  // Нижний правый

    glColor3f(0.0f,0.0f,1.0f);        // Синяя сторона (Левая)
    glVertex3f(-1.0f,  1.0f,  1.0f);  // Верхний правый угол квадрата
    glVertex3f(-1.0f,  1.0f, -1.0f);  // Верхний левый
    glVertex3f(-1.0f, -1.0f, -1.0f);  // Нижний левый
    glVertex3f(-1.0f, -1.0f,  1.0f);  // Нижний правый

    glColor3f(1.0f,0.0f,1.0f);        // Фиолетовая сторона (Правая)
    glVertex3f( 1.0f,  1.0f, -1.0f);  // Верхний правый угол квадрата
    glVertex3f( 1.0f,  1.0f,  1.0f);  // Верхний левый
    glVertex3f( 1.0f, -1.0f,  1.0f);  // Нижний левый
    glVertex3f( 1.0f, -1.0f, -1.0f);  // Нижний правый

    glEnd();                          // Закончили квадраты
  }


Приложение Б. SDL2 рыбы по LazyFoo SDL2 C++ tutorials
-----------------------------------------------------

  01. Hello.

  // Initialize SDL       SDL_Init( SDL_INIT_VIDEO)
  // Create window        SDL_CreateWindow( sTitle, wX, wY, w, h, flags)
  // Get window surface   SDL_GetWindowSurface( window)
  // Fill the surface     SDL_FillRect( surface, rect, color)
  // Update the surface   SDL_UpdateWindowSurface( window)
  // Wait                 SDL_Delay( ms)
  // Destroy window       SDL_DestroyWindow( window )
  // Quit SDL subsystems  SDL_Quit();

  01. Image.

  // Initialize SDL       SDL_Init( SDL_INIT_VIDEO)
  // Create window        SDL_CreateWindow( sTitle, wX, wY, w, h, flags)
  // Get window surface   SDL_GetWindowSurface( window)

  // Load media           SDL_LoadBMP( sFileName)
  // Apply the image      SDL_BlitSurface( surface, src, surface, dst)

  // Update the surface   SDL_UpdateWindowSurface( window)
  // Wait                 SDL_Delay( ms)

  // Deallocate surface   SDL_FreeSurface( surface)
  // Destroy window       SDL_DestroyWindow( window )
  // Quit SDL subsystems  SDL_Quit();

  03. Events

  // Initialize SDL       SDL_Init( SDL_INIT_VIDEO)
  // Create window        SDL_CreateWindow( sTitle, wX, wY, w, h, flags)
  // Get window surface   SDL_GetWindowSurface( window)

  // Load media           SDL_LoadBMP( sFileName)

  // Events loop          SDL_PollEvent( &event_handler)
    // Apply the image      SDL_BlitSurface( surface, src, surface, dst)
    // Update the surface   SDL_UpdateWindowSurface( window)

  // Deallocate surface   SDL_FreeSurface( surface)
  // Destroy window       SDL_DestroyWindow( window )
  // Quit SDL subsystems  SDL_Quit();

  04. KeyPresses

  // Initialize SDL       SDL_Init( SDL_INIT_VIDEO)
  // Create window        SDL_CreateWindow( sTitle, wX, wY, w, h, flags)
  // Get window surface   SDL_GetWindowSurface( window)

  // Load media           loadSurface( sFileName)

  // Events loop          SDL_PollEvent( &event_handler)
    // Apply the image      SDL_BlitSurface( surface, src, surface, dst)
    // Update the surface   SDL_UpdateWindowSurface( window)

  // Deallocate surface   SDL_FreeSurface( surface)
  // Destroy window       SDL_DestroyWindow( window )
  // Quit SDL subsystems  SDL_Quit();

  Куб от ivan4b.ru

  init() 14 операций: 2 SDL 12 OpenGL

  в цикле
    SDL_PollEvent(&event)
    drawCube(xrf, yrf, zrf); 36 операций с OpenGL
    SDL_Delay( 10);
    glFlush();
    SDL_GL_SwapWindow(window);

  SDL_Quit();

