Форум программистов, компьютерный форум, киберфорум
Наши страницы
OpenGL
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
MrLinder
0 / 0 / 0
Регистрация: 04.10.2014
Сообщений: 41
1

Не загружается текстура в OpenGL (OpenGL + Классы)

07.10.2015, 01:00. Просмотров 574. Ответов 5
Метки нет (Все метки)

Здравствуйте! Пишу движок для игры. Первый прототип я сделал процедурно. Все работает как надо.

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



Ниже код максимально упрощенный

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glext.h>
#include <GL/wglext.h>
 
#include <iostream>
#include <fstream>
using namespace std;
 
GLuint texture_id[1];
 
class Create
{
    int NumTextur;                  //Количество текстур
 
    unsigned long image_size;   
 
    typedef struct pixel{       //Тип данных для пикселя
        unsigned char ged;      //красная компонента цвета
        unsigned char green;    //зеленая компонента цвета
        unsigned char blue; //синяя компонента цвета
    }pixel_type;                // имя пиксельного типа
        
    typedef struct pixel_array{     //Тип данных для массива структур пикселей
        pixel_type *array_of_pixel; //Двумерный массив для пикселей пиксельного типа
        long height;                    //высота изображения
        long width;                     //ширина изображения
    }pixel_array_type;              //имя пикселеного массива
 
    typedef struct texture_package          //Структтура для считанных текстур
    {
        pixel_array_type* pixel_array;  //массив для массивов счетианных пикселе
    } TEXTURES;                             //тип данных определяющий массив паксельных массивов
    
    BITMAPFILEHEADER header;            //Заголововчный файл растровой графики (14 байт)
    BITMAPINFOHEADER info_header;   //Информационный заголовок растрового массива (40 байт) 
    
    TEXTURES* texture_array;
public:
    Create();
    void Loading(const char*);
    void parse_texture_file(ifstream &, int);
};
 
Create::Create()
{
    NumTextur = 1;  
    image_size = 0; 
 
    texture_array = new TEXTURES[NumTextur];  // Выдяляем память для массива паксельных массивов(текстуры.)
        
    for ( int i = 0; i < NumTextur; ++i)            //Инициализация и обнудение всего содержимого струтктуры
    {
        texture_array[i].pixel_array = new pixel_array_type;
        texture_array[i].pixel_array->array_of_pixel = NULL;
        texture_array[i].pixel_array->height = 0;
        texture_array[i].pixel_array->width = 0;
    }
}
 
void Create::Loading(const char* path)
{
        ifstream bmp_file;
        bmp_file.open((char*)path, ios::in | ios::binary);
        
        parse_texture_file(bmp_file, 0); //Поток подключенный к файлу, индекс для данной текстуры
}
 
void Create::parse_texture_file(ifstream &bmp_file, int which_texture)
{
    // Читаем первую структуру (BITMAPFILEHEADER)   
    bmp_file.read((char*)&header.bfType, sizeof(header.bfType));
    bmp_file.read((char*)&header.bfSize, sizeof(header.bfSize));
    bmp_file.read((char*)&header.bfReserved1, sizeof(header.bfReserved1));
    bmp_file.read((char*)&header.bfReserved2, sizeof(header.bfReserved2));
    bmp_file.read((char*)&header.bfOffBits, sizeof(header.bfOffBits));
    
    // Читаем вторую структуру (BITMAPINFOHEADER) чтобы узнать размер буфера пикселей
    bmp_file.read((char*)&info_header, sizeof(info_header));
    
    if(info_header.biSizeImage == 0)  //размер картинки в байтах. Если изображение несжато, то здесь должен быть ноль. 
    {       // считаем вручную
        image_size = info_header.biWidth * 3 + info_header.biWidth % 4;
        image_size *= info_header.biHeight;         // считаем вручную
    }
    else    // иначе - берем как есть
        image_size = info_header.biSizeImage;   
    
    bmp_file.seekg(header.bfOffBits, ios::beg);     //Смещаемся к буферу пикселей (header.bfOffBits байтов, считая от начала файла ios::beg) Смещение, с которого начинается само изображение (растр).
 
    //Присваиваем значения размеров изображения 
    texture_array[which_texture].pixel_array->height = info_header.biHeight;    //присваиваем значения из biHeight
    texture_array[which_texture].pixel_array->width = info_header.biWidth;  //присваиваем значения из biWidth   
 
    // Создаем  массив под структуры пикселя
    texture_array[which_texture].pixel_array->array_of_pixel = new pixel_type[texture_array[which_texture].pixel_array->height * texture_array[which_texture].pixel_array->width];  //выделяем память строк
 
    int length_str = (3 * texture_array[which_texture].pixel_array->width + 3) & (-4);  // длина строки в файле, включая округление вверх до кратного 4
    int n = length_str - texture_array[which_texture].pixel_array->width * 3;               // количество байтов выравнивания в строке
    
    //присваиваем значения массиву      
    for ( int j = 0; j < texture_array[which_texture].pixel_array->height * texture_array[which_texture].pixel_array->width; ++j) 
    {
        bmp_file.read((char*)&texture_array[which_texture].pixel_array->array_of_pixel[j], sizeof(pixel_type));
 
        for (int k = 0; k < n; ++k)                 // пропуск байтов выравнивания
            bmp_file.get();
    }
    bmp_file.close();   
 
    glGenTextures(which_texture, &texture_id[which_texture]);  //генерирует уникальные имена для текстур
    glBindTexture(GL_TEXTURE_2D, texture_id[which_texture]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texture_array[which_texture].pixel_array->width, texture_array[which_texture].pixel_array->height, GL_BGR, GL_UNSIGNED_BYTE, texture_array[which_texture].pixel_array->array_of_pixel);
}
 
