diff --git a/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp b/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp index 15cc371126..41f9ce20d0 100644 --- a/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp +++ b/Source/Core/DolphinWX/Src/Android/ButtonManager.cpp @@ -181,13 +181,8 @@ namespace ButtonManager void DrawButtons() { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - for(auto it = m_buttons.begin(); it != m_buttons.end(); ++it) - DrawButton((*it)->GetTexture(), (*it)->GetCoords()); - - glDisable(GL_BLEND); + g_video_backend->Video_DrawTexture((*it)->GetTexture(), (*it)->GetCoords()); } // InputDevice diff --git a/Source/Core/DolphinWX/Src/Android/ButtonManager.h b/Source/Core/DolphinWX/Src/Android/ButtonManager.h index c312b9786a..f2b7c1c5cb 100644 --- a/Source/Core/DolphinWX/Src/Android/ButtonManager.h +++ b/Source/Core/DolphinWX/Src/Android/ButtonManager.h @@ -21,6 +21,7 @@ #include #include "CommonPaths.h" #include "Android/TextureLoader.h" +#include "VideoBackendBase.h" namespace ButtonManager { @@ -60,14 +61,21 @@ namespace ButtonManager class Button { private: - GLuint m_tex; + int m_tex; ButtonType m_button; ButtonState m_state; float m_coords[8]; public: Button(std::string filename, ButtonType button, float *coords) { - m_tex = LoadPNG((std::string(DOLPHIN_DATA_DIR "/") + filename).c_str()); + u32 width, height; + char *image; + image = LoadPNG((std::string(DOLPHIN_DATA_DIR "/") + filename).c_str(), width, height); + + m_tex = g_video_backend->Video_LoadTexture(image, width, height); + + free(image); + m_button = button; memcpy(m_coords, coords, sizeof(float) * 8); m_state = BUTTON_RELEASED; @@ -83,7 +91,7 @@ namespace ButtonManager GLuint GetTexture() { return m_tex; } float *GetCoords() { return m_coords; } - ~Button() { if(m_tex) glDeleteTextures(1, &m_tex); } + ~Button() { g_video_backend->Video_DeleteTexture(m_tex); } }; struct sBind diff --git a/Source/Core/DolphinWX/Src/Android/TextureLoader.cpp b/Source/Core/DolphinWX/Src/Android/TextureLoader.cpp index 077cf32a1a..093370da78 100644 --- a/Source/Core/DolphinWX/Src/Android/TextureLoader.cpp +++ b/Source/Core/DolphinWX/Src/Android/TextureLoader.cpp @@ -17,8 +17,7 @@ #include "GLInterface.h" #include - -GLuint LoadPNG(const char *filename) +char* LoadPNG(const char *filename, u32 &width, u32 &height) { FILE *infile; /* PNG file pointer */ png_structp png_ptr; /* internally used by libpng */ @@ -31,8 +30,8 @@ GLuint LoadPNG(const char *filename) int bit_depth; int color_type; - png_uint_32 width; /* PNG image width in pixels */ - png_uint_32 height; /* PNG image height in pixels */ + png_uint_32 _width; + png_uint_32 _height; unsigned int rowbytes; /* raw bytes at row n in image */ image_data = NULL; @@ -42,7 +41,7 @@ GLuint LoadPNG(const char *filename) /* Open the file. */ infile = fopen(filename, "rb"); if (!infile) - return 0; + return NULL; /* * 13.3 readpng_init() @@ -53,7 +52,7 @@ GLuint LoadPNG(const char *filename) if (!png_check_sig((unsigned char *) sig, 8)) { fclose(infile); - return 0; + return NULL; } /* @@ -62,14 +61,14 @@ GLuint LoadPNG(const char *filename) png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(infile); - return 4; /* out of memory */ + return NULL; /* out of memory */ } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); fclose(infile); - return 4; /* out of memory */ + return NULL; /* out of memory */ } @@ -80,7 +79,7 @@ GLuint LoadPNG(const char *filename) if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(infile); - return 0; + return NULL; } /* @@ -108,7 +107,7 @@ GLuint LoadPNG(const char *filename) /* read all the info up to the image data */ png_read_info(png_ptr, info_ptr); - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, + png_get_IHDR(png_ptr, info_ptr, &_width, &_height, &bit_depth, &color_type, NULL, NULL, NULL); /* Set up some transforms. */ @@ -129,22 +128,22 @@ GLuint LoadPNG(const char *filename) /* Allocate the image_data buffer. */ - if ((image_data = (char *) malloc(rowbytes * height))==NULL) { + if ((image_data = (char *) malloc(rowbytes * _height))==NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - return 4; + return NULL; } - if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) { + if ((row_pointers = (png_bytepp)malloc(_height*sizeof(png_bytep))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(image_data); image_data = NULL; - return 4; + return NULL; } /* set the individual row_pointers to point at the correct offsets */ - for (i = 0; i < height; ++i) + for (i = 0; i < _height; ++i) row_pointers[i] = (png_byte*)(image_data + i*rowbytes); @@ -161,19 +160,7 @@ GLuint LoadPNG(const char *filename) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(infile); - GLuint Texture = 0; - glGenTextures(1, &Texture); - - /* create a new texture object - * and bind it to texname (unsigned integer > 0) - */ - glBindTexture(GL_TEXTURE_2D, Texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image_data); - return Texture; + width = (u32)_width; + height = (u32)_height; + return image_data; } diff --git a/Source/Core/DolphinWX/Src/Android/TextureLoader.h b/Source/Core/DolphinWX/Src/Android/TextureLoader.h index 69575807e6..db55078f1d 100644 --- a/Source/Core/DolphinWX/Src/Android/TextureLoader.h +++ b/Source/Core/DolphinWX/Src/Android/TextureLoader.h @@ -17,5 +17,5 @@ #include "GLInterface.h" -GLuint LoadPNG(const char *filename); +char* LoadPNG(const char *filename, u32 &width, u32 &height); diff --git a/Source/Core/VideoCommon/Src/VideoBackendBase.h b/Source/Core/VideoCommon/Src/VideoBackendBase.h index 9c591d05a5..7f8c90b2be 100644 --- a/Source/Core/VideoCommon/Src/VideoBackendBase.h +++ b/Source/Core/VideoCommon/Src/VideoBackendBase.h @@ -103,6 +103,14 @@ public: virtual void Video_ClearMessages() = 0; virtual bool Video_Screenshot(const char* filename) = 0; + // Loads a texture, -1 on not loaded + // Texture is passed in as RGBA data + virtual int Video_LoadTexture(char *imagedata, u32 width, u32 height) = 0; + // Deletes a texture loaded from LoadTexture + virtual void Video_DeleteTexture(int texID) = 0; + // Draws a texture, arg1 is the value returned by LoadTexture, arg2 is the screen coordinates + virtual void Video_DrawTexture(int texID, float *coords) = 0; + virtual void Video_SetRendering(bool bEnabled) = 0; virtual void Video_GatherPipeBursted() = 0; @@ -155,6 +163,10 @@ class VideoBackendHardware : public VideoBackend void Video_ClearMessages(); bool Video_Screenshot(const char* filename); + int Video_LoadTexture(char *imagedata, u32 width, u32 height) { return -1; } + void Video_DeleteTexture(int texID) {} + void Video_DrawTexture(int texID, float *coords) {} + void Video_SetRendering(bool bEnabled); void Video_GatherPipeBursted(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp index a395025808..e56a4b7b37 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp @@ -122,12 +122,13 @@ void SWRenderer::DrawDebugText() SWRenderer::RenderText(debugtext_buffer, 21, 21, 0xDD000000); SWRenderer::RenderText(debugtext_buffer, 20, 20, 0xFFFFFF00); } -#ifdef ANDROID -// XXX: This /really/ shouldn't be here -// But for now, we don't have a generic way for all backends to draw the buttons on screen. -// Once that is implemented, we can remove this -void DrawButton(GLuint tex, float *coords) + +// XXX: We should /really/ be outputting textures to the texture image instead of this way. +void SWRenderer::DrawButton(int texID, float *coords) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //Texture rectangle uses pixel coordinates #ifndef USE_GLES GLfloat u_max = (GLfloat)width; @@ -147,7 +148,7 @@ void DrawButton(GLuint tex, float *coords) {1, 1} }; #endif - glBindTexture(TEX2D, tex); + glBindTexture(TEX2D, texID); glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, coords); glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, texverts); @@ -160,8 +161,10 @@ void DrawButton(GLuint tex, float *coords) glDisableVertexAttribArray(attr_tex); glBindTexture(TEX2D, 0); + + glDisable(GL_BLEND); } -#endif + void SWRenderer::DrawTexture(u8 *texture, int width, int height) { GLsizei glWidth = (GLsizei)GLInterface->GetBackBufferWidth(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h index ba856936cb..5629976978 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h @@ -16,6 +16,7 @@ namespace SWRenderer void RenderText(const char* pstr, int left, int top, u32 color); void DrawDebugText(); + void DrawButton(int texId, float *coords); void DrawTexture(u8 *texture, int width, int height); void SwapBuffer(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index c63ad2e446..6e1aff4e46 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -242,6 +242,32 @@ bool VideoSoftware::Video_Screenshot(const char *_szFilename) return false; } +int VideoSoftware::Video_LoadTexture(char *image, u32 width, u32 height) +{ + GLuint Texture = 0; + glGenTextures(1, &Texture); + + glBindTexture(GL_TEXTURE_2D, Texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + + return (int) Texture; +} +void VideoSoftware::Video_DeleteTexture(int texID) +{ + if (texID == -1) return; + glDeleteTextures(1, (GLuint*)&texID); +} +void VideoSoftware::Video_DrawTexture(int texID, float *coords) +{ + if (texID == -1) return; + SWRenderer::DrawButton(texID, coords); +} // ------------------------------- // Enter and exit the video loop // ------------------------------- diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h index 37fe817f07..a105e66eba 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h @@ -35,6 +35,10 @@ class VideoSoftware : public VideoBackend void Video_ClearMessages(); bool Video_Screenshot(const char* filename); + int Video_LoadTexture(char *imagedata, u32 width, u32 height); + void Video_DeleteTexture(int texID); + void Video_DrawTexture(int texID, float *coords); + void Video_SetRendering(bool bEnabled); void Video_GatherPipeBursted();