4 / 4 / 3
Регистрация: 15.12.2012
Сообщений: 192
1

Библиотека текстур - накладываются текстуры друг на друга

01.02.2016, 16:33. Показов 1708. Ответов 6
Метки нет (Все метки)

Текстуры накладываются друг на друга.
Какой параметр отвечает за то, чтобы разные текстуры были в разных местах?

Создал библиотеку текстур (в виде класса), которая содержит массив текстур (класс). В классе текстур есть поля:
Delphi
1
2
3
4
5
6
7
8
9
10
11
type
 TTexture = class(TObject)
 {*----Поля-----*}
  FTexPointer: GLuint;   //-Указатель на текстуру
  FName,                 //-Имя текстуры
  FPath,                 //-Путь к текстуре
  FMaterial: string;     //-Тип материала
  FWidth,                //-Ширина текстуры
  FHeight,               //-Высота текстуры
  FFormat: word;         //-Формат текстуры
  FpData: pointer;       //-Указатель данных текстуры
При загрузке, происходит чтение текстуры, ее параметров и создания карты точек. После чего отображаемый объект (квадрат) получает номер текстуры TexIndex в базе библиотеки текстур (номер элемента массива).
Так загружаются текстуры:
Delphi
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
function TMaterialLibrary.LoadJPGTexture(nm,pth: string):boolean;
var
  Data : Array of LongWord;
  W, Wdth : Integer;
  H, Hght : Integer;
  BMP : TBitmap;
  JPG : TJPEGImage;
  C : LongWord;
  Line : ^LongWord;
begin
  JPG:=TJPEGImage.Create;
  try
      JPG.LoadFromFile(pth);
    except
      MessageBox(0, PChar('Не могу загрузить JPG - "'+ pth +'"'), PChar('MaterialLibrary Unit'), MB_OK);
      Exit;
    end;
   // Create Bitmap
  BMP:=TBitmap.Create;
  BMP.pixelformat:=pf32bit;
  BMP.width:=JPG.width;
  BMP.height:=JPG.height;
  BMP.canvas.draw(0,0,JPG);        // Copy the JPEG onto the Bitmap
 
  //  BMP.SaveToFile('D:\test.bmp');
  Wdth :=BMP.Width;  
  Hght :=BMP.Height;
  SetLength(Data, Wdth*Hght);
 
  For H:=0 to Hght-1 do
  Begin
    Line :=BMP.scanline[Hght-H-1];   // flip JPEG
    For W:=0 to Wdth-1 do
    Begin
      c:=Line^ and $FFFFFF; // Need to do a color swap
      Data[W+(H*Wdth)] :=(((c and $FF) shl 16)+(c shr 16)+(c and $FF00)) or $FF000000;  // 4 channel.
      inc(Line);
    End;
  End;
 
  BMP.free;
  JPG.free;
 
  Texture[MNumber]:= TTexture.Create(Wdth,Hght,GL_RGBA,addr(Data[0]),nm,pth,'нет');
  MNumber:= MNumber+1;
  result:= true;
end;
Так они применяются во время отрисовки:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TObj.ApplyTexture;
begin
 with MaterialLibrary.Texture[TexIndex] do
 begin
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  {Texture blends with object background}
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); { only first two can be used }
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); { all of the above can be used }
  glGenTextures(TexIndex, @TexPointer);
  glBindTexture(GL_TEXTURE_2D, TexPointer);
 
  if Format = GL_RGBA then
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData)
  else
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);
 end;
end;
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Конвертация цвета из BGR в RGB//
procedure TMaterialLibrary.SwapRGB(data : Pointer; Size : Integer);
asm
  mov ebx, eax
  mov ecx, size
 
@@loop :
  mov al,[ebx+0]
  mov ah,[ebx+2]
  mov [ebx+2],al
  mov [ebx+0],ah
  add ebx,3
  dec ecx
  jnz @@loop
end;
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.02.2016, 16:33
Ответы с готовыми решениями:

Блоки накладываются друг на друга
Всем привет! Возникла проблема: блоки накладываются друг на друга. Левый, центральный, правый...

Элементы накладываются друг на друга
Элементы накладываются друг на друга. Работаю в NetBeans. Что происходит в началеМышь бегает по...

PictureBox накладываются друг на друга
Ребят, только не давно начал осваивать Windows Forms, так вот добавляю на форму 3 pictureBox-а...

Дивы накладываются друг на друга
распологаю весь контент в нутри дива .content { width:800px; } добавляю первый див ...

6
3230 / 1420 / 233
Регистрация: 26.02.2009
Сообщений: 7,372
Записей в блоге: 5
01.02.2016, 17:26 2
Цитата Сообщение от homelleon Посмотреть сообщение
Какой параметр отвечает за то, чтобы разные текстуры были в разных местах?
Обычно, текстурные координаты.
Цитата Сообщение от homelleon Посмотреть сообщение
//Конвертация цвета из BGR в RGB//
GL давно понимает BGR формат. См. параметр format. Так что конвертировать не особо нужно...

