我不能将PNG图像加载到2D纹理中并在窗体上绘制。
我需要非常快地绘制大量透明的png图像,这些图像是从一个较大的png图像中剪切出来的,在准备好的背景上,然后显示在屏幕上。
我不想使用任何控件,如果可能的话,尽量避免使用外部库。只是使用来自 Delphi 和OpenGL单元的Pngimage。
我能够在窗体上绘制位图图像,下面是我的代码:
procedure TForm1.InitOpenGL;
var
PixelFormat: GLuint;
pfd: TPixelFormatDescriptor;
begin
ZeroMemory(@pfd, SizeOf(pfd));
pfd.nSize := SizeOf(pfd);
pfd.nVersion := 1;
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
pfd.iPixelType := PFD_TYPE_RGBA;
pfd.cColorBits := 32;
pfd.cDepthBits := 24;
pfd.iLayerType := PFD_MAIN_PLANE;
hdc := GetDC(Handle);
PixelFormat := ChoosePixelFormat(hdc, @pfd);
SetPixelFormat(hdc, PixelFormat, @pfd);
hrc := wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, @renderImage);
glBindTexture(GL_TEXTURE_2D, renderImage);
bmp := TBitmap.Create;
try
bmp.LoadFromFile(imageFilename);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, bmp.Width, bmp.Height, GL_BGR, GL_UNSIGNED_BYTE, bmp.ScanLine[bmp.Height - 1]);
finally
//bmp.Free;
end;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glClearColor(0.0, 0.0, 0.0, 0.0);
end;
procedure TForm1.DrawScene;
var
imageWidth, imageHeight: Integer;
begin
glClear(GL_COLOR_BUFFER_BIT);
// Get the width and height of the image
glBindTexture(GL_TEXTURE_2D, renderImage);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, @imageWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, @imageHeight);
// Translate the quad to the center of the form
glTranslatef(0, 0, 0);
// Draw the quad with the adjusted vertices
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-bmp.Width/Form1.Width, -bmp.Height/Form1.Height);
glTexCoord2f(1, 0); glVertex2f(bmp.Width/Form1.Width, -bmp.Height/Form1.Height);
glTexCoord2f(1, 1); glVertex2f(bmp.Width/Form1.Width, bmp.Height/Form1.Height);
glTexCoord2f(0, 1); glVertex2f(-bmp.Width/Form1.Width, bmp.Height/Form1.Height);
glEnd;
SwapBuffers(hdc);
end;
但是ping的代码不起作用。在一些尝试中,我能够在屏幕上得到一些东西(随机像素几行),但我卡住了。PNG图像是在Gimp中创建的。
下面是代码。
procedure TForm1.InitOpenGL;
var
PixelFormat: GLuint;
pfd: TPixelFormatDescriptor;
begin
ZeroMemory(@pfd, SizeOf(pfd));
pfd.nSize := SizeOf(pfd);
pfd.nVersion := 1;
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
pfd.iPixelType := PFD_TYPE_RGBA;
pfd.cColorBits := 32;
pfd.cDepthBits := 24;
pfd.iLayerType := PFD_MAIN_PLANE;
hdc := GetDC(Handle);
PixelFormat := ChoosePixelFormat(hdc, @pfd);
SetPixelFormat(hdc, PixelFormat, @pfd);
hrc := wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, @renderImage);
glBindTexture(GL_TEXTURE_2D, renderImage);
png := TPngImage.Create;
try
png.LoadFromFile('image.png');
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, png.Width, png.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, png.AlphaScanline[png.Height - 1]);
finally
png.Free;
end;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glClearColor(0.0, 0.0, 0.0, 0.0);
end;
procedure TForm1.DrawScene;
var
imageWidth, imageHeight: Integer;
begin
glClear(GL_COLOR_BUFFER_BIT);
// Get the width and height of the image
glBindTexture(GL_TEXTURE_2D, renderImage);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, @imageWidth);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, @imageHeight);
// Translate the quad to the center of the form
glTranslatef(0, 0, 0);
// Draw the quad with the adjusted vertices
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-png.Width/Form1.Width, -png.Height/Form1.Height);
glTexCoord2f(1, 0); glVertex2f(png.Width/Form1.Width, -png.Height/Form1.Height);
glTexCoord2f(1, 1); glVertex2f(png.Width/Form1.Width, png.Height/Form1.Height);
glTexCoord2f(0, 1); glVertex2f(-png.Width/Form1.Width, png.Height/Form1.Height);
glEnd;
SwapBuffers(hdc);
end;
现在我没有得到任何错误,但没有绘制任何内容。
1条答案
按热度按时间kokeuurv1#
好的,这是从所需的点(左上角)绘制png图像或部分图像的代码。它只使用 Delphi 和OpenGL。现在它使用固定的管道,我将尝试切换到着色器,但这对我来说是一个很大的进步。
所需的纹理参数和绘制起点作为调用DrawTexture过程的参数传递。
我希望这能成为刚开始使用OpenGL的人的一个起点。