diff options
| author | Dusan Durech <dusan.d@centrum.sk> | 2008-11-09 15:48:16 +0100 |
|---|---|---|
| committer | Dusan Durech <dusan.d@centrum.sk> | 2008-11-09 15:48:16 +0100 |
| commit | 77459ad09cbcc1004801f527ce82caa2cbdf6451 (patch) | |
| tree | 2fa6efec9e66b813f552cf17111776ea71249bf9 | |
| parent | 74693f80cd8188303b3e164f478988133aef4c84 (diff) | |
support openGL rendering with makro SUPPORT_OPENGL, uses code in opengl branch
| -rw-r--r-- | CMakeLists.txt | 10 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | src/base/main.h | 3 | ||||
| -rw-r--r-- | src/client/font.c | 47 | ||||
| -rw-r--r-- | src/client/image.c | 132 | ||||
| -rw-r--r-- | src/client/image.h | 21 | ||||
| -rw-r--r-- | src/client/interface.c | 101 | ||||
| -rw-r--r-- | src/client/interface.h | 4 |
8 files changed, 258 insertions, 68 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9422473..210f604 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,9 +123,17 @@ IF ( Apple ) ADD_DEFINITIONS ( -DAPPLE ) ENDIF ( Apple ) ############################################################################### -# SDL SEARCH +# LIBS SEARCH ############################################################################### +MESSAGE ( STATUS "<Locating ZZIP library>" ) +MESSAGE ( STATUS "<******************************>" ) FIND_PACKAGE ( ZZIP REQUIRED ) +MESSAGE ( STATUS "<Locating OpenGL stuff>" ) +MESSAGE ( STATUS "<******************************>" ) +FIND_PACKAGE ( OpenGL REQUIRED ) +FIND_PACKAGE ( GLU REQUIRED ) +MESSAGE ( STATUS "<Locating SDL stuff>" ) +MESSAGE ( STATUS "<******************************>" ) IF ( NOT Server ) FIND_PACKAGE ( SDL REQUIRED ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a166b73..ff802e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,9 +7,12 @@ IF ( Server ) LINK_LIBRARIES ( ${ZZIP_LIBRARY} ${CMAKE_DL_LIBS} ) ELSE ( Server ) IF ( NO_Audio ) - LINK_LIBRARIES ( ${ZZIP_LIBRARY} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + LINK_LIBRARIES ( ${ZZIP_LIBRARY} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} + ${SDLTTF_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) ELSE ( NO_Audio ) - LINK_LIBRARIES ( ${ZZIP_LIBRARY} ${SDL_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ) + LINK_LIBRARIES ( ${ZZIP_LIBRARY} ${SDL_LIBRARY} ${SDLMIXER_LIBRARY} + ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} ) ENDIF ( NO_Audio ) LINK_LIBRARIES ( SDLmain ) ENDIF ( Server ) @@ -98,6 +101,7 @@ IF ( Server ) MESSAGE ( STATUS "<******************************>" ) SET ( SRC_compile ${SRC_base} ${SRC_server} ) ADD_EXECUTABLE ( ${APPNAME} ${SRC_compile} ) + ADD_SUBDIRECTORY ( downserver ) ENDIF ( Server ) ############################################################################### # CLIENT COMPILATION diff --git a/src/base/main.h b/src/base/main.h index a8b5f7b..7ea7111 100644 --- a/src/base/main.h +++ b/src/base/main.h @@ -17,6 +17,9 @@ # include "string_length.h" # include "path.h" + +//#define SUPPORT_OPENGL + extern char *getParam(char *s); extern char *getParamElse(char *s1, char *s2); extern bool_t isParamFlag(char *s); diff --git a/src/client/font.c b/src/client/font.c index 282b3d9..45ef5e4 100644 --- a/src/client/font.c +++ b/src/client/font.c @@ -1,6 +1,7 @@ #include "main.h" #include "interface.h" #include "font.h" +#include "image.h" static TTF_Font *g_font; static int fontSize; @@ -41,43 +42,44 @@ void initFont(char *file, int size) } /* - * Zobrazi text *s na suradnicu x y s farbou RGB + * Zobrazi text *string na suradnicu x y s farbou RGB */ -void drawFont(char *s, int x, int y, int r, int g, int b) +void drawFont(char *string, int x, int y, int r, int g, int b) { - SDL_Rect dst_rect; SDL_Surface *text; - SDL_Surface *p; - SDL_Color farba_pisma = { r, g, b, 0 }; + image_t *image; + SDL_Color font_color = {r, g, b, SDL_ALPHA_OPAQUE}; - //printf("drawFont %s\n", s); - assert(s != NULL); + assert( string != NULL ); - p = getSDL_Screen(); - text = TTF_RenderUTF8_Blended(g_font, s, farba_pisma); + text = TTF_RenderUTF8_Blended(g_font, string, font_color); - dst_rect.x = x; - dst_rect.y = y; + // because if string=="" TTF_RenderUTF8_Blended returns NULL + if( text != NULL ){ + image = newImage(text); + drawImage(image, x, y, 0, 0, image->w, image->h); + destroyImage(image); - SDL_BlitSurface(text, NULL, p, &dst_rect); - SDL_FreeSurface(text); +#ifdef SUPPORT_OPENGL + SDL_FreeSurface(text); // we don't need text anymore +#endif + }; } void drawFontMaxSize(char *s, int x, int y, int w, int h, int r, int g, int b) { SDL_Rect src_rect, dst_rect; SDL_Surface *text; - SDL_Surface *p; - SDL_Color farba_pisma = { r, g, b, 0 }; + image_t *i; + SDL_Color font_color = {r, g, b, SDL_ALPHA_OPAQUE}; int my_w, my_h; assert(s != NULL); - p = getSDL_Screen(); - text = TTF_RenderUTF8_Blended(g_font, s, farba_pisma); + text = TTF_RenderUTF8_Blended(g_font, s, font_color); my_w = text->w; @@ -100,8 +102,15 @@ void drawFontMaxSize(char *s, int x, int y, int w, int h, int r, int g, int b) dst_rect.x = x; dst_rect.y = y; - SDL_BlitSurface(text, &src_rect, p, &dst_rect); - SDL_FreeSurface(text); + i = newImage(text); + + //posibly broken + drawImage(i, x, y, 0, 0, my_w, my_h); + destroyImage(i); + +#ifdef SUPPORT_OPENGL + SDL_FreeSurface(text); // we don't need text anymore +#endif } /* diff --git a/src/client/image.c b/src/client/image.c index 6046732..c863849 100644 --- a/src/client/image.c +++ b/src/client/image.c @@ -65,6 +65,8 @@ static SDL_Surface *loadImage(const char *filename, int alpha) return ret; } + +#ifndef SUPPORT_OPENGL image_t *newImage(SDL_Surface * surface) { image_t *new; @@ -78,11 +80,89 @@ image_t *newImage(SDL_Surface * surface) return new; } +#endif -static void destroyImage(image_t * p) +#ifdef SUPPORT_OPENGL +/* + * returns closest bigger power of 2 to i + */ +unsigned int closestpoweroftwo(unsigned int i) +{ + int p; + p=0; + while(i){ + i=i>>1; + p++; + } + return 1<<(p-0); +} + +/* convert from SDL_Surface to image_t + * WARNING: newImage is indestructive to surface, caller is responsible for freeing surface + * surface is not needed for image_t after execution of newImage + */ + +image_t* newImage(SDL_Surface *surface) +{ + image_t *new; + Uint32 rmask, gmask, bmask, amask; + SDL_Surface *sdl_rgba_surface; + unsigned int bpp; + + //it is unoptimal to blit to buffer surface before actual loading to opengl texture but it is safer and simpler to implement + //it is unoptimal to always use RGBA texture + + // we set properties of our buffer sdl_rgba_surface + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; + bpp = 32; /*bits per pixel*/ + + assert(surface != NULL); + + new = malloc(sizeof(image_t)); + new->w = surface->w; + new->h = surface->h; + + //because some older hw is really slow when using textures with width and height which is not a power of two + new->tw = closestpoweroftwo(new->w); + new->th = closestpoweroftwo(new->h); + + sdl_rgba_surface = SDL_CreateRGBSurface( SDL_SWSURFACE, new->tw, new->th, bpp, rmask, gmask, bmask, amask); + + SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); // we unset SDL_SRCALPHA to preserve alpha channel of original image + SDL_BlitSurface(surface, 0, sdl_rgba_surface, 0); + + SDL_LockSurface(sdl_rgba_surface); // we ensure that we can read pixels from sdl_rgba_surface + + GLuint tid; + glGenTextures(1, &tid); //we ask for free texture id + glBindTexture(GL_TEXTURE_2D, tid); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, new->tw, new->th, 0, GL_RGBA, GL_UNSIGNED_BYTE, sdl_rgba_surface->pixels); + SDL_UnlockSurface(sdl_rgba_surface); + SDL_FreeSurface(sdl_rgba_surface); + + new->tex_id = tid; + + return new; +} +#endif + +void destroyImage(image_t * p) { assert(p != NULL); + +#ifndef SUPPORT_OPENGL SDL_FreeSurface((SDL_Surface *) p->image); +#endif + +#ifdef SUPPORT_OPENGL + glDeleteTextures(1, &p->tex_id); +#endif + free(p); } @@ -138,6 +218,7 @@ void delAllImageInGroup(char *group) delAllItemFromStorage(listStorage, group, destroyImage); } +#ifndef SUPPORT_OPENGL void drawImage(image_t * p, int x, int y, int px, int py, int w, int h) { static SDL_Surface *screen = NULL; @@ -157,6 +238,55 @@ void drawImage(image_t * p, int x, int y, int px, int py, int w, int h) SDL_BlitSurface(p->image, &src_rect, screen, &dst_rect); } +#endif + +#ifdef SUPPORT_OPENGL +/* + * Draws image on screen at [x,y], with width w and height h, top-left corner on image is at [px,py] + */ +void drawImage(image_t *image, int x,int y, int px, int py, int w, int h) +{ + /* x -coordinate of left border xx- coordinate of right border, + * y -coordinate of top border yy- coordinate of bottom border, + * t_ texture space d_ screen space, + */ + float t_x, t_y, t_xx, t_yy; + float d_x, d_y, d_xx, d_yy; + + // screen space + d_x = x; + d_y = y; + d_xx = x+w; + d_yy = y+h; + + // texture space (remember that texture space is from 0.0 to 1.0) + t_x = px/(float)image->tw; + t_y = py/(float)image->th; + t_xx = (px+w)/(float)image->tw; + t_yy = (py+h)/(float)image->th; + + glBindTexture(GL_TEXTURE_2D, image->tex_id); + + // 2--4 + // |\ | + // | \| + // 1--3 + glBegin(GL_TRIANGLE_STRIP); + //1 + glTexCoord2f(t_x,t_yy); + glVertex2f(d_x, d_yy); + //2 + glTexCoord2f(t_x, t_y); + glVertex2f(d_x, d_y); + //3 + glTexCoord2f(t_xx, t_yy); + glVertex2f(d_xx, d_yy); + //4 + glTexCoord2f(t_xx,t_y); + glVertex2f(d_xx, d_y); + glEnd(); +} +#endif /* * Odstrani zoznam obrazkov z pamate diff --git a/src/client/image.h b/src/client/image.h index 015c0d2..03e952d 100644 --- a/src/client/image.h +++ b/src/client/image.h @@ -3,7 +3,7 @@ # define IMAGE_H -//#include "image.h" +# include "main.h" # include "interface.h" # define IMAGE_NO_ALPHA 0 @@ -14,6 +14,10 @@ # define IMAGE_GROUP_USER "user" # define IMAGE_GROUP_OTHER "other" +#ifdef SUPPORT_OPENGL +#include <SDL_opengl.h> +#endif + /* typedef struct image_struct { @@ -23,14 +27,29 @@ typedef struct image_struct } image_data_t; */ +#ifndef SUPPORT_OPENGL typedef struct image_struct { int w; int h; SDL_Surface *image; } image_t; +#endif + +#ifdef SUPPORT_OPENGL +typedef struct image_struct +{ + int w; // width of actual picture + int h; // height of actual picture + GLuint tw; // width of allocated texture + GLuint th; // height of allocated texture + GLuint tex_id; // texture id +} image_t; +#endif extern bool_t isImageInicialized(); extern void initImageData(); +extern image_t* newImage(SDL_Surface *surface); +extern void destroyImage(image_t * p); extern image_t *addImageData(char *file, int alpha, char *name, char *group); extern image_t *getImage(char *group, char *name); extern void delImage(char *group, char *name); diff --git a/src/client/interface.c b/src/client/interface.c index f9fd0d5..4f7b9dc 100644 --- a/src/client/interface.c +++ b/src/client/interface.c @@ -17,7 +17,13 @@ static SDL_Surface *screen; static SDL_TimerID timer; // window flags +#ifndef SUPPORT_OPENGL static Uint32 g_win_flags = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_ANYFORMAT; +#endif + +#ifdef SUPPORT_OPENGL +static Uint32 g_win_flags = SDL_OPENGL; +#endif static bool_t isInterfaceInit = FALSE; @@ -76,6 +82,42 @@ void hotkey_screen() } } +#ifdef SUPPORT_OPENGL +/* + * Sets video mode and sets up OpenGL for this change + */ +SDL_Surface * SetVideoMode(int width, int height, int bpp, Uint32 flags) +{ + SDL_Surface *rval = 0; + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + rval = SDL_SetVideoMode(width, height, bpp, flags); + + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glClearDepth(1.0); + glDisable(GL_DEPTH_TEST); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrtho(0.0f,width, height,0.0f,-1.0f,1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_TEXTURE_2D); + + return rval; +} +#endif + int initSDL() { #ifdef DEBUG @@ -87,17 +129,14 @@ int initSDL() SDL_Quit(); return -1; } - // initialization of SDL - //screen = SDL_SetVideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, 0, g_win_flags); + +#ifndef SUPPORT_OPENGL screen = SDL_SetVideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, 0, g_win_flags); +#endif -/* - my_surface = SDL_CreateRGBSurface(screen->flags, WINDOW_SIZE_X, WINDOW_SIZE_Y, - screen->format->BitsPerPixel, - screen->format->Rmask, screen->format->Gmask, - screen->format->Bmask, screen->format->Amask); -*/ - //memset(my_surface->pixels, 128, 200); +#ifdef SUPPORT_OPENGL + screen = SetVideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, 0, g_win_flags); +#endif if (screen == NULL) { fprintf(stderr, "%s\n", SDL_GetError()); @@ -129,12 +168,13 @@ SDL_Surface *getSDL_Screen() void interfaceRefresh() { - //SDL_BlitSurface(my_surface, NULL, screen, NULL); - //SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); - - //drawImage(my_surface, 200, 100, 0, 0, 200, 200); +#ifndef SUPPORT_OPENGL SDL_Flip(screen); - //SDL_UpdateRect(screen, 400, 0, 400, 600); +#endif + +#ifdef SUPPORT_OPENGL + SDL_GL_SwapBuffers(); +#endif } void getMousePosition(int *x, int *y) @@ -177,22 +217,6 @@ void printPressAnyKey() } -/* -static void action_esc() -{ - if( strcmp(getScreen(), "world") == 0 ) - { - setScreen("analyze"); - } - - if( strcmp(getScreen(), "mainMenu") == 0 ) - { - quit(); - } - -} -*/ - int hack_slow() { static time_t lastTime = 0; @@ -211,7 +235,7 @@ int hack_slow() if( isSlowHack == FALSE && currentTime - lastTime >= 100 ) { - printf("start slow hack (%d)\n", currentTime - lastTime); + //printf("start slow hack (%d)\n", currentTime - lastTime); isSlowHack = TRUE; lastTime = getMyTime(); return 1; @@ -219,7 +243,7 @@ int hack_slow() if( isSlowHack == TRUE && currentTime - lastTime >= 50 ) { - printf("stop slow hack (%d)\n", currentTime - lastTime); + //printf("stop slow hack (%d)\n", currentTime - lastTime); isSlowHack = FALSE; lastTime = getMyTime(); return 0; @@ -227,7 +251,7 @@ int hack_slow() if( isSlowHack == TRUE ) { - printf("hack time interval %d\n", currentTime - lastTime); + //printf("hack time interval %d\n", currentTime - lastTime); } lastTime = getMyTime(); @@ -244,17 +268,6 @@ int eventAction() switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { -/* - case SDLK_ESCAPE: - action_esc(); - return 0; - break; -*/ -/* - case SDLK_F1: - if(!toggleFullscreen())return 0; - break; -*/ default: //neni potreba vyuzivat frontu stale if (keyboardBufferEnabled == TRUE) diff --git a/src/client/interface.h b/src/client/interface.h index b5df62a..3dbe5f3 100644 --- a/src/client/interface.h +++ b/src/client/interface.h @@ -12,6 +12,10 @@ # include <SDL_thread.h> # include "main.h" +#ifdef SUPPORT_OPENGL +#include <SDL_opengl.h> +#endif + /* #include <SDL_net.h> */ |