Если интересно, посмотрите здесь альтернативный вариант ООП-текстур для Delphi

Добавлено через 2 минуты
И да gluBuild2DMipmaps вроде только для текстур с разрешением = 2^n
1
4 / 4 / 3
Регистрация: 15.12.2012
Сообщений: 192
01.02.2016, 17:57  [ТС] 3
Спасибо за информацию. Но насчет разных мест - я имел в виду, как загрузить сначала, а потом выбрать из загруженных нужный параметр, чтобы наложить разные текстуры на разные объекты. Т.е. должен быть где-то порядковый номер.
В своем коде по идее я только передаю текстуре параметры о величине и формате. А потом вызываю текстуру, чтобы наложить)
TexPointer: GLuint; - поле объекта Texture[index].
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
...
\\для Texture[1]:
glGenTextures(1, @TexPointer);
glBindTexture(GL_TEXTURE_2D, TexPointer);
glBegin(...); \\1-ый объект
glEnd;
...
\\для Texture[2]:
glGenTextures(2, @TexPointer);
glBindTexture(GL_TEXTURE_2D, TexPointer);
glBegin(...);  \\2-ой объект
glEnd;
Но текстуры сливаются почему-то.

Добавлено через 16 минут
И еще. Посмотрел твою программу
TTexture2D - этот класс откуда и что из себя представляет?
0
3230 / 1420 / 233
Регистрация: 26.02.2009
Сообщений: 7,372
Записей в блоге: 5
01.02.2016, 18:27 4
homelleon, glGenTextures не нужно вызывать каждый кадр. Эта ф-ия возвращает n уникальных имён (ID) новых текстур.
У меня как раз в конструкторе TTexture он вызывается.(Это не самое лучшее решение, но для мелких программ удобно)
Идея в том что в инициализации мы загружаем текстуру 1 раз

Delphi
1
2
3
4
5
6
7
8
  texture := TTexture2D.Create;
  texture.Bind;
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
  texture.LoadFromFile( '..\..\радуга.bmp' );//могут быть jpg,png
А в цикле отрисовки только биндим(включаем нужную)
Delphi
1
2
3
4
5
6
7
  texture.Bind;
  glBegin( GL_QUADS );
    glVertex2d( FLimit.Re.min, FLimit.Im.min );
    glVertex2d( FLimit.Re.max, FLimit.Im.min );
    glVertex2d( FLimit.Re.max, FLimit.Im.max );
    glVertex2d( FLimit.Re.min, FLimit.Im.max );
  glEnd();
Ну и в конце не забываем убить текстуру
Delphi
1
texture.Free;
1
4 / 4 / 3
Регистрация: 15.12.2012
Сообщений: 192
01.02.2016, 19:55  [ТС] 5
А, я не знал, что не надо ее каждый раз запускать.
glGenTextures(n, TX):
n - Это количество текстур с именем TX?
А если так записать, то TX будут считаться разными?
Delphi
1
2
glGenTextures(1, Texture[0].TX);
glGenTextures(1, Texture[1].TX);
0
3230 / 1420 / 233
Регистрация: 26.02.2009
Сообщений: 7,372
Записей в блоге: 5
02.02.2016, 00:17 6
Цитата Сообщение от homelleon Посмотреть сообщение
glGenTextures(n, TX)
n - Это количество текстур с именем TX?
нет. TX должен быть указателем на массив из n элементов. Таким образом можно за один вызов glGenTextures получить n новых текстур(id)
Delphi
1
2
3
4
5
const n = 5;
var TX:array[1..n] of GLuint;
begin
  glGenTextures( n, @TX[1] ); // сразу 5 новых текстур
//...
Или то же самое только с дин.массивом:
Delphi
1
2
3
4
5
6
7
var ids:TArray<GLuint>;
      n:integer;
begin
  n := 5;
  SetLength( ids, n );// Length(ids) = n
  glGenTextures( Length(ids), Pointer(ids) );
//...
Если нужна всего 1 текстура, то можно так:
Delphi
1
2
3
var ID:GLuint;
begin
  glGenTextures( 1, @ID );
Цитата Сообщение от homelleon Посмотреть сообщение
А если так записать, то TX будут считаться разными?
Delphi
1
2
glGenTextures(1, Texture[0].TX);
glGenTextures(1, Texture[1].TX);
Да, только нужен адрес вместо самой переменной
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type 
  TTexture = class
    TX:GLuint;
  //...
  end;
 
var
  Texture:array[0..1] of TTexture;
 
begin
   Texture[0] := TTexture.Create;
   Texture[1] := TTexture.Create;
 
   glGenTextures( 1, @Texture[0].TX );
   glGenTextures( 1, @Texture[1].TX );
