![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
OpenGl & *.gms [Delphi, Windows]
sco © (2005-11-21 21:08:00)У меня есть книга по OpenGl Краснова, но там не написано как грузить gms файлы, я нашёл другую доку, применил, объект грузится, отображается, но не получается настроить нормали, объекты все чёрные как смоль. Я уже долго парюсь, но ничего не могу сделать, я ещё 11-классник, и поэтому высшей математикой не владею, и не знаю как расчитать эти нормали. Помогите пожалуйста или скажите что я делаю не так.
procedure LoadObjectFromFile(fileName: string; var obj: TGLMesh); // Загрузка файла
var
f : TextFile;
S : String;
i : Integer;
Vertex : TGLVertex;
Face : TGLFace;
// Normal: TGLVertex;
MaxVertex : GLFloat;
begin
AssignFile(f,FileName);
Reset(f);
// Пропускаем строки, пока не попадется 'New object'
repeat
ReadLn(f, S);
until (S = 'New object') or eof(f); // Читаем количество вершин и граней
if s='New object' then
begin
ReadLn(f,s); // Пропускаем строку TriMesh()
ReadLn(f,s); // Пропускаем строку numverts numfaces
with obj do
begin
Readln(f,VertexCount,FacesCount); // Выделяем память для хранения сетки
GetMem(Vertices,VertexCount*SizeOf(TGLVertex));
GetMem(Faces,FacesCount*SizeOf(TGLFace));
GetMem(FasetNormals,FacesCount*SizeOf(TGLVertex));
ReadLn(f, S); // Пропускаем строку "Mesh vertices" // Считываем вершины
for i := 0 to VertexCount - 1 do
begin
Readln(f,Vertex.x,Vertex.y,Vertex.z);
Vertices[i] := Vertex;
end;
ReadLn(f, S); // Пропускаем строку "end vertices"
ReadLn(f, S); // Пропускаем строку "Mesh faces" // Считываем грани
for i := 0 to FacesCount - 1 do
begin
Readln(f,Face[0],Face[1],Face[2]);
Face[0] := Face[0] - 1;
Face[1] := Face[1] - 1;
Face[2] := Face[2] - 1;
Faces[i] := Face;
end;
CloseFile(f);
CalcNormals(obj);
{ ReadLn(f, S); // Пропускаем строку "end faces"
ReadLn(f, S); // Пропускаем строку "Faset normals:" // Считываем нормали
for i := 0 to FacesCount - 1 do
begin
Readln(f,Normal.x,Normal.y,Normal.z);
FasetNormals[i] := Normal;
end;
{ MaxVertex := 0;
for i := 0 to VertexCount - 1 do
begin
MaxVertex := Max(MaxVertex,Vertices[i].x);
MaxVertex := Max(MaxVertex,Vertices[i].y);
MaxVertex := Max(MaxVertex,Vertices[i].z);
end;
fExtent := 1/MaxVertex;}
end;
end;
end;
procedure DrawObject(obj: TGLMesh);
var
i : Integer;
Face : TGLFace;
dvig: single;
begin
with obj do
begin
glColor3f(0,0,0);
{if Extent then }
fExtent:=0.005;
dvig:=1;
glTranslatef(dvig, dvig, 0.3);
glScalef(fExtent,fExtent,fExtent);
for i := 0 to FacesCount - 1 do
begin
glBegin(GL_TRIANGLES);
Face := Faces[i];
glNormal3fv(@FasetNormals[i]);
// glNormal3d(0,0.02,0.01);
glVertex3fv(@Vertices[Face[0]]);
glVertex3fv(@Vertices[Face[1]]);
glVertex3fv(@Vertices[Face[2]]);
glEnd;
end;
glTranslatef(-dvig,-dvig, +1);
end;
end;
procedure DestroyObject(var obj: TGLMesh);
begin
with obj do
begin
FreeMem(Vertices,VertexCount*SizeOf(TGLVertex));
FreeMem(Faces,FacesCount*SizeOf(TGLFace));
FreeMem(FasetNormals,FacesCount*SizeOf(TGLVertex));
end;
end;
{procedure CalcNormals(obj: TGLMesh);
var
i : Integer;
wrki, vx1, vy1, vz1, vx2, vy2, vz2 : GLfloat;
nx, ny, nz : GLfloat;
minX: GlFloat;
wrkVector : TGLVertex;
// pwrkVector : ^TGLVector;
wrkVector1, wrkVector2, wrkVector3 : TGLVertex;
// pwrkVector1, pwrkVector2, pwrkVector3 : ^TGLVector;
begin
with obj do
begin
For i := 0 to round (FacesCount / 3) - 1 do begin
wrkVector1 := Vertices[i*3];
wrkVector2 := Vertices[i*3+1];
wrkVector3 := Vertices[i*3+2];
minX:=min(min(vertices[i*3].x,vertices[i*3+1].x),vertices[i*3+2].x);
nX:=(vertices[i*3].x+vertices[i*3+1].x+vertices[i*3+2].x)/3;
ny:=(vertices[i*3].y+vertices[i*3+1].y+vertices[i*3+2].y)/3;
nz:=(vertices[i*3].z+vertices[i*3+1].z+vertices[i*3+2].z)/3;
FasetNormals[i]:=wrkVector;
end;
end;
end;}
procedure CalcNormals(var obj: TGLMesh);
var
i : Integer;
wrki, vx1, vy1, vz1, vx2, vy2, vz2 : GLfloat;
nx, ny, nz : GLfloat;
wrkVertex : TGLVertex;
wrkVertex1, wrkVertex2, wrkVertex3 : TGLVertex;
begin
with obj do
begin
for i := 0 to round (obj.VertexCount / 3) - 1 do
begin
wrkVertex1:=Vertices[i*3];
wrkVertex2:=Vertices[i*3+1];
wrkVertex3:=Vertices[i*3+2];
vx1 := wrkVertex1.x - wrkVertex2.x;
vy1 := wrkVertex1.y - wrkVertex2.y;
vz1 := wrkVertex1.z - wrkVertex2.z;
vx2 := wrkVertex2.x - wrkVertex3.x;
vy2 := wrkVertex2.y - wrkVertex3.y;
vz2 := wrkVertex2.z - wrkVertex3.z;
// вектор перпендикулярен центру треугольника
nx := vy1 * vz2 - vz1 * vy2;
ny := vz1 * vx2 - vx1 * vz2;
nz := vx1 * vy2 - vy1 * vx2;
// получаем унитарный вектор единичной длины
wrki := sqrt (nx * nx + ny * ny + nz * nz);
If wrki = 0 then wrki := 1; // для предотвращения деления на ноль
wrkVertex.x := nx / wrki;
wrkVertex.y := ny / wrki;
wrkVertex.z := nz / wrki;
FasetNormals[i].x:=wrkVertex;
end;
end;
end;
Кефир87 (2005-11-22 17:38:00) [21]Не мучай свет слишком сильно! Для начала сделай просто
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
Там по умолчанию источник находится где-то в безконечности и таких проблем как " Может Источник света слишком отдалён или что-нибудь такое" быть не должно.
PS форум и правда не поддерживает 8)
sco (2005-11-22 16:01:00) [22]Частично проблема решена, но теперь цвета либо чёрный, либо белый. Может Источник света слишком отдалён или что-нибудь такое. У меня на экране помещаются где-то 2.5*2.5 едениц координат (x*y). Я бы кинул скрин, но помоему форум это не поддерживает.
sco (2005-11-22 16:01:00) [23]Частично проблема решена, но теперь цвета либо чёрный, либо белый. Может Источник света слишком отдалён или что-нибудь такое. У меня на экране помещаются где-то 2.5*2.5 едениц координат (x*y). Я бы кинул скрин, но помоему форум это не поддерживает.
Кефир87 (2005-11-21 22:31:00) [24]А с чего бы об этом должно быть написано в Краснове? 8)
Вот здесь http://delphigfx.mastak.ru/3d/004/3d_4.htmвсе прекрасно про сей формат написано и нормали там есть, фасетный и сглаженные, ничего считать не надо.
А вот так можно расчитать нормали (фасетные), только если вершины в правильном порядке записаны 8)
procedure Normalize3f(var a:TVector);
var d:Single;
begin
d:=sqrt(sqr(a.x)+sqr(a.y)+sqr(a.z));
if d = 0 then d :=1;
a.x:=a.x/d;
a.y:=a.y/d;
a.z:=a.z/d;
end;
function DoTheNormal(A, B, C : TVector):TVector;
var
vx1,vy1,vz1,vx2,vy2,vz2:Single;
begin
{
vx1 = A.x - B.x
vy1 = A.y - B.y
vz1 = A.z - B.z
vx2 = B.x - C.x
vy2 = B.y - C.y
vz2 = B.z - C.z
N.x = (vy1 * vz2 - vz1 * vy2)
N.y = (vz1 * vx2 - vx1 * vz2)
N.z = (vx1 * vy2 - vy1 * vx2)
}
vx1 := A.x - B.x;
vy1 := A.y - B.y;
vz1 := A.z - B.z;
vx2 := B.x - C.x;
vy2 := B.y - C.y;
vz2 := B.z - C.z;
Result.x := vy1 * vz2 - vz1 * vy2;
Result.y := vz1 * vx2 - vx1 * vz2;
Result.z := vx1 * vy2 - vy1 * vx2;
Normalize3f(Result);
end;
Думаю что
TVector = record
x,y,z:sGLFloat;
end;
Объяснять не надо 8)
grouzd[E]v (2005-11-21 22:14:00) [25]Нахер gms, не трать время, все равно выкинешь. Экспортируй сам.
Нормали в гугле видел, в той статейке тоже есть (а вот если будешь сам грузить, то эта проблема отпадает =) - ну это если нормали нужно ПРОСЧИТАТЬ ессно.
Если для макса - file > export > ascii (ase) или maxscript
На 11 класс можешь даже не списывать - даже и не посмотрят =)
Good Luck
ps с днем рождения, кстати =)
---
... we are walking on a thin line and you better avoid the risk ...
XProger (2005-11-21 21:55:00) [26]Для расчёта нормалей высшая математика не нужна! Векторная агебра 8-9 класс.
Свет хоть включен?
DR0N (2005-11-21 21:25:00) [27]
//----------------------------------------------------------------------------//
//DRON's OpenGl Engine V 1.0 http://dronprogs.mirgames.ru //
//Copyright (C) 2005 Korotkov Andrew //
// //
//This program is free software; you can redistribute it and/or //
//modify it under the terms of the GNU General Public License //
//as published by the Free Software Foundation; either version 2 //
//of the License, or (at your option) any later version. //
// //
//This program is distributed in the hope that it will be useful, //
//but WITHOUT ANY WARRANTY; without even the implied warranty of //
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
//GNU General Public License ( http://www.gnu.org/copyleft/gpl.html) //
//for more details. //
//----------------------------------------------------------------------------//
unit GL_Mesh_DMD;
interface
uses
Classes, OpenGL, Math;
Type
PGLVertex = ^TGLVertex;
TGLVertex = record
x,y,z : GLFloat;
end;
PGLVector = ^TGLVector;
TGLVector = array[0..2] of GLFloat;
PGLFace = ^TGLFace;
TGLFace = array[0..2] of GLInt;
PGLVertexArray = ^TGLVertexArray;
TGLVertexArray = array[Word] of TGLVertex;
PGLFacesArray = ^TGLFacesArray;
TGLFacesArray = array[word] of TGLFace;
TGLMultyMesh = class;
TGLMesh = class
Vertices : PGLVertexArray;
Faces : PGLFacesArray;
FasetNormals : PGLVertexArray;
SmoothNormals : PGLVertexArray;
Width,Height,Depth : GLFloat;
VertexCount : Integer;
FacesCount : Integer;
fExtent,fExtentX,fExtentY,fExtentZ : GLFloat;
ScaleType : byte;
Parent : TGLMultyMesh;
public
procedure CalcNormals;
procedure CalcSmoothNormals;
procedure Draw(Smooth,Textured : Boolean);
destructor Destroy; override;
end;
TGLMultyMesh = class
Meshes : TList;
CurrentFrame : Integer;
fExtent,fExtentX,fExtentY,fExtentZ : GLFloat;
ScaleType : byte;
fSmooth : Boolean;
fAllScale : GLFloat;
TexVertices : PGLVertexArray;
TexFaces : PGLFacesArray;
TexVCount, TexFCount : Integer;
TexturePresent : Boolean;
public
procedure LoadFromFile( const FileName : String );
procedure Draw;
constructor Create;
destructor Destroy; override;
published
end;
function Max(v1,v2:GLFloat):GLFloat;
function Min(v1,v2:GLFloat) : GLFloat;
implementation
uses GlDrawFunc3D;
{------------------------------------------------------------------}
function Max(v1,v2:GLFloat) : GLFloat;
begin
if v1 >= v2 then result := v1
else result := v2;
end;
function Min(v1,v2:GLFloat) : GLFloat;
begin
if v1 <= v2 then result := v1
else result := v2;
end;
{------------------------------------------------------------------}
procedure TGLMesh.CalcSmoothNormals;
var i, j : integer;
Face : TGLFace;
length : single;
begin
for i:=0 to VertexCount - 1 do
begin
SmoothNormals[i].X:=0;
SmoothNormals[i].Y:=0;
SmoothNormals[i].Z:=0;
end;
for i:=0 to FacesCount-1 do
begin
Face := Faces[i];
for j:=0 to 2 do
begin
SmoothNormals[Face[j]].X:=SmoothNormals[Face[j]].X+FasetNormals[i].X;
SmoothNormals[Face[j]].Y:=SmoothNormals[Face[j]].Y+FasetNormals[i].Y;
SmoothNormals[Face[j]].Z:=SmoothNormals[Face[j]].Z+FasetNormals[i].Z;
end;
end;
for i:=0 to VertexCount - 1 do
begin
length:=sqrt(sqr(SmoothNormals[i].X) + sqr(SmoothNormals[i].Y) + sqr(SmoothNormals[i].Z));
SmoothNormals[i].X:=SmoothNormals[i].X/length;
SmoothNormals[i].Y:=SmoothNormals[i].Y/length;
SmoothNormals[i].Z:=SmoothNormals[i].Z/length;
end;
end;
{------------------------------------------------------------------}
procedure TGLMesh.CalcNormals;
var
i : Integer;
wrki, vx1, vy1, vz1, vx2, vy2, vz2 : GLfloat;
nx, ny, nz : GLfloat;
wrkVector : TGLVertex;
wrkVector1, wrkVector2, wrkVector3 : TGLVertex;
wrkFace : TGLFace;
begin
For i := 0 to FacesCount - 1 do begin
wrkFace := Faces[i];
wrkVector1 := Vertices[wrkFace[0]];
wrkVector2 := Vertices[wrkFace[1]];
wrkVector3 := Vertices[wrkFace[2]];
vx1 := wrkVector1.x - wrkVector2.x;
vy1 := wrkVector1.y - wrkVector2.y;
vz1 := wrkVector1.z - wrkVector2.z;
vx2 := wrkVector2.x - wrkVector3.x;
vy2 := wrkVector2.y - wrkVector3.y;
vz2 := wrkVector2.z - wrkVector3.z;
nx := vy1 * vz2 - vz1 * vy2;
ny := vz1 * vx2 - vx1 * vz2;
nz := vx1 * vy2 - vy1 * vx2;
wrki := sqrt (nx * nx + ny * ny + nz * nz);
wrkVector.x := nx / wrki;
wrkVector.y := ny / wrki;
wrkVector.z := nz / wrki;
FasetNormals[i] := wrkVector;
end;
end;
{------------------------------------------------------------------}
procedure TGLMesh.Draw(Smooth, Textured: Boolean);
var
i : Integer;
Face,TexFace : TGLFace;
TexVertex : TGLVertex;
begin
for i := 0 to FacesCount - 1 do begin
glBegin(GL_TRIANGLES);
Face := Faces[i];
if Smooth then begin
glNormal3fv(@SmoothNormals[Face[0]]);
if Textured then begin
TexFace := Parent.TexFaces[i];
TexVertex := Parent.TexVertices[TexFace[0]];
_glTexCoord2f(TexVertex.x,1-TexVertex.y);
end;
glVertex3fv(@Vertices[Face[0]]);
glNormal3fv(@SmoothNormals[Face[1]]);
if Textured then begin
TexFace := Parent.TexFaces[i];
TexVertex := Parent.TexVertices[TexFace[1]];
_glTexCoord2f(TexVertex.x,1-TexVertex.y);
end;
glVertex3fv(@Vertices[Face[1]]);
glNormal3fv(@SmoothNormals[Face[2]]);
if Textured then begin
TexFace := Parent.TexFaces[i];
TexVertex := Parent.TexVertices[TexFace[2]];
_glTexCoord2f(TexVertex.x,1-TexVertex.y);
end;
glVertex3fv(@Vertices[Face[2]]);
end else begin
glNormal3fv(@FasetNormals[i]);
if Textured then begin
TexFace := Parent.TexFaces[i];
TexVertex := Parent.TexVertices[TexFace[0]];
_glTexCoord2f(TexVertex.x,1-TexVertex.y);
end;
glVertex3fv(@Vertices[Face[0]]);
if Textured then begin
TexFace := Parent.TexFaces[i];
TexVertex := Parent.TexVertices[TexFace[1]];
_glTexCoord2f(TexVertex.x,1-TexVertex.y);
end;
glVertex3fv(@Vertices[Face[1]]);
if Textured then begin
TexFace := Parent.TexFaces[i];
TexVertex := Parent.TexVertices[TexFace[2]];
_glTexCoord2f(TexVertex.x,1-TexVertex.y);
end;
glVertex3fv(@Vertices[Face[2]]);
end;
glEnd;
end;
end;
DR0N (2005-11-21 21:25:00) [28]
{------------------------------------------------------------------}
destructor TGLMesh.Destroy;
begin
FreeMem(Vertices,VertexCount*SizeOf(TGLVertex));
FreeMem(SmoothNormals,VertexCount*SizeOf(TGLVertex));
FreeMem(Faces,FacesCount*SizeOf(TGLFace));
FreeMem(FasetNormals,FacesCount*SizeOf(TGLVector));
end;
{------------------------------------------------------------------}
procedure TGLMultyMesh.LoadFromFile;
var
OverallMaxVertex : single;
f : TextFile;
S : String;
procedure ReadNextMesh(AParent : TGLMultyMesh);
var
i : Integer;
Vertex : TGLVertex;
Face : TGLFace;
MaxVertex,MaxVertexX,MaxVertexY,MaxVertexZ : GLFloat;
NextMesh : TGLMesh;
MinX,MinY,MinZ,MaxX,MaxY,MaxZ :GLFloat;
begin
NextMesh := TGLMesh.Create;
repeat
ReadLn(f, S);
until (S = 'numverts numfaces') or eof(f);
Readln(f,NextMesh.VertexCount,NextMesh.FacesCount);
GetMem(NextMesh.Vertices,NextMesh.VertexCount*SizeOf(TGLVertex));
GetMem(NextMesh.SmoothNormals,NextMesh.VertexCount*SizeOf(TGLVector));
GetMem(NextMesh.Faces,NextMesh.FacesCount*SizeOf(TGLFace));
GetMem(NextMesh.FasetNormals,NextMesh.FacesCount*SizeOf(TGLVector));
ReadLn(f,S);
for i := 0 to NextMesh.VertexCount - 1 do
begin
Readln(f,Vertex.x,Vertex.y,Vertex.z);
NextMesh.Vertices[i] := Vertex;
end;
ReadLn(f,S);
ReadLn(f,S);
for i := 0 to NextMesh.FacesCount - 1 do
begin
Readln(f,Face[0],Face[1],Face[2]);
Face[0] := Face[0] - 1;
Face[1] := Face[1] - 1;
Face[2] := Face[2] - 1;
NextMesh.Faces[i] := Face;
end;
NextMesh.CalcNormals;
NextMesh.CalcSmoothNormals;
MinX:=0.0;
MinY:=0.0;
MinZ:=0.0;
MaxX:=0.0;
MaxY:=0.0;
MaxZ:=0.0;
for i:=0 to NextMesh.VertexCount - 1 do
begin
MinX:=Min(MinX,NextMesh.Vertices[i].x);
MinY:=Min(MinY,NextMesh.Vertices[i].Y);
MinZ:=Min(MinZ,NextMesh.Vertices[i].Z);
MaxX:=Max(MaxX,NextMesh.Vertices[i].x);
MaxY:=Max(MaxY,NextMesh.Vertices[i].Y);
MaxZ:=Max(MaxZ,NextMesh.Vertices[i].Z);
end;
NextMesh.Width := MaxX - MinX;
NextMesh.Height:= MaxY - MinY;
NextMesh.Depth := MaxZ - MinZ;
MaxVertex := 0;
for i := 0 to NextMesh.VertexCount - 1 do
begin
OverallMaxVertex := Max(OverallMaxVertex,NextMesh.Vertices[i].x);
OverallMaxVertex := Max(OverallMaxVertex,NextMesh.Vertices[i].y);
OverallMaxVertex := Max(OverallMaxVertex,NextMesh.Vertices[i].z);
end;
for i := 0 to NextMesh.VertexCount - 1 do
begin
MaxVertex := Max(MaxVertex,NextMesh.Vertices[i].x);
MaxVertex := Max(MaxVertex,NextMesh.Vertices[i].y);
MaxVertex := Max(MaxVertex,NextMesh.Vertices[i].z);
end;
NextMesh.fExtent := 1/MaxVertex;
MaxVertexX := 0; MaxVertexY := 0; MaxVertexZ := 0;
for i := 0 to NextMesh.VertexCount - 1 do
begin
MaxVertexX := Max(MaxVertexX,NextMesh.Vertices[i].x);
MaxVertexY := Max(MaxVertexY,NextMesh.Vertices[i].y);
MaxVertexZ := Max(MaxVertexZ,NextMesh.Vertices[i].z);
end;
NextMesh.fExtentX := 1/MaxVertexX; NextMesh.fExtentY := 1/MaxVertexY; NextMesh.fExtentZ := 1/MaxVertexZ;
NextMesh.Parent := AParent;
Meshes.Add(NextMesh);
end;
Procedure ReadTextureBlock;
var
i : Integer;
Vertex : TGLVertex;
Face : TGLFace;
begin
Readln(f,S);
Readln(f,TexVCount,TexFCount);
if Assigned(TexVertices) then FreeMem(TexVertices);
if Assigned(TexFaces) then FreeMem(TexFaces);
GetMem(TexVertices,TexVCount*SizeOf(TGLVertex));
GetMem(TexFaces,TexFCount*SizeOf(TGLFace));
Readln(f,S);
if S <> 'Texture vertices:' then begin
TexturePresent := False;
Exit;
end;
for i := 0 to TexVCount - 1 do begin
Readln(f,Vertex.x,Vertex.y,Vertex.z);
TexVertices[i] := Vertex;
end;
Readln(f,S);
Readln(f,S);
for i := 0 to TexFCount - 1 do begin
Readln(f,Face[0],Face[1],Face[2]);
Face[0] := Face[0] - 1;
Face[1] := Face[1] - 1;
Face[2] := Face[2] - 1;
TexFaces[i] := Face;
end;
TexturePresent := True;
end;
begin
fAllScale:=0.0;
OverallMaxVertex:=0.0;
Meshes := TList.Create;
AssignFile(f,FileName);
Reset(f);
While not Eof(f) do begin
Readln(f,S);
if S = 'New object' then ReadNextMesh(Self);
if S = 'New Texture:' then ReadTextureBlock;
end;
CloseFile(f);
fAllScale:=1/OverallMaxVertex;
end;
{------------------------------------------------------------------}
procedure TGLMultyMesh.Draw;
begin
glPushMatrix();
case ScaleType of
1: begin
fExtent := TGLMesh(Meshes.Items[CurrentFrame]).fExtent;
glScalef(fExtent,fExtent,fExtent);
end;
2: begin
fExtentX := TGLMesh(Meshes.Items[CurrentFrame]).fExtentX;
fExtentY := TGLMesh(Meshes.Items[CurrentFrame]).fExtentY;
fExtentZ := TGLMesh(Meshes.Items[CurrentFrame]).fExtentZ;
glScalef(fExtentX,fExtentY,fExtentZ);
end;
3: glScalef(fAllScale,fAllScale,fAllScale);
end;//case
TGLMesh(Meshes.Items[CurrentFrame]).Draw(fSmooth,TexturePresent);
glPopMatrix();
end;
{------------------------------------------------------------------}
constructor TGLMultyMesh.Create;
begin
CurrentFrame := 0;
end;
{------------------------------------------------------------------}
destructor TGLMultyMesh.Destroy;
Var i : Integer;
begin
for i := 0 to Meshes.Count - 1 do
TGLMesh(Meshes.Items[i]).Destroy;
Meshes.Free;
TexVertices:=nil;
TexFaces:=nil;
end;
end.
Наслаждайся....