예제 #1
0
/**
 * @brief Load an image by file name.
 * @param aName Name of the file.
 */
void PCShaderSurface::LoadImage(HashString const &aName)
{
    /* If the file was already loaded,
       let's avoid assigning a new id. */
    TextureData const& textureData = GetManager()->GetTextureData(aName);
    if(textureData.mTextureID != (unsigned)-1)
    {
        mTextureID = textureData.mTextureID;
        SetTextureSize(Vector3(textureData.mWidth, textureData.mHeight, 0));
    }
    // else we load the image from file
    else if((mSurface = IMG_Load(Common::RelativePath("Art", aName).c_str())))
    {
        if ((mSurface->w & (mSurface->w - 1)) != 0 )
        {
            DebugLogPrint("warning: width of image: %s is not a power of 2\n", aName.ToCharArray());
        }

        if ((mSurface->h & (mSurface->h - 1)) != 0 )
        {
            DebugLogPrint("warning: height of image: %s is not a power of 2\n", aName.ToCharArray());
        }

        SetTextureSize(Vector3(mSurface->w, mSurface->h, 0));
        mNumberOfColors = mSurface->format->BytesPerPixel;
        if (mNumberOfColors == 4)
        {
            if (mSurface->format->Rmask == 0x000000ff)
                mTextureFormat = GL_RGBA;
            else
#ifndef _WIN32
                mTextureFormat = GL_BGRA;
#else
                mTextureFormat = GL_RGBA;
#endif
        }
        else if (mNumberOfColors == 3)
        {
            if (mSurface->format->Rmask == 0x000000ff)
                mTextureFormat = GL_RGB;
            else
#ifndef _WIN32
                mTextureFormat = GL_BGR;
#else
                mTextureFormat = GL_RGB;
#endif
        }
        else
        {
            DebugLogPrint("warning: image %s is not truecolor...  this will probably break\n", aName.ToCharArray());
            DebugLogPrint("warning: bytes per pixel for image %s: %d\n", aName.ToCharArray(), mNumberOfColors);
        }

        AddTexturePairing(aName);
    }
    else
    {
        DebugLogPrint("warning: file: %s not found or incompatible format, check this out\n", aName.ToCharArray());
    }
}
예제 #2
0
/**
 * @brief Loads a text surface in font.
 * @param aFont Font to use.
 * @param aText Text to render.
 * @param aForegroundColor Color of the text.
 * @param aBackgroundColor Color of the background.
 * @param aSize Size of font.
 * @param aMaxWidth Max width of a single line (in pixels).
 * @return
 */
Vector3 PCShaderSurface::LoadText(HashString const &aFont, HashString const &aText, Vector4 const &aForegroundColor, Vector4 const &aBackgroundColor, int aSize, int aMaxWidth)
{
    // Endianness is important here
    Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    rmask = 0xff000000;
    gmask = 0x00ff0000;
    bmask = 0x0000ff00;
    amask = 0x000000ff;
#else
    rmask = 0x000000ff;
    gmask = 0x0000ff00;
    bmask = 0x00ff0000;
    amask = 0xff000000;
#endif

    HashString const textureDataHash = aFont + aText + Common::IntToString(aSize);
    TextureData const& data = GetManager()->GetTextureData(textureDataHash);
    if(data.mTextureID != (unsigned)-1)
    {
        Vector3 size = Vector3(data.mWidth, data.mHeight, 0);
        mTextureID = data.mTextureID;
        SetTextureSize(size);
        return size;
    }
    else
    {
        if(!TTF_WasInit())
            TTF_Init();
        mFont = TTF_OpenFont(Common::RelativePath("Fonts", aFont).c_str(), aSize);
        if(!mFont)
        {
            mFont = NULL;
            DebugLogPrint("warning: file not found or incompatible format, check this out\n");
            DebugLogPrint("%s", TTF_GetError());
            return Vector3(0, 0, 0);
        }

        // Create text texture
        SDL_Color fgColor = {(Uint8)aForegroundColor.x, (Uint8)aForegroundColor.y, (Uint8)aForegroundColor.z, (Uint8)aForegroundColor.w};
        //SDL_Color bgColor = {(Uint8)aBackgroundColor.x, (Uint8)aBackgroundColor.y, (Uint8)aBackgroundColor.z, (Uint8)aBackgroundColor.w};
        SDL_Surface *msg = TTF_RenderText_Blended_Wrapped(mFont, aText.ToCharArray(), fgColor, aMaxWidth);
        if(!msg)
        {
            DebugLogPrint("TTF_RenderText failed: %s", TTF_GetError());
            assert(msg);
        }

        mTextureFormat = GL_RGBA;
        mSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, msg->w, msg->h, 32, rmask, gmask, bmask, amask);
        SetTextureSize(Vector3(mSurface->w, mSurface->h, 0));
        SDL_BlitSurface(msg, NULL, mSurface, NULL);

        AddTexturePairing(textureDataHash);

        return Vector3(mSurface->w, mSurface->h, 0);
    }
}
예제 #3
0
/**
 * @brief Load shaders.
 * @param aVertexShaderFilename Name of vertex shader.
 * @param aFragmentShaderFilename Name of fragment shader.
 */
void PCShaderSurface::LoadShaders(HashString const &aVertexShaderFilename, HashString const &aFragmentShaderFilename)
{
    mVertexShaderFileName = aVertexShaderFilename;
    mFragmentShaderFileName = aFragmentShaderFilename;

    HashString shaderKey = aVertexShaderFilename + aFragmentShaderFilename;

    if(GetManager()->ShaderDataExists(shaderKey))
    {
        mProgramID = GetManager()->GetShaderData(shaderKey).mProgramID;
        return;
    }

    std::ifstream vertexFile(Common::RelativePath("Shaders", aVertexShaderFilename.ToCharArray()).c_str());
    std::ifstream fragmentFile(Common::RelativePath("Shaders", aFragmentShaderFilename.ToCharArray()).c_str());
    if(vertexFile.is_open() && fragmentFile.is_open())
    {
        GLenum program = glCreateProgram();
        GLenum vertexShader = glCreateShader(GL_VERTEX_SHADER);
        GLenum fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        GLint didCompile = 0;
        GLint isLinked = 0;

        HashString vertexFileContents = std::string((std::istreambuf_iterator<char>(vertexFile)), std::istreambuf_iterator<char>());
        const char* vertexContents = vertexFileContents.ToCharArray();

        // Compile
        glShaderSource(vertexShader, 1, &vertexContents, NULL);
        glCompileShader(vertexShader);
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &didCompile);
        if(didCompile == GL_FALSE)
        {
            DebugLogPrint("VERTEX SHADER %s READ:\n%s\n", aVertexShaderFilename.ToCharArray(), vertexContents);

            GLint maxLength = 0;
            glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);

            //The maxLength includes the NULL character
            std::vector<char> infoLog(maxLength);
            glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &infoLog[0]);

            DebugLogPrint("GLERROR %s: %s\n", aVertexShaderFilename.ToCharArray(), &infoLog[0]);

            //We don't need the shader anymore.
            glDeleteShader(vertexShader);
        }

        HashString fragmentFileContents = std::string((std::istreambuf_iterator<char>(fragmentFile)), std::istreambuf_iterator<char>());
        const char* fragmentContents = fragmentFileContents.ToCharArray();
        glShaderSource(fragmentShader, 1, &fragmentContents, NULL);
        glCompileShader(fragmentShader);
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &didCompile);
        if(didCompile == GL_FALSE)
        {
            DebugLogPrint("FRAGMENT SHADER %s READ:\n%s\n", aFragmentShaderFilename.ToCharArray(), fragmentContents);

            GLint maxLength = 0;
            glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);

            //The maxLength includes the NULL character
            std::vector<char> infoLog(maxLength);
            glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &infoLog[0]);

            DebugLogPrint("GLERROR %s: %s\n", aFragmentShaderFilename.ToCharArray(), &infoLog[0]);

            //We don't need the shader anymore.
            glDeleteShader(fragmentShader);
        }

        // Linking
        glAttachShader(program, vertexShader);
        glAttachShader(program, fragmentShader);
        glLinkProgram(program);
        glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
        if(isLinked == GL_FALSE)
        {
            GLint maxLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

            //The maxLength includes the NULL character
            std::vector<GLchar> infoLog(maxLength);
            glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);

            //We don't need the program anymore.
            glDeleteProgram(program);
            //Don't leak shaders either.
            glDeleteShader(vertexShader);
            glDeleteShader(fragmentShader);

            DebugLogPrint("GL LINK ERROR: %s\n", &infoLog[0]);
        }

        GetManager()->AddShaderPairing(shaderKey, ShaderData(program, vertexShader, fragmentShader, vertexContents, fragmentContents));

        mProgramID = program;
    }
    else
    {
        DebugLogPrint("No shader with name %s or %s found\n", aVertexShaderFilename.ToCharArray(), aFragmentShaderFilename.ToCharArray());
        assert(!"Shader file not found.");
    }
}