void Display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glColor3f(0.0, 1.0, 0.0);    //Координаты  ()3 перные но пока что видим 2 оси X и Y.
            
        glBegin(GL_LINES); 
            glVertex3f (0,0,0);    //x,y,z
            glVertex3f (0,0,500); //x,y,z
        glEnd();
        glBegin(GL_LINES); 
            glVertex3f (0,0,0);    //x,y,z
            glVertex3f (0,500,0); //x,y,z
        glEnd();
        glBegin(GL_LINES); 
            glVertex3f (0,0,0);    //x,y,z
            glVertex3f (400,0,0); //x,y,z
        glEnd();
        
        
        glEnable(GL_TEXTURE_2D);     
        
        glPushMatrix();
            
            glTranslatef(-110,0,0);
            glBindTexture(GL_TEXTURE_2D, texture_id[0]);
            glColor3f(1.0, 1.0, 1.0);   //Квадрат на который будем натягивать текстуру
                glBegin(GL_QUADS);
                    glTexCoord2d(0,0); glVertex2d(-100,-100 );  //нижний левый угол
                    glTexCoord2d(0,1); glVertex2d(-100, 100 );    //верний левый
                    glTexCoord2d(1,1); glVertex2d( 100, 100 );    //верхний правый
                    glTexCoord2d(1,0); glVertex2d( 100,-100 );  //нижний правый
                glEnd();  
        glPopMatrix();
            
    glDisable(GL_TEXTURE_2D);
 
glutSwapBuffers();
 
}
 
void Init()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-450, 450, -525, 525, 1.0, 0.0);
}
 
int main(int argc, char** argv)
{
    Create *World = new Create();
             World->Loading("ceiling.bmp");
    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(950, 937);
    glutInitWindowPosition(150,0);
    glutCreateWindow("Load Area "); 
    
    glutDisplayFunc(Display);  
    
    Init();
    
    glutMainLoop();
 
    delete World;
    return 0;
}
0
Миниатюры
Не загружается текстура в OpenGL (OpenGL + Классы)  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.10.2015, 01:00
Ответы с готовыми решениями:

Текстура и OpenGL
Собрал например шар, ниже часть кода от него. Можно ли в OpenGL одеть текстуру...

Текстура в OpenGL
Создала текстуру, всё хорошо, рисует, но не рисует линию почему-то, а просто...

2d текстура в openGL
3 дня дерзаю интернет, так и не наткнулся ни на 1 полностью реализованный...

3d текстура. OpenGL, glut
Доброго времени суток! Интересует такой вопрос. Возможно ли каким-то образом...

Текстовая текстура в OpenGL (Delphi)
Здравствуйте, форумчане. Вопрос нетривиальный. Весь нет прогуглил, но ответ...

5
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
07.10.2015, 02:56 2
А байты выравнивания зачем пропускаешь? Они там не для размера файла а для выравнивания сканлайнов именно в памяти. И пропускаешь их почему то после каждого пикселя.

glGenTextures(which_texture, &texture_id[which_texture]);
может надо
glGenTextures(1, &texture_id[which_texture]); ?
А то он у тебя получается 0 Id генерирует. Первый параметр - сколько Id сгенерировать. а wich_texture у тебя насколько понимаю равно 0?

