v 0. Pasted by Anonymous as cpp at 2014-10-31 19:10:54 MSK and set expiration to never.

Paste will expire never.

  1. #include "nu_StdHeader.h"
  2. #include "nu_TextureGL.h"
  3. #include "nu_ProjectFiles.h"
  4. #include "nu_Xml.h"
  5. #include "nu_RenderGL.h"
  6. #include "nu_Pak.h"
  7. #include "nu_LoadDDS.h"
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "nu_TextureSetting.h"
  11. #include "nu_TextureLoader.h"
  12. #include "nu_FboGL.h"
  13. #include "nu_FileStream.h"
  14. #include "nu_Sampler.h"
  15.  
  16. #if IS_IPHONE_PLATFORM == 1
  17. #   include "PVRTTexture.h"
  18. #endif
  19.  
  20. using namespace Nuligine;
  21.  
  22. TextureGpuGL::TextureGpuGL(Scene *_scene) : TextureGpuRaw(_scene){
  23.     tex = 0;
  24.     sampler_not_set = true;
  25. }
  26. TextureGpuGL::~TextureGpuGL(){
  27.     nu_assert(tex == 0);
  28. }
  29. void TextureGpuGL::ApplySampler(const Sampler &sam){
  30.     if (cur_sampler != sam || sampler_not_set){
  31.         cur_sampler = sam;
  32.         sampler_not_set = true;
  33.         bool has_mips = desc.mip_count > 1 && sam.useMipMaps;
  34.         GLenum target = GL_TEXTURE_2D;
  35. //      if (isCanRepeat() || true){
  36. //          bool is_point = (ts && ts->point_filter) || Desc().is_use_point_filtr;
  37.         if (sam.filtr == sft_Linear){
  38.             GL(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, has_mips ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
  39.             GL(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
  40.             GL(glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sam.maxAnisotropy));
  41. //            if(desc.mip_count > 1 ){
  42. //                //GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5));
  43. //                GL(glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 5));
  44. //            }
  45.         }else if (sam.filtr == sft_Pixel){
  46.             GL(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, has_mips ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST));
  47.             GL(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
  48.             GL(glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sam.maxAnisotropy));
  49.         }else
  50.             nu_assert_force;
  51.         GLint wrap = sam.wrap == swt_Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE;
  52.         GL(glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap));
  53.         GL(glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap));
  54.         GL(glTexParameteri(target, GL_TEXTURE_WRAP_R, wrap));
  55.        
  56.     }
  57. }
  58. void TextureGpuGL::DoDeleteInThreadGPU(){
  59.     if( in_fbos.NotEmpty() ){
  60.         RenderGL *gl = (RenderGL*)scene->render;
  61.         //for (size_t i = 0; i < in_fbos.Size(); i++)
  62.         //  gl->DeleteFbo(in_fbos[i]);
  63.         //in_fbos.Clear();
  64.         while( in_fbos.NotEmpty() ){
  65.             gl->DeleteFbo( in_fbos[0] );
  66.         }
  67.     }
  68.     if( tex > 0 )
  69.         GL( glDeleteTextures(1, &tex) );
  70.     tex = 0;
  71. }
  72. void TextureGpuGL::CreateTextureAsunc( size_t &size_move_to_gpu ){
  73.     if (desc.is_render_target){
  74.         Create(nullptr, desc.init_data.bits());
  75.         desc.init_data = UI_Image();
  76.     }
  77.     else if ( desc.is_from_file ){
  78.         if( desc.is_cube )
  79.             DoLoadCube( size_move_to_gpu );
  80.         else
  81.             DoLoad2D( size_move_to_gpu, use_setting );
  82.     }
  83. }
  84.  
  85. //gl_internalformat = GL_DEPTH_COMPONENT;
  86. //GL(glTexImage2D(GL_TEXTURE_2D, 0, gl_internalformat, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL));
  87.  
  88. #define SETF(_my, _internal,_format,_type) if(format == _my){ gl_internal_format = _internal; gl_format = _format; gl_type = _type; return; }
  89.  
  90. #if IS_APPLE_PLATFORM == 1
  91. #   define GL_RGB32F GL_RGB32F_ARB
  92. #endif
  93. #if IS_IPHONE_PLATFORM == 1
  94. #   define GL_R16 GL_RG16F
  95. #   define GL_RG16 GL_RG16F
  96. #   define GL_RGBA16 GL_RGBA16F
  97. #   define GL_HALF_FLOAT_ARB GL_HALF_FLOAT_OES
  98. #   define GL_DEPTH_COMPONENT32 GL_DEPTH_COMPONENT24
  99. #endif
  100.  
  101. void GetGLFormat(TexFormat format, GLint &gl_internal_format, GLenum &gl_format, GLenum &gl_type){
  102. #if IS_IPHONE_PLATFORM == 1
  103.     if(RenderGL::GetIs_ES_2_0()){
  104.         SETF(TF_RGBA_8_UNORM, GL_RGBA, GL_BGRA, GL_UNSIGNED_BYTE);
  105.  
  106.         SETF(TF_R_8_UNORM, GL_R8_EXT, GL_RED_EXT, GL_UNSIGNED_BYTE);
  107.         SETF(TF_R_16_UNORM, GL_R16F_EXT, GL_RED_EXT, GL_HALF_FLOAT_ARB);
  108.         SETF(TF_R_32_FLOAT, GL_R32F_EXT, GL_RED_EXT, GL_FLOAT);
  109.         // 2 channels
  110.         SETF(TF_RG_16_UNORM, GL_RG16F_EXT, GL_BGRA, GL_HALF_FLOAT_ARB);
  111.         // 4 channels
  112.         //SETF(TF_RGBA_4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_BYTE);
  113.         //SETF(TF_RGB_5_A1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_BYTE);
  114.         SETF(TF_RGBA_8_UNORM, GL_RGBA8_OES, GL_BGRA, GL_UNSIGNED_BYTE);
  115.         SETF(TF_RGB_10_A2_UNORM, GL_RGBA8_OES, GL_BGRA, GL_UNSIGNED_BYTE);
  116.         SETF(TF_RGBA_16_UNORM, GL_RGBA16F_EXT, GL_BGRA, GL_HALF_FLOAT_ARB);
  117.         SETF(TF_RGBA_16_FLOAT, GL_RGBA16F_EXT, GL_BGRA, GL_FLOAT);
  118.         SETF(TF_RGBA_32_FLOAT, GL_RGBA16F_EXT, GL_BGRA, GL_FLOAT);
  119.         // Depth
  120.         SETF(TF_D_16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
  121.         SETF(TF_D_24, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
  122.         SETF(TF_D_24_S8, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
  123.         SETF(TF_D_32, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
  124.        
  125.         nu_assert_force;
  126.     }
  127. #endif
  128.     // 1 channels
  129.     SETF(TF_R_8_UNORM, GL_R8, GL_RED, GL_UNSIGNED_BYTE);
  130.     SETF(TF_R_16_UNORM, GL_R16, GL_RED, GL_HALF_FLOAT_ARB);
  131.     SETF(TF_R_32_FLOAT, GL_R32F, GL_RED, GL_FLOAT);
  132.     // 2 channels
  133.     SETF(TF_RG_16_UNORM, GL_RG16, GL_BGRA, GL_HALF_FLOAT_ARB);
  134.     // 4 channels
  135.     //SETF(TF_RGBA_4_UNORM, GL_RGBA4, GL_BGRA, GL_UNSIGNED_BYTE);
  136.     //SETF(TF_RGB_5_A1_UNORM, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_BYTE);
  137.     SETF(TF_RGBA_8_UNORM, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE);
  138.     SETF(TF_RGB_10_A2_UNORM, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV);
  139.     SETF(TF_RGBA_16_UNORM, GL_RGBA16, GL_BGRA, GL_HALF_FLOAT_ARB);
  140.     SETF(TF_RGBA_16_FLOAT, GL_RGBA16F, GL_BGRA, GL_FLOAT);
  141.     SETF(TF_RGBA_32_FLOAT, GL_RGBA32F, GL_BGRA, GL_FLOAT);
  142.     // Depth
  143.     SETF(TF_D_16, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
  144.     SETF(TF_D_24, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
  145.     SETF(TF_D_24_S8, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
  146.     SETF(TF_D_32, GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_FLOAT);
  147.     //
  148.     nu_assert_force;
  149. }
  150. #undef SETF
  151.  
  152. void TextureGpuGL::Create(TextureSetting *ts, void *init_data){
  153.     TexFormat format = Desc().format;
  154.     GLint gl_internalformat = 0;
  155.     GLenum gl_format = 0, gl_type = 0;
  156.     GetGLFormat(format, gl_internalformat, gl_format, gl_type);
  157.     nu_assert(gl_internalformat);
  158.     nu_assert(gl_format);
  159.     nu_assert(gl_type);
  160.     int w = Desc().width;
  161.     int h = Desc().height;
  162.     GLenum target = Desc().is_cube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
  163.     nu_assert( tex == 0 );
  164.     GL(glGenTextures(1, &tex));
  165.     GL(glActiveTexture(GL_TEXTURE0));   
  166.     GL(glBindTexture(target, tex));
  167.     if (Desc().is_cube){
  168.         if(!RenderGL::GetIs_ES_2_0()){
  169.             GL(glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
  170.             GL(glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0));
  171.             GL(glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0));
  172.         }
  173.         for (int i = 0; i < 6; i++)
  174.             GL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl_internalformat, w, h, 0, gl_format, gl_type, init_data));
  175.     }
  176.     else{
  177.         GL(glTexImage2D(target, 0, gl_internalformat, w, h, 0, gl_format, gl_type, init_data));
  178.     }
  179.     if (format == TF_D_16 && Desc().name == "use_gpu_shadow_2d" && !RenderGL::GetIs_ES_2_0()){
  180.         GL(glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL));
  181.         GL(glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE));
  182.     }
  183.     GL(glBindTexture(target, 0));
  184. }
  185.  
  186. void TextureGpuGL::ReadTextureData(){
  187.     if( GetCanUse() &&  Desc().width && Desc().height ){
  188.         LOCKER( readed_data_mutex );
  189.         readed_data_size = Desc().width * Desc().height * 4;
  190.         nu_assert(readed_data == nullptr);
  191.         NU_ALLOC( readed_data, readed_data_size );
  192.         GL( glFinish() );
  193.         GL( glBindTexture( GL_TEXTURE_2D, tex ) );
  194. #if IS_IPHONE_PLATFORM == 1
  195.         GLuint framebuffer = 0;
  196.         GLint glDefaultRenderBuffer = 0;
  197.         GL( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &glDefaultRenderBuffer) );
  198.         GL( glGenFramebuffers(1, &framebuffer) );
  199.         GL( glBindFramebuffer(GL_FRAMEBUFFER, framebuffer) );
  200.         GL( glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0) );
  201.         GLenum status;
  202.         GL( status = glCheckFramebufferStatus(GL_FRAMEBUFFER) );
  203.         if (status != GL_FRAMEBUFFER_COMPLETE) {
  204.             std::cout << "Problem with OpenGL framebuffer after specifying color render buffer: \n";
  205.             nu_assert_force;
  206.         }
  207.         GL( glReadPixels(0, 0, Desc().width, Desc().height,GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte*)readed_data ) );
  208.         GL( glBindFramebuffer(GL_FRAMEBUFFER, glDefaultRenderBuffer) );
  209.         GL( glDeleteFramebuffers(1, &framebuffer) );
  210. #else
  211.         GL( glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLubyte*)readed_data ) );
  212. #endif
  213.         GL( glBindTexture( GL_TEXTURE_2D, 0 ) );
  214.     }
  215. }
  216.  
  217. void TextureGpuGL::DoLoad2D( size_t &size_move_to_gpu, TextureSetting *ts ){
  218.     nu_assert( tex == 0 );
  219.     GL( glGenTextures(1, &tex) );
  220.     nu_assert( tex );
  221.     GL( glBindTexture( GL_TEXTURE_2D, tex) );
  222.     nu_assert_ptr( file_streams[0] );
  223.     CachFile *f= file_streams[0]->GetCachFile();
  224.     if( f->NotEmpty() ){       
  225.         if( load_format[0] == tlf_DDS )
  226.             LoadDDS( size_move_to_gpu, f, ts, GL_TEXTURE_2D, true );
  227.         else if( load_format[0] == tlf_PVR )
  228.             LoadPVR( size_move_to_gpu, f, ts, GL_TEXTURE_2D, true );
  229.         else if( load_format[0] == tlf_Source )
  230.             LoadFromSource( size_move_to_gpu, f, ts, GL_TEXTURE_2D, true );
  231.         GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, desc.mip_count - 1));
  232.     }
  233.     GL( glBindTexture(  GL_TEXTURE_2D, 0 ) );
  234. }
  235. void TextureGpuGL::DoLoadCube(  size_t &size_move_to_gpu ){
  236.     nu_assert( !tex );
  237.     nu_assert( tex == 0 );
  238.     GL( glGenTextures(1, &tex ) );
  239.     nu_assert( tex );
  240.     GL( glBindTexture( GL_TEXTURE_CUBE_MAP, tex ) );
  241.     GL( glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
  242.     GL( glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
  243.     // GL( glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0) ); really not use, but save for maby later
  244.     GL( glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0) );
  245.     GL( glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE  ) );
  246.     GL( glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE  ) );
  247.     TextureSetting *ts = scene->GetTextureSettings()->Get( Desc().name );
  248.     for( int i =0; i < 6; i++ ){
  249.         FileStream *fs = file_streams[i];
  250.         if( fs ){
  251.             CachFile *f= fs->GetCachFile();
  252.             if( f->NotEmpty() ){
  253.                 if( load_format[i] == tlf_Source )
  254.                     LoadFromSource( size_move_to_gpu, f, nullptr, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, false );
  255.                 else if( load_format[i] == tlf_DDS )
  256.                     LoadDDS( size_move_to_gpu, f, ts, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, false  );
  257.                 else if( load_format[i] == tlf_PVR )
  258.                     LoadPVR( size_move_to_gpu, f, ts, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, false  );
  259.             }
  260.         }
  261.     }
  262.     GL( glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ) );
  263. }
  264.  
  265. void TextureGpuGL::LoadFromSource( size_t &size_move_to_gpu, CachFile *f , TextureSetting *ts, GLenum target, bool can_mip_map ){
  266.     UNUSED( ts );
  267.     nu_assert( f );
  268.     TextureLoader loader;
  269.     loader.Load( desc.name, f, scene->GetProjectFiles() );
  270.     loader.SetTextureSetting( ts );
  271.     loader.FlipVertical();
  272.     void *data = loader.GetData();
  273.     if( data ){
  274.         desc.width = loader.GetW();
  275.         desc.height = loader.GetH();
  276.         size_move_to_gpu += desc.width * desc.height * 4;
  277.         GL( glTexImage2D(target, 0, GL_RGBA, Desc().width, Desc().height,0, GL_BGRA, GL_UNSIGNED_BYTE, data) );
  278.         desc.mip_count = 1;
  279.         if(RenderGL::GetIs_ES_2_0() == false){
  280. #if IS_IPHONE_PLATFORM == 0
  281.             GL(glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE));
  282. #endif
  283.             GL(glGenerateMipmap(target));
  284.             desc.mip_count = ceil(Math::Log2(nu_max(desc.width, desc.height))) + 1;
  285.         }
  286.     }
  287. }
  288. void TextureGpuGL::WriteTextureData( void *data, int mip, int w, int h ){
  289.     GL( glBindTexture( GL_TEXTURE_2D, tex) );
  290.     GL( glTexImage2D(GL_TEXTURE_2D, mip, 4, w, h,0, GL_BGRA, GL_UNSIGNED_BYTE, data ) );
  291.     GL( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, desc.mip_count-1 ) );
  292.     GL( glBindTexture( GL_TEXTURE_2D, 0) );
  293. }
  294. void TextureGpuGL::LoadPVR( size_t &size_move_to_gpu ,CachFile *f, TextureSetting *ts, GLenum target, bool can_mip_map  )
  295. {
  296.    UNUSED(ts);
  297. #if IS_IPHONE_PLATFORM == 1
  298.    if( !f->GetData() )
  299.        return;
  300.    char *m_pData = (char*)f->GetData();
  301.    GLenum m_glFormat = 0;
  302.    GLenum m_glType = 0;
  303.    int m_uiBPP = 0;
  304.    unsigned int m_uiMIP = 0;
  305.    char* m_pTextureData = 0;
  306.    bool m_bCompressed = false;
  307.    unsigned int m_iNumFaces = 0;
  308.    if(*(PVRTuint32*)m_pData != PVRTEX3_IDENT){
  309.        //std::cout<<"[CParser_PVR::Load] OLD PVR format"<<std::endl;
  310.        PVR_Texture_Header* pHeader;
  311.        pHeader = (PVR_Texture_Header*)m_pData;
  312.        switch (pHeader->dwpfFlags & PVRTEX_PIXELTYPE){
  313.        case OGL_PVRTC2:
  314.            if(pHeader->dwAlphaBitMask){
  315.                m_uiBPP = 2;
  316.                m_glFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  317.            }
  318.            else{
  319.                m_uiBPP = 2;
  320.                m_glFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  321.            }
  322.            break;
  323.        case OGL_PVRTC4:
  324.            if(pHeader->dwAlphaBitMask){
  325.                m_uiBPP = 4;
  326.                m_glFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  327.            }
  328.            else{
  329.                m_uiBPP = 4;
  330.                m_glFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  331.            }
  332.            break;
  333.        default:
  334.            std::cout<<"[CParser_PVR::Load] Unsupported format for Texture Name : "<< desc.name.ToUtf8() <<"\n";
  335.            return;
  336.        }
  337.        desc.width = pHeader->dwWidth;
  338.        desc.height = pHeader->dwHeight;
  339.        m_uiMIP = pHeader->dwMipMapCount ? pHeader->dwMipMapCount : 1;
  340.        m_bCompressed = true;
  341.        m_pTextureData = m_pData + pHeader->dwHeaderSize;
  342.        m_iNumFaces = 1;
  343.    }
  344.    else{
  345.        //std::cout<<"[CParser_PVR::Load] NEW PVR format"<<std::endl;
  346.        PVRTextureHeaderV3* pHeader = (PVRTextureHeaderV3*)m_pData;
  347.        PVRTuint64 iPixelFormat = pHeader->u64PixelFormat;
  348.        switch (iPixelFormat){
  349.        case 0:{
  350.            m_uiBPP = 2;
  351.            m_glFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  352.        }
  353.            break;
  354.        case 1:{
  355.            m_uiBPP = 2;
  356.            m_glFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  357.        }
  358.            break;
  359.        case 2:{
  360.            m_uiBPP = 4;
  361.            m_glFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  362.        }
  363.        case 3:{
  364.            m_uiBPP = 4;
  365.            m_glFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  366.        }
  367.            break;
  368.        default:
  369.            std::cout<<"[CParser_PVR::Load] Unsupported format for Texture Name : "<<desc.name.ToUtf8() <<"\n";
  370.            return;
  371.        }
  372.        desc.width = pHeader->u32Width;
  373.        desc.height = pHeader->u32Height;
  374.        m_uiMIP = pHeader->u32MIPMapCount ? pHeader->u32MIPMapCount : 1;
  375.        m_bCompressed = true;
  376.        m_pTextureData = m_pData + PVRTEX3_HEADERSIZE + pHeader->u32MetaDataSize;
  377.        m_iNumFaces = pHeader->u32NumFaces;
  378.    }
  379.    int skip_count = GetCountSckipMipLevels(m_uiMIP);
  380.     bool is_use_mips = GetUseMipLevels();
  381.    int use_mip_count = 0;
  382.    char* pData = m_pTextureData;
  383.    for(unsigned int iFaces = 0; iFaces < m_iNumFaces; iFaces++){
  384.        if (m_bCompressed){
  385.            int cur_w = desc.width;
  386.            int cur_h = desc.height;
  387.            for (int level = 0; cur_w > 0 && cur_h > 0; ++level){
  388.                GLsizei iSize = std::max(32, cur_w * cur_h * m_uiBPP / 8);
  389.                if (skip_count == 0 ){
  390.                    GL(glCompressedTexImage2D(target + iFaces, use_mip_count, m_glFormat, cur_w, cur_h, 0, iSize, pData));
  391.                    size_move_to_gpu += iSize;
  392.                    use_mip_count++;
  393.                    if (!is_use_mips)
  394.                        break;
  395.                }
  396.                else{
  397.                    skip_count--;
  398.                }
  399.                pData += iSize;
  400.                cur_w >>= 1; cur_h >>= 1;
  401.            }
  402.        }
  403.        else
  404.        {
  405.            nu_todo_assert_force;
  406.            GL(glTexImage2D(target + iFaces, 0, m_glFormat, Desc().width, Desc().height, 0, m_glFormat, m_glType, pData));
  407.            //glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
  408.            GL(glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST));
  409.            //glGenerateMipmap(iTextureTarget + iFaces);
  410.        }
  411.    }
  412.     desc.mip_count = use_mip_count;
  413. #endif
  414. }
  415.  
  416.  
  417.  
  418.  
  419. #if IS_IPHONE_PLATFORM == 0
  420. struct DdsLoadInfo
  421. {
  422.     bool compressed;
  423.     bool swap;
  424.     bool palette;
  425.     unsigned int divSize;
  426.     unsigned int blockBytes;
  427.     GLenum internalFormat;
  428.     GLenum externalFormat;
  429.     GLenum type;
  430. };
  431.  
  432. DdsLoadInfo loadInfoDXT1 = {true, false, false, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,0,0};
  433. DdsLoadInfo loadInfoDXT3 = {true, false, false, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,0,0};
  434. DdsLoadInfo loadInfoDXT5 = {true, false, false, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,0,0};
  435. DdsLoadInfo loadInfoBGRA8 ={false, false, false, 1, 4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE};
  436. DdsLoadInfo loadInfoBGR8 = {false, false, false, 1, 3, GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE};
  437. DdsLoadInfo loadInfoBGR5A1={false, true, false, 1, 2, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV};
  438. DdsLoadInfo loadInfoBGR565={false, true, false, 1, 2, GL_RGB5, GL_RGB, GL_UNSIGNED_SHORT_5_6_5};
  439. DdsLoadInfo loadInfoIndex8={false, false, true, 1, 1, GL_RGB8, GL_BGRA, GL_UNSIGNED_BYTE};
  440. #endif // #if IS_OPENGL_ES2 == 0
  441.  
  442. void TextureGpuGL::LoadDDS( size_t &size_move_to_gpu, CachFile *f, TextureSetting *ts, GLenum target, bool can_mip_map ){
  443.     UNUSED(ts);
  444. #if IS_IPHONE_PLATFORM == 0
  445.     if( !f->GetData() )
  446.         return;
  447.     DDS_header hdr;
  448.     unsigned int x = 0;
  449.     unsigned int y = 0;
  450.     unsigned int mipMapCount = 0;
  451.     size_t read_offset = 0;
  452.     memcpy( &hdr,  f->GetData(), sizeof( hdr ) );
  453.     read_offset += sizeof( hdr );
  454.     if( hdr.dwMagic != DDS_MAGIC || hdr.dwSize != 124 || !(hdr.dwFlags & DDSD_PIXELFORMAT) || !(hdr.dwFlags & DDSD_CAPS) ){
  455.         std::cout << "Error load DDS texture, tex: " << desc.name.To1251() << "\n";
  456.         return;
  457.     }
  458.     int xSize = hdr.dwWidth;
  459.     int ySize = hdr.dwHeight;
  460.     desc.width = xSize;
  461.     desc.height = ySize;
  462.     //assert( !(xSize & (xSize-1)) );
  463.     //assert( !(ySize & (ySize-1)) );
  464.     DdsLoadInfo * li;
  465.     if( PF_IS_DXT1( hdr.sPixelFormat ) )            li = &loadInfoDXT1;
  466.     else if( PF_IS_DXT3( hdr.sPixelFormat ) )       li = &loadInfoDXT3;
  467.     else if( PF_IS_DXT5( hdr.sPixelFormat ) )       li = &loadInfoDXT5;
  468.     else if( PF_IS_BGRA8( hdr.sPixelFormat ) )      li = &loadInfoBGRA8;
  469.     else if( PF_IS_BGR8( hdr.sPixelFormat ) )       li = &loadInfoBGR8;
  470.     else if( PF_IS_BGR5A1( hdr.sPixelFormat ) )     li = &loadInfoBGR5A1;
  471.     else if( PF_IS_BGR565( hdr.sPixelFormat ) )     li = &loadInfoBGR565;
  472.     else if( PF_IS_INDEX8( hdr.sPixelFormat ) )     li = &loadInfoIndex8;
  473.     else {
  474.         std::cout << "Error load DDS texture, tex: " << desc.name.To1251() << " unknown pixel format\n";
  475.         return;
  476.     }
  477.     x = xSize;
  478.     y = ySize;
  479.     mipMapCount = ( (hdr.dwFlags & DDSD_MIPMAPCOUNT) && can_mip_map ) ? hdr.dwMipMapCount : 1;
  480.     if( mipMapCount > 1 ) {
  481.         GL( glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ) );
  482.     }
  483.     desc.mip_count = mipMapCount;
  484.     GLenum format2, cFormat;
  485.     int skip = GetCountSckipMipLevels(mipMapCount);
  486.     if (!GetUseMipLevels())
  487.         mipMapCount = skip + 1;
  488.     int use_mip_count= 0;
  489.     if( li->compressed ) {
  490.         size_t size = nu_max( li->divSize, x )/li->divSize * nu_max( li->divSize, y )/li->divSize * li->blockBytes;
  491.         //assert( size == hdr.dwPitchOrLinearSize );
  492.         nu_assert( hdr.dwFlags & DDSD_LINEARSIZE );
  493.         format2 = cFormat = li->internalFormat;
  494.         for( unsigned int ix = 0; ix < mipMapCount; ++ix ) {
  495.             unsigned char * data = (unsigned char *)f->GetData( read_offset );
  496.             read_offset += size;
  497.             if (skip == 0){
  498.                 size_move_to_gpu += size;
  499.                 GL(glCompressedTexImage2D(target, use_mip_count, li->internalFormat, x, y, 0, size, data));
  500.                 use_mip_count++;
  501.             }
  502.             else{
  503.                 skip--;
  504.             }
  505.             x = (x+1)>>1;
  506.             y = (y+1)>>1;
  507.             size = nu_max( li->divSize, x )/li->divSize * nu_max( li->divSize, y )/li->divSize * li->blockBytes;
  508.         }
  509.     }
  510.     else if( li->palette ) {
  511.         //  currently, we unpack palette into BGRA
  512.         //  I'm not sure we always get pitch...
  513.         nu_assert( hdr.dwFlags & DDSD_PITCH );
  514.         nu_assert( hdr.sPixelFormat.dwRGBBitCount == 8 );
  515.         size_t size = hdr.dwPitchOrLinearSize * ySize;
  516.         //  And I'm even less sure we don't get padding on the smaller MIP levels...
  517.         nu_assert( size == x * y * li->blockBytes );
  518.         format2 = li->externalFormat;
  519.         cFormat = li->internalFormat;
  520.         unsigned int * unpacked = (unsigned int *)malloc( size*sizeof( unsigned int ) );
  521.         unsigned int palette[ 256 ];
  522.         //fread( palette, 4, 256, f );
  523.         memcpy( &palette[0], f->GetData( read_offset ), 256 * 4 );
  524.         read_offset += 256 * 4 ;
  525.         for( unsigned int ix = 0; ix < mipMapCount; ++ix ){
  526.             unsigned char * data = (unsigned char *)f->GetData( read_offset );
  527.             read_offset += size;
  528.             //fread( data, 1, size, f );
  529.             for( unsigned int zz = 0; zz < size; ++zz )
  530.                 unpacked[ zz ] = palette[ data[ zz ] ];
  531.             if (skip == 0){
  532.                 size_move_to_gpu += size;
  533.                 GL(glPixelStorei(GL_UNPACK_ROW_LENGTH, y));
  534.                 GL(glTexImage2D(target, use_mip_count, li->internalFormat, x, y, 0, li->externalFormat, li->type, unpacked));
  535.                 use_mip_count++;
  536.             }
  537.             else{
  538.                 skip--;
  539.             }
  540.             x = (x+1)>>1;
  541.             y = (y+1)>>1;
  542.             size = x * y * li->blockBytes;
  543.         }
  544.         free( unpacked );
  545.     }
  546.     else {
  547.         if( li->swap ) {
  548.             GL( glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_TRUE ) );
  549.         }
  550.         uint32 size = x * y * li->blockBytes;
  551.         format2 = li->externalFormat;
  552.         cFormat = li->internalFormat;
  553.         //fixme: how are MIP maps stored for 24-bit if pitch != ySize*3 ?
  554.         for( unsigned int ix = 0; ix < mipMapCount; ++ix ) {
  555.             unsigned char * data = (unsigned char *)f->GetData( read_offset );
  556.             read_offset += size;
  557.             if (skip == 0){
  558.                 size_move_to_gpu += size;
  559.                 GL(glPixelStorei(GL_UNPACK_ROW_LENGTH, y));
  560.                 GL(glTexImage2D(target, use_mip_count, li->internalFormat, x, y, 0, li->externalFormat, li->type, data));
  561.                 use_mip_count++;
  562.             }
  563.             else{
  564.                 skip--;
  565.             }
  566.             x = (x+1)>>1;
  567.             y = (y+1)>>1;
  568.             size = x * y * li->blockBytes;
  569.         }
  570.         GL( glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE ) );
  571.     }
  572.     desc.mip_count = use_mip_count;
  573. #endif // #if IS_OPENGL_ES2 == 0
  574. }