Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Текстура в OpenGL


Автор: Prolss 19.5.2011, 19:03
Помогите пожалуйсто.  Скачал исходник с ним папка "Data" в ней файл .bmp  Куда кидать .bmp незнаю. Куда не пробовал ложить, не компилится.. Вот код:
Код
#include <windows.h>        // Заголовочный файл для Windows
#include <gl\gl.h>            // Заголовочный файл для OpenGL32 библиотеки
#include <gl\glu.h>            // Заголовочный файл для GLu32 библиотеки
#include <gl\glaux.h>        // Заголовочный файл для GLaux библиотеки

static HGLRC hRC;        // Постоянный контекст рендеринга
static HDC hDC;            // Приватный контекст устройства GDI

GLfloat    xrot;            // Вращение X
GLfloat    yrot;            // Y 
GLfloat    zrot;            // Z  

GLuint    texture[1];            // Место для одной текстуры

BOOL    keys[256];        // Массив для процедуры обработки клавиатуры

// Загрузка картинки и конвертирование в текстуру
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);
}

GLvoid InitGL(GLsizei Width, GLsizei Height)    // Вызвать после создания окна GL
{
    LoadGLTextures();            // Загрузка текстур
    glEnable(GL_TEXTURE_2D);    // Разрешение наложение текстуры

    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,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
                            // Вычислить соотношение геометрических размеров для окна
    glMatrixMode(GL_MODELVIEW);// Выбор матрицы просмотра модели
}

GLvoid ReSizeGLScene(GLsizei Width, GLsizei Height)
{
    if (Height==0)        // Предотвращение деления на ноль, если окно слишком мало
        Height=1;

    glViewport(0, 0, Width, Height);
        // Сброс текущей области вывода и перспективных преобразований

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

    gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
        // Вычисление соотношения геометрических размеров для окна
    glMatrixMode(GL_MODELVIEW);    // Выбор матрицы просмотра модели
}