Добавлено через 9 минут
Да кстати, средства ОС для загрузки BMP использовать не пробовал? и надежней получается. А загрузку текстуры из файла и ее заброску в видеопямять лучше разделить. Т.к. форматы файлов могут а последствии и добавится. Соответственно сделать загрузку в видео из BMP образа в памяти методом рендера (он в последствии может быть не единственным), а подгрузку из форматов - методами кодеков, вызываемыми из менеджера ресурсов.
Что то в таком духе:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
unsigned TGLRender::CreateTexture(HBITMAP Bitmap) {
    if (!Bitmap)
        return 0;
    unsigned ret;
    BITMAP Bmp;
    GetObject(Bitmap, sizeof(Bmp), &Bmp);
    if (!Bmp.bmBits)
        return 0;
    glGenTextures(1, &ret);
    glBindTexture(GL_TEXTURE_2D, ret);
 
    gluBuild2DMipmaps(GL_TEXTURE_2D, Bmp.bmBitsPixel / 8, Bmp.bmWidth,
        Bmp.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, Bmp.bmBits);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
        GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
        GL_LINEAR_MIPMAP_LINEAR);
    return ret;
 
};
    unsigned TGame::LoadTexture(char *FileName) {
        char Path[255];
        strcpy(Path, TexturesPath);
        strcat(Path, FileName);
 
        HBITMAP Bitmap = (HBITMAP)LoadImageA(NULL, Path, IMAGE_BITMAP, 0, 0,
            LR_LOADFROMFILE | LR_CREATEDIBSECTION);
        int ret=Device->CreateTexture(Bitmap);
        if (ret) {
            Textures.push_back(ret);
        }
        return ret;
 
    }
1
MrLinder
0 / 0 / 0
Регистрация: 04.10.2014
Сообщений: 41
07.10.2015, 21:05  [ТС] 3
Fulcrum_013,

Добавлено через 26 секунд
Fulcrum_013, Ситуация не поменялась, по прежнему белый квадрат, самое интересное то что если все очтавить так же только убрать класс, то появляется текстура. а с классом нет. но почему???

Добавлено через 1 минуту
Да кстати, средства ОС для загрузки BMP использовать не пробовал?
нет. а как это?.
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
07.10.2015, 21:07 4
Цитата Сообщение от MrLinder Посмотреть сообщение
нет. а как это?.
Это вот так:
C++
1
2
HBITMAP Bitmap = (HBITMAP)LoadImageA(NULL, Path, IMAGE_BITMAP, 0, 0,
            LR_LOADFROMFILE | LR_CREATEDIBSECTION);
0
MrLinder
0 / 0 / 0
Регистрация: 04.10.2014
Сообщений: 41
07.10.2015, 21:09  [ТС] 5
Fulcrum_013,

А загрузку текстуры из файла и ее заброску в видеопямять лучше разделить.
А чем это разделение заключается ?

ок позже попробую разобраться в том способе который вы предлагаете.

Добавлено через 35 секунд
Но мне бы сейчас хотелось решить тем способом которым я делал.)
0
Fulcrum_013
1588 / 1071 / 124
Регистрация: 14.12.2014
Сообщений: 8,822
Завершенные тесты: 3
07.10.2015, 21:37 6
В классе есть поля которые совпадают по имени с глобальными переменными?
Нпример texture_id?
Цитата Сообщение от MrLinder Посмотреть сообщение
А чем это разделение заключается ?
Там пример кода. Один метод рендера (TGLRender::CreateTexture), другой, метод менеджера ресурсов (TGame::LoadTexture). Менеджер ресурсов подгружает BMP и отдает рендеру для загрузки а память (вызов Device->CreateTexture) Device - указатель на объект-обертку рендера. Преимущество в чем - там в Render может сидеть не только TGLREnder но и к примеру TDX9Render или TDX10Render или TDX11Render или вообще что угодно порожденное от базового класса TRender. А в загрузчике при этом оставлена точка расширения для подгрузки из любого формата. Т.е. рендер даже не задумывается в результате как подгружать текстуру, а менеджер подгрузки - как запихивать в видеопамять. В результате получается простой способ иметь возможность подгрузки любого поддерживаемого формата для любого из поддерживаемых рендеров.
1
07.10.2015, 21:37
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.10.2015, 21:37

OpenGL + Win8, не отображается текстура
Столкнулся с такой проблемой у меня не отображается текстура, не выдаёт ошибку,...

Используется лишь последняя текстура (OpenGL)
//создаю массив текстур, массив путей для них, и перечисление идентификаторов...

OpenGl под C#. Текстура отображается неверно
Недавно разобрался как использовать Tao для взаимодействия OpenGL и C#, и вот ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru