Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.11.20;
Скачать: CL | DM;

Вниз

Сглаживание   Найти похожие ветки 

 
Зм1й ©   (2005-07-01 11:32) [0]

Подскажите пожалуйста, как в OpenGL сделать, чтобы модели выводились сглажеными, и текстуры на них тоже были сглаженые?


 
A22 ©   (2005-07-01 11:45) [1]

glEnable( GL_LINES_SMOOTH ); - это антиалиасинг (вообще нынче его в дровах видеокарты регулируют, мало кого волнует этот флаг)

на текстуры надо устанавливать фильтры min/mag/mip:
glGetTexParameterfv( GL_TEXTURE_1D или GL_TEXTURE_2D,
                    GL_TEXTURE_XXX_FILTER,
                    тип фильтра );
конкретнее о параметрах смотри в хелпе


 
Зм1й ©   (2005-07-01 13:52) [2]


> glEnable( GL_LINES_SMOOTH );

не помогает, модели всё равно выводятся "гранёными"

> на текстуры надо устанавливать фильтры

Я пишу

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

Но не помогает


 
A22 ©   (2005-07-01 14:50) [3]

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

то же с фильтрацией, ибо в OpenGL по умолчанию линейная фильтрация текстур


 
Зм1й ©   (2005-07-01 15:18) [4]

У меня везде стоит "выбирается приложением" (я так и думал, ведь в играх у меня сглаживание присутствует), но модели не сглаживаются. Причём странно то, что Quadratic объекты выводятся сглаженными, а обычные нет...


 
A22 ©   (2005-07-01 15:59) [5]

блин, ну, тогда 100% вариант антиалиасинга: создаешь RenderTarget (для OpenGL у nVidia был модуль дополнительный.. PBuffer что ли) - копию экрана, размером раза в 2 по обеим осях превышающаю экран. Рендеришь сцену тудыть, потом используешь данный буфер как текстуру и с линейной фильтрацией выводишь ее а весь экран. По сути, это просто увеличение разрешения + фильтрация, зато работать будет везде и всегда, вне зависимости от установок дров и т.д.


 
Зм1й ©   (2005-07-01 16:24) [6]


> По сути, это просто увеличение разрешения + фильтрация


Так текстура-то у меня не фильтруется, выводится по квадратикам!
К тому же должно же быть какое-то более стандартное решение, ведь, я повторяю, Quadric объекты нормально сглаживаются...


 
A22 ©   (2005-07-01 16:39) [7]

приведи, плз, код. так, видимо, не разберусь.


 
Зм1й ©   (2005-07-01 17:10) [8]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, OpenGL, ExtCtrls;

type
 TForm1 = class(TForm)
   Timer1: TTimer;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure Timer1Timer(Sender: TObject);
   procedure FormKeyDown(Sender: TObject; var Key: Word;
     Shift: TShiftState);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

 procedure LoadModel;
 procedure PrepareImage(bmap: string);
 function SetFullScreenMode: Boolean;

implementation

{$R *.dfm}

type
 TPoint= record
    X, Y, Z, U, V, nX, nY, nZ: GLfloat;
 end;

var
 DC: hDC;
 RC: HGLRC;

 Vertex1, Vertex2, Vertex3, VertexTemp: Array[0..3239] of TPoint;

 Angle: GLfloat= 0;
 Angle2: GLfloat= 0;
 LightPos: Array[0..3] of GLfloat= (1.0, 500.0, -10.0, 0.5);

 Bits: Array [0..256, 0..256, 0..2] of GLubyte;

 Phase: 1..2= 1;

procedure TForm1.FormCreate(Sender: TObject);
var
 nPixelFormat: Integer;
 pfd: TPixelFormatDescriptor;
 i: Integer;
begin
 /// Full Screen

 SetFullScreenMode;
 Left:=0;
 Top:=0;
 Width:=800;
 Height:=600;
 BorderStyle:=bsNone;

 /// Device

 DC:=GetDC(Handle);

 /// Pixel Fmt

 FillChar(pfd, SizeOf(pfd), 0);

 pfd.dwFlags   := PFD_DRAW_TO_WINDOW or
                PFD_SUPPORT_OPENGL or
                PFD_DOUBLEBUFFER;
 nPixelFormat := ChoosePixelFormat(DC, @pfd);
 SetPixelFormat(DC, nPixelFormat, @pfd);

 /// Device 2

 RC:=wglCreateContext(DC);

 wglMakeCurrent(DC, RC);

 /// Caps

 glEnable(GL_DEPTH_TEST);

 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glEnable(GL_COLOR_MATERIAL);
 glLightfv(GL_LIGHT0, GL_POSITION, @LightPos);

 glEnable(GL_NORMALIZE);
 glEnable(GL_CULL_FACE);
 glEnable(GL_LINE_SMOOTH);

 /// View

 glViewPort(0, 0, ClientWidth, ClientHeight);

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity;
 gluPerspective(30, 800/600, 1, 100);

 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity;
 glTranslatef(0, 0, -50);
 glScalef(0.1, 0.1, 0.1);
 glRotatef(-90, 1, 0, 0);
 glRotatef(30, 1, 0, 0);
 glRotatef(120, 0, 0, 1);

 /// Colors

 glClearColor(0.5, 0.7, 1.0, 1);
 glColor3f(1, 1, 1);

 /// Model

 LoadModel;

 for i:=0 to 3239 do begin
    VertexTemp[i].X:=Vertex1[i].X-Vertex2[i].X;
    VertexTemp[i].Y:=Vertex1[i].Y-Vertex2[i].Y;
    VertexTemp[i].Z:=Vertex1[i].Z-Vertex2[i].Z;

    VertexTemp[i].nX:=Vertex1[i].nX-Vertex2[i].nX;
    VertexTemp[i].nY:=Vertex1[i].nY-Vertex2[i].nY;
    VertexTemp[i].nZ:=Vertex1[i].nZ-Vertex2[i].nZ;
 end;

 /// Texture

 PrepareImage("Cool_man.bmp");
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 wglMakeCurrent(0, 0);
 wglDeleteContext(RC);
 ReleaseDC(Handle, DC);
 DeleteDC(DC);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
 i: Integer;
begin
 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

 glPushMatrix;

 glRotatef(Angle, 0, 0, 1);

 Angle2:=Angle2+0.01;
 if Angle2>0.15 then begin
    Angle2:=0;
    if Phase= 1 then Phase:=2 else Phase:=1;
 end;

 case Phase of

 1: for i:=0 to 3239 do begin
    Vertex3[i-1].X:=Vertex3[i-1].X-VertexTemp[i-1].X*Angle2;
    Vertex3[i-1].Y:=Vertex3[i-1].Y-VertexTemp[i-1].Y*Angle2;
    Vertex3[i-1].Z:=Vertex3[i-1].Z-VertexTemp[i-1].Z*Angle2;

    Vertex3[i-1].nX:=Vertex3[i-1].nX-VertexTemp[i-1].nX*Angle2;
    Vertex3[i-1].nY:=Vertex3[i-1].nY-VertexTemp[i-1].nY*Angle2;
    Vertex3[i-1].nZ:=Vertex3[i-1].nZ-VertexTemp[i-1].nZ*Angle2;
 end;

 2: for i:=0 to 3239 do begin
    Vertex3[i-1].X:=Vertex3[i-1].X+VertexTemp[i-1].X*Angle2;
    Vertex3[i-1].Y:=Vertex3[i-1].Y+VertexTemp[i-1].Y*Angle2;
    Vertex3[i-1].Z:=Vertex3[i-1].Z+VertexTemp[i-1].Z*Angle2;

    Vertex3[i-1].nX:=Vertex3[i-1].nX+VertexTemp[i-1].nX*Angle2;
    Vertex3[i-1].nY:=Vertex3[i-1].nY+VertexTemp[i-1].nY*Angle2;
    Vertex3[i-1].nZ:=Vertex3[i-1].nZ+VertexTemp[i-1].nZ*Angle2;
 end;

 end;

 glEnable(GL_TEXTURE_2D);

 for i := 1 to 1080 do begin
 glBegin(GL_TRIANGLES);

    glNormal3f(-Vertex3[i*3-3].nX, -Vertex3[i*3-3].nY, -Vertex3[i*3-3].nZ);

    glTexCoord2d(Vertex3[i*3-3].U, Vertex3[i*3-3].V);
    glVertex3f(Vertex3[i*3-3].X, Vertex3[i*3-3].Y, Vertex3[i*3-3].Z);

    glTexCoord2d(Vertex3[i*3-3+1].U, Vertex3[i*3-3+1].V);
    glVertex3f(Vertex3[i*3+1-3].X, Vertex3[i*3+1-3].Y, Vertex3[i*3+1-3].Z);

    glTexCoord2d(Vertex3[i*3-3+2].U, Vertex3[i*3-3+2].V);
    glVertex3f(Vertex3[i*3+2-3].X, Vertex3[i*3+2-3].Y, Vertex3[i*3+2-3].Z);

 glEnd;
 end;

 glDisable(GL_TEXTURE_2D);

 glColor3f(0, 1, 0);
 glScalef(200, 200, 200);
 glRotatef(90, 1, 0, 0);
 glTranslatef(0, -0.5, 0);

 glBegin(GL_QUADS);
    glNormal3f(1, 0, 1);
    glVertex3f(-1, 0, -1);
    glVertex3f(-1, 0, 1);
    glVertex3f(1, 0, 1);
    glVertex3f(1, 0, -1);
 glEnd;

 glTranslatef(0, 0.5, 0);
 glRotatef(-90, 1, 0, 0);
 glScalef(0.005, 0.005, 0.005);
 glColor3f(1, 1, 1);

 glPopMatrix;

 SwapBuffers(DC);
end;


 
Зм1й ©   (2005-07-01 17:10) [9]

procedure LoadModel;
var
 f: TextFile;
 i: Integer;
 n: GLfloat;
begin
 AssignFile(f, "cm1.txt");
 Reset(f);

 for i:=0 to 3239 do begin
    Read(f, Vertex1[i].X);
    Read(f, Vertex1[i].Y);
    Read(f, Vertex1[i].Z);

    Read(f, Vertex1[i].U);
    Read(f, Vertex1[i].V);

    Read(f, Vertex1[i].nX);
    Read(f, Vertex1[i].nY);
    Read(f, Vertex1[i].nZ);
 end;

 CloseFile(f);

 AssignFile(f, "cm1.txt");
 Reset(f);

 for i:=0 to 3239 do begin
    Read(f, Vertex3[i].X);
    Read(f, Vertex3[i].Y);
    Read(f, Vertex3[i].Z);

    Read(f, Vertex3[i].U);
    Read(f, Vertex3[i].V);

    Read(f, Vertex3[i].nX);
    Read(f, Vertex3[i].nY);
    Read(f, Vertex3[i].nZ);
 end;

 CloseFile(f);

 AssignFile(f, "cm2.txt");
 Reset(f);

 for i:=0 to 3239 do begin
    Read(f, Vertex2[i].X);
    Read(f, Vertex2[i].Y);
    Read(f, Vertex2[i].Z);

    Read(f, Vertex2[i].U);
    Read(f, Vertex2[i].V);

    Read(f, Vertex2[i].nX);
    Read(f, Vertex2[i].nY);
    Read(f, Vertex2[i].nZ);
 end;

 CloseFile(f);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
begin
 if Key= VK_ESCAPE then Close;
 if Key= VK_RIGHT then Angle:=Angle+2;
 if Key= VK_LEFT then Angle:=Angle-2;
end;

procedure PrepareImage(bmap: string);
type
 PPixelArray = ^TPixelArray;
 TPixelArray = array [0..0] of Byte;
var
 Bitmap : TBitmap;
 Data : PPixelArray;
 BMInfo : TBitmapInfo;
 I, ImageSize : Integer;
 Temp : Byte;
 MemDC : HDC;
begin
 Bitmap := TBitmap.Create;
 Bitmap.LoadFromFile (bmap);
 with BMinfo.bmiHeader do begin
   FillChar (BMInfo, SizeOf(BMInfo), 0);
   biSize := sizeof (TBitmapInfoHeader);
   biBitCount := 24;
   biWidth := Bitmap.Width;
   biHeight := Bitmap.Height;
   ImageSize := biWidth * biHeight;
   biPlanes := 1;
   biCompression := BI_RGB;
   MemDC := CreateCompatibleDC (0);
   GetMem (Data, ImageSize * 3);
   try
     GetDIBits (MemDC, Bitmap.Handle, 0, biHeight, Data,
                BMInfo, DIB_RGB_COLORS);
     For I := 0 to ImageSize - 1 do begin
         Temp := Data [I * 3];
         Data [I * 3] := Data [I * 3 + 2];
         Data [I * 3 + 2] := Temp;
     end;
     glTexImage2d(GL_TEXTURE_2D, 0, 3, biWidth,
                  biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
   finally
     FreeMem (Data);
     DeleteDC (MemDC);
     Bitmap.Free;
   end;
 end;

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
end;

function SetFullscreenMode: Boolean;
var
dm: TDevMode;
begin
with dm do
begin
  dmSize:=SizeOf(dm);
  dmBitsPerPel:=16;
  dmPelsWidth:=800;
  dmPelsHeight:=600;
  dmFields:=DM_BITSPERPEL or DM_PELSWIDTH or DM_PELSHEIGHT;
  Result:=ChangeDisplaySettings(dm, CDS_FULLSCREEN)= DISP_CHANGE_SUCCESSFUL;
end;
end;

end.


 
Зм1й ©   (2005-07-01 17:12) [10]

PS. Это код тренировочного примера, поэтому он такой глупый и использует VCL


 
A22 ©   (2005-07-01 17:24) [11]

выведи модель одновременно с quadrick-объектами. покажи плз код, который, выводя квадрики сглаженными, нарисует модель коряво


 
Sapersky   (2005-07-01 17:38) [12]

модели всё равно выводятся "гранёными"

Нормали криво считаются, скорее всего. Попробуй нарисовать их короткими отрезками вместе с моделью - будет видно.


 
Зм1й ©   (2005-07-01 17:46) [13]


> A22 ©   (01.07.05 17:24) [11]


При создании формы добавил

var
Quadric : GLUquadricObj;

...

Quadric := gluNewQuadric;

glNewList (1, GL_COMPILE);
  gluSphere (Quadric, 10.5, 24, 24);
glEndList;


В процедуре таймера перед выводом модели добавил

glCallList(1);

Сфера сглаживается, а модель - нет!


> Sapersky   (01.07.05 17:38) [12]

Может быть конечно, но нормали грузятся из файла


 
A22 ©   (2005-07-01 17:54) [14]

так, чтобы удостовериться в деталях: на сферу накинь текстуру и на модель. что, фильтрация на них по-разному будет работать при одних и тех же флагах??


 
Зм1й ©   (2005-07-01 18:24) [15]

Сфера, в отличии от модели, имеет сглаженные границы между полигонами. Но текстура у неё тоже нефильтрованная


 
A22 ©   (2005-07-01 18:48) [16]

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


 
Зм1й ©   (2005-07-01 18:49) [17]

Именно так


 
A22 ©   (2005-07-01 19:07) [18]

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


 
Зм1й ©   (2005-07-01 19:19) [19]

Спасибо, попробую. А как быть с текстурой?


 
XProger ©   (2005-07-02 11:21) [20]

Зм1й,
GL_LINEAR_MIPMAP_LINEAR
gluBuild2DMipmaps(...)


 
Зм1й ©   (2005-07-02 11:57) [21]


> XProger ©   (02.07.05 11:21) [20]
> Зм1й,
> GL_LINEAR_MIPMAP_LINEAR
> gluBuild2DMipmaps(...)

тот же эффект.

Я конечно не хочу показаться навязчивым, но со сглаживанием модели у меня тоже ничего не выходит. Я расчитываю нормали по такому алгоритму:

 for j:=0 to 3239 do begin
    for i:=j+1 to 3239 do begin
       if (Vertex1[j].X= Vertex1[i].X)
       and (Vertex1[j].Y= Vertex1[i].Y)
       and (Vertex1[j].Z= Vertex1[i].Z)
       then begin
          Vertex1[j].nX:=(Vertex1[j].nX+Vertex1[i].nX);
          Vertex1[j].nY:=(Vertex1[j].nY+Vertex1[i].nY);
          Vertex1[j].nZ:=(Vertex1[j].nZ+Vertex1[i].nZ);

          n:=Sqrt(Sqr(Vertex1[j].nX)+Sqr(Vertex1[j].nY)+Sqr(Vertex1[j].nZ));
          Vertex1[j].nX:=Vertex1[j].nX/n;
          Vertex1[j].nY:=Vertex1[j].nY/n;
          Vertex1[j].nZ:=Vertex1[j].nZ/n;

          Vertex1[i].nX:=Vertex1[j].nX;
          Vertex1[i].nY:=Vertex1[j].nY;
          Vertex1[i].nZ:=Vertex1[j].nZ;
       end;
    end;
 end;

но сглаживания не происходит :(


 
Зм1й ©   (2005-07-02 13:17) [22]

УРРАААА! Я добился чтобы моя модель выводилась сглаженной! Спасибо А22 за супералгоритм! Однако с текстурой всё обстоит хуже, она по-прежнему выводится "квадратиками". Может я некорректно объяснил задачу? Мне нужно, чтобы между пикселами текстуры был плавный переход, другими словами - билейная фильтрация.


 
Зм1й ©   (2005-07-05 16:29) [23]

Всё сделал. Теперь ВСЁ сглажено!!! Обсуждение закрыто



Страницы: 1 вся ветка

Текущий архив: 2005.11.20;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.033 c
14-1130665217
Piter
2005-10-30 12:40
2005.11.20
3gp в AVI


2-1130767781
stud
2005-10-31 17:09
2005.11.20
получить код ошибки


2-1130428006
Bogdan1024
2005-10-27 19:46
2005.11.20
ООПрограммирование


6-1123706619
Trojan_nt
2005-08-11 00:43
2005.11.20
Помогите создать статистику DSN Инета


8-1120231094
psa247
2005-07-01 19:18
2005.11.20
Алгоритм развевающегося флага OPENGL