Модераторы: Rickert, Alexeis, BorisVorontsov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> BCB, OpenGL, проблема с текстурой, Неверные цвета BITMAP 
V
    Опции темы
InfMag
Дата 31.12.2010, 04:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



***


Профиль
Группа: Завсегдатай
Сообщений: 1037
Регистрация: 21.11.2004

Репутация: нет
Всего: 4



Обучаюсь работе с OpenGL по урокам NeHe. Использую C++Builder 2010.
По ходу обучения возникли несостыковки. Функция от библиотеки glaux.h не захотела работать. На всякий случай для начала полный код моей программы:
Код

// OpenGL - урок номер 4, лепим текстуру на 3д
// ---------------------------------------------------------------------------

#include <vcl.h>
#include <windows.h>
#pragma hdrstop

#include <tchar.h>

#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
// ---------------------------------------------------------------------------

HGLRC hRC; // постоянный контекст рендеринга 
HDC hDC; // постоянный контекст устройства GDI 
HWND hWnd; // дескриптор главного окна 
HINSTANCE appInstance; // дескриптор приложения 

bool keys[256]; // массив, используемый для операций с клавиатурой 
bool active = true; // флаг активности приложения, чтобы приостановить пр. при его минимизации 
bool fullscreen = true;

GLuint texture[1]; // всего 1, но начинается с 0

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); // прототип функции 
GLvoid ReSizeGLScene( GLsizei width, GLsizei height );
int InitGL( GLvoid );
int DrawGLScene( GLvoid );
GLvoid KillGLWindow( GLvoid );
bool CreateGLWindow( LPCWSTR title, int width, int height, int bits, bool fullscreenflag );
GLvoid LoadGLTextures();

#pragma argsused

WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) {
    //appInstance = hInstance; // считываем по другому при создании окна
    MSG msg; // структура для хранения сообщения windows
    bool done = false; // логическая переменная для выхода из цикла

    // Спрашивает пользователя, какой режим экрана он предпочитает
    if ( MessageBox( NULL, "Запустить приложение вполноэкранном режиме?", "Выбор режима запуска", MB_YESNO|MB_ICONQUESTION ) == IDNO ) {
        fullscreen = false; // оконный режим
    }

    // Создать наше OpenGL окно
    if ( !CreateGLWindow( String("OpenGL lolo").c_str(), 1024, 768, 32, fullscreen ) ) {
        return 0; // выйти, если окно не может быть создано
    }

    while ( !done ) {
        if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { // Есть ли в очереди какое-нибудь сообщение?
            if ( msg.message == WM_QUIT ) {
                done = true;
            } else {
                TranslateMessage( &msg ); // Переводим сообщение
                DispatchMessage( &msg ); // Отсылаем сообщение
            }
        } else { // если нет сообщений
            // Прорисовываем сцену.
            if ( active ) {
                if ( keys[ VK_ESCAPE ] ) {
                    done = true;
                } else {           
                    DrawGLScene();
                    SwapBuffers( hDC ); // меняем буфер (двойная буфферизация)
                }
            }

            if ( keys[ VK_F1 ] ) {
                keys[ VK_F1 ] = false;
                KillGLWindow();
                fullscreen = !fullscreen;

                // Пересоздаём наше OpenGL окно
                if ( !CreateGLWindow( String("OpenGL lolo").c_str(), 1024, 768, 32, fullscreen ) ) {
                    return 0;
                }
            }
        }
    }

    // shutdown
    KillGLWindow(); // крушим окно
    return msg.wParam; // выходим из программы
}
// --------------------------------------------------------------------------- 

GLvoid ReSizeGLScene( GLsizei width, GLsizei height ) { // изменить размер и инициализировать окно GL
    if ( height == 0 ) { // предотвращаем <del>конец света</del> деление на ноль 
        height = 1;
    }
    glViewport( 0, 0, width, height ); // сброс текущей области вывода 

    glMatrixMode( GL_PROJECTION ); // выбор матрицы проекций
    glLoadIdentity(); // сброс матрицы проекции

    // Вычисление соотношения геометрических размеров для окна GLUlib
    gluPerspective( 45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f );

    glMatrixMode( GL_MODELVIEW ); // выбор матрицы вида модели
    glLoadIdentity(); // сброс матрицы вида модели
}

