Наложение текстуры Opengl

  • Автор темы Jeefo
  • Дата начала
J

Jeefo

Всем добрый вечер :)

Столкнулся со следующей проблемой. Нужно натянуть на квад текстуру, подгруженную из бмп-файла, размер 64x64 заранее известен. Почитал Краснова, казалось бы несложно, вот код, который получился:

Код:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OpenGL;

type
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
rc: HGLRC;
tex: array[0..63, 0..63, 0..2] of Byte;
procedure LoadTex;
public
{ Public declarations }
end;

var
MainForm: TMainForm;

implementation


{$R *.dfm}

procedure TMainForm.FormCreate(Sender: TObject);
var
pfd: TPixelFormatDescriptor;
nPixelFormat: Integer;
begin
FillChar(pfd, SizeOf(TPixelFormatDescriptor), 0);
pfd.nSize := SizeOf(TPixelFormatDescriptor);
pfd.nVersion := 1;
pfd.dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
pfd.iPixelType := PFD_TYPE_RGBA;
pfd.cColorBits := 24;
pfd.iLayerType := PFD_MAIN_PLANE;
nPixelFormat := ChoosePixelFormat(Canvas.Handle, @pfd);
SetPixelFormat(Canvas.Handle, nPixelFormat, @pfd);
rc := wglCreateContext(Canvas.Handle);
wglMakeCurrent(Canvas.Handle, rc);
LoadTex;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
wglMakeCurrent(0, 0);
wglDeleteContext(rc);
end;

procedure TMainForm.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewPort(0, 0, ClientWidth, ClientHeight);
gluOrtho2D(-5, 5, -5, 5);
FormPaint(Self);
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);

glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-1, -1);
glTexCoord2f(0, 1); glVertex2f(-1, 1);
glTexCoord2f(1, 1); glVertex2f(1, 1);
glTexCoord2f(1, 0); glVertex2f(1, -1);
glEnd();

glDisable(GL_TEXTURE_2D);

glFlush;
SwapBuffers(Canvas.Handle);
end;

procedure TMainForm.LoadTex;
var
b: TBitmap;
i, j: Integer;
begin
b := TBitmap.Create;
b.LoadFromFile('C:\GOLD.BMP');
for i := 0 to 63 do
for j := 0 to 63 do begin
tex[i, j, 0] := GetRValue(b.Canvas.Pixels[i,j]);
tex[i, j, 1] := GetGValue(b.Canvas.Pixels[i,j]);
tex[i, j, 2] := GetBValue(b.Canvas.Pixels[i,j]);
end;
b.Free;
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, @tex);
end;

end.

Однако текстура отображается перевернутой. Думал накосячил с координатами, почитал NeHe, нет, все верно: (0;0) на нижний левый угол, (0;1) на верхний левый и т.д. Где ошибся?

Delphi 7
 
D

Dock1100

Если используеш GlScene, то посмотри тут:
 
J

Jeefo

Если используеш GlScene, то посмотри тут:

Нет, использую модуль OpenGL, что идет в комплекте с дельфями..

Added

Попробовал заменить функцию загрузки текстуры более универсальной (все из того же Краснова), и вуаля - работает нормально :KillMe:
Вот собственно вид, который приобрела функция:
Код:
procedure TMainForm.LoadTex;
type
PPixelArray = ^TPixelArray;
TPixelArray = array [0..0] of Byte;
var
Bitmap : TBitmap;
Data : PPixelArray;
BMInfo : TBitmapInfo;
I, ImageSize : Integer;
Temp : Byte;
MemDC : HDC;
begin
Bitmap := TBitmap.Create;
Bitmap.LoadFromFile('C:\GOLD.BMP');
with BMinfo.bmiHeader do begin
FillChar (BMInfo, SizeOf(BMInfo), 0);
biSize := sizeof (TBitmapInfoHeader);
biBitCount := 24;
biWidth := Bitmap.Width;
biHeight := Bitmap.Height;
ImageSize := biWidth * biHeight;
biPlanes := 1;
biCompression := BI_RGB;
MemDC := CreateCompatibleDC (0);
GetMem (Data, ImageSize * 3);
try
GetDIBits (MemDC, Bitmap.Handle, 0, biHeight, Data,
BMInfo, DIB_RGB_COLORS);
For I := 0 to ImageSize - 1 do begin
Temp := Data [I * 3];
Data [I * 3] := Data [I * 3 + 2];
Data [I * 3 + 2] := Temp;
end;
glTexImage2d(GL_TEXTURE_2D, 0, 3, biWidth,
biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
finally
FreeMem (Data);
DeleteDC (MemDC);
Bitmap.Free;
end;
end;
end;

Тогда вопрос слегка изменился: в чем же подвох предыдущего способа?
 
D

Dock1100

Незнаю я в 3d почти не разбираюсь
 
N

niello

Получение данных с канваса не правильное. Вот ты используешь:
Код:
tex[i, j, 0] := GetRValue(b.Canvas.Pixels[i,j]);
А надо: tex[i, j, 0] := GetRValue(b.Canvas.Pixels[j,i]);
j-координата по Х, i-по Y.
 
X

Xakep

2niello, это большой роли не сыграет, просто текстура перевернется...
ты текстуру не биндишь после строчки glEnable(GL_TEXTURE_2D) нужно вписать еще это:
glBindTexture(GL_TEXTURE_2D,@tex);
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!