Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с рисованием текстуры (OpenGL)

88K
05 мая 2013 года
napoleon80386
4 / / 05.05.2013
Здравствуйте. Пишу простой авиасимулятор. Дошёл до генерации ландшафта. Деревья собираюсь рисовать так: накладывать на квадрат и несколько раз поворачивать картинку дерева. Она в BMP файле (цветов могу сделать сколько надо). Вот код загрузки текстуры:

Код:
void LoadTreeTextures (void)
{
    /* TODO: пробежать в цикле все имена файлов */
    AUX_RGBImageRec *TreeImage;
    TreeImage = auxDIBImageLoad("Resources/TreeTextures/tree1.bmp");
    glGenTextures( 1, &TreeTextures[0] );
    glBindTexture( GL_TEXTURE_2D, TreeTextures[0] );
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexImage2D( GL_TEXTURE_2D, 0, 3, TreeImage->sizeX, TreeImage->sizeY, 0,
                    GL_RGB, GL_UNSIGNED_BYTE, TreeImage->data );
}
А вот код рисования:

Код:
void DrawTree (double c)
{
    int TextureNumber = rand() % TREE_TEXTURES_NUM;
    CVertex3 QPoint1 = {0, 0, c}, QPoint2={0.7, 0, c}, QPoint3={0.7, 0.7, c}, QPoint4={0, 0.7, c};

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    /* Включаем загрузку текстур */
    glEnable(GL_TEXTURE_2D);

    glColor3d (1, 1, 1);       
    glBindTexture( GL_TEXTURE_2D, TreeTextures[0]);
    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex3f(QPoint1.x, QPoint1.y, QPoint1.z);    // Нижний левый угол
        glTexCoord2f(0, 1); glVertex3f(QPoint2.x, QPoint2.y, QPoint2.z);    // Нижний правый угол
        glTexCoord2f(1, 1); glVertex3f(QPoint3.x, QPoint3.y, QPoint3.z);    // Верхний правый угол
        glTexCoord2f(1, 0); glVertex3f(QPoint4.x, QPoint4.y, QPoint4.z);    // Верхний левый угол
    glEnd();               
}
Текстура грузится, но не рисуется. Вместо неё - просто белый квадрат. Скажите, пожалуйста, что я делаю не так?
360
05 мая 2013 года
P*t*
474 / / 15.02.2007
На первый взгляд все правильно.

Попробуйте запустить какой-нибудь использующий текстуры пример opengl и вносить в него изменения, приближая к вашей программе: убрать из примера все лишнее, подсунуть туда вашу текстуру, убрать лишние glEnable и т.д.
А потом останется только определить, после какого изменения текстура перестанет прорисовываться.
88K
05 мая 2013 года
napoleon80386
4 / / 05.05.2013
Цитата: P*t*
На первый взгляд все правильно.

Попробуйте запустить какой-нибудь использующий текстуры пример opengl и вносить в него изменения, приближая к вашей программе: убрать из примера все лишнее, подсунуть туда вашу текстуру, убрать лишние glEnable и т.д.
А потом останется только определить, после какого изменения текстура перестанет прорисовываться.



http://pastebin.com/7UFQvrA3 - этот пример работает. Только тут отличий особых я не вижу.

326
05 мая 2013 года
sadovoya
757 / / 19.11.2005
Когда-то использовал OpenGL и узнал, что иногда нет ошибок в коде но программа не работает. Связано было с потерей контекста устройства вывода. Если окно, реальное "виндовое" (может получать фокус), то все нормально. Если это "псевдодискриптор", то контекст время от времени теряется. Может дело в том на чем рисуете?

Ах да, там всякие еще repaint, refresh, update окна могут понадобиться.
360
06 мая 2013 года
P*t*
474 / / 15.02.2007
Цитата: napoleon80386
http://pastebin.com/7UFQvrA3 - этот пример работает. Только тут отличий особых я не вижу.



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

88K
06 мая 2013 года
napoleon80386
4 / / 05.05.2013
Цитата: sadovoya
Когда-то использовал OpenGL и узнал, что иногда нет ошибок в коде но программа не работает. Связано было с потерей контекста устройства вывода. Если окно, реальное "виндовое" (может получать фокус), то все нормально. Если это "псевдодискриптор", то контекст время от времени теряется. Может дело в том на чем рисуете?

Ах да, там всякие еще repaint, refresh, update окна могут понадобиться.



Простите, но я понятия не имею о том, что Вы говорите. У меня есть 2 окна - виндовское и глутовское. Рисую в глутовском (виндовское содержит лишь кнопку запуска).

http://yadi.sk/d/56JvAQ1w4b3uH - вот полный проект (общий доступ закрою, когда проблема будет решена). Посмотрите, пожалуйста, вдруг найдёте какую-то грубую левую ошибку.
У меня есть лишь одно основное отличие - там текстура накладывается на цилиндр, при рисовании которого эта текстура передаётся одним из параметров (glCylinder). А у меня это - квадрат, который не одной функцией рисуется.

326
06 мая 2013 года
sadovoya
757 / / 19.11.2005
Посмотрел, боюсь плохой из меня советчик: 1)давно это было; 2)там у вас glut, а я с ним плохо знаком. Но, glut насколько помню облегчает взаимодействие с ОС, в частности, думаю, предположенной проблемы потери контекста с ним не будет. Еще порылся в исходниках у себя и нашел немного отличий. Исходник, правда, на Delphi, но синтаксис, относящийся к OpenGL близкий.

Код:
procedure TfrmGL.BmpTexture;
var
  i, j: Integer;
begin
   bitmap := TBitmap.Create;
   bitmap.LoadFromFile('gold.bmp'); // загрузка текстуры из файла

   {--- заполнение битового массива ---}
    for i := 0 to 63 do
      for j := 0 to 63 do begin
        bits [i, j, 0] := GetRValue(bitmap.Canvas.Pixels[i,j]);
        bits [i, j, 1] := GetGValue(bitmap.Canvas.Pixels[i,j]);
        bits [i, j, 2] := GetBValue(bitmap.Canvas.Pixels[i,j]);
        bits [i, j, 3] := 255;
    end;

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                 64, 64,     // здесь задается размер текстуры
                 0, GL_RGBA, GL_UNSIGNED_BYTE, @bits);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);
end;

Это загрузка и инициализация текстуры. Файл gold.bmp рисуется на кубе. Размеры файла 64x64. Глубина цвета как в вашей картинке 24-бита, но почему-то добавлен альфа-канал при считывании в массив. Тот-же альфа канал фигурирует и в glTexImage2D у меня. Смущает это меня, к сожалению уже не помню нафига так сделано :) Посмотрите этот код, может натолкнет на какие-то мысли.

Да, смущает альфа-канал потому, что прозрачность в той задаче не к чему была, а он тут добавлен "насильно". Возможно это было связано с каким-то требованием библиотеки.
88K
06 мая 2013 года
napoleon80386
4 / / 05.05.2013
Всем спасибо, всё как-то разрешилось. Я что-то поменял в загрузке текстуры с адресами, указателями и прочей лабудой, которую я как не понимал, так и не понимаю. И вынес загрузку BMP в отдельную функцию (как это сделано в функции LoadBMP одного из уроков тов. NeHe).
326
06 мая 2013 года
sadovoya
757 / / 19.11.2005
Ура! Я кстати от этой лабуды OpenGL тоже устал -- все в нем пропиши, да еще с кучей нюансов.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог