cocos2d-x 源码分析




std::string FileUtils::fullPathForFilename(const std::string &filename)
{   //如果文件名为string的size()==0
    if (filename.empty())
    {
        return "";
    }
    //如果是绝对路径
    if (isAbsolutePath(filename))
    {
        return filename;
    }

    // Already Cached ?  如果已经缓存了,则直接从缓存里面取
    auto cacheIter = _fullPathCache.find(filename);
    if( cacheIter != _fullPathCache.end() )
    {
        return cacheIter->second;
    }
    
    // Get the new file name. 获得一份新文件名
    const std::string newFilename( getNewFilename(filename) );
    
	std::string fullpath;
    //cbegin()返回确定范围中第一个元素地址的const 迭代器。cend()指向刚超出范围末尾的位置的 const 随机访问迭代器。
    for (auto searchIt = _searchPathArray.cbegin(); searchIt != _searchPathArray.cend(); ++searchIt)
    {
        for (auto resolutionIt = _searchResolutionsOrderArray.cbegin(); resolutionIt != _searchResolutionsOrderArray.cend(); ++resolutionIt)
        {
            fullpath = this->getPathForFilename(newFilename, *resolutionIt, *searchIt);
            
            if (fullpath.length() > 0)
            {
                // Using the filename passed in as key.
                _fullPathCache.insert(std::make_pair(filename, fullpath));
                return fullpath;
            }
        }
    }
    
    CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", filename.c_str());

    // XXX: Should it return nullptr ? or an empty string ?
    // The file wasn't found, return the file name passed in.
    return filename;
}



/**
   获取文件的路径
   @param 文件名
   @param 文件夹
   @param 文件路径
*/
std::string FileUtils::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath)
{
    std::string file = filename;
    std::string file_path = "";
    size_t pos = filename.find_last_of("/");   //找到文件名匹配“/”最后一个字符的索引,没有返回npos
    if (pos != std::string::npos)
    {
        file_path = filename.substr(0, pos+1);  //截取字符串获得文件路径
        file = filename.substr(pos+1);          //截取字符串获得文件名
    }
    
    // searchPath + file_path + resourceDirectory   搜索路径 + 文件路径 + 资源文件夹
    std::string path = searchPath;
    path += file_path;
    path += resolutionDirectory;
    //获取目录的完整路径和文件名。调用相应平台的获取路径的方法。
    path = getFullPathForDirectoryAndFilename(path, file);
    
    //CCLOG("getPathForFilename, fullPath = %s", path.c_str());
    return path;
}




static Data getData(const std::string& filename, bool forString)
{
    if (filename.empty())
    {
        return Data::Null;
    }
    
    Data ret;
    unsigned char* buffer = nullptr;
    ssize_t size = 0;
    const char* mode = nullptr;  //文件读取模式
    if (forString)
        mode = "rt";
    else
        mode = "rb";
    
    do
    {
        // Read the file from hardware   从硬件读取文件
        std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
        FILE *fp = fopen(fullPath.c_str(), mode);
        CC_BREAK_IF(!fp);
        fseek(fp,0,SEEK_END); //移动文件指针到指定的位置。fp是文件的指针,0 是起源的字节,SEEK_END 文件尾,从文件头读到文件尾
        size = ftell(fp);  //获取当前文件指针的位置。
        fseek(fp,0,SEEK_SET);  //从文件头读到文件开始处
        
        if (forString)
        {
            buffer = (unsigned char*)malloc(sizeof(unsigned char) * (size + 1));  //分配内存
            buffer[size] = '\0';   //某位加'\0',可能表示结束吧
        }
        else
        {
            buffer = (unsigned char*)malloc(sizeof(unsigned char) * size);
        }
        
        size = fread(buffer, sizeof(unsigned char), size, fp);  //读取文件
        fclose(fp);  //关闭文件
    } while (0);
    
    if (nullptr == buffer || 0 == size)
    {
        std::string msg = "Get data from file(";
        msg.append(filename).append(") failed!");
        CCLOG("%s", msg.c_str());
    }
    else
    {
        ret.fastSet(buffer, size);  //设置Data的数据 _bytes = bytes;  _size = size;
    }
    
    return ret;
}



// 返回data的字节
std::string FileUtils::getStringFromFile(const std::string& filename)
{
    Data data = getData(filename, true);
    if (data.isNull())
    	return "";
    
    std::string ret((const char*)data.getBytes());
    return ret;
}



bool GLProgram::initWithByteArrays(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray)
{

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    GLboolean hasCompiler = false;
    glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
    _hasShaderCompiler = (hasCompiler == GL_TRUE);

    if(!_hasShaderCompiler)
    {
        return initWithPrecompiledProgramByteArray(vShaderByteArray,fShaderByteArray);
    }
#endif
    //创建一个空程序对象并返回一个它可以引用的非0值。
    _program = glCreateProgram();
   //openGL 的错误输出
    CHECK_GL_ERROR_DEBUG();

    _vertShader = _fragShader = 0;

    if (vShaderByteArray)
    {
        if (!compileShader(&_vertShader, GL_VERTEX_SHADER, vShaderByteArray))
        {
            CCLOG("cocos2d: ERROR: Failed to compile vertex shader");
            return false;
       }
    }

    // Create and compile fragment shader
    if (fShaderByteArray)
    {
        if (!compileShader(&_fragShader, GL_FRAGMENT_SHADER, fShaderByteArray))
        {
            CCLOG("cocos2d: ERROR: Failed to compile fragment shader");
            return false;
        }
    }

    if (_vertShader)
    {
  
//将一个着色器对象绑定到一个程度对象
        glAttachShader(_program, _vertShader);
    }
    CHECK_GL_ERROR_DEBUG();

    if (_fragShader)
    {
        glAttachShader(_program, _fragShader);
    }
    _hashForUniforms = nullptr;
    
    CHECK_GL_ERROR_DEBUG();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    _shaderId = CCPrecompiledShaders::getInstance()->addShaders(vShaderByteArray, fShaderByteArray);
#endif

    return true;
}


注意 : 

 CHECK_GL_ERROR_DEBUG(); 是OpenGL得debug错误输出,有用



