This is my request, in TAd2DBitmapTexture can you add a procedure to load directly from memory?
We could skip one step to copy a block of memory (usually using TAd2dBitmap as Raw proxy). This is usefull & more fast to load a texture directly from our defined raw buffer, without need copy it to TAd2dBitmap first. Especially to load video buffer as dynamic texture.
I have modify the code (currently in OpenGL driver), each time I update from CVS I must edit the new code to make it fit of my need. Can you add this to CVS version?
// this procedure copied from LoadFromBitmap and modify some variable to fit the requirements.
procedure TOGLBitmapTexture.LoadFromMemory(const Src: Pointer; const AWidth,
AHeight: Integer; const ABitDepth: TAdBitDepth);
var
mem:PByte;
w,h,x,y:integer;
pnt32:PRGBARec;
cur16:PWord;
cur32:PLongWord;
newtex: boolean;
begin
//Calculate power of two size of the texture
w := 1 shl ceil(log2(AWidth));
h := 1 shl ceil(log2(AHeight));
//Decide whether a new texture object has to be created
if (w <> FWidth) or (h <> FHeight) or
(ABitDepth <> FBitDepth) or (not Loaded) then
begin
FlushTexture;
new(PCardinal(FTexture));
glGenTextures(1,FTexture);
newtex := true;
end else
newtex := false;
//Bind the current texture
glBindTexture(GL_TEXTURE_2D, PCardinal(FTexture)^);
//Reserve memory for storing the texture data
GetMem(mem,w *h * Ord(ABitDepth) div 8);
try
if ABitDepth = ad32Bit then
begin
if newtex or FParent.FMipmaps then
begin
cur32 := PLongWord(mem);
pnt32 := Src;
for y := 0 to AHeight - 1 do
begin
Move(pnt32^, cur32^, AWidth * 4);
inc(pnt32, AWidth);
inc(cur32, w);
end;
end;
if FParent.FMipmaps then
begin
FHasMipMap := true;
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_BGRA, GL_UNSIGNED_BYTE, mem)
end
else
begin
if newtex then
begin
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
w, h,
0, GL_BGRA, GL_UNSIGNED_BYTE, mem);
end else
begin
glTexSubImage2D(
GL_TEXTURE_2D, 0,
0, 0, BaseWidth, BaseHeight,
GL_BGRA, GL_UNSIGNED_BYTE, Src)
end;
end;
end
else
begin
cur16 := PWord(mem);
pnt32 := Src;
for y := 0 to AHeight - 1 do
begin
for x := 0 to w - 1 do
begin
if (x < AWidth) then
begin
cur16^ := ABGRTo16Bit(pnt32^.a,pnt32^.b,pnt32^.g,pnt32^.r);
inc(pnt32);
end;
inc(cur16);
end;
end;
thank you for your suggestion. Actually I didn't implement it as you did, because I want the plugin interface to be as lightweight as possible.
I simply added a class TAd2DMemoryBitmap that is derived from the new TAd2DCustomBitmap class. TAd2DMemoryBitmap requests the memory and the width and the height of the bitmap in the constructor.
Looking for the changes...
- There are many changes :)
- 2 classes added in AdBitmapClass.pas --> You rock dude!
- Looking other change(s) ... :D
>> Actually I didn't implement it as you did, because I want the plugin interface to be as lightweight as >> possible.
Brilliant!, the plugin interface keep simplicity.
Actually, I have the same idea previously, but considering we still need create a new DirectBitmapBuffer object to do the same job (need some a times to create the object in Delphi). But I 100% agree with you, that was the wise one ;)
Great and thanks again!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thx, I downloaded acinerella and compiled delphi module. Tried several video files but audio did not work. Maybe its each developer should compile own acinerella.dll FFMPEG binary. I don't have a working C compiler system (or lack of C/C++ toolset skills).
No wait..., acinerella_demo.exe was writing audio to a out.wav file instead of the audio device :-)
I do have some .wmv files with WMAPro3 audio track but those does not work in an acinerella.dll (precomiled static ffmpeg binary). No suprise really, WMAPro3 seems to be a problem for opensource projects.
Would you willing to post a 3d texture example with audio playback playber?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This is my request, in TAd2DBitmapTexture can you add a procedure to load directly from memory?
We could skip one step to copy a block of memory (usually using TAd2dBitmap as Raw proxy). This is usefull & more fast to load a texture directly from our defined raw buffer, without need copy it to TAd2dBitmap first. Especially to load video buffer as dynamic texture.
I have modify the code (currently in OpenGL driver), each time I update from CVS I must edit the new code to make it fit of my need. Can you add this to CVS version?
abstract class:
TAd2DBitmapTexture = class(...)
public
...
procedure LoadFromMemory(const Src: Pointer; const AWidth, AHeight: Integer; const ABitDepth: TAdBitDepth); virtual; abstract;
...
end;
OpenGL:
// this procedure copied from LoadFromBitmap and modify some variable to fit the requirements.
procedure TOGLBitmapTexture.LoadFromMemory(const Src: Pointer; const AWidth,
AHeight: Integer; const ABitDepth: TAdBitDepth);
var
mem:PByte;
w,h,x,y:integer;
pnt32:PRGBARec;
cur16:PWord;
cur32:PLongWord;
newtex: boolean;
begin
//Calculate power of two size of the texture
w := 1 shl ceil(log2(AWidth));
h := 1 shl ceil(log2(AHeight));
//Decide whether a new texture object has to be created
if (w <> FWidth) or (h <> FHeight) or
(ABitDepth <> FBitDepth) or (not Loaded) then
begin
FlushTexture;
new(PCardinal(FTexture));
glGenTextures(1,FTexture);
newtex := true;
end else
newtex := false;
//Bind the current texture
glBindTexture(GL_TEXTURE_2D, PCardinal(FTexture)^);
//Set some properties
FWidth := w;
FHeight := h;
FBitDepth := ABitDepth;
FBaseWidth := AWidth;
FBaseHeight := AHeight;
FHasMipMap := false;
//Reserve memory for storing the texture data
GetMem(mem,w *h * Ord(ABitDepth) div 8);
try
if ABitDepth = ad32Bit then
begin
if newtex or FParent.FMipmaps then
begin
cur32 := PLongWord(mem);
pnt32 := Src;
for y := 0 to AHeight - 1 do
begin
Move(pnt32^, cur32^, AWidth * 4);
inc(pnt32, AWidth);
inc(cur32, w);
end;
end;
if FParent.FMipmaps then
begin
FHasMipMap := true;
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_BGRA, GL_UNSIGNED_BYTE, mem)
end
else
begin
if newtex then
begin
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
w, h,
0, GL_BGRA, GL_UNSIGNED_BYTE, mem);
end else
begin
glTexSubImage2D(
GL_TEXTURE_2D, 0,
0, 0, BaseWidth, BaseHeight,
GL_BGRA, GL_UNSIGNED_BYTE, Src)
end;
end;
end
else
begin
cur16 := PWord(mem);
pnt32 := Src;
for y := 0 to AHeight - 1 do
begin
for x := 0 to w - 1 do
begin
if (x < AWidth) then
begin
cur16^ := ABGRTo16Bit(pnt32^.a,pnt32^.b,pnt32^.g,pnt32^.r);
inc(pnt32);
end;
inc(cur16);
end;
end;
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA16, w, h, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, mem);
end;
finally
FreeMem(mem,w*h* Ord(ABitDepth) div 8);
end;
end;
// we still can use LoadFromMemory to load from TAd2dBitmap
procedure TOGLBitmapTexture.LoadFromBitmap(ABmp: TAd2dBitmap; ABitDepth: TAdBitDepth);
begin
LoadFromMemory(ABmp.ScanLine, ABmp.Width, ABmp.Height, ABitDepth);
end;
Thanks!
Hello,
thank you for your suggestion. Actually I didn't implement it as you did, because I want the plugin interface to be as lightweight as possible.
I simply added a class TAd2DMemoryBitmap that is derived from the new TAd2DCustomBitmap class. TAd2DMemoryBitmap requests the memory and the width and the height of the bitmap in the constructor.
Here is an example:
adbmp := TAd2DMemoryBitmap.Create(buf.Memory, buf.Width, buf.Height);
FTexture.LoadFromBitmap(adbmp, ad32Bit);
adbmp.Free;
I used the new class in the video module, what makes it really faster (especially with HD-Videos).
So thank you again,
Andreas
Wooha... that's the point!
Updating from CVS... done!
Looking for the changes...
- There are many changes :)
- 2 classes added in AdBitmapClass.pas --> You rock dude!
- Looking other change(s) ... :D
>> Actually I didn't implement it as you did, because I want the plugin interface to be as lightweight as >> possible.
Brilliant!, the plugin interface keep simplicity.
Actually, I have the same idea previously, but considering we still need create a new DirectBitmapBuffer object to do the same job (need some a times to create the object in Delphi). But I 100% agree with you, that was the wise one ;)
Great and thanks again!
Can I ask which video library you use to get a plain video pixel buffer?
Do you have a simple demo to show how it works.
thx.
I'm using Acinerella. See http://acinerella.sourceforge.net/ there's a demo included.
Thx, I downloaded acinerella and compiled delphi module. Tried several video files but audio did not work. Maybe its each developer should compile own acinerella.dll FFMPEG binary. I don't have a working C compiler system (or lack of C/C++ toolset skills).
No wait..., acinerella_demo.exe was writing audio to a out.wav file instead of the audio device :-)
I do have some .wmv files with WMAPro3 audio track but those does not work in an acinerella.dll (precomiled static ffmpeg binary). No suprise really, WMAPro3 seems to be a problem for opensource projects.
Would you willing to post a 3d texture example with audio playback playber?
Have a look on
http://andorra.sourceforge.net/tutots/videoplayer.7z