1
4 / 4 / 3
Регистрация: 15.12.2012
Сообщений: 192
09.02.2016, 10:18  [ТС] 7
Не выходит загрузить разные текстуры. Накладываются последняя загруженная текстура. Не знаю в чем дело.
У каждого объекта есть индекс текстуры. При отрисовки у меня происходит вот это:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
procedure TOQuad.Draw;
begin
 inherited Draw;
 if Textured then
 begin
  with MaterialLibrary.Texture[TexIndex] do
 begin
 glBindTexture(GL_TEXTURE_2D, TexPointer);
  if Format = GL_RGBA then
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, pData)
  else
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, Width, Height, GL_RGB, GL_UNSIGNED_BYTE, pData);
 end;
    glPointSize(Size);
 glBegin(GL_QUADS);
  GLNormal(0,1,0);
  GLTexture(0,0); GLVertex(Coord[0].X,Coord[0].Y,Coord[0].Z);
  GLTexture(1,0); GLVertex(Coord[1].X,Coord[1].Y,Coord[1].Z);
  GLTexture(1,1); GLVertex(Coord[2].X,Coord[2].Y,Coord[2].Z);
  GLTexture(0,1); GLVertex(Coord[3].X,Coord[3].Y,Coord[3].Z);
 glEnd;
 end
end;
А до этого я при создании формы указываю вот это:
Delphi
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
 with ML do
  begin
   LoadTexture('ДеревоЯщик','textures\WoodBox.jpg');
   LoadTexture('ДеревоЯщик1','textures\WoodBox 1.jpg');
  end;
for i := 0 to QuadCount-1 do
   begin
    with Quads.Items[i] do
    begin
     Move(-4+2*i,0,0);
     MaterialLibrary:=ML;
     SetTexture('ДеревоЯщик');
     Textured:= true;
    end;
   end;
for i := 0 to CubeCount-1 do
   begin
    with Cubes.Items[i] do
    begin
     Move(-4+2*i,-2,0);
     MaterialLibrary:=ML;
     SetTexture('ДеревоЯщик1');
     Textured:=true;
    end;
   end;
Добавлено через 6 минут
SetTexture('ДеревоЯщик1'); ищет в библиотеке текстуру с заданным именем и присваивает объекту индекс текстур, равный индексу элемента массива класса TTexture, являющимся полем библиотеки текстур (по сути библиотека работает как список).

Добавлено через 1 минуту
Delphi
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
procedure TObj.SetTexture(nm: string);
var
 i: integer;
 found: boolean;
begin
 if MaterialLibrary.MNumber>0 then
 begin
  found:=false;
  i:=0;
  repeat
   if nm = string(MaterialLibrary.Texture[i].Name) then
   begin
    found:= true;
    TexIndex:=i;
   end;
   i:=i+1;
  until (found = true) or (i = MaterialLibrary.MNumber);
  if found = false then
  begin
   MessageBox(0, PChar(Self.Name+':В библиотеке нет текстуры '+nm), PChar('GameObjects Unit'), MB_OK);
   Exit;
  end;
 end
 else
 begin
  MessageBox(0, PChar(Self.Name+': В библиотеке нет текстур '), PChar('GameObjects Unit'), MB_OK);
  Exit;
 end;
end;
Добавлено через 3 минуты
На всякий случай:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//-Задание вершин в OpenGL-//
procedure TPrimitive.GLVertex(coorX,coorY,coorZ: double);
begin
  glVertex3f(coorX,coorY,coorZ);
end;
 
//-Задание цвета в OpenGL-//
procedure TPrimitive.GLColor(colorR,colorG,colorB: double);
begin
  glColor3f(colorR,colorG,colorB);
end;
 
//-Задание вершин в OpenGL-//
procedure TPrimitive.GLNormal(coorX,coorY,coorZ: double);
begin
 glNormal3f(coorX,coorY,coorZ);
end;
 
procedure TPrimitive.GLTexture(coorX,coorY: Double);
begin
 glTexCoord2f(coorX,coorY);
end;
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.02.2016, 10:18
Помогаю со студенческими работами здесь

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

Блоки накладываются друг на друга
Уважаемые форумчане, подскажите пожалуйста где ошибка в коде, если не трудно, знаю мелочь какая-то ...

Блоки накладываются друг на друга
Здравствуйте. Подскажите, как сделать, чтобы когда сжимается один div, то дивы находящиеся под ним...

Кнопки накладываются друг на друга
&lt;StackPanel&gt; &lt;Grid&gt; &lt;Grid.ColumnDefinitions&gt; ...

Накладываются копии звука друг на друга
написал такой код onClipEvent (enterFrame) { if ( this.hitTest(_root.finish) ) { snd = new...

Агенты в очереди накладываются друг на друга
Здравствуйте, форумчане. Очередь у меня в блоке Seize. Почему-то агенты в анимации накладываются...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru