Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2005.11.20;
Скачать: [xml.tar.bz2];

Вниз

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

 
Зм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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.062 c
3-1128584984
msguns
2005-10-06 11:49
2005.11.20
Access. Записи детала в одну строку


2-1131193537
JBL
2005-11-05 15:25
2005.11.20
Rave Reports


14-1130497437
штамм
2005-10-28 15:03
2005.11.20
На каком C приводятся примеры в Windows SDK ?


14-1130665217
Piter
2005-10-30 12:40
2005.11.20
3gp в AVI


2-1130757178
alpine
2005-10-31 14:12
2005.11.20
Не пойму в чём дело ?!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский