Форум: "Игры";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];
ВнизОптимизация Найти похожие ветки
← →
-=S.S=- © (2005-08-30 13:41) [0]Доброе время суток !
Какие у вас будут идеи по оптимизации данного кода ?
program scr;
uses
Windows,
Messages,
OpenGL, SysUtils,
MyMath in "MyMath.pas";
var
wndclass : WNDCLASSEX;
Handle : HWND;
DC : HDC;
msg : TMSG;
type
GlArray = Array [0..7] of GLfloat;
GlArrColor = Array [0..2] of GlFloat;
type
TVector3f = class
public
X,Y,Z : GLfloat;
Constructor Create(_X,_Y,_Z : glFloat);
end;
const
resolution = 32;
ColorsCount = 10;
ColorMap : array [0..ColorsCount-1] of GlArrColor =
((1,0,0),(0,1,0),(0,0,1),(0,1,1),(1,0,1),(1,1,0),
(1,1,1),(0.5,0.2,0.8),(0.7,0.2,1),(0.7,0.45,0.1));
Max_Rand = 1;
var
u, v, du,dv : GLfloat;
q,n,c : TVector3f;
temp : GlArray;
Temp1,K : Integer;
rotate1 : GlFloat =0;
ListCall : Cardinal;
Function GetColor (xx : GLfloat) : TVector3f;
Var
a : GLfloat;
idx1,idx2: Integer;
idx3 : GLfloat;
function CalcFrac(c1, c2: GLfloat; fr : GLfloat): GLfloat;
begin
result := c1 * fr + c2*(1-fr);
end;
Begin
a := xx*ColorsCount/(2*PI);
if a > ColorsCount then a := ColorsCount;
idx1 := Floor(a);
idx2 := Ceil(a);
idx3 := frac(a);
result := TVector3f.Create(0,0,0);
result.X := CalcFrac(ColorMap[idx1][0], ColorMap[idx2][0], idx3 );
result.Y := CalcFrac(ColorMap[idx1][1], ColorMap[idx2][1], idx3 );
result.Z := CalcFrac(ColorMap[idx1][2], ColorMap[idx2][2], idx3 );
End;
Function CalcNormal(V1,V2,V3 : TVector3f):TVector3f;
Begin
Result := TVector3f.Create(0,0.1,1);
End;
Function Eval(theta, phi : glFloat; m : GlArray) : TVector3f;
Var
r : glFloat;
p : TVector3f;
Begin
p := TVector3f.Create(0,0,0);
r := 0;
r := R + power(sin(m[0]*phi), m[1]);
r := R + power(cos(m[2]*phi), m[3]);
r := R + power(sin(m[4]*theta), m[5]);
r := R + power(cos(m[6]*theta), m[7]);
p.x := r * sin(phi) * cos(theta);
p.y := r * cos(phi);
p.z := r * sin(phi) * sin(theta);
Result := p;
end;
procedure Draw();
Var
i,j : Integer;
Begin
// ListCall := glGenLists(96);
// glNewList(ListCall,GL_COMPILE);
du := 2*PI / resolution; ///* Theta */
dv := PI / resolution; //* Phi */
glBegin(GL_QUADS);
for i := 0 to resolution do
Begin
u := i * du;
for j:=0 to resolution do
Begin
v := j * dv;
q := Eval(u,v,temp);
n := CalcNormal(q,
Eval(u+du/10,v,temp),
Eval(u,v+dv/10,temp));
c := GetColor(u);
glNormal3f(n.x,n.y,n.z);
glColor3f(c.x,c.y,c.z);
glVertex3f(q.x,q.y,q.z);
c.Free;
q.Free;
n.Free;
q := Eval(u+du,v,temp);
n := CalcNormal(q,
Eval(u+du+du/10,v,temp),
Eval(u+du,v+dv/10,temp));
c := GetColor(u+du);
glNormal3f(n.x,n.y,n.z);
glColor3f(c.x,c.y,c.z);
glVertex3f(q.x,q.y,q.z);
c.Free;
q.Free;
n.Free;
q := Eval(u+du,v+dv,temp);
n := CalcNormal(q,
Eval(u+du+du/10,v+dv,temp),
Eval(u+du,v+dv+dv/10,temp));
c := GetColor(u+du);
glNormal3f(n.x,n.y,n.z);
glColor3f(c.x,c.y,c.z);
glVertex3f(q.x,q.y,q.z);
c.Free;
q.Free;
n.Free;
q := Eval(u,v+dv,temp);
n := CalcNormal(q,
Eval(u+du/10,v+dv,temp),
Eval(u,v+dv+dv/10,temp));
c := GetColor(u);
glNormal3f(n.x,n.y,n.z);
glColor3f(c.x,c.y,c.z);
glVertex3f(q.x,q.y,q.z);
c.Free;
q.Free;
n.Free;
end;
end;
glEnd();
// glEndList();
End;
function WndProc(hwnd: DWORD; message: UINT; wParam: Longint; lParam: LongInt): LongInt; stdcall;
begin
if (message = WM_CHAR) and (wParam = VK_ESCAPE) then
begin
PostQuitMessage(0);
Result := 0;
end
else
Result := DefWindowProc(hwnd, message, wParam, lParam);
end;
var
pfd : PIXELFORMATDESCRIPTOR;
iFormat : integer;
w, h : integer;
{ TVector3f }
constructor TVector3f.Create(_X, _Y, _Z: glFloat);
begin
Self.X := _X;
Self.Y := _Y;
Self.Z := _Z;
end;
begin
randomize;
ZeroMemory(@wndclass, sizeof(WNDCLASSEX));
with wndclass do
begin
cbSize := sizeof(WNDCLASSEX);
style := CS_HREDRAW or CS_VREDRAW or CS_OWNDC;
lpfnWndProc := @WndProc;
lpszClassName := "SS";
end;
RegisterClassEx(wndclass);
w := GetSystemMetrics(SM_CXSCREEN);
h := GetSystemMetrics(SM_CYSCREEN);
glViewPort(0, 0, w, h);
Handle := CreateWindowEx(WS_EX_APPWINDOW,
"SS", "SS",
WS_POPUP,
0, 0, w, h, 0, 0, 0, nil);
DC := GetDC(Handle);
FillChar(pfd, SizeOf(PIXELFORMATDESCRIPTOR), 0);
with pfd do
begin
nSize := SizeOf(TPIXELFORMATDESCRIPTOR);
nVersion := 1;
dwFlags := PFD_DRAW_TO_WINDOW or
PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER;
iPixelType := PFD_TYPE_RGBA;
cColorBits := 16;
cDepthBits := 16;
iLayerType := PFD_MAIN_PLANE;
end;
iFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, iFormat, @pfd);
wglMakeCurrent(DC, wglCreateContext(DC));
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ShowWindow(Handle, SW_SHOW);
ShowCursor(false);
glClear(GL_COLOR_BUfFER_BIT or GL_DEPTH_BUfFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(90, 640/480, 0.5, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glTranslatef(0, 0, -7);
glEnable(GL_DEPTH_TEST);
for K:=0 to 7 do
begin
Temp1 := Random(Max_Rand)+1;
temp[k]:=temp1;
end;
// draw();
while true do
begin
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(msg);
DispatchMessage(msg);
if msg.message = WM_QUIT then Exit;
end;
glClear(GL_COLOR_BUfFER_BIT or GL_DEPTH_BUfFER_BIT);
glRotated(2,0.8,1,0.2);
for K:=0 to 7 do
begin
if (k mod 2) = 0 then
temp[k]:=temp[k]+0.01;
end;
draw();
// glCallList(ListCall);
glPushMatrix();
SwapBuffers(DC);
end;
end.
← →
-=S.S=- © (2005-08-30 13:42) [1]Модуль MyMath.pas
unit MyMath;
interface
function Floor(const X: Extended): Integer;
function Ceil(const X: Extended): Integer;
function Power(const Base, Exponent: Extended): Extended;
function IntPower(const Base: Extended; const Exponent: Integer): Extended;
implementation
function IntPower(const Base: Extended; const Exponent: Integer): Extended;
asm
mov ecx, eax
cdq
fld1 { Result := 1 }
xor eax, edx
sub eax, edx { eax := Abs(Exponent) }
jz @@3
fld Base
jmp @@2
@@1: fmul ST, ST { X := Base * Base }
@@2: shr eax,1
jnc @@1
fmul ST(1),ST { Result := Result * X }
jnz @@1
fstp st { pop X from FPU stack }
cmp ecx, 0
jge @@3
fld1
fdivrp { Result := 1 / Result }
@@3:
fwait
end;
function Power(const Base, Exponent: Extended): Extended;
begin
if Exponent = 0.0 then
Result := 1.0 { n**0 = 1 }
else if (Base = 0.0) and (Exponent > 0.0) then
Result := 0.0 { 0**n = 0, n > 0 }
else if (Frac(Exponent) = 0.0) and (Abs(Exponent) <= MaxInt) then
Result := IntPower(Base, Integer(Trunc(Exponent)))
else
Result := Exp(Exponent * Ln(Base))
end;
function Ceil(const X: Extended): Integer;
begin
Result := Integer(Trunc(X));
if Frac(X) > 0 then
Inc(Result);
end;
function Floor(const X: Extended): Integer;
begin
Result := Integer(Trunc(X));
if Frac(X) < 0 then
Dec(Result);
end;
end.
← →
Darthman © (2005-08-30 15:13) [2]Что именно из сего кода надо оптимизировать? Телепатов пока нету :)
← →
XProger © (2005-08-30 15:36) [3]Darthman, человеку просто влом работать над своим алгоритмом ;)
← →
Darthman © (2005-08-30 17:52) [4]Телепаты тут :)))
← →
MeF Dei Corvi © (2005-08-30 18:25) [5]
> Модуль MyMath.pas
Где-то я уже видел эти функции...
← →
MrAngel (2005-08-30 21:04) [6]У меня есть идея - перепиши всё на ассемблер :-)
← →
tesseract © (2005-08-30 22:17) [7]У меня тоже идея - я твйрдо уверен, что Create/free операция помедленне чем эстонская борзая - избавься от них
← →
DR0N © (2005-08-31 00:09) [8]А я твердо уверенн, что не надо такие темы создавать =)
← →
-=S..S=- (2005-09-06 15:52) [9]Извените ... инета не было ...
Она прога слишком медленно работает :( ...
Create, Free можно конечно убрать ... но тогда она вообще всю память сожрёт.
2 Xproger Мне не впадло .. просто я новичёк в OpenGL и хотел спросить как это лутше сделать ... для этого же и существуют форумы ... не так ли ?
Пытался сделать через Листы .. но тогда будет без анимации .. а это не интересно
> MeF Dei Corvi © (30.08.05 18:25) [5]
Я их выдер из какого то модуля ... что бы его полностью не включать
← →
A22 © (2005-09-06 16:02) [10]2 -=S..S=-
"она медленно работает" к коду такого объема неприменимо. конкретно: что надо сделать, что сделано, что не так, что требуется исправить\ускорить?
При грамотной постановке вопроса увеличиваются шансы получить грамотные ответы...
← →
Zer0 © (2005-09-06 16:31) [11]SuperFormula или Spherical Harmonics?
для начла... очень топорный подход - изпользовать создание и уничтожение класса tvector в рилтайме три раза(!) для одной точки.
аффтар срочно убей себя апстену.
(кто мешает написать процедуру ChangeVector? или просто
TVector3f = record
X,Y,Z : GLfloat;
end;
function setvec(const x,y,z:GLfloat):TVector3f;
begin
result.x:=x; result.y:=y; result.z:=z;
end;
)
можно многое заоптимизить исходя из того что phi и theta изменяются дискретно и не очень часто => считать небольшую табличку
нормали можно найти аналитическим путем взяв производные.
так как в треугольниках меняется только положение точек то можно использовать упакованные координаты и массивы индексные точек в трегуольниках (index arrays). потом можно взять тот же самый VBO и GL_STRIPS...
← →
-=S..S=- (2005-09-06 16:39) [12]SuperFormula или Spherical Harmonics?
Оно самое )
> Zer0 © (06.09.05 16:31) [11]
Уже более менее интересно ... Спасибо !!!
Дома попробую ... а то на работе Линукс ...
Мож чего на асм перепишу ...
← →
XProger © (2005-09-07 00:29) [13]-=S..S=-, ты сначала бы определил самую медленную процедуру, а потом за асмом бежал...
У тебя около половины всех полигонов расположены не лицевой гранью к камере, следовательно можно провести ручной куллинг таких граней :)
← →
-=S..S=- (2005-09-07 10:31) [14]
> следовательно можно провести ручной куллинг таких граней
> :)
Сорри за тупизм ... но что это такое - Кулинг ?
Т.е не выводить те грани которые не будут видны ?
Но тогда мне кажеться что расчёт того виден ли этот полигон займёт больше процессорного времени чем просто вывести его
← →
XProger © (2005-09-07 19:38) [15]Когда кажется сам знаешь что делать надо, так что, не поленись и проверь... ;)
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.013 c