cheat-engine/Cheat Engine/Tutorial/graphical/renderobject.pas
2018-05-22 12:40:25 +02:00

210 lines
4.4 KiB
ObjectPascal

unit renderobject;
{$mode objfpc}{$H+}
{$modeswitch advancedrecords}
interface
uses
Classes, SysUtils,GL, GLext, glu, types;
type
TRenderObject=class(TObject)
private
children: array of TRenderObject;
fTextureCoords: record
x: single;
y: single;
x2: single;
y2: single;
end;
protected
fChildrenOnly: boolean;
procedure renderRelative; virtual;
function getWidth:single; virtual; abstract;
procedure setWidth(w: single); virtual;
function getHeight:single; virtual; abstract;
procedure setHeight(h: single); virtual;
function getTexture: integer; virtual; abstract;
function getLeft: single; virtual;
function getRight: single; virtual;
function getTop: single; virtual;
function getBottom: single; virtual;
public
valid: boolean;
x,y: single;
rotationpoint: TPointF;
rotation: single;
procedure render; virtual;
procedure addChild(child: TRenderObject);
procedure removeChild(child: TRenderObject);
procedure setTextureCoords(_x: single; _y: single; _x2: single; _y2: single);
constructor create;
property width: single read getWidth write setWidth;
property height: single read getHeight write setHeight;
property left: single read getLeft;
property right: single read getRight;
property top: single read getTop;
property bottom: single read getBottom;
property texture: integer read getTexture;
property childrenonly: boolean read fChildrenOnly write fChildrenOnly;
end;
implementation
function TRenderObject.getLeft: single;
begin
//todo: deal with rotation (or just let the caller deal with that)
result:=x-width*((rotationpoint.x+1)/2);
end;
function TRenderObject.getRight: single;
begin
//rx=-1 : x+0 | x+w*0
//rx=0 : x+w/2 | x+w*0.5
//rx=1 : x+w/1 | x+w*1
//(rx+1)/2:
//-1 -> (-1+1)/2=0/2=0
//0 -> (0+1)/2=1/2=0.5
//1 -> (1+1)/2=2/2=1
result:=x+width*((rotationpoint.x+1)/2);
end;
function TRenderObject.getTop: single;
begin
result:=y-height*((rotationpoint.y+1)/2);
end;
function TRenderObject.getBottom: single;
begin
result:=y+height*((rotationpoint.y+1)/2);
end;
procedure TRenderObject.setWidth(w: single);
begin
//
end;
procedure TRenderObject.setHeight(h: single);
begin
//
end;
procedure TRenderObject.addChild(child: TRenderObject);
begin
setlength(children, length(children)+1);
children[length(children)-1]:=child;
end;
procedure TRenderObject.removeChild(child: TRenderObject);
var i,j: integer;
begin
for i:=0 to length(children)-1 do
if children[i]=child then
begin
for j:=i to length(children)-2 do
children[j]:=children[j+1];
setlength(children, length(children)-1);
end;
end;
procedure TRenderObject.setTextureCoords(_x: single; _y: single; _x2: single; _y2: single);
begin
fTextureCoords.x:=_x;
fTextureCoords.y:=_y;
fTextureCoords.x2:=_x2;
fTextureCoords.y2:=_y2;
end;
procedure TRenderObject.renderRelative;
var w, h: single;
dw,dh: single;
rx,ry: single;
i: integer;
begin
//set the texture
glBindTexture(GL_TEXTURE_2D, getTexture);
glActiveTexture(GL_TEXTURE0);
w:=width; // / 2;
h:=height;// / 2;
dw:=width / 2;
dh:=height / 2;
glTranslatef(x,-y,0);
glRotatef(-rotation,0,0,0.5);
rx:=-rotationpoint.x;
ry:=-rotationpoint.y;
if rx<>0 then
rx:=dw*rx;
if ry<>0 then
ry:=-1*dh*ry;
if fChildrenOnly=false then
begin
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glTexCoord2f(fTextureCoords.x,fTextureCoords.y2);
glVertex2f(rx+dw*-1, ry+dh*-1);
glTexCoord2f(fTextureCoords.x2,fTextureCoords.y2);
glVertex2f(rx+dw, ry+dh*-1);
glTexCoord2f(fTextureCoords.x2,fTextureCoords.y);
glVertex2f(rx+dw, ry+dh);
glTexCoord2f(fTextureCoords.x,fTextureCoords.y);
glVertex2f(rx+dw*-1, ry+dh);
glEnd();
end;
//render children
for i:=0 to length(children)-1 do
begin
glPushMatrix();
children[i].renderRelative;
glPopMatrix();
end;
end;
procedure TRenderObject.render;
begin
glLoadIdentity();
glPushMatrix();
renderRelative();
glPopMatrix();
end;
constructor TRenderObject.create;
begin
fTextureCoords.x:=0;
fTextureCoords.y:=0;
fTextureCoords.x2:=1;
fTextureCoords.y2:=1;
end;
end.