int InitGL( GLvoid ) { // все установки касаемо GL происходят тут
    LoadGLTextures(); // загрузка текстур
    glEnable( GL_TEXTURE_2D ); // разрешение наложения текстур

    glShadeModel( GL_SMOOTH ); // разрешить плавное цветовое сглаживание
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); // очистка экрана в чёрный цвет
    glClearDepth( 1.0f ); // разрешить очистку буфера глубины
    glEnable( GL_DEPTH_TEST ); // разрешить тест глубины
    glDepthFunc( GL_LEQUAL ); // тип теста глубины

    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // улучшение в вычислении перспективы
    
    return true; // инициализация прошла успешно
}

int DrawGLScene( GLvoid ) { // тут происходит вся прорисовка
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // очистить экран и буфер глубины

    glLoadIdentity(); // сбросить текущую матрицу

    static GLfloat rQuad;

    // Куб
    glTranslatef( 0.0f, 0.0f, -5.0f );
    glRotatef( rQuad, 0.5f, 1.0f, 0.5f );
    //glRotatef( rQuad, 0.0f, 1.0f, 0.0f );
    //glColor3f( 1.0f, 0.0f, 1.0f );
    glBindTexture( GL_TEXTURE_2D, texture[0] );
    glBegin( GL_QUADS );
        // лицо
        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, 1.0f, 1.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, 1.0f, 1.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f );
        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, -1.0f, 1.0f );

        // правый бок
        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f, 1.0f, -1.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, 1.0f, 1.0f );
        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, -1.0f );

        // жопа
        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, -1.0f );
        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, 1.0f, -1.0f );
        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, -1.0f, -1.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 1.0f, -1.0f, -1.0f );

        // левый бок
        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -1.0f, 1.0f, -1.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f, 1.0f, 1.0f );
        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, 1.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, -1.0f );

        // голова
        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, 1.0f, 1.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( -1.0f, 1.0f, -1.0f );
        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, 1.0f, -1.0f );
        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 1.0f, 1.0f, 1.0f );

        // нижняя
        glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, 1.0f );
        glTexCoord2f( 1.0f, 0.0f ); glVertex3f( -1.0f, -1.0f, -1.0f );
        glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, -1.0f );
        glTexCoord2f( 0.0f, 1.0f ); glVertex3f( 1.0f, -1.0f, 1.0f );
    glEnd();

    rQuad -= 0.05f;

    return true; // прорисовка прошла успешно
}

GLvoid KillGLWindow( GLvoid ) { // корректное разрушение форточки
    if ( fullscreen ) {
        ChangeDisplaySettings( NULL, 0 ); // переключаемся в оконный режим (востанавливаютяс настройки экрана по умолчанию)
        ShowCursor( true ); // показываем курсор
    }

    if ( hRC ) {
        if ( !wglMakeCurrent( NULL, NULL ) ) { // возможно ли освободить RC от DC
            MessageBox( NULL, "Невозможно освободить RC от DC.", "Ошибка завершения", MB_OK|MB_ICONINFORMATION );
        }
        if ( !wglDeleteContext( hRC ) ) { // возможно ли удалить RC
            MessageBox( NULL, "Невозможно удалить RC.", "Ошибка завершения", MB_OK|MB_ICONINFORMATION );
        }
        hRC = NULL; // устанавливаем RC в нул (я так понял убиваем линк и тем самым освобождаем память)
    }

    if ( hDC && !ReleaseDC( hWnd, hDC ) ) { // возможно ли уничтожить DC
        MessageBox( NULL, "Невозможно освободить DC.", "Ошибка завершения", MB_OK|MB_ICONINFORMATION );
        hDC = NULL;
    }

    if ( hWnd && !DestroyWindow(hWnd) ) { // возможно ли уничтожить окно
        MessageBox( NULL, "Невозможно освободить окно.", "Ошибка завершения", MB_OK|MB_ICONINFORMATION );
        hWnd = NULL;
    }

    if ( !UnregisterClass( "OpenGL", appInstance ) ) { // возможно ли разрегистрировать класс
        MessageBox( NULL, "Невозможно разрегистрировать класс окна.", "Ошибка завершения", MB_OK|MB_ICONINFORMATION );
        appInstance = NULL;
    }
}