GLvoid DrawGLScene(GLvoid)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0f,0.0f,-5.0f);
    glRotatef(xrot,1.0f,0.0f,0.0f);        // Вращение по оси X
    glRotatef(yrot,0.0f,1.0f,0.0f);            // Вращение по оси Y
    glRotatef(zrot,0.0f,0.0f,1.0f);            // Вращение по оси Z
    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(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, 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, 1.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(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();
    xrot+=1.3f;            // Ось вращения X
    yrot+=1.2f;                // Ось вращения Y
    zrot+=1.4f;                // Ось вращения Z
}

LRESULT CALLBACK WndProc(
                HWND    hWnd,
                UINT    message,
                WPARAM    wParam,
                LPARAM    lParam)
{
    RECT    Screen;        // используется позднее для размеров окна
    GLuint    PixelFormat;
    static    PIXELFORMATDESCRIPTOR pfd=
    {
        sizeof(PIXELFORMATDESCRIPTOR),    // Размер этой структуры
        1,                // Номер версии (?)
        PFD_DRAW_TO_WINDOW |// Формат для Окна
        PFD_SUPPORT_OPENGL |// Формат для OpenGL
        PFD_DOUBLEBUFFER,// Формат для двойного буфера
        PFD_TYPE_RGBA,    // Требуется RGBA формат
        16,                // Выбор 16 бит глубины цвета
        0, 0, 0, 0, 0, 0,// Игнорирование цветовых битов (?)
        0,                // нет буфера прозрачности
        0,                // Сдвиговый бит игнорируется (?)
        0,                // Нет буфера аккумуляции
        0, 0, 0, 0,        // Биты аккумуляции игнорируются (?)
        16,                // 16 битный Z-буфер (буфер глубины)  
        0,                // Нет буфера траффарета
        0,                // Нет вспомогательных буферов (?)
        PFD_MAIN_PLANE,    // Главный слой рисования
        0,                // Резерв (?)
        0, 0, 0            // Маски слоя игнорируются (?)
    };
    switch (message)    // Тип сообщения
    {
        case WM_CREATE:
        hDC = GetDC(hWnd);    // Получить контекст устройства для окна
        PixelFormat = ChoosePixelFormat(hDC, &pfd);
            // Найти ближайшее совпадение для нашего формата пикселов
        if (!PixelFormat)
        {
            MessageBox(0,"Can't Find A Suitable PixelFormat.","Error",MB_OK|MB_ICONERROR);
            PostQuitMessage(0);
            // Это сообщение говорит, что программа должна завершится
            break;    // Предтовращение повтора кода
        }
        if(!SetPixelFormat(hDC,PixelFormat,&pfd))
        {
            MessageBox(0,"Can't Set The PixelFormat.","Error",MB_OK|MB_ICONERROR);
            PostQuitMessage(0);
            break;
        }
        hRC = wglCreateContext(hDC);
        if(!hRC)
        {
            MessageBox(0,"Can't Create A GL Rendering Context.","Error",MB_OK|MB_ICONERROR);
            PostQuitMessage(0);
            break;
        }
        if(!wglMakeCurrent(hDC, hRC))
        {
            MessageBox(0,"Can't activate GLRC.","Error",MB_OK|MB_ICONERROR);
            PostQuitMessage(0);
            break;
        }
        GetClientRect(hWnd, &Screen);
        InitGL(Screen.right, Screen.bottom);
        break;

        case WM_DESTROY:
        case WM_CLOSE:
        ChangeDisplaySettings(NULL, 0);

        wglMakeCurrent(hDC,NULL);
        wglDeleteContext(hRC);
        ReleaseDC(hWnd,hDC);

        PostQuitMessage(0);
        break;

        case WM_KEYDOWN:
        keys[wParam] = TRUE;
        break;

        case WM_KEYUP:
        keys[wParam] = FALSE;
        break;

        case WM_SIZE:
        ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
        break;

        default:
    return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (0);
}

int WINAPI WinMain(
        HINSTANCE hInstance,
        HINSTANCE hPrevInstance, 
        LPSTR lpCmdLine,
        int nCmdShow)
{
    MSG        msg;    // Структура сообщения Windows
    WNDCLASS    wc; // Структура класса Windows для установки типа окна
    HWND        hWnd;// Сохранение дискриптора окна

    wc.style            = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    wc.lpfnWndProc        = (WNDPROC) WndProc;
    wc.cbClsExtra        = 0;
    wc.cbWndExtra        = 0;
    wc.hInstance        = hInstance;
    wc.hIcon            = NULL;
    wc.hCursor            = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground    = NULL;
    wc.lpszMenuName        = NULL;
    wc.lpszClassName    = "OpenGL WinClass";

    if(!RegisterClass(&wc))
    {
    MessageBox(0,"Failed To Register The Window Class.","Error",MB_OK|MB_ICONERROR);
    return FALSE;
    }

    hWnd = CreateWindow(
    "OpenGL WinClass",
    "Jeff Molofee's GL Code Tutorial ... NeHe '99",    // Заголовок вверху окна

    WS_POPUP |
    WS_CLIPCHILDREN |
    WS_CLIPSIBLINGS,

    0, 0,            // Позиция окна на экране
    640, 480,        // Ширина и высота окна

    NULL,
    NULL,
    hInstance,
    NULL);

    if(!hWnd)
    {
    MessageBox(0,"Window Creation Error.","Error",MB_OK|MB_ICONERROR); 
        return FALSE;
    }

    DEVMODE dmScreenSettings;            // Режим работы

    memset(&dmScreenSettings, 0, sizeof(DEVMODE));    // Очистка для хранения установок
    dmScreenSettings.dmSize    = sizeof(DEVMODE);        // Размер структуры Devmode
    dmScreenSettings.dmPelsWidth    = 640;            // Ширина экрана
    dmScreenSettings.dmPelsHeight    = 480;            // Высота экрана
    dmScreenSettings.dmFields    = DM_PELSWIDTH | DM_PELSHEIGHT;    // Режим Пиксела
    ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
    // Переключение в полный экран

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
    SetFocus(hWnd);

    while (1)
    {
        // Обработка всех сообщений
        while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
        {
            if (GetMessage(&msg, NULL, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            else
            {
                return TRUE;
            }
        }

        DrawGLScene();                // Нарисовать сцену
        SwapBuffers(hDC);            // Переключить буфер экрана
        if (keys[VK_ESCAPE]) SendMessage(hWnd,WM_CLOSE,0,0);    // Если ESC - выйти
    }
}



Вот ошибки:
 Linking...
Source1.obj : error LNK2019: unresolved external symbol _auxDIBImageLoadA@4 referenced in function "void __cdecl LoadGLTextures(void)" (?LoadGLTextures@@YAXXZ)
D:\downloads\vs2008\vvss\opkart\Debug\opkart.exe : fatal error LNK1120: 1 unresolved externals

Автор: Rickert 24.5.2011, 14:28
А при чём здесь местоположения *.bmp рисунка? Вам необходимо подключить glaux библиотеку.

Автор: Vetos 24.5.2011, 20:38
Для того чтоб это сделать, нужно скачать glaux.dll, glaux.lib, glaux.h. Незнаю, это моё ИМХО, но я бы не советовал использовать эту библиотеку, есть элементарный загрузчик *.tga файлов для текстуры, и кроме GL и стандартных Win библиотек ничего подключать не надо. 
Если всетаки glaux то закинь glaux.dll в папку с проектом, и с исполняемым файлом её также надо таскать(вроде как, вдруг у когото на компе нет этой DLL)

P.S. Заметил что это код NeHe, у него же есть урок и по загрузке TGA, посмотри его.

Автор: Prolss 25.5.2011, 02:45
У меня все библиотеки подключены.. Посмотрю tga

Автор: Prolss 26.5.2011, 22:26
Rickert, наверно вы правы.. но вроде все(glaux) подключены..
Vetos, с TGA. всё получилось. Спасибо!
 Скажите пожалуйсто, почему отдельно .exe не работает. "Прога" работает только когда в среде компилишь..
 У меня VS 2008

Автор: Vetos 27.5.2011, 00:17
скинь скрин проекта, тоесть дерево каталогов, пооткрывай в проводнике, сделай скрин в паинте обрежь и закинь сюда. Если не работает на другом компе, тогда какая ошибка, если на твоем, опять же какая ошибка? Перед компиляцией нужно выбрать Release, появится одноименная папочка, exe нужно брать оттуда(это если вдруг ехе ты берешь из Debug).

Вообщем берешь exe из Release, если текстуры и (или) модели(или)еще чего имеется, закидываешь в папку с ехе, вообщем глянь как я собираю. Если вдруг используешь какую либо нестандартную библиотеку, в папку с исполняемым файлом также необходимо закинуть DLL.
Вообщем посмотри поковыряй если чо пиши smile 

Автор: Prolss 27.5.2011, 00:49
То как ты сделал скрин, я чёто не пойму как делать.. Вот что происходит "запуская" отдельно .exe :

Через Release, тоже самое..

Автор: Vetos 27.5.2011, 17:48
Хех, ну онож тебе пишет что неможет найти текстуру)))и изза этого непроходит инициализацию.
Вообщем что тебе нужно для зборки приложения:
1) Исполняемый файл(он у тебя есть и отлично работает!)
2) Файл(ы) с текстурой(ами), которую(е) ты используешь.

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

Если неполучается, тогда скинь мне пути фалов ехе и текстуры, я тебе тогда скажу точно что куда положить smile 

Автор: Prolss 27.5.2011, 18:32
Vetos, Спасибо! работает... Жаль, я плюс поставить не могу(надо 100постов), а можно как то запихнуть текстуру в .exe ?

Автор: Vetos 28.5.2011, 11:49
Да, можно! Только вначале нужно написать прогу, которая загрузит в память TGA(ето есть у NeHe smile ), а потом создаст текстовый файл, в котором будут циферки. Т.е. по 3 циферки на пиксель текстуры.Если текстура 256 на 256, то таких циферок должно быть 256*256*3. Когда будет текстовый файл, можно будет обьявить в коде одномерный массив и скопировать с текстового файла эти циферки. Для текстуры 2Х2 это будет выглядеть так:

Код

GLbyte TextureMas = {239,249,255,198,239,249,255,229,29,255,34,67};


потом просто скармливаешь этот массив ОГЛу примерно так:

Код

 glTexImage2D(GL_TEXTURE_2D, 0, 3, sizeX(здесь 2), sizeY(здесь 2), 0, GL_RGB, GL_UNSIGNED_BYTE, TextureMas);



Скорее всего существует еще несколько способов, но это самый простой(или нет?)))))
Ввобщем думаю принцип понятен. Если ты не можешь(или нехочешь) заморачиваться с переводом массива в текстовый файл, можешь набрать цвета пиксело вручную smile. Гг, но если текстура 512Х512, то это получиться 512*512*3= 786432 циферки. Думаю набирать вручную будет неочень приятно smile 

