|
1 | 1 | (******************************************************************************)
|
2 | 2 | (* uOpenGLGraphikEngine.pas ??.??.???? *)
|
3 | 3 | (* *)
|
4 |
| -(* Version : 0.10 *) |
| 4 | +(* Version : 0.11 *) |
5 | 5 | (* *)
|
6 | 6 | (* Author : Uwe Schächterle (Corpsman) *)
|
7 | 7 | (* *)
|
|
38 | 38 | (* 0.08 - Fix Memleaks *)
|
39 | 39 | (* 0.09 - Fix LoadAlphaColorGraphik *)
|
40 | 40 | (* 0.10 - Fix speedup graphik loading *)
|
| 41 | +(* 0.11 - Fix LoadAlphaGraphikItem did not respect png *) |
| 42 | +(* transparency *) |
41 | 43 | (* *)
|
42 | 44 | (******************************************************************************)
|
43 | 45 | Unit uopengl_graphikengine;
|
|
136 | 138 | Function LoadGraphik(Const Graphik: TBitmap; Name: String; Stretch: TStretchmode = smNone): Integer; overload; // Laden einer Graphik ohne Alphakanal
|
137 | 139 | Function LoadAlphaColorGraphik(Filename: String; Color: TRGB; Stretch: TStretchmode = smNone): Integer; overload; // Lädt eine Alphagraphik und setzt den Wert von Color = Transparent.
|
138 | 140 | Function LoadAlphaColorGraphik(Const Graphik: TBitmap; Name: String; Color: TRGB; Stretch: TStretchmode = smNone): Integer; overload; // Lädt eine Alphagraphik und setzt den Wert von Color = Transparent.
|
| 141 | + Function LoadAlphaColorGraphikItem(Const Graphik: TBitmap; Name: String; Color: TRGB; Stretch: TStretchmode = smNone): TGraphikItem; overload; |
139 | 142 | (*
|
140 | 143 | Funktionen die NICHT Machen was sie sollen
|
141 | 144 |
|
|
1243 | 1246 | b.free;
|
1244 | 1247 | End;
|
1245 | 1248 |
|
| 1249 | +Function TOpenGL_GraphikEngine.LoadAlphaColorGraphikItem( |
| 1250 | + Const Graphik: TBitmap; Name: String; Color: TRGB; Stretch: TStretchmode |
| 1251 | + ): TGraphikItem; |
| 1252 | +Var |
| 1253 | + img, i: integer; |
| 1254 | +Begin |
| 1255 | + // TODO: Das sollte so umgeschrieben werden, dass alle Funtionen LoadAlphaColorGraphikItem aufrufen und man sich hier das Suchen sparen kann |
| 1256 | + img := LoadAlphaColorGraphik(Graphik, Name, Color, Stretch); |
| 1257 | + For i := 0 To high(FImages) Do Begin |
| 1258 | + If FImages[i].Image = img Then Begin |
| 1259 | + result := FImages[i]; |
| 1260 | + exit; |
| 1261 | + End; |
| 1262 | + End; |
| 1263 | + raise exception.Create('TOpenGL_GraphikEngine.LoadAlphaColorGraphikItem: Unable to load'); |
| 1264 | +End; |
| 1265 | + |
1246 | 1266 | Function TOpenGL_GraphikEngine.LoadAlphaColorGraphik(Filename: String; Color: TRGB; Stretch: TStretchmode): Integer; // Lädt eine Alphagraphik und setzt den Wert von Color = Transparent.
|
1247 | 1267 | Var
|
1248 | 1268 | Data: String;
|
|
1296 | 1316 | Function TOpenGL_GraphikEngine.LoadAlphaGraphikItem(Filename: String; Stretch: TStretchmode): TGraphikItem;
|
1297 | 1317 | Var
|
1298 | 1318 | OpenGLData: Array Of Array[0..3] Of Byte;
|
| 1319 | + tmp, AlphaMask: Array Of Array Of Byte; |
1299 | 1320 | Data: String;
|
| 1321 | + //ba, |
1300 | 1322 | b2, b: Tbitmap;
|
1301 | 1323 | jp: TJPEGImage;
|
1302 | 1324 | png: TPortableNetworkGraphic;
|
1303 |
| - nw, nh, ow, oh: INteger; |
| 1325 | + nw, nh, ow, oh: Integer; |
1304 | 1326 | IntfImg1: TLazIntfImage;
|
1305 | 1327 | CurColor: TFPColor;
|
1306 | 1328 | c, j, i: Integer;
|
| 1329 | + fi, fj, uu, vv, u, v: Single; |
| 1330 | + xi, yi: integer; |
1307 | 1331 | bool: {$IFDEF USE_GL}Byte{$ELSE}Boolean{$ENDIF};
|
1308 | 1332 | Begin
|
1309 | 1333 | (*
|
|
1312 | 1336 | Es sollte einem nur Klar sein dass hier evtl noch deutlich nachgebessert werden muß.
|
1313 | 1337 | *)
|
1314 | 1338 | {$WARNING not Implemented correctly}
|
| 1339 | + AlphaMask := Nil; |
1315 | 1340 | If FileExists(Filename) Then Begin
|
1316 | 1341 | Data := LowerCase(Filename);
|
1317 | 1342 | // Graphik bereits geladen
|
|
1340 | 1365 | png.TransparentColor := clBlack;
|
1341 | 1366 | png.Transparent := false;
|
1342 | 1367 | b.assign(png);
|
| 1368 | + setlength(AlphaMask, b.Width, b.Height); |
| 1369 | + IntfImg1 := b.CreateIntfImage; |
| 1370 | + For i := 0 To b.Width - 1 Do Begin |
| 1371 | + For j := 0 To b.Height - 1 Do Begin |
| 1372 | + AlphaMask[i, j] := IntfImg1.Colors[i, j].Alpha Shr 8; |
| 1373 | + End; |
| 1374 | + End; |
| 1375 | + IntfImg1.free; |
1343 | 1376 | png.free;
|
1344 | 1377 | End
|
1345 | 1378 | Else Begin
|
1346 | 1379 | b.LoadFromFile(Filename);
|
1347 | 1380 | End;
|
1348 | 1381 | // create the raw image
|
1349 |
| - IntfImg1 := TLazIntfImage.Create(0, 0); |
1350 | 1382 | nw := b.width;
|
1351 | 1383 | nh := b.height;
|
1352 | 1384 | ow := b.width;
|
|
1366 | 1398 | b2.PixelFormat := pf24bit;
|
1367 | 1399 | b2.width := nw;
|
1368 | 1400 | b2.height := nh;
|
1369 |
| - // b2.canvas.StretchDraw(rect(0, 0, nw, nh), b); |
1370 | 1401 | If Stretch = smStretch Then Begin
|
1371 | 1402 | Stretchdraw(b2.canvas, rect(0, 0, nw, nh), b, imBilinear);
|
1372 | 1403 | End
|
1373 | 1404 | Else Begin
|
1374 | 1405 | Stretchdraw(b2.canvas, rect(0, 0, nw, nh), b, imNearestNeighbour);
|
1375 | 1406 | End;
|
| 1407 | + //{ |
| 1408 | + If assigned(AlphaMask) Then Begin |
| 1409 | + If Stretch = smStretch Then Begin |
| 1410 | + Raise exception.Create('TOpenGL_GraphikEngine.LoadAlphaGraphikItem: missing implementation for Bilinear'); |
| 1411 | + End; |
| 1412 | + tmp := Nil; |
| 1413 | + setlength(tmp, nw, nh); |
| 1414 | + // Die Formeln sehen heftig aus, aber sind genau dass was raus |
| 1415 | + // Kommt wenn man die ugraphic.pas variante "auspackt" |
| 1416 | + For i := 0 To nw - 1 Do Begin |
| 1417 | + u := i / (nw - 1); |
| 1418 | + uu := u * b.Width; |
| 1419 | + xi := trunc(uu); |
| 1420 | + fi := uu - xi; |
| 1421 | + For j := 0 To nh - 1 Do Begin |
| 1422 | + v := j / (nh - 1); |
| 1423 | + vv := v * b.Height; |
| 1424 | + yi := trunc(vv); |
| 1425 | + fj := vv - yi; |
| 1426 | + If fi <= 0.5 Then Begin |
| 1427 | + If fj <= 0.5 Then Begin |
| 1428 | + tmp[i, j] := AlphaMask[min(xi, high(AlphaMask)), min(yi, high(AlphaMask[0]))]; |
| 1429 | + End |
| 1430 | + Else Begin |
| 1431 | + tmp[i, j] := AlphaMask[min(xi, high(AlphaMask)), min(yi + 1, high(AlphaMask[0]))]; |
| 1432 | + End; |
| 1433 | + End |
| 1434 | + Else Begin |
| 1435 | + If fj <= 0.5 Then Begin |
| 1436 | + tmp[i, j] := AlphaMask[min(xi + 1, high(AlphaMask)), min(yi, high(AlphaMask[0]))]; |
| 1437 | + End |
| 1438 | + Else Begin |
| 1439 | + tmp[i, j] := AlphaMask[min(xi + 1, high(AlphaMask)), min(yi + 1, high(AlphaMask[0]))]; |
| 1440 | + End; |
| 1441 | + End; |
| 1442 | + End; |
| 1443 | + End; |
| 1444 | + SetLength(AlphaMask, 0, 0); |
| 1445 | + AlphaMask := tmp; |
| 1446 | + End; //} |
1376 | 1447 | b.free;
|
1377 | 1448 | b := b2;
|
| 1449 | + b2 := Nil; |
| 1450 | + { |
| 1451 | + If assigned(AlphaMask) Then Begin // TODO: Das geht zwar, aber mit Effizients hat das nichts mehr zu tun ... Der Obige Code ist schneller, aber kann Bilinear nicht .. |
| 1452 | + ba := TBitmap.Create; |
| 1453 | + ba.PixelFormat := pf24bit; |
| 1454 | + ba.Width := length(AlphaMask); |
| 1455 | + ba.Height := length(AlphaMask[0]); |
| 1456 | + IntfImg1 := ba.CreateIntfImage; |
| 1457 | + For i := 0 To ba.Width - 1 Do Begin |
| 1458 | + For j := 0 To ba.Height - 1 Do Begin |
| 1459 | + CurColor.Red := AlphaMask[i, j] Shl 8; |
| 1460 | + CurColor.Green := AlphaMask[i, j] Shl 8; |
| 1461 | + CurColor.Blue := AlphaMask[i, j] Shl 8; |
| 1462 | + CurColor.Alpha := AlphaMask[i, j] Shl 8; |
| 1463 | + IntfImg1.Colors[i, j] := CurColor; |
| 1464 | + End; |
| 1465 | + End; |
| 1466 | + ba.LoadFromIntfImage(IntfImg1); |
| 1467 | + IntfImg1.free; |
| 1468 | + b2 := TBitmap.create; |
| 1469 | + b2.PixelFormat := pf24bit; |
| 1470 | + b2.width := nw; |
| 1471 | + b2.height := nh; |
| 1472 | + If Stretch = smStretch Then Begin |
| 1473 | + Stretchdraw(b2.canvas, rect(0, 0, nw, nh), ba, imBilinear); |
| 1474 | + End |
| 1475 | + Else Begin |
| 1476 | + Stretchdraw(b2.canvas, rect(0, 0, nw, nh), ba, imNearestNeighbour); |
| 1477 | + End; |
| 1478 | + ba.free; |
| 1479 | + IntfImg1 := b2.CreateIntfImage; |
| 1480 | + setlength(AlphaMask, nw, nh); |
| 1481 | + For i := 0 To b2.Width - 1 Do Begin |
| 1482 | + For j := 0 To b2.Height - 1 Do Begin |
| 1483 | + CurColor := IntfImg1.Colors[i, j]; |
| 1484 | + AlphaMask[i, j] := CurColor.Red Shr 8; |
| 1485 | + End; |
| 1486 | + End; |
| 1487 | + IntfImg1.free; |
| 1488 | + b2.free; |
| 1489 | + End; //} |
1378 | 1490 | End;
|
1379 | 1491 | End;
|
1380 | 1492 | smClamp: Begin
|
1381 | 1493 | nw := GetNextPowerOfTwo(b.width);
|
1382 | 1494 | nh := GetNextPowerOfTwo(b.height);
|
1383 | 1495 | If (nw <> b.width) Or (nh <> b.height) Then Begin
|
| 1496 | + If assigned(AlphaMask) Then Begin |
| 1497 | + tmp := Nil; |
| 1498 | + setlength(tmp, nw, nh); |
| 1499 | + For i := 0 To nw - 1 Do Begin |
| 1500 | + For j := 0 To nh - 1 Do Begin |
| 1501 | + If (i < b.width) And (j < b.height) Then Begin |
| 1502 | + tmp[i, j] := AlphaMask[i, j]; |
| 1503 | + End |
| 1504 | + Else Begin |
| 1505 | + tmp[i, j] := 0; |
| 1506 | + End; |
| 1507 | + End; |
| 1508 | + End; |
| 1509 | + setlength(AlphaMask, 0, 0); |
| 1510 | + AlphaMask := tmp; |
| 1511 | + End; |
1384 | 1512 | b2 := TBitmap.create;
|
1385 | 1513 | b2.PixelFormat := pf24bit;
|
1386 | 1514 | b2.width := nw;
|
|
1392 | 1520 | End;
|
1393 | 1521 | End;
|
1394 | 1522 | // load the raw image from the bitmap handles
|
1395 |
| - IntfImg1.LoadFromBitmap(B.Handle, B.MaskHandle); |
| 1523 | + IntfImg1 := b.CreateIntfImage; |
1396 | 1524 | {$IFDEF DEBUGGOUTPUT}
|
1397 | 1525 | writeln('OpenGL size : ' + inttostr(b.width) + 'x' + inttostr(b.height));
|
1398 | 1526 | OpenGLBufCount := OpenGLBufCount + (b.width * b.height * 4);
|
|
1409 | 1537 | OpenGLData[c, 0] := CurColor.Red Div 256;
|
1410 | 1538 | OpenGLData[c, 1] := CurColor.green Div 256;
|
1411 | 1539 | OpenGLData[c, 2] := CurColor.blue Div 256;
|
1412 |
| - If (OpenGLData[c, 0] = Fuchsia.r) And |
1413 |
| - (OpenGLData[c, 1] = Fuchsia.g) And |
1414 |
| - (OpenGLData[c, 2] = Fuchsia.b) Then |
1415 |
| - OpenGLData[c, 3] := 255 |
1416 |
| - Else |
1417 |
| - OpenGLData[c, 3] := 0; |
| 1540 | + If assigned(AlphaMask) Then Begin |
| 1541 | + OpenGLData[c, 3] := 255 - AlphaMask[i, j]; |
| 1542 | + End |
| 1543 | + Else Begin |
| 1544 | + If (OpenGLData[c, 0] = Fuchsia.r) And |
| 1545 | + (OpenGLData[c, 1] = Fuchsia.g) And |
| 1546 | + (OpenGLData[c, 2] = Fuchsia.b) Then |
| 1547 | + OpenGLData[c, 3] := 255 |
| 1548 | + Else |
| 1549 | + OpenGLData[c, 3] := 0; |
| 1550 | + End; |
1418 | 1551 | inc(c);
|
1419 | 1552 | End;
|
1420 | 1553 | End;
|
|
0 commit comments