Matematyka 3D dla Delphi i efekty graficzne :U

0

Ponizsza funkcja powinna nakladac na primityw wyskalowana teksture w zaleznosci od pozycji swiatla itp....

zeby narysowac w pelni oswietlony model uzywam petli ktora jedzie po wszystkich face'ach modelu i naklada teksture niestety nie dziala :-0

rysujmy te swaitlo:

glcolor3f(1,0,0);
GLENABLE(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glbindtexture(gl_texture_2d,lighttex);
glcolor3f(1,0,0);
for i:=0 to high(terrain.face) do
GET_PLANE_POINT_LIGHT(terrain,terrain.arrays[i][0].normal3f,i,[swiatlo],terrain.colarrays[i]);   
GLDISABLE(GL_BLEND);
function GET_PLANE_POINT_LIGHT(model : tglarrayselectionmodel; normal : t3dpoint; faceindex : integer;
 lights : array of tnoxx_gllight;var facepoint : array of t3dpoint) : textpoint;


var
wektor : t3dpoint;
distance : single;
distance2 : single;
i,j,n : integer;
LIGHT_COLLISION_IN_FACE : boolean;
LIGHT_LINE : tline;
DELTA   : single;
A,B,C   : single;
KTOREWIERZCHOLKI        : array of boolean;
newverts                : array of t3dpoint;
coords : array of textpoint;
pierwszy : t3dpoint;

FACECENTERPOINT : t3dpoint;
begin
{       function line_func(a,b,x                                                : single)       : single;
        function getxfromfunc(y,a,b                                             : single)       : single;
        function get_line_parameter(x1,x2,y1,y2                                 : single)       : single;
        function get_line_b(y,a,x                                               : single)       : single;
        function lines_equation(a1,b1,a2,b2                                     : single)       : boolean;                      }
//              Y -> XZ
//              X -> YZ
//              Z -> XY

distance := getplaned(normal,lights[0].pos);
distance2 := getplaned(normal,facepoint[0]);
if distance > lights[0].radius then exit;

{if
classifyapointagainstaplane(lights[0].pos,
normal,
distance) <> isFront then exit;      }

WEKTOR.x := NORMAL.x;//*distance*10000;
WEKTOR.y := NORMAL.y;//*distance*10000;
WEKTOR.z := NORMAL.z;//*distance*10000;


//LIGHT_COLLISION_IN_FACE := IntersectedPolygon(facepoint,[lights[0].pos,WEKTOR],length(facepoint));  //get our collision with plane

setlength(coords,length(model.arrays[faceindex]));
//setlength(KTOREWIERZCHOLKI,length(model.arrays[faceindex]));
//BOOLtable_equalsTO(false,KTOREWIERZCHOLKI);
                               //,WEKTOR]
pierwszy := GET_PINTERSECTION_LINE_PLANE(normal,distance2, WEKTOR,LIGHTS[0].pos);


pierwszy.y :=  pierwszy.Y-lights[0].radius;
pierwszy.x :=  pierwszy.X-lights[0].radius;
pierwszy.z :=  pierwszy.Z-lights[0].radius;

if (NORMAL.X >= NORMAL.Y) and (NORMAL.X >= NORMAL.Z) then   //DLA X -> YZ  Y = X
begin
for n:=0 to high(model.arrays[faceindex]) do
if
n2ddistance(lights[0].pos.y,lights[0].pos.z,model.arrays[faceindex][n].vertex3f.y,model.arrays[faceindex][n].vertex3f.z)
> lights[0].radius then exit;



for n:=0 to high(model.arrays[faceindex]) do
begin
coords[n].x := (model.arrays[faceindex][n].vertex3f.z-pierwszy.z)/2*lights[0].radius;
coords[n].y := (model.arrays[faceindex][n].vertex3f.y-pierwszy.y)/2*lights[0].radius;
end;

end;



if (NORMAL.Y >= NORMAL.X) and (NORMAL.Y >= NORMAL.Z) then   //DLA Y -> XZ Y=Z
begin
for n:=0 to high(model.arrays[faceindex]) do
if
n2ddistance(lights[0].pos.x,lights[0].pos.z,model.arrays[faceindex][n].vertex3f.x,model.arrays[faceindex][n].vertex3f.z)
> lights[0].radius then exit;


for n:=0 to high(model.arrays[faceindex]) do
begin
coords[n].x := (model.arrays[faceindex][n].vertex3f.x-pierwszy.x)/2*lights[0].radius;
coords[n].y := (model.arrays[faceindex][n].vertex3f.z-pierwszy.z)/2*lights[0].radius;
end;

end;


if (NORMAL.Z >= NORMAL.X) and (NORMAL.Z >= NORMAL.Y) then   //DLA Z -> XY   Z=Y
begin
for n:=0 to high(model.arrays[faceindex]) do
if
n2ddistance(lights[0].pos.x,lights[0].pos.Y,model.arrays[faceindex][n].vertex3f.x,model.arrays[faceindex][n].vertex3f.Y)
> lights[0].radius then exit;



for n:=0 to high(model.arrays[faceindex]) do
begin
coords[n].x := (model.arrays[faceindex][n].vertex3f.x-pierwszy.x)/2*lights[0].radius;
coords[n].y := (model.arrays[faceindex][n].vertex3f.y-pierwszy.y)/2*lights[0].radius;
end;

end;


//CALUCULATE LAST COORDS
//for n:=0 to high(model.arrays[faceindex]) do
{if coords[n].x > 1 then coords[n].x := 1;
if coords[n].y > 1 then coords[n].y := 1;   }


//showmessage(floattostr(coords[n].x));
GLDISABLE(GL_BLEND);
FACECENTERPOINT := t3dpointsum(facepoint);
gldisable(GL_TEXTURE_2D);
glcolor3f(1,1,1);
//createsphere(FACECENTERPOINT.x,FACECENTERPOINT.y,FACECENTERPOINT.z,1,4);
glbegin(GL_LINES);
glvertex3f(FACECENTERPOINT.x,FACECENTERPOINT.y,FACECENTERPOINT.z);
glvertex3f(FACECENTERPOINT.x,FACECENTERPOINT.y+3,FACECENTERPOINT.z);
glend;    
glcolor3f(1,0,0);

glENABLE(GL_TEXTURE_2D); glENABLE(GL_BLEND);

matrixtoglenable(model.face[faceindex].matrix);
//if length(coords) <=0 then exit;


for n:=0 to high(coords) do
begin
//unit1.panel1.caption := 'FACE VERTEX '+inttostr(n)+' ( '+floattostr(coords[n].x)+' ) , ( '+floattostr(coords[n].y)+' )';
glvertex3fv(@model.arrays[faceindex][n].vertex3f);
gltexcoord2f(coords[n].x,coords[n].y);
end;
glend();

     {
LIGHT_LINE.a := get_line_parameter(lights[0].pos.Y,temp_intersect_v.Y,lights[0].pos.Z,temp_intersect_v.Z);
LIGHT_LINE.b := get_line_b(lights[0].pos.Z,LIGHT_LINE.a,lights[0].pos.Y);                   }

//result.x := temp_intersect_v.Y-/(model.arrays[faceindex][0].vertex3f.y
end;

EFEKT DZIALANIA KODU TAKI:

  1. Model ma tylko jeden face stworzony z wielu roznacych sie od siebie trojkatow, rysowany za pomoca GL_TRIANGLES
    user image

  2. Model stworzony z tylu face'ow ile trojaktow, rysowany za pomoca GL_TRIANGLES
    user image

BIALE PASKI TO TYLKO LINIE KTORE WYCHODZA Z SRODKA FACE'A DO GORY :C

czy ktos sie orientuje czemu to zle skaluje? Rysunki powinny wygladac jak projekcja jedej tekstury na model (po prostu jedno swiatlo - jedno czerwone kolko) a tam ich jest wiecej i jakies dziwne x_X

reszta kodu:

type t3dpoint = record
x : single;
y : single;
z : single;
end;

function t3dpointsum(points : array of t3dpoint) : t3dpoint;
var
i : integer;
divider : integer;
begin
result.x := 0;
result.y := 0;
result.z := 0;
divider := length(points);
for i:=0 to high(points) do
begin
result.x := result.x + points[i].x;
result.y := result.y + points[i].y;
result.z := result.z + points[i].z;
end;

result.x := result.x/divider;
result.y := result.y/divider;
result.z := result.z/divider;
end;


function n2ddistance(first_point, second_point : textpoint) : single;overload;
begin
result := sqrt(sqr(first_point.x-second_point.x)+sqr(first_point.y-second_point.y));
end;


function GET_PINTERSECTION_LINE_PLANE(PLANE_NORMAL : t3dpoint; DIST : single; LINE_NORMAL : t3dpoint; LINEPOINTSTART : t3dpoint) : t3dpoint;
var
tm : single; //factor
tn : single; //factor
begin
tn :=(PLANE_NORMAL.x*LINE_NORMAL.x)+(PLANE_NORMAL.y*LINE_NORMAL.y)+(PLANE_NORMAL.z*LINE_NORMAL.z);
if tn = 0 then exit;
tm := -1*((PLANE_NORMAL.x*LINEPOINTSTART.x)+(PLANE_NORMAL.y*LINEPOINTSTART.y)+(PLANE_NORMAL.z*LINEPOINTSTART.z)+DIST)/tn;
result.x := LINEPOINTSTART.x +  LINE_NORMAL.x*tm;
result.y := LINEPOINTSTART.y +  LINE_NORMAL.y*tm;
result.z := LINEPOINTSTART.z +  LINE_NORMAL.z*tm;
end;

I tu jeszcze jakby cos brakowalo

type tglArraySelectionModel=record
header                          : tArraySelectionFileHeader;
face                            : array of tngasface;
TEXCOORDARRAYS                  : array of tngastexcoord;
COLARRAYS                       : array of array of t3dpoint;
TEXARRAYS                       : array of array of textpoint;
arrays                          : array of
                                        array of tinasmcoord;
collisionmap                    : array of array of tngascollisionmap;
shaders                         : array of gluint; //This is an array of gllist    [BGLCMD Scripting definitions]
face_uses_shader                : array of boolean;
face_types                      : array of tngasface_type;
vis_vertex                      : array of tcollision_vert;
lightmap_luxel                  : array of tngas_lightmap_face;
textures                        : array of gluint;
light_textures                  : array of gluint;
lights                          : array of tngaslight;

AMBIENT                         : t3dpoint;
texture                         : gluint;
loadedtex                       : boolean;
maxx,minx                       : single;
maxy,miny                       : single;
maxz,minz                       : single;
isother                         : byte;
first_pass_render_arg           : text4dpoint;      //r,g,b,a
PORTAL_FILE                     : TPVS_FILE;
end;

type tnoxx_gllight=record
pos             : t3dpoint;
rgba            : text4dpoint;
pointpos        : t3dpoint;
effect          : tglnl_effect;
intensity       : single; //light factor 0..1
radius          : single;
loadtex         : boolean;
texture         : gluint;
end;
0

Pewnie źle lub wcale nie razciągasz tej tekstury na cały obszar.

skala = nfac; // nfac = max(nx,ny); - liczba tych quads w poziomie i pionie
// albo skalax i skalay oddzielnie, ale wtedy się zdeformuje

coords[i].x *= skala;
coords[i].y *= skala;

może lepiej użyć glTexGen...

albo wszystko (teren i reszta) zrobić z pomocą: glMap2 + glEvalCoord...

0

nie wczytywalem sie w kod ale poniewaz powinienes miec taki efekt ze to kolko jest o wiele wieksze (bardziej rozciagniete) czyli niektore polygony poeinny byc calkiem jasne (te blizej swiatla) wiec radze zrobic test: sprobuj zmienic polozenie swiatla najpierw wzluz osi x potem osobno y i z i zobacz czy prawidlowo zmieniaja sie kulka na tych face'ach. Jesli nic sie nie zmieni to w ogóle jest cos nie tak , ale moze tylko jedna skladowa kuleje.

Robisz luminacje na teksturach 1D+2D czy uzywasz tekstury 2D ?

Pozdr. skalniak</ort>

0

//sorka 2 razy mi sie wkleil post

0

nie wiem co to znaczy luminacja, ale nakladam teksture 2d na teksture 2d :C

1 użytkowników online, w tym zalogowanych: 0, gości: 1