1#include "graphics.h"
2
3Graphics::Graphics
( Client
* client
)
4{
5 if ( !al_init_image_addon() )
6 this->client->Error
( "Failed to initialize the image addon" );
7}
8
9Graphics::~Graphics
()
10{
11 for ( unsigned int i
= 0; i
< this->bitmap.size
(); i
++ )
12 {
13 if ( this->bitmap
[i
] )
14 al_destroy_bitmap( this->bitmap
[i
] );
15 }
16
17 al_shutdown_image_addon();
18}
19
20int Graphics::Load
( const char* filename,
int resID
)
21{
22 ALLEGRO_BITMAP* newBitmap
= NULL
;
23 ALLEGRO_LOCKED_REGION* locked
;
24 BITMAP bm
;
25
26 HMODULE module
= LoadLibrary
( filename
);
27 if ( !module
)
28 {
29 this->client->Error
( "Failed to LoadLibrary: %s", filename
);
30 return -1;
31 }
32
33 HBITMAP bitmap
= LoadBitmap
( module, MAKEINTRESOURCE
( resID
) );
34 if ( !bitmap
)
35 {
36 this->client->Error
( "Failed to LoadBitmap: %i", resID
);
37 return -1;
38 }
39
40 if ( !GetObject
( bitmap,
sizeof( bm
),
reinterpret_cast<LPSTR>
( &bm
) ) )
41 {
42 this->client->Error
( "Failed to GetObject" );
43 return -1;
44 }
45
46 al_set_new_bitmap_flags( ALLEGRO_MEMORY_BITMAP
);
47
48 newBitmap
= al_create_bitmap( bm.bmWidth, bm.bmHeight
);
49
50 locked
= al_lock_bitmap( newBitmap, ALLEGRO_PIXEL_FORMAT_RGB_888, ALLEGRO_LOCK_READWRITE
);
51 BYTE
*data
= reinterpret_cast<BYTE
*>(locked->data
);
52
53 int pitch
= bm.bmWidth
* locked->pixel_size
;
54 pitch
= ( pitch
+ 3 ) & ~
3;
55
56 BYTE
*pixels
= new BYTE
[bm.bmHeight
* pitch
];
57
58 BITMAPINFOHEADER bi
;
59 ZeroMemory
( &bi,
sizeof( BITMAPINFOHEADER
) );
60 bi.biSize
= sizeof( BITMAPINFOHEADER
);
61 bi.biBitCount
= al_get_pixel_format_bits( locked->format
);
62 bi.biPlanes
= 1;
63 bi.biWidth
= bm.bmWidth
;
64 bi.biHeight
= -abs( bm.bmHeight
);
65 bi.biClrUsed
= 256;
66 bi.biCompression
= BI_RGB
;
67
68 BITMAPINFO
*binfo
= static_cast<BITMAPINFO
*>( std::malloc
( sizeof( BITMAPINFO
) + sizeof( RGBQUAD
) * 256 ) );
69 binfo->bmiHeader
= bi
;
70
71 HDC hdc
= GetDC
( NULL
);
72
73 GetDIBits
( hdc, bitmap,
0, bm.bmHeight, pixels, binfo, DIB_RGB_COLORS
);
74
75 delete( binfo
);
76
77 ReleaseDC
(NULL, hdc
);
78
79 int height
= std::abs
( std::min
( int( bm.bmHeight
),
int( al_get_bitmap_height( newBitmap
) ) ) );
80 int width
= std::abs
( std::min
( pitch,
int( locked->pitch
) ) );
81
82 for ( int y
= 0; y
< height
; ++y
)
83 std::memcpy
( data
+ locked->pitch
* y, pixels
+ pitch
* y, width
);
84
85 DeleteObject
( bitmap
);
86 FreeLibrary
( module
);
87
88 delete[] pixels
;
89
90 al_unlock_bitmap( newBitmap
);
91
92 al_set_new_bitmap_flags( ALLEGRO_VIDEO_BITMAP
);
93
94 ALLEGRO_BITMAP* clonedBitmap
= al_clone_bitmap( newBitmap
);
95 if ( !clonedBitmap
)
96 {
97 this->client->Error
( "Failed to clone the bitmap" );
98 return -1;
99 }
100
101 al_destroy_bitmap( newBitmap
);
102
103 for ( unsigned int i
= 0; i
< this->bitmap.size
(); i
++ )
104 {
105 if ( !this->bitmap
[i
] )
106 {
107 this->bitmap
[i
] = clonedBitmap
;
108#ifdef DEBUG
109 printf( "Loaded Image: %s %i #%i\n", filename, resID, i
);
110#endif // DEBUG
111
112 return i
;
113 }
114 }
115
116 this->bitmap.push_back
( clonedBitmap
);
117
118#ifdef DEBUG
119 printf( "Loaded Image: %s %i #%i\n", filename, resID, this->bitmap.size
() - 1 );
120#endif // DEBUG
121
122 return this->bitmap.size
() - 1;
123}
124
125void Graphics::Delete
( int id
)
126{
127 al_destroy_bitmap( this->bitmap
[id
] );
128 this->bitmap
[id
] = NULL
;
129
130#ifdef DEBUG
131 printf( "Deleted Image: %i\n", id
);
132#endif // DEBUG
133}
134
135void Graphics::Blit
( int id,
float x,
float y,
float z
)
136{
137 this->GLBlit
( this->bitmap
[id
], x, y, z
);
138}
139
140void Graphics::BlitRegion
( int id,
int sx,
int sy,
int width,
int height,
float dx,
float dy,
float z
)
141{
142 ALLEGRO_BITMAP* bmpSub
= al_create_sub_bitmap( this->bitmap
[id
], sx, sy, width, height
);
143
144 if ( bmpSub
)
145 {
146 this->GLBlit
( bmpSub, dx, dy, z
);
147 }
148 else
149 this->client->Error
( "Failed to create sub bitmap" );
150}
151
152void Graphics::GLBlit
( ALLEGRO_BITMAP* bmp,
float x,
float y,
float z
)
153{
154 int width
= al_get_bitmap_width( bmp
) ;
155 int height
= al_get_bitmap_height( bmp
);
156 GLuint texture
;
157
158 glEnable
( GL_TEXTURE_2D
);
159
160 glBlendFunc
( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
);
161 glEnable
( GL_BLEND
);
162
163 glTexParameteri
( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
);
164 glTexParameteri
( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
);
165
166 glGenTextures
( 1,
&texture
);
167
168 texture
= al_get_opengl_texture( bmp
);
169
170 glBindTexture
( GL_TEXTURE_2D, texture
);
171
172 glLoadIdentity
();
173
174 glBegin
( GL_QUADS
);
175 glColor4ub
( 255,
255,
255,
255 );
176
177 glTexCoord2f
( 0,
0 ); glVertex3f
( x, y
+ height, z
);
178 glTexCoord2f
( 1,
0 ); glVertex3f
( x
+ width, y
+ height, z
);
179 glTexCoord2f
( 1,
1 ); glVertex3f
( x
+ width, y, z
);
180 glTexCoord2f
( 0,
1 ); glVertex3f
( x, y, z
);
181 glEnd
();
182}
183
184void Graphics::MakeTransparent
( int id,
int r,
int g,
int b
)
185{
186 al_convert_mask_to_alpha( this->bitmap
[id
],
al_map_rgb( r, g, b
) );
187}