Форум программистов, компьютерный форум, киберфорум
OpenGL
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
290 / 87 / 28
Регистрация: 25.01.2016
Сообщений: 529
Записей в блоге: 1
1

Загрузка obj

08.10.2017, 04:38. Показов 3502. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, сегодня понадобилось загрузить 3д модельку в программу. Короче, очень долго мучился, и так ничего не получилось.
В общем, как загрузить?
Язык C++
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.10.2017, 04:38
Ответы с готовыми решениями:

Загрузка из obj
Короче, решил сделать такой, небольшой конвертер из obj, в собственный формат. Не получается...

Загрузка .obj
Проблема в следующем: есть файл .obj внутри данные о кубике. Гружу его для отображения в OpenGL, но...

Загрузка obj моделей
Здравствуйте. не подскажите простых библиотек для загрузки obj моделей (использую C#, а sharpGl что...

Загрузка OBJ моделей
Obj формирую c4d r13. Вопрос первый: как экспортировать нормали(знаю есть riptide, но он платный)...

11
61 / 58 / 11
Регистрация: 25.04.2017
Сообщений: 509
08.10.2017, 04:54 2
Парсить строки умеешь?
0
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,378
08.10.2017, 08:15 3
Библиотека графических примитивов. Отдаю всем хорошим людям - не жалко
0
290 / 87 / 28
Регистрация: 25.01.2016
Сообщений: 529
Записей в блоге: 1
08.10.2017, 10:07  [ТС] 4
vxg, Здесь всё на borland C++ builder 6, а у меня visual C++ 2005

Добавлено через 38 минут
Я скопипастил код
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
#pragma hdrstop
 
#include <tchar.h>
#include <stdio.h>
 
/* функции загрузки файлов**********************************************/
 //для установки консоль на паузу
#include <conio.h>
//вывод данных в консоль
#include <iostream>
//функции работы с файлом
#include <fstream>
//функции работы с файлом
#include <sstream>
//функции работы со строками
#include <string.h>
#include <cstring>
using namespace std;
//переменная для чтения строк из файла
 string line;
//переменная ссылка на читаемый файл файл
 fstream My_File_obj;
//точки из которых будет состоять обьект
float* coords;
int* Index;
 
int  coords_index=0, Fase_index=0; //номер текущей прочитанной коордианты точки
 
struct coord
{
   float x;
   float y;
   float z;
};
struct polygons
{
   coord* point; //1 точки
};
//точка
coord* MyMass;
//полигоны
polygons* models;
//количества точек
 int point=1;
//собераем координаты в индексы
 int p=0;
//собираем обьект в единую структуру
void Compare(float* Coords, int* indexs, int count_fase, int count_point)
{
//задаем массив для точек
  MyMass = new  coord[count_point/3];
  //(coord*) malloc (count_point/3);
//задаем массив для полигонов
  models = new polygons[count_fase/4];
  //(polygons*) malloc (count_fase/4);
 
//перебираем точки и присваиваем координаты каждой с индеса 1
  for (int i = 0; i < count_point; i+=3)
  {
    MyMass[point].x=Coords[i+0]; //координата Х
    MyMass[point].y=Coords[i+1]; //координата Y
    MyMass[point].z=Coords[i+2]; //координата Z
   point++;
  }
   p=0;
   //перебираем ребра и присваиваем координаты в зависимости от индекса точки
   for (int f = 0; f < count_fase; f+=4)
   {
    models[p].point=new coord[4];
        for (int s = 0; s < 4; s++)
          models[p].point[s]= MyMass[indexs[f+s]];
 
 /*
  models[p].point[1]= MyMass[indexs[f+1]];
  models[p].point[2]= MyMass[indexs[f+2]];
  models[p].point[3]= MyMass[indexs[f+3]];     */
    p++;
   }
 
}
//читаем файл
void Rad_file_obj(char* name_file)
{
My_File_obj.open(name_file);
//открываем файл
   if (My_File_obj.is_open())
   { //если открыли будем читать данные из файла
     cout << "file open";
     //перечитсывем файл до концы
    My_File_obj.seekg (0, ios::end);
    //получаем количество считанных из файла символов
    int  File_Size = My_File_obj.tellg();
     //задаем размер временного массива для координат
    float*   Tmp_Coords = (float*) malloc (File_Size);
     //задаем размер временного массива индексов точек поверхности
    int*     Tmp_faseArray=(int*) malloc (File_Size);
    //устанавливаем в 0 элемент массива
    coords_index=0;
    Fase_index=0;
    //устанавливаем курсор в начало файла
    My_File_obj.seekg (0, ios::beg);
 
    int countpoint=0;
    int countfase=0;
     //читаем файл до конца
     while (!My_File_obj.eof())
        {
            //читаем строку текста из файла
             getline (My_File_obj,line);
             //проверяем первые два символа строки
             if ((line.c_str()[0] == 'v')&&(line.c_str()[1]==' '))
             {
                //обнуляем 1 символ
                    line[0] = ' ';
                //обнуляем 1 символ
                    line[1] = ' ';
                //чтобы функция правельно разбирала координаты обнуляем начало строки
                sscanf(line.c_str(),"%f %f %f ",
                                &Tmp_Coords[coords_index+0],   //координата X
                                &Tmp_Coords[coords_index+1], //координата Y
                                &Tmp_Coords[coords_index+2]  //координата Z
                       );
 
 
 
               //сдвигаем индекс на 3 так как 3 координаты
               coords_index+=3;
                //расчет точек
               countpoint++;
             }
        //проверяем не нашли ли грань
           if ((line.c_str()[0] == 'f')&&(line.c_str()[1]==' '))
           {
            //обнуляем 1 символ
                line[0] = ' ';
            //получаем параметры поверхности
            //     v1       v2     v3      v3
             int tmp_point[4], tmp_normal[4], tmp_texture[4];
              sscanf(line.c_str(),"%i/%i/%i%i/%i/%i%i/%i/%i%i/%i/%i",
              // номер точки  номер нормали   номер текстуры
                &tmp_point[0],&tmp_normal[0], &tmp_texture[0]  //p1
               ,&tmp_point[1],&tmp_normal[1], &tmp_texture[1]  //p2
               ,&tmp_point[2],&tmp_normal[2], &tmp_texture[2]  //p3
               ,&tmp_point[3],&tmp_normal[3], &tmp_texture[3]  //p4
              );
 
             //сохраняем индексы в массив
              Tmp_faseArray[Fase_index+0]=tmp_point[0]; //сохраняем первый индекс точки
              Tmp_faseArray[Fase_index+1]=tmp_point[1]; //сохраняем второй индекс точки
              Tmp_faseArray[Fase_index+2]=tmp_point[2]; //сохраняем третий индекс точки
              Tmp_faseArray[Fase_index+3]=tmp_point[3]; //сохраняем четвертый индекс точки
 
 
 
             Fase_index+=4;
             countfase++;
           }
        }
 
      //определяем параметры полигонов для рисования
      Compare(Tmp_Coords,Tmp_faseArray,Fase_index,coords_index );
  }
  else
   {
   //если не открыли не будем читать
     cout << "file not open";
   }
 
 
}
/*реализация OpenGL********************************************************/
#include  "glut.h"
#include <windows.h>
 GLfloat  tx=0;            // Сдвиг по оси X
GLfloat     ty=0;            // Y
GLfloat     tz=0;            // Z
GLfloat  rx=0;            // Угол поворта сцены вокруг оси X
GLfloat  ry=0;            // Y
GLint     tt=0;            // Активная плоскось: 0 - XY, 1 - XZ
 
int mx=0,my=0;                // Координаты мыши
bool ldown=false,        // Нажата левая клавиша мыши?
     rdown =false;
 
 
float size=1;
 
void Draw_Obj()
{
   /*
       glEnable(GL_ALPHA_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glEnable(GL_LIGHTING);
    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
    glEnable(GL_NORMALIZE);
    float light0_diffuse[] = {1, 1, 1};
    float light0_direction[] = {-1, -1, 0, 100};
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, light0_direction);
                                                         */
    for (int  i = 0; i < p; i++)
    {
    //рисуем каркас из линий
    //GL_POLYGON  GL_POINTS   GL_LINES GL_POLYGON GL_QUADS
        glColor3f(0,0,0);
        glBegin(GL_LINE_LOOP);
        for (int s=0; s<4; s++)
        glVertex3f(models[i].point[s].x,models[i].point[s].y,models[i].point[s].z);
        glEnd();
     //рисуем полигоны
        glColor3f(0,1,0);
        glBegin(GL_POLYGON);
        for (int s=0; s<4; s++)
        glVertex3f(models[i].point[s].x,models[i].point[s].y,models[i].point[s].z);
        glEnd();
    }
 
 
}
 
void MouseMotion(int x, int y)    //Перемешение мыши
{
    if (ldown)        // Левая кнопка
    {
        rx+=0.5*(y-my);    //Изменение угола поворота
        ry+=0.5*(x-mx);
        mx=x;
        my=y;
       //    glutPostRedisplay();    //Перерисовать экран
    }
 
    if (rdown)    //Правая
    {
        tx+=0.01*(x-mx);    //Перемещение вдоль активной плоскости
        if (tt)
            tz+=0.01*(y-my);
        else
            ty+=0.01*(my-y);
        mx=x;
        my=y;
    }
        cout <<"\n X="<< tx<< " Y= " << ty<<" Z="<< tz ;
}
 
 
void Mouse(int button, int state, int x, int y)        //Обработка щелчков мыши
{
    cout << "\nbutton "<< button << "state" << state;
 
    if (button==GLUT_LEFT_BUTTON)        //Левая кнопка
    {
        switch (state)
        {
            case GLUT_DOWN:        //Если нажата
                ldown=true;        //установить флаг
                mx=x;            //Запомнить координаты
                my=y;
                break;
            case GLUT_UP:
                ldown=false;
                break;
        }
    }
    if (button==GLUT_RIGHT_BUTTON)    //Правая кнопка
    {
        switch (state)
        {
            case GLUT_DOWN:
                rdown=true;
                mx=x;
                my=y;
                break;
            case GLUT_UP:
                rdown=false;
                break;
        }
    }
 
 
}
 
 
void Display()
{
   glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
 
    glColor3f(0.1,0.7,0.2);
    glClearColor(0.5, 0.5, 0.75, 1);
 
 //    glClearColor(0.5f, 0.5f, 0.5f, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 
 
   glPushMatrix();
   glTranslatef(tx,ty,tz);        //Перемещение и поворт объекта
        glRotatef(rx,1,0,0);
        glRotatef(ry,0,1,0);
        glScalef(size,size,size);        //Перемещение и поворт объекта
         Draw_Obj();            //Вывод объекта на экран
  glPopMatrix();
  glutSwapBuffers();
}
 
void Keyboard(unsigned char key,int x,int y)            //Обработка сообщений от клавиатуры
{
    switch (key)
    {
        case VK_ESCAPE:        //Если нажата клавиша ESC - выход
            exit(0);
        break;
            case '+':        //Если нажата клавиша ESC - выход
             size+=0.1f;
        break;
        case '-':        //Если нажата клавиша ESC - выход
             size-=0.1f;
        break;
    }
   if (size<0) size=0;
}
 void IDLE()
{
glutPostRedisplay();
}
void InitOpenGL(int argc, _TCHAR* argv[])
{
 
 
   //включаем потдержку OpenGL в приложении
    glutInit(&argc, argv);
//задаем параметры рисования картинки
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
//устанавливаем размеры окна для картинки
    glutInitWindowSize(640, 480);
//устанавливаем позицию окна
    glutInitWindowPosition(100, 100);
//создаем окно и указываем ему заголовок
    glutCreateWindow("My first Pack Man");
//вызываем функцию рисования окна
    glutDisplayFunc(Display);
//обработка нажатия клавиш
    glutKeyboardFunc(Keyboard);
 
    glutMouseFunc(Mouse);
 
    glutMotionFunc(MouseMotion);
 
    glutIdleFunc(IDLE);
 
//запускаем бесконечный цикл работы приложения
    glutMainLoop();
}
 
/**************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
//загружаем файл
cout <<"Loading cube2.obj";
  Rad_file_obj("cube2.obj");
//загружаем граяический примитив с список отображения
 
//запускаем OpenGL
   InitOpenGL(argc, argv);
    return 0;
}
, ничего не работает.
Линкер ругается на ------ Build started: Project: text, Configuration: Debug Win32 ------
Compiling...
main.cpp
.\main.cpp(122) : warning C4996: 'sscanf' was declared deprecated
C:\Program Files\Microsoft Visual Studio 8\VC\include\stdio.h(311) : see declaration of 'sscanf'
Message: 'This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
.\main.cpp(145) : warning C4996: 'sscanf' was declared deprecated
C:\Program Files\Microsoft Visual Studio 8\VC\include\stdio.h(311) : see declaration of 'sscanf'
Message: 'This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'
Linking...
Embedding manifest...
Build log was saved at "file://c:\Documents and Settings\Администратор\Рабочий стол\Проекты\ Не мои\test\text\text\Debug\BuildLog.htm"
text - 0 error(s), 2 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
0
Модератор
3388 / 2160 / 352
Регистрация: 13.01.2012
Сообщений: 8,378
09.10.2017, 06:43 5
TButton, а вы разве нашли в функциях загрузки из obj или в функциях рисования что-то специфичное для борланда? Не смешно
0
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
09.10.2017, 18:46 6
Лучший ответ Сообщение было отмечено TButton как решение

Решение

TButton, умеете рисовать квадрат заданного цвета на OpenGL с помощью двух треугольников? А кубик заданного цвета в 3D? А плоскость и кубик с наложенными текстурами? Вот эти необходимые данные нужно научиться извлекать из файла .obj и .mtl после экспорта из Blender. Нужно научиться открывать программно файлы из C++, считывать всю информацию, пробегаться по символам считанным из файла с помощь for, while и анализировать считанную информаци с помощью if, чтобы добыть: координаты вершин, цвета, текстурные координаты и т.д.
1
290 / 87 / 28
Регистрация: 25.01.2016
Сообщений: 529
Записей в блоге: 1
15.10.2017, 09:51  [ТС] 7
Цитата Сообщение от 8Observer8 Посмотреть сообщение
Нужно научиться открывать программно файлы из C++, считывать всю информацию

Добавлено через 32 минуты
Я решил всё таки сделать это на билдере, и знаете, у меня получилось загрузить модельку. Правда в ней куча дырок, но это можно исправить. Главный минус в том, что при работе, программа виснет. Вот код:
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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <gl\glu.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HWND ghRC, ghDC;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
 
BOOL bSetupPixelFormat(HDC hdc)
      {
          PIXELFORMATDESCRIPTOR pfd, *ppfd;
          int pixelformat;
          ppfd = &pfd;
          ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
          ppfd->nVersion = 1;
          ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
          ppfd->dwLayerMask = PFD_MAIN_PLANE;
          ppfd->iPixelType = PFD_TYPE_RGBA;
          ppfd->cColorBits = 16; // ãëóáèíà öâåòà
          ppfd->cDepthBits = 16;   // ðàçìåð áóôåðà ãëóáèíû
          ppfd->cAccumBits = 0;
          ppfd->cStencilBits = 0;  //  ðàçìåð áóôåðà òðàôàðåòà
          if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0)  // ïîäáîð ôîðìàòà ïèêñåëåé
          {
              MessageBox(NULL, "ChoosePixelFormat failed", "Error",
        MB_OK);
              return FALSE;
          }
          if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) // óñòàíîâêà äåñêðèïòîðà ôîðìàòà ïèêñåëé
          // â êîíòåêñòå óñòðîéñòâà
          {
              MessageBox(NULL, "SetPixelFormat failed", "Error",
        MB_OK);
              return FALSE;
          }
          return TRUE;
      }
 
 
 
void __fastcall TForm1::FormShow(TObject *Sender)
{
ghDC = GetDC(Handle);
         if (!bSetupPixelFormat(ghDC))
            Close();
         ghRC = wglCreateContext(ghDC);
         wglMakeCurrent(ghDC, ghRC);
         glClearColor(0.0, 0.0, 0.0, 0.0);
         FormResize(Sender);
         glEnable(GL_COLOR_MATERIAL);
         glEnable(GL_DEPTH_TEST);
         glEnable(GL_LIGHTING);
         glEnable(GL_LIGHT0);
           float p[4]={3,3,3,1},
                 d[3]={-1,-1,-3};
         glLightfv(GL_LIGHT0,GL_POSITION,p);
         glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,d);
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
glViewport( 0, 0, Width, Height );
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  glOrtho(-5,5, -5,5, 2,12);
  gluLookAt(0,0,5, 0,0,0, 0,1,0);
  glMatrixMode( GL_MODELVIEW );
        
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(ghRC)
        {
          wglMakeCurrent(ghDC,0);
          wglDeleteContext(ghRC);
        }
        if(ghDC)
          ReleaseDC(Handle, ghDC);
 
}
 
void Load(String fname){
TStringList *S = new TStringList();
S->LoadFromFile(fname);
S->Text=StringReplace(S->Text, ".", ",", TReplaceFlags()<< rfReplaceAll << rfIgnoreCase);
String S1,S2,S3;
for(int i =0; i<S->Count; i++){
glBegin(GL_QUADS);
int k=0;
S1="";
S2="";
S3="";
String V = S->Strings[i];
for(int j=3; j<V.Length()+1; j++){
if(V[1]=='v'){
if(k==0)
S1=S1+V[j];
if(k==1)
S2=S2+V[j];
if(k==2)
S3=S3+V[j];
if(V[j]==' '){
k++;
}
}
}
double i1,i2,i3;
if(S1!=""){
i1=StrToFloat(S1);
i2=StrToFloat(S2);
i3=StrToFloat(S3);
}
glVertex3f(i1,i2,i3);
k=0;
}
glEnd();
}
 
void Draw()
      {
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        glColor3f(0,1,0);
         Load("tt.obj");
        glRotatef(3, 0,1,0);
        SwapBuffers(ghDC);
      }
 
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Draw();
}
//---------------------------------------------------------------------------
0
290 / 87 / 28
Регистрация: 25.01.2016
Сообщений: 529
Записей в блоге: 1
15.10.2017, 09:59  [ТС] 8
Скрин
Миниатюры
Загрузка obj  
0
5158 / 2770 / 465
Регистрация: 05.10.2013
Сообщений: 7,321
Записей в блоге: 147
15.10.2017, 10:06 9
Цитата Сообщение от TButton Посмотреть сообщение
Главный минус в том, что при работе, программа виснет.
Она временно виснет на момент загрузки модели? А когда модель загружена, то нормально работает? Или как-то по-другому виснет?
0
1824 / 732 / 99
Регистрация: 01.10.2012
Сообщений: 3,746
15.10.2017, 10:53 10
Цитата Сообщение от TButton Посмотреть сообщение
, ничего не работает.
Ну как же не работает если пишет
Цитата Сообщение от TButton Посмотреть сообщение
Build: 1 succeeded
Цитата Сообщение от TButton Посмотреть сообщение
for(int i =0; i<S->Count; i++)
{
glBegin(GL_QUADS);
int k=0; S1=""; S2=""; S3="";
String V = S->Strings[i];
for(int j=3; j<V.Length()+1; j++)
{ if(V[1]=='v')
...
Шо за нетерплячка? Хотите и грузить и сразу рисовать - не много ли? Так конечно работать не будет. Сначала надо создать контейнеры, считать туда хотя бы вертексы и нормали, потом считать фейсы. А потом главное - "расшарить", то есть преобразовать из формата obj в данные OpenGL. Если хотите это сделать сами напишу подробнее.
1
290 / 87 / 28
Регистрация: 25.01.2016
Сообщений: 529
Записей в блоге: 1
15.10.2017, 12:51  [ТС] 11
Igor3D, Спасибо за хороший совет!
Всё сделал, прога не виснет. Действительно, надо было из obj в 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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#include <gl\glu.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HWND ghRC, ghDC;
double vex1[999999], vex2[999999], vex3[999999], count;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 
 
BOOL bSetupPixelFormat(HDC hdc)
      {
          PIXELFORMATDESCRIPTOR pfd, *ppfd;
          int pixelformat;
          ppfd = &pfd;
          ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
          ppfd->nVersion = 1;
          ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
          ppfd->dwLayerMask = PFD_MAIN_PLANE;
          ppfd->iPixelType = PFD_TYPE_RGBA;
          ppfd->cColorBits = 16; // ãëóáèíà öâåòà
          ppfd->cDepthBits = 16;   // ðàçìåð áóôåðà ãëóáèíû
          ppfd->cAccumBits = 0;
          ppfd->cStencilBits = 0;  //  ðàçìåð áóôåðà òðàôàðåòà
          if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0)  // ïîäáîð ôîðìàòà ïèêñåëåé
          {
              MessageBox(NULL, "ChoosePixelFormat failed", "Error",
        MB_OK);
              return FALSE;
          }
          if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) // óñòàíîâêà äåñêðèïòîðà ôîðìàòà ïèêñåëé
          // â êîíòåêñòå óñòðîéñòâà
          {
              MessageBox(NULL, "SetPixelFormat failed", "Error",
        MB_OK);
              return FALSE;
          }
          return TRUE;
      }
 
    void Load(String fname);
 
void __fastcall TForm1::FormShow(TObject *Sender)
{
ghDC = GetDC(Handle);
         if (!bSetupPixelFormat(ghDC))
            Close();
         ghRC = wglCreateContext(ghDC);
         wglMakeCurrent(ghDC, ghRC);
         glClearColor(0.0, 0.0, 0.0, 0.0);
         FormResize(Sender);
         glEnable(GL_COLOR_MATERIAL);
         glEnable(GL_DEPTH_TEST);
         glEnable(GL_LIGHTING);
         glEnable(GL_LIGHT0);
           float p[4]={3,3,3,1},
                 d[3]={-1,-1,-3};
         glLightfv(GL_LIGHT0,GL_POSITION,p);
         glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,d);
 
         ///
         Load("tt.obj");
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
glViewport( 0, 0, Width, Height );
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();
  glOrtho(-5,5, -5,5, 2,12);
  gluLookAt(0,0,5, 0,0,0, 0,1,0);
  glMatrixMode( GL_MODELVIEW );
 
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
if(ghRC)
        {
          wglMakeCurrent(ghDC,0);
          wglDeleteContext(ghRC);
        }
        if(ghDC)
          ReleaseDC(Handle, ghDC);
 
}
 
void Load(String fname){
TStringList *S = new TStringList();
S->LoadFromFile(fname);
S->Text=StringReplace(S->Text, ".", ",", TReplaceFlags()<< rfReplaceAll << rfIgnoreCase);
String S1,S2,S3;
for(int i =0; i<S->Count; i++){
glBegin(GL_QUADS);
int k=0;
S1="";
S2="";
S3="";
String V = S->Strings[i];
for(int j=3; j<V.Length()+1; j++){
Application->ProcessMessages();
if(V[1]=='v'){
if(k==0)
S1=S1+V[j];
if(k==1)
S2=S2+V[j];
if(k==2)
S3=S3+V[j];
if(V[j]==' '){
k++;
}
}
}
double i1,i2,i3;
if(S1!=""){
i1=StrToFloat(S1);
i2=StrToFloat(S2);
i3=StrToFloat(S3);
}
vex1[i]=i1;
vex2[i]=i2;
vex3[i]=i3;
k=0;
count++;
}
glEnd();
}
 
void PD(){
glBegin(GL_QUADS);
for(int i=0; i<count; i++){
glVertex3f(vex1[i], vex2[i], vex3[i]);
}
glEnd();
}
 
void Draw()
      {
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        glColor3f(1,1,1);
        PD();
        glRotatef(-3, 0,1,0);
        SwapBuffers(ghDC);
      }
 
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Draw();
 
}
//---------------------------------------------------------------------------
0
1824 / 732 / 99
Регистрация: 01.10.2012
Сообщений: 3,746
16.10.2017, 09:04 12
Цитата Сообщение от TButton Посмотреть сообщение
Действительно, надо было из obj в OpenGL переводить, а потом рисовать!
C++
Ну пока Вы ничего не перевели, просто рисуете вертексы надеясь что они идут по 4 для фейса. У какой-то конкретной модели это может быть и так, но в общем случае нет

OpenGL принимает данные в виде массивов (атрибутов и.т.п.) позиций, нормалей, UV и др. Все массивы должны иметь одинаковое число эл-тов. Поэтому простой кубик имеет 24 вертекса. Хотя углов 8, нормали в них разные, поэтому приходится создавать по 3 вертекса в каждом. Это часто называют "per-vertex data"

Obj файл организован иначе, в нем массивы могут иметь разную длину, напр тот же кубик можно записать как 8 вертексов и 6 нормалей. Зато фейс имеет индексы для каждого атрибута (а не всего 1 как в OpenGL). Это называют "per-face data", Например в obj файле записан такой фейс

f 52982/42174/47242 52981/42173/47241 53005/42041/47109

Это надо понимать так: фейс имеет 3 вертекса (тр-к). Первый вертекс ссылается на эл-т 52982 в массиве позиций, 42174 в массиве UV и 47242 в массиве нормалей. То же и для остальных вертексов. Все индексы начинаются с 1 (а не с 0 как в C/C++). Все массивы должны быть считаны до начала чтения фейсов
0
16.10.2017, 09:04
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.10.2017, 09:04
Помогаю со студенческими работами здесь

Загрузка obj модели в OpenGl
Есть .obj файл типа: v 1.25022 0 -0.0571689 vt -49.2212 2.25074 vn 0 -1 -0 v 0.108959 0...

Загрузка текстур на obj модельку
Здравствуйте, есть obj моделька, которую я экспортировал из блендера с uv текстурками. Так вот, как...

*.obj и нормали
Написал примитивный парсер для *.obj формата. В основном модели грузятся с такими глюками как в...

файл .obj
Пишу свою открывашку для файла .obj, пытаюсь разобраться в формате, ответе пожалуйста на несколько...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru