Autor Beitrag
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Do 26.05.05 14:31 
Hallo, ich möchte ein bild laden, dieses intern auf die nächstgelegene Potenz von 2 strecken, dann in einem image mit stretch ausgeben, von dort aus aber irgendwie in der gestreckten größe weiterbenutzen, ok mein ansatz ist etwas umständlich deshalb möchte ich mein problem erklären:

-Ich habe ein image (später sinds mehrere), dort möchte ich ein bild reinladen, das gleiche bild soll dann als textur für ein opengl objekt genommen werden, welches ich dann vorher auf eine potenz von 2 strecken möchte (am besten strecken und nicht quetschen), wie mache ich das am besten ? ein bild in ne variable laden ? und wie mache ich das strecken und die berechnung ?


ich glaube ich lade ein bild und speicher den pfad, dann lade ich es nochmal extra ins opengl aber ich möchte es vorher auf eine potenz von 2 strecken also zb 2, 4, 8, 16, 32, ... 1024 ...
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 27.05.05 07:59 
Wo liegt das Problem dabei: Beim Strecken oder bei der 2er-Potenz?

Das Strecken sollte mit BitBlt und internen Bitmap-Objekten relativ einfach sein.

Die 2er-Potenz: Weißt du nicht, wie du die nächste 2er-Potenz bekommst?
Einfach mit mod 2 die Differenz zum nächstunteren Wert holen, diese nächstuntere 2er-Potenz dann noch mit 2 multiplizieren.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 481

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 27.05.05 08:13 
user profile iconjaenicke hat folgendes geschrieben:
Einfach mit mod 2 die Differenz zum nächstunteren Wert holen, diese nächstuntere 2er-Potenz dann noch mit 2 multiplizieren.
Also das klappt nicht. Überlege mal, was du da rechnest. Ich würde das eher so machen:
ausblenden Delphi-Quelltext
1:
2:
next2erPotenz:=1;
while next2erPotenz<MeineZahl do next2erPotenz:=next2erPotenz*2;

_________________
We are, we were and will not be.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 27.05.05 08:16 
NewSize := 1 shl ceil(ln( OldSize )/ln(2));Gibt auch noch Möglichkeiten ohne Floats aber dann kannste es (soweit ich es grad überblicken kann) nicht einfach auf eine Zeile schreiben.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 27.05.05 08:20 
Autsch, klar, das ist Blödsinn. :oops:
Wie ich darauf gekommen bin, weiß ich schon nicht mehr, zuerst hatte ich auch mit ner Schleife überlegt, und dann gabs nen Kurzschluss im Gehirn ;-) .
:autsch:
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 27.05.05 08:50 
Das ganze noch in der Economy-Version in log(log(high(Integer))) Schritten (deswegen ausgeschrieben) 8)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
var
 I, J: Integer;
begin
  I := OldSize; 

  J := I shr 1;
  J := J or J shr (1 shl 0);
  J := J or J shr (1 shl 1);
  J := J or J shr (1 shl 2);
  J := J or J shr (1 shl 3);
  J := J or J shr (1 shl 4);
  if J and I = 0 then
   J := I else
   J := (I and not J)*2;

  NewSize := J;
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 12:27 
gut, danke, aber das mit dem strecken habe ich noch nicht hinbkommen :roll:

EDIT: habs hinbekommen:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
function NextPotOfTwo(Number: integer): integer;
var
 I, J: Integer;
begin
  Result := 0;
  I := Number;
  J := I shr 1;  
  J := J or J shr (1 shl 0);  
  J := J or J shr (1 shl 1);  
  J := J or J shr (1 shl 2);  
  J := J or J shr (1 shl 3);  
  J := J or J shr (1 shl 4);  
  if J and I = 0 then  
    J := I else
      J := (I and not J)*2;
  Result := J;
end;

function ResizeBmp(bitmp: TBitmap; wid, hei: Integer): Boolean;
var 
  TmpBmp: TBitmap;
  ARect: TRect;
begin
  Result := False;
  try
    TmpBmp := TBitmap.Create;
    try
      TmpBmp.Width  := wid;
      TmpBmp.Height := hei;
      ARect := Rect(0, 0, wid, hei);
      TmpBmp.Canvas.StretchDraw(ARect, Bitmp);
      bitmp.Assign(TmpBmp);
    finally
      TmpBmp.Free;
    end;
    Result := True;
  except
    Result := False;
  end;
end;

procedure TMainForm.Vorne1Click(Sender: TObject);
begin
  if opendialog1.Execute then
    begin
      front.picture.loadfromfile(opendialog1.FileName);
      IMG_Front := Timage.Create(MainForm);
      try
        IMG_Front.Picture.loadfromfile(opendialog1.filename);
        ResizeBmp(IMG_Front.picture.Bitmap, NextPotOfTwo(IMG_Front.Width), NextPotOfTwo(IMG_Front.Height));
        IMG_Front.picture.bitmap.PixelFormat := pf32bit;
        TFront.AssignFromBitmap(IMG_Front.picture.Bitmap);
        TFront.GenTexture;
      finally
        IMG_Front.Free;
      end;
    end;
end;

8)
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 13:14 
leider noch ein problem, wenn ein bild schon im richtigen format ist, dann wird es trotzdem größer gemacht und sieht dann als textur wieder pixelig aus, wie kann ich machen, dass ja nach dem was dichter ist (kleiner oder größer) es so gestreckt wird, dass die nächstgelegene 2er potenz erreicht ist, oder falls es schon eine ist, dass dann nichts passiert :?
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 27.05.05 14:40 
Liefert NextPotOfTwo nicht dieselbe Zahl zurück, wenn sie schon eine 2-er Potenz ist? Falls das nicht der Fall ist, ist's ein Programmierfehler von mir. Kann's im Moment nicht nachprüfen, da ich im Moment kein Zugang zu einem Delphi hab.
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 14:42 
nee es liefert die nächst höhere, die nächst niedrigere müsste da aber auch rein
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 27.05.05 15:18 
Vielleicht probierst du das hier:
ausblenden Delphi-Quelltext
1:
NewSize := 1 shl round(ln( OldSize )/ln(2));					
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 15:20 
jo der bringts, danke echt schon klein ^^

aber wenn es gleich ist scheint es immer noch nicht zu funktionieren, wie könnte ich denn abfragen, ob eine zahl eine potenz von 2 ist ?
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 27.05.05 15:31 
geht mit if zahl mod 2 = 0 then
oder so ;)
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
function isMultipleOfTwo(zahl: dword): boolean; register;
asm
   sar eax, 1
   mov eax, 1
   jc @false
   ret
   @false:
   mov eax, 0
end;

procedure TForm1.Button1Click(Sender: TObject);
  var zahl:integer;
begin
  zahl := 3;
if isMultipleOfTwo(zahl) then showmessage('true');
end;

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 15:34 
Zitat:

if zahl mod 2 = 0 then

das gilt für gerade zahlen (multiplikanten von 2) (das wort hab ich mir grad ausgedacht :lol: )

demnach wäre 10 eine potenz von 2 was ja nicht stimmt :!:
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 27.05.05 15:43 
ups, du meintest potenzen...wart mal kurz...ich überleg mir was :)

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 15:52 
vielleich so ?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function ispotoftwo(Number: integer): boolean;
begin
  result := false;
  if (Number mod (1 shl round(ln(Number) / ln(2)))) = 0 then
    result := true;
end;

function NearestPotOfTwo(Number: integer): integer;
begin
  result := 1 shl round(ln(Number) / ln(2));
  if ispotoftwo(number) then
    result := number;
end;


Zuletzt bearbeitet von F34r0fTh3D4rk am Fr 27.05.05 15:53, insgesamt 1-mal bearbeitet
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 27.05.05 15:52 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
function isPotenzOfTwo(zahl: dword): boolean; register;
asm
   xor ecx, ecx
   xor edi, edi
   @loop:
   cmp edi, 32
   je @ende
   sar eax, 1
   inc edi
   jnc @lastbitzero
   inc ecx
   @lastbitzero:
   jmp @loop
   @ende:
   cmp ecx, 1
   je @true
   mov eax, 0
   jmp @out
   @true:
   mov eax, 1
   @out:
end;


edit: oder noch schneller: (falls jemand nen schnelleren weg kennt bitte schreien ;) )
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function isPotenzOfTwo(zahl: dword): boolean; register;
asm
   xor ecx, ecx
   cmp eax, 2
   jl @false
   @loop:
   cmp ecx, 32
   je @lookup
   sar eax, 1
   inc ecx
   jc @lookup
   jmp @loop
   @lookup:
   cmp eax, 0
   jg @false
   mov eax, 1
   jmp @out
   @false:
   xor eax, eax
   @out:
end;

edit2: funktion 2 korriegiert ^^

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...


Zuletzt bearbeitet von retnyg am Fr 27.05.05 16:26, insgesamt 2-mal bearbeitet
F34r0fTh3D4rk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Fr 27.05.05 15:55 
scheint auch nicht zu gehen, wenn ich das bild nicht resize stimmt es :idea:

aber beide prozeduren scheinen zu stimmen :!:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
function ispotoftwo(Number: integer): boolean;
asm
   xor ecx, ecx  
   cmp eax, 2  
   jl @false  
   @loop:  
   cmp ecx, 32  
   je @lookup  
   sar eax, 1  
   inc ecx  
   jc @lookup  
   jmp @loop  
   @lookup:  
   cmp eax, 0  
   jg @false  
   mov eax, 1  
   jmp @out  
   @false:  
   xor eax, eax  
   @out:  
end;

function NearestPotOfTwo(Number: integer): integer;
begin
  if ispotoftwo(number) then
    result := number else
      result := 1 shl round(ln(Number) / ln(2));
end;

function ResizeBmp(bitmp: TBitmap; w, h: Integer): Boolean;
var 
  TmpBmp: TBitmap;
  ARect: TRect;
begin
  Result := False;
  try
    TmpBmp := TBitmap.Create;
    try
      TmpBmp.Width  := w;
      TmpBmp.Height := h;
      ARect := Rect(0, 0, w, h);
      TmpBmp.Canvas.StretchDraw(ARect, Bitmp);
      bitmp.Assign(TmpBmp);
    finally
      TmpBmp.Free;
    end;
    Result := True;
  except
    Result := False;
  end;
end;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TMainForm.Rechts1Click(Sender: TObject);
begin
  if opendialog1.Execute then
    begin
      SideR.picture.loadfromfile(opendialog1.FileName);
      IMG_Right := Timage.Create(MainForm);
      try
        IMG_Right.Picture.loadfromfile(opendialog1.filename);
        ResizeBmp(IMG_Right.picture.Bitmap, NearestPotOfTwo(IMG_Right.Width), NearestPotOfTwo(IMG_Right.Height));
        IMG_Right.picture.bitmap.PixelFormat := pf32bit;
        TRight.AssignFromBitmap(IMG_Right.picture.Bitmap);
        TRight.GenTexture;
      finally
        IMG_Right.Free;
      end;
    end;
end;
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Fr 27.05.05 17:16 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben:
nee es liefert die nächst höhere, die nächst niedrigere müsste da aber auch rein
Bei mir funktioniert's:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function NextPotOfTwo(I: integer): integer;
var
 J: Integer;
begin
  J := I shr 1;
  J := J or J shr (1 shl 0);
  J := J or J shr (1 shl 1);
  J := J or J shr (1 shl 2);
  J := J or J shr (1 shl 3);
  J := J or J shr (1 shl 4);
  if J and I = 0 then          // isPotenzOfTwo?
   Result := I else            //  selbe Zahl zurückgeben
   Result := (I and not J)*2;  //  nächst höhere 2-er-Potenz zurückgeben
end;
NextPotOfTwo(16)=16
NextPotOfTwo(32)=32
usw.
Wie ihr auch sieht ist bei mir die isPotenzOfTwo-Abfrage auch schon in der Funktion enthalten (siehe Highlight).

user profile iconretnyg hat folgendes geschrieben:
falls jemand nen schnelleren weg kennt bitte schreien ;)
Wie ich schon angegeben hab ist meine Funktion O(log(log(max(integer))) und deine O(log(Input)) (falls ich deinen Code richtig verstehe). Somit ist meine zu mindest asymptotisch gesehen viel schneller ;)
retnyg
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2754

SNES, GB, GBA, CPC, A500, 486/66, P4/3.0HT: NintendOS, AmigaOS, DoS
Delphi 5, Delphi 7
BeitragVerfasst: Fr 27.05.05 17:23 
user profile icondelfiphan hat folgendes geschrieben:

user profile iconretnyg hat folgendes geschrieben:
falls jemand nen schnelleren weg kennt bitte schreien ;)
Wie ich schon angegeben hab ist meine Funktion O(log(log(max(integer))) und deine O(log(Input)) (falls ich deinen Code richtig verstehe). Somit ist meine zu mindest asymptotisch gesehen viel schneller ;)

sorry, aber von logarithmusfunktionen hab ich keinen plan :gruebel:
meine funktion geht bit für bit durch den parameter, und gibt true zurück, wenn nur ein bit auf 1 steht

_________________
es gibt leute, die sind genetisch nicht zum programmieren geschaffen.
in der regel haben diese leute die regel...