Added missing launcher
[mupen64plus-pandora.git] / source / rice_gles / src / OGLTexture.cpp
1 /*
2 Copyright (C) 2003 Rice1964
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18
19 #include <stdlib.h>
20
21 #include "Config.h"
22 #include "Debugger.h"
23 #include "OGLDebug.h"
24 #include "OGLGraphicsContext.h"
25 #include "OGLTexture.h"
26 #include "TextureManager.h"
27
28 #ifdef HAVE_GLES
29 #define GL_RGBA4                          0x8056
30 #endif
31
32 COGLTexture::COGLTexture(uint32 dwWidth, uint32 dwHeight, TextureUsage usage) :
33     CTexture(dwWidth,dwHeight,usage),
34     m_glFmt(GL_RGBA)
35 {
36     // FIXME: If usage is AS_RENDER_TARGET, we need to create pbuffer instead of regular texture
37
38     m_dwTextureFmt = TEXTURE_FMT_A8R8G8B8;  // Always use 32bit to load texture
39     glGenTextures( 1, &m_dwTextureName );
40     OPENGL_CHECK_ERRORS;
41
42     // Make the width and height be the power of 2
43     uint32 w;
44     for (w = 1; w < dwWidth; w <<= 1);
45     m_dwCreatedTextureWidth = w;
46     for (w = 1; w < dwHeight; w <<= 1);
47     m_dwCreatedTextureHeight = w;
48     
49     if (dwWidth*dwHeight > 256*256)
50         TRACE4("Large texture: (%d x %d), created as (%d x %d)", 
51             dwWidth, dwHeight,m_dwCreatedTextureWidth,m_dwCreatedTextureHeight);
52     
53     m_fYScale = (float)m_dwCreatedTextureHeight/(float)m_dwHeight;
54     m_fXScale = (float)m_dwCreatedTextureWidth/(float)m_dwWidth;
55
56     m_pTexture = malloc(m_dwCreatedTextureWidth * m_dwCreatedTextureHeight * GetPixelSize());
57 //#ifndef HAVE_GLES
58
59     switch( options.textureQuality )
60     {
61     case TXT_QUALITY_DEFAULT:
62         if( options.colorQuality == TEXTURE_FMT_A4R4G4B4 ) 
63             m_glFmt = GL_RGBA4;
64         break;
65     case TXT_QUALITY_32BIT:
66         break;
67     case TXT_QUALITY_16BIT:
68             m_glFmt = GL_RGBA4;
69         break;
70     };
71
72 //#endif
73     LOG_TEXTURE(TRACE2("New texture: (%d, %d)", dwWidth, dwHeight));
74 }
75
76 COGLTexture::~COGLTexture()
77 {
78     // FIXME: If usage is AS_RENDER_TARGET, we need to destroy the pbuffer
79
80     glDeleteTextures(1, &m_dwTextureName );
81     OPENGL_CHECK_ERRORS;
82     free(m_pTexture);
83     m_pTexture = NULL;
84     m_dwWidth = 0;
85     m_dwHeight = 0;
86 }
87
88 bool COGLTexture::StartUpdate(DrawInfo *di)
89 {
90     if (m_pTexture == NULL)
91         return false;
92
93     di->dwHeight = (uint16)m_dwHeight;
94     di->dwWidth = (uint16)m_dwWidth;
95     di->dwCreatedHeight = m_dwCreatedTextureHeight;
96     di->dwCreatedWidth = m_dwCreatedTextureWidth;
97     di->lpSurface = m_pTexture;
98     di->lPitch = GetPixelSize()*m_dwCreatedTextureWidth;
99
100     return true;
101 }
102
103 void COGLTexture::EndUpdate(DrawInfo *di)
104 {
105     COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext); // we need this to check if the GL extension is avaible
106
107     glBindTexture(GL_TEXTURE_2D, m_dwTextureName);
108     OPENGL_CHECK_ERRORS;
109
110     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
111     OPENGL_CHECK_ERRORS;
112
113     // mipmap support
114     if(options.mipmapping)
115     {
116         int m_maximumAnistropy = pcontext->getMaxAnisotropicFiltering(); //if getMaxAnisotropicFiltering() return more than 0, so aniso is supported and maxAnisotropicFiltering is set
117
118         // Set Anisotropic filtering (mipmapping have to be activated, aniso filtering is not effective without)
119         if( m_maximumAnistropy )
120         {
121             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_maximumAnistropy);
122             OPENGL_CHECK_ERRORS;
123         }
124
125         // Set Mipmap
126         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
127         OPENGL_CHECK_ERRORS;
128
129 #if SDL_VIDEO_OPENGL
130         // Tell to hardware to generate mipmap (himself) when glTexImage2D is called
131         glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
132 #elif SDL_VIDEO_OPENGL_ES2
133         glGenerateMipmap(GL_TEXTURE_2D);
134 #endif
135         OPENGL_CHECK_ERRORS;
136     }
137     else
138     {
139         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
140         OPENGL_CHECK_ERRORS;
141     }
142
143     // Copy the image data from main memory to video card texture memory
144 #if SDL_VIDEO_OPENGL
145 #ifdef HAVE_GLES
146         // first change format BGRA->RGBA and reduce bit if needed
147         unsigned char*  m_glesTex;
148         if (m_glFmt == GL_RGBA4) {
149                 m_glesTex = (unsigned char*)malloc(m_dwCreatedTextureHeight*m_dwCreatedTextureWidth*2);
150                 unsigned short *p = (unsigned short*)m_glesTex;
151                 unsigned char *f = (unsigned char*)m_pTexture;
152                 for (int j=0; j<m_dwCreatedTextureHeight; j++)
153                         for (int i=0; i<m_dwCreatedTextureWidth; i++) {
154                                 // *f = B, *(f+1) = G, *(f+2) = R, *(f+3) = A
155                                 // RRRR GGGG BBBB AAAA
156                                 *(p++)= ((*(f+2))&0xf0)>>4 | ((*(f+1))&0xf0) | (((*f))&0xf0)<<4 | ((*(f+3))&0xf0)<<8;
157                                 f+=4;
158                 }
159                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, m_glesTex);
160         } else {
161                 m_glesTex = (unsigned char*)malloc(m_dwCreatedTextureHeight*m_dwCreatedTextureWidth*4);
162                 unsigned int *p = (unsigned int*)m_glesTex;
163                 unsigned char *f = (unsigned char*)m_pTexture;
164                 for (int j=0; j<m_dwCreatedTextureHeight; j++)
165                         for (int i=0; i<m_dwCreatedTextureWidth; i++) {
166                                 // *f = B, *(f+1) = G, *(f+2) = R, *(f+3) = A
167                                 // AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
168                                 *(p++)= ((*(f+2))) | ((*(f+1)))<<8 | ((*f))<<16 | ((*(f+3)))<<24;
169                                 f+=4;
170                 }
171                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_glesTex);
172         }
173         free(m_glesTex);
174 #else
175     glTexImage2D(GL_TEXTURE_2D, 0, m_glFmt, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_pTexture);
176 #endif
177 #elif SDL_VIDEO_OPENGL_ES2
178     //GL_BGRA_IMG works on adreno but not inside profiler.
179     glTexImage2D(GL_TEXTURE_2D, 0, m_glFmt, m_dwCreatedTextureWidth, m_dwCreatedTextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pTexture);
180 #endif
181     OPENGL_CHECK_ERRORS;
182 }
183
184
185 // Keep in mind that the real texture is not scaled to fix the created opengl texture yet.
186 // when the image is need to be scaled, ScaleImageToSurface in CTexure will be called to 
187 // scale the image automatically
188