2 Copyright 2006 Marten Richter
\r
4 This file is part of VOMP.
\r
6 VOMP is free software; you can redistribute it and/or modify
\r
7 it under the terms of the GNU General Public License as published by
\r
8 the Free Software Foundation; either version 2 of the License, or
\r
9 (at your option) any later version.
\r
11 VOMP is distributed in the hope that it will be useful,
\r
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 GNU General Public License for more details.
\r
16 You should have received a copy of the GNU General Public License
\r
17 along with VOMP; if not, write to the Free Software
\r
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
23 #include "surfaceopengl.h"
\r
24 #include "osdopengl.h"
\r
29 inline unsigned int InternalColour(unsigned int c){
\r
30 return (c &0x000000FF)<<16 |
\r
32 (c &0x00FF0000)>>16 |
\r
36 SurfaceOpenGL::SurfaceOpenGL(int id)
\r
46 SurfaceOpenGL::~SurfaceOpenGL()
\r
53 glDeleteTextures(1,&gltexture);
\r
58 int SurfaceOpenGL::create(UINT width, UINT height)
\r
60 OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));
\r
61 //osd->BeginPainting();
\r
64 if (this == screen) { // We do not need locking here, since the osd calls this
\r
67 while (sheight < height) { // should be a power of 2
\r
70 while (swidth < width) { // should be a power of 2
\r
73 glGenTextures(1, &gltexture);
\r
75 glBindTexture(GL_TEXTURE_2D, gltexture);
\r
77 void *image = malloc(sheight * swidth * 4);
\r
78 memset(image, 0, sheight * swidth * 4);
\r
79 /* for (int i=0;i< sheight * swidth * 4; i++) { //fill it with garbage, useful for debugging
\r
80 ((char*)image)[i]=i%255;
\r
82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, swidth, sheight, 0, GL_RGBA,
\r
83 GL_UNSIGNED_BYTE, image);
\r
88 data=(char*)malloc(sizeof(uint32_t)*width*height);
\r
92 //osd->EndPainting();
\r
97 void SurfaceOpenGL::display()
\r
101 int SurfaceOpenGL::fillblt(int x, int y, int width, int height, unsigned int c) {
\r
103 //since this might be called before surface
\r
104 //allocation we will wait in this case, hopefully without deadlocks
\r
105 if (screen == this || !data ) {
\r
106 //This should not happen!
\r
107 srf_mutex.Unlock();
\r
111 /* OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
113 osd->BeginPainting();
\r
115 glViewport(0,0,swidth,sheight);*/
\r
117 //osd->EndPainting();
\r
118 srf_mutex.Unlock();
\r
120 unsigned int my_c=InternalColour(c);
\r
122 int iheight=height;
\r
123 if (height+y>sheight) iheight=sheight-y;
\r
125 if (width+x>swidth) iwidth=swidth-y;
\r
128 unsigned int column;
\r
129 for (line = y; line < (iheight + y); line++) {
\r
130 uint32_t *row = ((unsigned int*) (((char*) data) + (swidth * line + x)
\r
131 * sizeof(uint32_t)));
\r
132 for (column = 0; column < iwidth; column++) {
\r
133 row[column] = my_c;
\r
137 /* if (d3dsurface->UnlockRect() != D3D_OK) {
\r
138 osd->EndPainting();
\r
141 osd->EndPainting();*/
\r
147 void SurfaceOpenGL::startFastDraw(){
\r
151 void SurfaceOpenGL::endFastDraw(){
\r
152 srf_mutex.Unlock();
\r
155 void SurfaceOpenGL::drawPixel(int x, int y, Colour & colour, bool fastdraw) {
\r
156 int c = ( (0xFF000000 )
\r
157 | (colour.red << 16)
\r
158 | (colour.green << 8)
\r
159 | (colour.blue ) );
\r
161 drawPixel(x, y, c, fastdraw);
\r
164 void SurfaceOpenGL::drawPixel(int x, int y, unsigned int c, bool fastdraw) {
\r
165 //FixMe: locking for every single Pixel will be painfully slow
\r
166 if (screen == this) {
\r
167 //This should not happen!
\r
171 return; //why does this happen
\r
175 srf_mutex.Lock(); //since this might be called before surface
\r
177 //allocation we will wait in this case, hopefully without deadlocks
\r
179 //osd = ((OsdWin*) (Osd::getInstance()));
\r
181 if (x >= swidth || y >= sheight)
\r
182 return; //do not draw outside the surface
\r
184 unsigned int my_c=InternalColour(c);
\r
186 unsigned int*row = (unsigned int*) (((char*) data + (swidth * y + x)
\r
187 * sizeof(uint32_t)));
\r
191 srf_mutex.Unlock(); //since this might be called before surface
\r
196 void SurfaceOpenGL::drawHorzLine(int x1, int x2, int y, unsigned int c)
\r
198 fillblt(x1, y, x2-x1, 1, c);
\r
201 void SurfaceOpenGL::drawVertLine(int x, int y1, int y2, unsigned int c)
\r
203 fillblt(x, y1, 1, y2-y1, c);
\r
206 void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm)
\r
208 // Temporary code? Draw one pixel at a time using drawPixel()
\r
210 for (UINT j = 0; j < bm.getHeight(); ++j)
\r
211 for (UINT i = 0; i < bm.getWidth(); ++i)
\r
212 drawPixel(x+i, y+j, bm.getColour(i,j),true);
\r
216 int SurfaceOpenGL::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
\r
218 srf_mutex.Lock();//since this might be called before surface
\r
219 //allocation we will wait in this case, hopefully without deadlocks
\r
220 /* if (!d3dsurface) {
\r
221 return 0; //why does this happen
\r
223 OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));
\r
225 GLuint screengltexture=((SurfaceOpenGL*)screen)->getTexture();
\r
227 osd->BeginPainting();
\r
228 glBindTexture(GL_TEXTURE_2D, screengltexture);
\r
229 //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3 %d",glGetError());
\r
231 for (int y=0;y<h;y++) { //hopefully this is not too slow
\r
232 glTexSubImage2D(GL_TEXTURE_2D,0,dx,(dy+y),w,1,GL_RGBA,GL_UNSIGNED_BYTE,
\r
233 data+((y+sy)*swidth+sx)*sizeof(uint32_t));
\r
234 // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark43 %d",glGetError());
\r
237 //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError());
\r
238 osd->EndPainting();
\r
239 srf_mutex.Unlock();
\r
243 int SurfaceOpenGL::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
\r
245 //I don't see code using this function, so I skip it, since it is a MVP specific interface
\r
249 void SurfaceOpenGL::screenShot(const char* fileName)
\r
251 //Isn't this for debugging only, so I won't implement it yet
\r
254 void SurfaceOpenGL::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
\r
256 //Isn't this for debugging only, so I won't implement it yet
\r
260 void SurfaceOpenGL::drawJpeg(const char *fileName,int x, int y,int *width, int *height){
\r
262 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
263 //allocation we will wait in this case, hopefully without deadlocks
\r
265 return ; //why does this happen
\r
267 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
270 D3DXIMAGE_INFO image_inf;
\r
271 osd->BeginPainting();
\r
272 // D3DXGetImageInfoFromFile(fileName,&image_inf);
\r
273 D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
\r
274 RECT dest_rec={x,y,x+image_inf.Width,
\r
275 y+image_inf.Height};
\r
276 /* if (D3DXLoadSurfaceFromFile(
\r
284 &image_inf)!=D3D_OK) {
\r
285 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
288 if (D3DXLoadSurfaceFromResource(
\r
297 &image_inf)!=D3D_OK) {
\r
298 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
301 osd->EndPainting();
\r
302 *width=image_inf.Width;
\r
303 *height=image_inf.Height;
\r
308 void SurfaceOpenGL::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
\r
309 WaitForSingleObject(event,INFINITE); //since this might be called before surface
\r
310 //allocation we will wait in this case, hopefully without deadlocks
\r
312 return ; //why does this happen
\r
314 OsdWin* osd=((OsdWin*)(Osd::getInstance()));
\r
317 D3DXIMAGE_INFO image_inf;
\r
318 osd->BeginPainting();
\r
319 // D3DXGetImageInfoFromFile(fileName,&image_inf);
\r
320 D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
\r
321 RECT dest_rec={x,y,x+image_inf.Width,
\r
322 y+image_inf.Height};
\r
323 /* if (D3DXLoadSurfaceFromFile(
\r
331 &image_inf)!=D3D_OK) {
\r
332 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
335 /* if (D3DXLoadSurfaceFromResource(
\r
344 &image_inf)!=D3D_OK) {
\r
345 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
348 if (D3DXLoadSurfaceFromFileInMemory(
\r
357 &image_inf)!=D3D_OK) {
\r
358 Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
\r
361 osd->EndPainting();
\r
362 *width=image_inf.Width;
\r
363 *height=image_inf.Height;
\r