Statistics
| Branch: | Tag: | Revision:

root / Client / UOverlayUI.pas @ 0:95bd93c28625

History | View | Annotate | Download (6.8 kB)

1
(*
2
 * CDDL HEADER START
3
 *
4
 * The contents of this file are subject to the terms of the
5
 * Common Development and Distribution License, Version 1.0 only
6
 * (the "License").  You may not use this file except in compliance
7
 * with the License.
8
 *
9
 * You can obtain a copy of the license at
10
 * http://www.opensource.org/licenses/cddl1.php.
11
 * See the License for the specific language governing permissions
12
 * and limitations under the License.
13
 *
14
 * When distributing Covered Code, include this CDDL HEADER in each
15
 * file and include the License file at
16
 * http://www.opensource.org/licenses/cddl1.php.  If applicable,
17
 * add the following below this CDDL HEADER, with the fields enclosed
18
 * by brackets "[]" replaced with your own identifying * information:
19
 *      Portions Copyright [yyyy] [name of copyright owner]
20
 *
21
 * CDDL HEADER END
22
 *
23
 *
24
 *      Portions Copyright 2007 Andreas Schneider
25
 *)
26
unit UOverlayUI;
27
28
{$mode objfpc}{$H+}
29
30
interface
31
32
uses
33
  Classes, SysUtils, Gl, GLU, ImagingTypes, ImagingClasses, ImagingOpenGL,
34
  OpenGLContext, ImagingUtility;
35
  
36
type
37
38
  { TGLArrow }
39
40
  TGLArrow = class(TObject)
41
    constructor Create(AGraphic: TSingleImage);
42
    destructor Destroy; override;
43
  protected
44
    FGraphic: TSingleImage;
45
    FTexture: GLuint;
46
    FRealWidth: Integer;
47
    FRealHeight: Integer;
48
    FWidth: Integer;
49
    FHeight: Integer;
50
    FCurrentX: Integer;
51
    FCurrentY: Integer;
52
    procedure UpdateTexture;
53
  public
54
    property Width: Integer read FWidth;
55
    property Height: Integer read FHeight;
56
    property CurrentX: Integer read FCurrentX;
57
    property CurrentY: Integer read FCurrentY;
58
  
59
    function HitTest(AX, AY: Integer): Boolean;
60
    procedure DrawGL(AX, AY: Integer; AActive: Boolean = False);
61
  end;
62
  
63
  { TOverlayUI }
64
65
  TOverlayUI = class(TObject)
66
    constructor Create;
67
    destructor Destroy; override;
68
  protected
69
    FArrows: array[0..7] of TGLArrow;
70
    FActiveArrow: Integer;
71
    FVisible: Boolean;
72
  public
73
    property ActiveArrow: Integer read FActiveArrow write FActiveArrow;
74
    property Visible: Boolean read FVisible write FVisible;
75
    function HitTest(AX, AY: Integer): Integer;
76
    procedure Draw(AContext: TOpenGLControl);
77
  end;
78
79
implementation
80
81
uses
82
  UResourceManager;
83
84
{ TGLArrow }
85
86
constructor TGLArrow.Create(AGraphic: TSingleImage);
87
var
88
  caps: TGLTextureCaps;
89
begin
90
  inherited Create;
91
  FRealWidth := AGraphic.Width;
92
  FRealHeight := AGraphic.Height;
93
  GetGLTextureCaps(caps);
94
  if caps.PowerOfTwo then
95
  begin
96
    if IsPow2(FRealWidth) then FWidth := FRealWidth else FWidth := NextPow2(FRealWidth);
97
    if IsPow2(FRealHeight) then FHeight := FRealHeight else FHeight := NextPow2(FRealHeight);
98
  end else
99
  begin
100
    FWidth := FRealHeight;
101
    FHeight := FRealHeight;
102
  end;
103
  FGraphic := TSingleImage.CreateFromParams(FWidth, FHeight, ifA8R8G8B8);
104
  AGraphic.CopyTo(0, 0, FRealWidth, FRealHeight, FGraphic, 0, 0);
105
  FTexture := 0;
106
end;
107
108
destructor TGLArrow.Destroy;
109
begin
110
  if FGraphic <> nil then FreeAndNil(FGraphic);
111
  if FTexture <> 0 then glDeleteTextures(1, @FTexture);
112
  inherited Destroy;
113
end;
114
115
procedure TGLArrow.UpdateTexture;
116
begin
117
  if (FGraphic <> nil) and (FRealWidth > 0) and (FRealWidth > 0) then
118
  begin
119
    FTexture := CreateGLTextureFromImage(FGraphic.ImageDataPointer^, 0, 0, False);
120
121
    glBindTexture(GL_TEXTURE_2D, FTexture);