Автор: Prolss 28.5.2011, 12:12
Vetos , спасибо ещё раз , буду "вникать"...
Прошу прощение за наглость(прсто вы один кто помогает).. вы не могли бы мне чего нибудь посоветовать по решению ошибок в GLAUX(в инете много интересных примеров тот же нехе). 
 .lib, .dll, и .h от GLAUX, вроде закинул(туда где и glu,glut..)но всё равно те же ошибки что в 1посте писал.. может дело в коде?

Автор: Vetos 28.5.2011, 13:31
Да, в коде  smile напиши так:
Код

#include <windows.h>        // Заголовочный файл для Windows
#include <gl\gl.h>            // Заголовочный файл для OpenGL32 библиотеки
#include <gl\glu.h>            // Заголовочный файл для GLu32 библиотеки
#include <gl\glaux.h>        // Заголовочный файл для GLaux библиотеки

#pragma comment(lib,"glaux.lib")


просто либу нужно еще в настройках проекта прописать, но проще через прагму коммент)))

Автор: Prolss 28.5.2011, 17:25
Цитата(Vetos @ 28.5.2011,  13:31)
Да, в коде  smile напиши так:
Код

#include <windows.h>        // Заголовочный файл для Windows
#include <gl\gl.h>            // Заголовочный файл для OpenGL32 библиотеки
#include <gl\glu.h>            // Заголовочный файл для GLu32 библиотеки
#include <gl\glaux.h>        // Заголовочный файл для GLaux библиотеки

#pragma comment(lib,"glaux.lib")


просто либу нужно еще в настройках проекта прописать, но проще через прагму коммент)))

Vetos, не помогает, выдаёт:

lesson6.cpp
       d:\downloads\vs2008\vvss\lesson06\lesson6.cpp(41) : warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
        c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(237) : see declaration of 'fopen'
Linking...
lesson6.obj : error LNK2019: unresolved external symbol _auxDIBImageLoadA@4 referenced in function "struct _AUX_RGBImageRec * __cdecl LoadBMP(char *)" (?LoadBMP@@YAPAU_AUX_RGBImageRec@@PAD@Z)
.\Debug/Lesson6.exe : fatal error LNK1120: 1 unresolved externals 
 
Читал чтобы не было этого - > warning C4996: 'fopen',  надо это: _CRT_SECURE_NO_WARNINGS  прописать в project/CC++/Preprocessor/Preprocessor Definitions,
прописал но не чего не изменилось.. 
PS: у меня работают все (GLAUX) примеры,исходники в которых не используются текстуры, а примеры с текстурами не работают..

Автор: Vetos 28.5.2011, 18:43
Незнаю у меня все работает и без прагмы, в уроках нехе в настройках проекта либа уже прописана.
Вообщем возьми поменяй свою либу, возможно она у тебя старая.

Автор: Prolss 28.5.2011, 19:55
Vetos, Ура!!! всё,всё работает.. в 101раз СПАСИБО!
Странно както ты выложил GLAUX, 1998г.., а у меня стоял 2006года и  вес чуть больше.. поменял на твой и всё заработало..  вот мой файл(glaux):

Автор: Prolss 28.5.2011, 19:55
Vetos, Ура!!! всё,всё работает.. в 101раз СПАСИБО!
Странно както ты выложил GLAUX, 1998г.., а у меня стоял 2006года и  вес чуть больше.. поменял на твой и всё заработало..  вот мой файл(glaux):

Автор: Vetos 28.5.2011, 23:00
Ну вот и отлично, поставь пожалуйсто галочку в опциях темы(пометить вопрос решенным) smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)