bool CreateGLWindow( LPCWSTR title, int width, int height, int bits, bool fullscreenflag ) {
    GLuint PixelFormat; // хранит результат после поиска
    WNDCLASS wc;
    DWORD dwExStyle; // расширенный стиль окна
    DWORD dwStyle; // обычный стиль окна

    RECT WindowRect; // сюда соберём углы краёв, чтобы по ним запонлять окно (типа)
    WindowRect.left = (long)0;
    WindowRect.right = (long)width;
    WindowRect.top = (long)0;
    WindowRect.bottom = (long)height;

    fullscreen = fullscreenflag;

    appInstance = GetModuleHandle( NULL ); // считываем дескриптом приложения
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // перерисуем при перемещении и создаём скрытый DC
    wc.lpfnWndProc = (WNDPROC)WndProc; // процедура обработки сообщений
    wc.cbClsExtra = 0; // нет доп. инф. для окна
    wc.cbWndExtra = 0; // нет доп. инф. для окна
    wc.hInstance = appInstance;
    wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); // иконка по умолчанию
    wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // загружаем указатель мышки
    wc.hbrBackground = NULL; // фон не требуется для GL
    wc.lpszMenuName = NULL; // меню в окне не будет
    wc.lpszClassName = "OpenGL";

    if ( !RegisterClass( &wc ) ) { // пытаемся зарегить класс окна
        MessageBox( NULL, "Ошибка регистрации класса окна.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false; // выход и возврат false
    }

    if ( fullscreen ) {
        DEVMODE dmScreenSettings; // режим устройства
        memset( &dmScreenSettings, 0, sizeof( dmScreenSettings ) ); // очистка для хранения установок
        dmScreenSettings.dmSize = sizeof( dmScreenSettings ); // размер структуры DEVMODE
        dmScreenSettings.dmPelsWidth = width;
        dmScreenSettings.dmPelsHeight = height;
        dmScreenSettings.dmBitsPerPel = bits;
        dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; // режим пикселя

        // Пытаемся установить выбранный режим и получить результат.  Примечание: CDS_FULLSCREEN убирает панель управления.
        if ( ChangeDisplaySettings( &dmScreenSettings, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) {
            // Если переключение в полноэкранный режим невозможно, будет предложено два варианта: оконный режим или выход.
            if ( MessageBox( NULL, "Невозможно воспользоваться полноэкранным режимом.\nИспользовать оконный режим?", "GL", MB_YESNO|MB_ICONEXCLAMATION ) == IDYES ) {
                fullscreen = false; // выбор оконного режима
            } else {
                // Выскакивающее окно, сообщающее пользователю о закрытие окна.
                MessageBox( NULL, "Дальнейшее выполнение программы невозможно.\nНажмите OK, чтобы завершить работу с приложением.", "Ошибка", MB_OK|MB_ICONSTOP );
                return false;
            }
        }
    }

    if ( fullscreen ) { // остались ли в полноэкранном режиме
        dwExStyle = WS_EX_APPWINDOW;
        dwStyle = WS_POPUP;
        ShowCursor( false );
    } else {
        dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle = WS_OVERLAPPEDWINDOW;
    }

    AdjustWindowRectEx( &WindowRect, dwStyle, false, dwExStyle ); // подбирает окну подходящие размеры

    if ( !( hWnd = CreateWindowEx( dwExStyle, "OpenGL", String(title).t_str(), WS_CLIPSIBLINGS|WS_CLIPCHILDREN|dwStyle, 0, 0, WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top, NULL, NULL, appInstance, NULL ) ) ) {
        KillGLWindow(); // восстановить экран
        MessageBox( NULL, "Ошибка создания окна.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }

    static PIXELFORMATDESCRIPTOR pfd = { // pfd сообщает Windows каким будет вывод на экран каждого пикселя
        sizeof( PIXELFORMATDESCRIPTOR ), // Размер дескриптора данного формата пикселей
        1, // номер версии
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA, // требуется ргба формат
        bits, // вибирается бит глубины цвета
        0, 0, 0, 0, 0, 0, // игнорирование цветовых битов
        0, // нет буфера прозрачности
        0, // сдвиговый бит игнорируется
        0, // нет буфера-накопителя
        0, 0, 0, 0, // биты накопления игнорируются
        32, // 32-битный З-буфер (буфер глубины)
        0, // нет буфера трафарета
        0, // нет вспомогательных буферов
        PFD_MAIN_PLANE, // главный слой рисования
        0, // зарезервировано
        0, 0, 0 // маски слоя игнорируются
    };

    if ( !( hDC = GetDC( hWnd ) ) ) { // можем ли получить контекст устройства
        KillGLWindow(); // восстанавливаем экран
        MessageBox( NULL, "Невозможно получить DC.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }

    if ( !( PixelFormat = ChoosePixelFormat( hDC, &pfd ) ) ) { // найден ли подходящий формат пикселя
        KillGLWindow(); // восстанавливаем экран
        MessageBox( NULL, "Не найден подходящий формат пикселя.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }

    if ( !SetPixelFormat( hDC, PixelFormat, &pfd ) ) { // возможно ли установить формат пикселя
        KillGLWindow(); // восстанавливаем экран
        MessageBox( NULL, "Невозможно установить формат пикселя.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }

    if ( !( hRC = wglCreateContext( hDC ) ) ) { // возможно ли установить контекст рендеринга
        KillGLWindow(); // восстанавливаем экран
        MessageBox( NULL, "Невозможно установить контекст рендеринга.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }

    if ( !wglMakeCurrent( hDC, hRC ) ) { // попытка активировать контекст рендеринга
        KillGLWindow(); // восстанавливаем экран
        MessageBox( NULL, "Невозможно активировать контекст рендеринга.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }

    ShowWindow( hWnd, SW_SHOW );
    SetForegroundWindow( hWnd ); // слегка повышаем приоритет проги
    SetFocus( hWnd );
    ReSizeGLScene( width, height ); // Настроим перспективу для нашего OpenGL экрана.

    if ( !InitGL() ) {
        KillGLWindow(); // восстанавливаем экран
        MessageBox( NULL, "Произошла ошибка инициализации.", "Ошибка", MB_OK|MB_ICONEXCLAMATION );
        return false;
    }
}

LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
    switch ( uMsg ) {
    case WM_ACTIVATE: // проверка сообщения активности окна
        if ( !HIWORD( wParam ) ) { // проверяем состояние минимизации
            active = true;
        } else {
            active = false;
        }
        return 0;
        
    case WM_SYSCOMMAND: // перехватываем системную команду
        if ( wParam == SC_SCREENSAVE || wParam == SC_MONITORPOWER ) {
            return 0;
        }
        break;

    case WM_CLOSE:
        PostQuitMessage(0); // отправляем сообщение о выходе
        return 0; // вернуться назад

    case WM_KEYDOWN:
        keys[ wParam ] = true;
        return 0;

    case WM_KEYUP:
        keys[ wParam ] = false;
        return 0;

    case WM_SIZE:
        ReSizeGLScene( LOWORD(lParam), HIWORD(lParam) ); // Младшее слово=Width, старшее слово=Height
        return 0;
    }
    return DefWindowProc( hWnd, uMsg, wParam, lParam ); // пересылаем все необработанные сообщения
}

// Загрузка картинки и конвертирование в текстуру (используется AUXlib)
GLvoid LoadGLTextures() {
    // загрузка картинки
    Graphics::TBitmap *texture1 = new Graphics::TBitmap;
    texture1->LoadFromResourceName( (int)appInstance, "TX5" );
    //texture1->PixelFormat = pf32bit;

    // создание текстуры
    glGenTextures( 1, &texture[0] );
    glBindTexture( GL_TEXTURE_2D, texture[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, texture1->Width, texture1->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture1->ScanLine[ texture1->Width-1 ] );
}


Вот тут загружаются текстуры:
Код

// Загрузка картинки и конвертирование в текстуру (используется AUXlib)
GLvoid LoadGLTextures() {
    // загрузка картинки
    Graphics::TBitmap *texture1 = new Graphics::TBitmap;
    texture1->LoadFromResourceName( (int)appInstance, "TX5" );
    //texture1->PixelFormat = pf32bit;

    // создание текстуры
    glGenTextures( 1, &texture[0] );
    glBindTexture( GL_TEXTURE_2D, texture[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, texture1->Width, texture1->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture1->ScanLine[ texture1->Width-1 ] );
}


Загружаю я, как видно, через библиотеку Graphics, иным способом, нежели в статье обучения, вместо GL_RGB использую GL_RGBA, иначе не понятно что вообще с текстурой творится. В оригинале (статье) эта функция описана так:
Код

GLvoid LoadGLTextures()
{
    // Загрузка картинки
    AUX_RGBImageRec *texture1;
    texture1 = auxDIBImageLoad("Data/NeHe.bmp");

    // Создание текстуры
    glGenTextures(1, &texture[0]);
    glBindTexture(GL_TEXTURE_2D, texture[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, texture1->sizeX, texture1->sizeY, 0,
    GL_RGB, GL_UNSIGNED_BYTE, texture1->data);
}

Функция auxDIBImageLoad() вызывает ошибку, в общем-то не факт, что в ней одной дело. Своим методом я выдёгиваю тот же BITMAP из ресурсов. Картинка загружается, всё хорошо, да вот беда! С цветами что-то не так, как будто один из каналов пропадает или местами меняются, даже не знаю. В общем любая картинка становится синеватого оттенка. Сколько ни бился, чего не перепробовал, а получилось только так. Кто-нибудь может подсказать в чём проблема с этими цветами? И как заставить GL отображать текстуру с правильными цветами, истинными?
PM   Вверх
Alexeis
Дата 31.12.2010, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 5
Всего: 459



Цитата(InfMag @  31.12.2010,  05:58 Найти цитируемый пост)
Функция auxDIBImageLoad() вызывает ошибку, в общем-то не факт, что в ней одной дело. Своим методом я выдёгиваю тот же BITMAP из ресурсов. Картинка загружается, всё хорошо, да вот беда! 

  Думаю проблема в том, что поменялись местами красный и синий каналы. Там есть некторая особенность в формате битмапа. На сайте Nehe также можно найти заменитель функции auxDIBImageLoad http://nehe.gamedev.net/counter.asp?file=f...replacement.zip


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
InfMag
Дата 31.12.2010, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



***


Профиль
Группа: Завсегдатай
Сообщений: 1037
Регистрация: 21.11.2004

Репутация: нет
Всего: 4



УРА!
Alexeis, спасибо за ссылку! Я ей конечно весьма своеобразно воспользовался и не по назначению smile
В общем файл там CPP, довольно странный, даже компилить не пытался, всего две функции bool NeHeLoadBitmap() и BOOL Initialize() и вторая внезапно обрывается.
Код

BOOL Initialize (GL_Window* window, Keys* keys)                            // Any GL Init Code & User Initialiazation Goes Here
{
    g_window    = window;
    g_keys        = keys;

    // Start Of User Initialization
    if (!NeHeLoadBitmap("Data/NeHe.bmp", texture[0]))                    // Load The Bitmap
        return FALSE;                                                    // Return False If Loading Failed

Но до этого места я не дошёл. Попробовал пару способов и обратил внимание на BITMAP формат и вытаскивание из хендла. В общем вот что получилось:
Код

GLvoid LoadGLTextures() {
    // загрузка картинки
    Graphics::TBitmap *TXS = new Graphics::TBitmap;
    TXS->LoadFromResourceName( (int)appInstance, "M32A" );
    BITMAP BMP;
    GetObject( TXS->ReleaseHandle(), sizeof(BMP), &BMP );

    // Создание текстуры с фильтром по соседним пикселям
    glGenTextures( 1, &texture[0] );
    glBindTexture( GL_TEXTURE_2D, texture[0] );
    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, 3, BMP.bmWidth, BMP.bmHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, BMP.bmBits );

    glGenTextures( 1, &texture[1] );
    glBindTexture( GL_TEXTURE_2D, texture[1] );
    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, BMP.bmWidth, BMP.bmHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, BMP.bmBits );

    glGenTextures( 1, &texture[2] );
    glBindTexture( GL_TEXTURE_2D, texture[2] );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, BMP.bmWidth, BMP.bmHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, BMP.bmBits );

    free( TXS ); // освобождение памяти под структуру
}

Это конечно вариант от продолжения моих изучений, но вот в чём была собственно суть:
  • Я объявил чистый BITMAP BMP;
  • Стырил в него картинку из BITMAP хэндла GetObject( TXS->ReleaseHandle(), sizeof(BMP), &BMP );
  • И уже при конечном создании текстуры чрез glTextImage2D() задавал параметр GL_BGRA_EXT вместо GL_RGBA (с приставкой A, ибо БМП у меня 32 бита с альфаканалом)
  • И в той же функции ссылался на BMP.bmBits вместо TXS->ScanLine[ TXS->Width-1 ]
GL_BGRA_EXT - тут-то и зарыт видимо секрет smile Не RBG порядок, а BGR.
Проблема решена!

Добавлено через 9 минут и 35 секунд
Тут главное аккуратный выбор между GL_BGRA_EXT и GL_BGR_EXT, ибо если неправильно выбрать - программа падает. Можно определялку сделать, чтобы автоматом варьировалось.
Для 32бит (с альфа каналом) BGRA
Для 24бит (там нет альфа-канала) BGR
PM   Вверх
Alexeis
Дата 31.12.2010, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 5
Всего: 459



Цитата(InfMag @  31.12.2010,  20:53 Найти цитируемый пост)
Для 24бит (там нет альфа-канала) BGR 

  В файле и в памяти Windows Bitmap цвета хранятся именно в таком порядке.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Вы можете найти полезным что...
Alexeis
Rickert
  • Английская документация по DirectX лежит где-то здесь.
  • Английская документация по OpenGL лежит где-то там.
  • Гейм-дев у нас обсуждают где-то тут

Ждём вас! С уважением, Alexeis, Rickert.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Мультимедия, OpenGL/DirectX | Следующая тема »


 




[ Время генерации скрипта: 0.1451 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.