122
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
123
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
124
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
125
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
126
  end;
127
end;
128
129
function TGLArrow.HitTest(AX, AY: Integer): Boolean;
130
begin
131
  if (AX > -1) and (AX < FRealWidth) and (AY > -1) and (AY < FRealHeight) then
132
  begin
133
    Result := (FGraphic <> nil) and (Cardinal(PIntegerArray(FGraphic.Bits)^[AY * FWidth + AX] and $FF000000) > 0);
134
  end else
135
    Result := False;
136
end;
137
138
procedure TGLArrow.DrawGL(AX, AY: Integer; AActive: Boolean = False);
139
begin
140
  FCurrentX := AX;
141
  FCurrentY := AY;
142
143
  if FTexture = 0 then UpdateTexture;
144
145
  if FTexture <> 0 then
146
  begin
147
    if AActive then
148
    begin
149
      glEnable(GL_COLOR_LOGIC_OP);
150
      glLogicOp(GL_COPY_INVERTED);
151
    end;
152
153
    glBindTexture(GL_TEXTURE_2D, FTexture);
154
    glBegin(GL_QUADS);
155
      glTexCoord2f(0, 0); glVertex2d(AX, AY);
156
      glTexCoord2f(1, 0); glVertex2d(AX + FWidth, AY);
157
      glTexCoord2f(1, 1); glVertex2d(AX + FWidth, AY + FHeight);
158
      glTexCoord2f(0, 1); glVertex2d(AX, AY + FHeight);
159
    glEnd;
160
    
161
    if AActive then
162
      glDisable(GL_COLOR_LOGIC_OP);
163
  end;
164
end;
165
166
{ TOverlayUI }
167
168
constructor TOverlayUI.Create;
169
var
170
  i: Integer;
171
  arrow: TSingleImage;
172
begin
173
  inherited Create;
174
  FActiveArrow := -1;
175
  FVisible := False;
176
  
177
  arrow := TSingleImage.CreateFromStream(ResourceManager.GetResource(0));
178
  for i := 0 to 3 do
179
  begin
180
    FArrows[2*i] := TGLArrow.Create(arrow);
181
    arrow.Rotate(-90);
182
  end;
183
  arrow.Free;
184
  arrow := TSingleImage.CreateFromStream(ResourceManager.GetResource(1));
185
  for i := 0 to 3 do
186
  begin
187
    FArrows[2*i+1] := TGLArrow.Create(arrow);
188
    arrow.Rotate(-90);
189
  end;
190
  arrow.Free;
191
end;
192
193
destructor TOverlayUI.Destroy;
194
var
195
  i: Integer;
196
begin
197
  for i := 0 to 7 do
198
    if FArrows[i] <> nil then FreeAndNil(FArrows[i]);
199
    
200
  inherited Destroy;
201
end;
202
203
function TOverlayUI.HitTest(AX, AY: Integer): Integer;
204
var
205
  i: Integer;
206
begin
207
  Result := -1;
208
  i := 0;
209
  while (i <= 7) and (Result = -1) do
210
  begin
211
    if FArrows[i].HitTest(AX - FArrows[i].CurrentX, AY - FArrows[i].CurrentY) then
212
      Result := i;
213
    Inc(i);
214
  end;
215
end;
216
217
procedure TOverlayUI.Draw(AContext: TOpenGLControl);
218
begin
219
  if FVisible then
220
  begin
221
    FArrows[0].DrawGL(10, 10, FActiveArrow = 0);
222
    FArrows[1].DrawGL(AContext.Width div 2 - FArrows[1].Width div 2, 10,
223
                      FActiveArrow = 1);
224
    FArrows[2].DrawGL(AContext.Width - 10 - FArrows[2].Width, 10,
225
                      FActiveArrow = 2);
226
227
    FArrows[3].DrawGL(AContext.Width - 10 - FArrows[3].Width,
228
                      AContext.Height div 2 - FArrows[3].Height div 2,
229
                      FActiveArrow = 3);
230
231
    FArrows[4].DrawGL(AContext.Width - 10 - FArrows[4].Width,
232
                      AContext.Height - 10 - FArrows[4].Height,
233
                      FActiveArrow = 4);
234
    FArrows[5].DrawGL(AContext.Width div 2 - FArrows[5].Width div 2,
235
                      AContext.Height - 10 - FArrows[5].Height,
236
                      FActiveArrow = 5);
237
    FArrows[6].DrawGL(10, AContext.Height - 10 - FArrows[6].Height,
238
                      FActiveArrow = 6);
239
240
    FArrows[7].DrawGL(10, AContext.Height div 2 - FArrows[7].Height div 2,
241
                      FActiveArrow = 7);
242
  end;
243
end;
244
245
end.
246