// 编译着色器
bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source)
{
    GLint status;
 
    if (!source)
    {
        return false;
    }
   //修改在特定平台下的type值,并添加上一些着色器的代码
    const GLchar *sources[] = {
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_LINUX && CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
        (type == GL_VERTEX_SHADER ? "precision highp float;\n" : "precision mediump float;\n"),
#endif
        "uniform mat4 CC_PMatrix;\n"
        "uniform mat4 CC_MVMatrix;\n"
        "uniform mat4 CC_MVPMatrix;\n"
        "uniform vec4 CC_Time;\n"
        "uniform vec4 CC_SinTime;\n"
        "uniform vec4 CC_CosTime;\n"
        "uniform vec4 CC_Random01;\n"
        "uniform sampler2D CC_Texture0;\n"
        "uniform sampler2D CC_Texture1;\n"
        "uniform sampler2D CC_Texture2;\n"
        "uniform sampler2D CC_Texture3;\n"
        "//CC INCLUDES END\n\n",
        source,
    };
    //创建一个着色器对象
    *shader = glCreateShader(type);
// 替换一个着色器对象中的源代码。
第一个参数:指定源代码被替换你的着色器对象的句柄,
第二个参数:指定string和length数组中得元素数量,
第三个参数:指定一个包含将要被载入着色器源代码的字符串的指针数组
第四个参数:指定字符串长度数组。
//着色器对象中原来存储的任何源代码将完全被替换。
//如果最后一个参数为nullptr,那么每个字符串将被假定以空结束符结束。否则,它将指向一个为每一个string的相应元素包含一个字符串长度的数组
    glShaderSource(*shader, sizeof(sources)/sizeof(*sources), sources, nullptr);
<span style="font-family: Arial, Helvetica, sans-serif;">//编译一个着色器对象,编译已经被存储到有shader指定的着色器对象的源代码字符串。 P519 opengl超级宝典</span>
    glCompileShader(*shader);

// 返回一个来自着色器对象的参数
// GL_COMPILE_STATUS  在最后一次着色器上编译操作成功的情况下返回GL_TURE,否则返回GL_FALSE。
 P602 超级宝典
    glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);

    if (! status)
    {
        GLsizei length;
// 获取被请去用来存储返回源代码字符串的缓冲区的大小
        glGetShaderiv(*shader, GL_SHADER_SOURCE_LENGTH, &lengt
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: cocos2d-x是一款流行的开源游戏引擎,它可以用作开发本地移动游戏和桌面游戏。利用cocos2d-x游戏源码,开发人员可以快速构建流畅、高效、具有吸引力的游戏。该引擎使用C ++语言和脚本语言Lua来实现游戏开发,用户可以根据自己的需要进行选择。 cocos2d-x游戏源码包含许多强大的功能和工具,例如精灵、动画、场景管理、碰撞检测和音频控制等。通过这些功能,开发人员可以方便地创建各种类型的游戏,例如动作游戏、射击游戏、冒险游戏和益智游戏等。 此外,cocos2d-x游戏源码还具有高度定制化的特性,允许开发人员根据他们的需求自定义游戏元素。这种定制化可以通过改进游戏画面,添加新的模式和关卡,甚至整个新的游戏玩法来完成。 总之,cocos2d-x游戏源码是一款功能强大、易于使用和高度定制的游戏引擎,它可以帮助开发人员快速开发各种类型的游戏。无论你是专业开发人员还是无经验的游戏制作者,cocos2d-x都是一个极好的选择。 ### 回答2: Cocos2d-x游戏源码是使用Cocos2d-x引擎进行开发的游戏程序代码。Cocos2d-x引擎是一个开源的跨平台游戏引擎,可以支持iOS、Android、Windows Phone、Windows、MacOS和Linux等多个平台,并且提供了丰富的游戏开发API和工具集。Cocos2d-x游戏源码包含了游戏的核心逻辑、UI设计、动画效果、音频效果等各方面的代码,可以作为开发者学习和借鉴的重要资料。 由于Cocos2d-x引擎支持多种编程语言(如C++、Lua等),因此Cocos2d-x游戏源码也会有对应的编程语言版本。开发者可以通过阅读Cocos2d-x游戏源码,了解游戏开发过程中的技术细节,学习如何使用Cocos2d-x引擎进行游戏开发。同时,开发者也可以通过对Cocos2d-x游戏源码进行修改和优化,来满足游戏的特定需求,提升游戏的性能和用户体验。 总之,Cocos2d-x游戏源码是游戏开发者必备的重要资源,可以帮助开发者更好地了解游戏开发技术,提升游戏开发水平。 ### 回答3: cocos2d-x是一款优秀的游戏开发引擎,其源码包含了许多功能强大的游戏开发工具和API。使用cocos2d-x可以帮助开发者更快速更高效地开发出优秀的游戏作品。 cocos2d-x的游戏源码非常丰富,其包含了许多不同类型的游戏示例和模板,如平面射击、塔防、解谜等,这些示例可以帮助开发者更好地了解cocos2d-x的使用方法和原理。 cocos2d-x源码还包含了许多强大的API和工具,例如场景管理、动画控制、音频引擎等,这些工具和API能够帮助开发者更好地完成游戏的开发和调试。 此外,cocos2d-x源码还提供了完整的游戏开发框架,包括资源管理、内存管理、事件机制等,这些框架可以帮助开发者更好地组织代码和提高代码的可维护性。 总的来说,cocos2d-x游戏源码提供了丰富的工具和API,可以帮助开发者更高效地进行游戏开发,大大降低了开发难度和成本,是一款非常适合游戏开发者使用的引擎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值