예제 #1
0
파일: Text.cpp 프로젝트: dtbinh/Game3D
Text* Text::create(Properties* properties)
{
    // Check if the Properties is valid and has a valid namespace.
    if (!properties || strcmp(properties->getNamespace(), "text") != 0)
    {
        GP_ERROR("Properties object must be non-null and have namespace equal to 'text'.");
        return NULL;
    }

    // Get font path.
    const char* fontPath = properties->getString("font");
    if (fontPath == NULL || strlen(fontPath) == 0)
    {
        GP_ERROR("Text is missing required font file path.");
        return NULL;
    }

    // Get text
    const char* text = properties->getString("text");
    if (text == NULL || strlen(text) == 0)
    {
        GP_ERROR("Text is missing required 'text' value.");
        return NULL;
    }

    // Get size
    int size = properties->getInt("size"); // Default return is 0 if a value doesn't exist
    if (size < 0)
    {
        GP_WARN("Text size must be a positive value, with zero being default font size. Using default font size.");
        size = 0;
    }

    // Get text color
    kmVec4 color = { 1.0f, 1.0f ,1.0f, 1.0f };
    if (properties->exists("color"))
    {
        switch (properties->getType("color"))
        {
        case Properties::VECTOR3:
            color.w = 1.0f;
            properties->getVector3("color", (kmVec3*)&color);
            break;
        case Properties::VECTOR4:
            properties->getVector4("color", &color);
            break;
        case Properties::STRING:
        default:
            properties->getColor("color", &color);
            break;
        }
    }

    // Create
    return Text::create(fontPath, text, color, size);
}
예제 #2
0
Effect* Effect::createFromFile(const char* vshPath, const char* fshPath, const char* defines)
{
    GP_ASSERT(vshPath);
    GP_ASSERT(fshPath);

    // Search the effect cache for an identical effect that is already loaded.
    std::string uniqueId = vshPath;
    uniqueId += ';';
    uniqueId += fshPath;
    uniqueId += ';';
    if (defines)
    {
        uniqueId += defines;
    }
    std::map<std::string, Effect*>::const_iterator itr = __effectCache.find(uniqueId);
    if (itr != __effectCache.end())
    {
        // Found an exiting effect with this id, so increase its ref count and return it.
        GP_ASSERT(itr->second);
        itr->second->addRef();
        return itr->second;
    }

    // Read source from file.
    char* vshSource = FileSystem::readAll(vshPath);
    if (vshSource == NULL)
    {
        GP_ERROR("Failed to read vertex shader from file '%s'.", vshPath);
        return NULL;
    }
    char* fshSource = FileSystem::readAll(fshPath);
    if (fshSource == NULL)
    {
        GP_ERROR("Failed to read fragment shader from file '%s'.", fshPath);
        SAFE_DELETE_ARRAY(vshSource);
        return NULL;
    }

    Effect* effect = createFromSource(vshPath, vshSource, fshPath, fshSource, defines);
    
    SAFE_DELETE_ARRAY(vshSource);
    SAFE_DELETE_ARRAY(fshSource);

    if (effect == NULL)
    {
        GP_ERROR("Failed to create effect from shaders '%s', '%s'.", vshPath, fshPath);
    }
    else
    {
        // Store this effect in the cache.
        effect->_id = uniqueId;
        __effectCache[uniqueId] = effect;
    }

    return effect;
}
예제 #3
0
파일: Label.cpp 프로젝트: reven86/GamePlay
void Label::addListener(Control::Listener* listener, int eventFlags)
{
    if ((eventFlags & Control::Listener::TEXT_CHANGED) == Control::Listener::TEXT_CHANGED)
    {
        GP_ERROR("TEXT_CHANGED event is not applicable to this control.");
    }
    if ((eventFlags & Control::Listener::VALUE_CHANGED) == Control::Listener::VALUE_CHANGED)
    {
        GP_ERROR("VALUE_CHANGED event is not applicable to this control.");
    }

    Control::addListener(listener, eventFlags);
}
예제 #4
0
void FileSystem::createFileFromAsset(const char* path)
{
#ifdef __ANDROID__
    static std::set<std::string> upToDateAssets;

    GP_ASSERT(path);
    std::string fullPath(__resourcePath);
    std::string resolvedPath = FileSystem::resolvePath(path);
    fullPath += resolvedPath;

    std::string directoryPath = fullPath.substr(0, fullPath.rfind('/'));
    struct stat s;
    if (stat(directoryPath.c_str(), &s) != 0)
        makepath(directoryPath, 0777);

    // To ensure that the files on the file system corresponding to the assets in the APK bundle
    // are always up to date (and in sync), we copy them from the APK to the file system once
    // for each time the process (game) runs.
    if (upToDateAssets.find(fullPath) == upToDateAssets.end())
    {
        AAsset* asset = AAssetManager_open(__assetManager, resolvedPath.c_str(), AASSET_MODE_RANDOM);
        if (asset)
        {
            const void* data = AAsset_getBuffer(asset);
            int length = AAsset_getLength(asset);
            FILE* file = fopen(fullPath.c_str(), "wb");
            if (file != NULL)
            {
                int ret = fwrite(data, sizeof(unsigned char), length, file);
                if (fclose(file) != 0)
                {
                    GP_ERROR("Failed to close file on file system created from APK asset '%s'.", path);
                    return;
                }
                if (ret != length)
                {
                    GP_ERROR("Failed to write all data from APK asset '%s' to file on file system.", path);
                    return;
                }
            }
            else
            {
                GP_ERROR("Failed to create file on file system from APK asset '%s'.", path);
                return;
            }

            upToDateAssets.insert(fullPath);
        }
    }
#endif
}
예제 #5
0
char* FileSystem::readAll(const char* filePath, int* fileSize)
{
    GP_ASSERT(filePath);

    // Open file for reading.
    FILE* file = openFile(filePath, "rb");
    if (file == NULL)
    {
        GP_ERROR("Failed to load file: %s", filePath);
        return NULL;
    }

    // Obtain file length.
    if (fseek(file, 0, SEEK_END) != 0)
    {
        GP_ERROR("Failed to seek to the end of the file '%s' to obtain the file length.", filePath);
        return NULL;
    }
    int size = (int)ftell(file);
    if (fseek(file, 0, SEEK_SET) != 0)
    {
        GP_ERROR("Failed to seek to beginning of the file '%s' to begin reading in the entire file.", filePath);
        return NULL;
    }

    // Read entire file contents.
    char* buffer = new char[size + 1];
    int read = (int)fread(buffer, 1, size, file);
    if (read != size)
    {
        GP_ERROR("Failed to read complete contents of file '%s' (amount read vs. file size: %d < %d).", filePath, (int)read, (int)size);
        SAFE_DELETE_ARRAY(buffer);
        return NULL;
    }

    // Force the character buffer to be NULL-terminated.
    buffer[size] = '\0';

    // Close file and return.
    if (fclose(file) != 0)
    {
        GP_ERROR("Failed to close file '%s'.", filePath);
    }

    if (fileSize)
    {
        *fileSize = size; 
    }
    return buffer;
}
예제 #6
0
AudioSource* AudioSource::clone(NodeCloneContext &context) const
{
    GP_ASSERT(_buffer);

    ALuint alSource = 0;
    AL_CHECK( alGenSources(1, &alSource) );
    if (AL_LAST_ERROR())
    {
        GP_ERROR("Error generating audio source.");
        return NULL;
    }
    AudioSource* audioClone = new AudioSource(_buffer, alSource);

    _buffer->addRef();
    audioClone->setLooped(isLooped());
    audioClone->setGain(getGain());
    audioClone->setPitch(getPitch());
    audioClone->setVelocity(getVelocity());
    if (Node* node = getNode())
    {
        Node* clonedNode = context.findClonedNode(node);
        if (clonedNode)
        {
            audioClone->setNode(clonedNode);
        }
    }
    return audioClone;
}
예제 #7
0
static void makepath(std::string path, int mode)
{
    std::vector<std::string> dirs;
    while (path.length() > 0)
    {
        int index = path.find('/');
        std::string dir = (index == -1 ) ? path : path.substr(0, index);
        if (dir.length() > 0)
            dirs.push_back(dir);
        
        if (index + 1 >= path.length() || index == -1)
            break;
            
        path = path.substr(index + 1);
    }
    
    struct stat s;
    std::string dirPath;
    for (unsigned int i = 0; i < dirs.size(); i++)
    {
        dirPath += "/";
        dirPath += dirs[i];
        if (stat(dirPath.c_str(), &s) != 0)
        {
            // Directory does not exist.
            if (mkdir(dirPath.c_str(), 0777) != 0)
            {
                GP_ERROR("Failed to create directory: '%s'", dirPath.c_str());
                return;
            }
        }
    }
    return;
}
예제 #8
0
void ParticleEmitter::setTextureBlending(TextureBlending textureBlending)
{
    GP_ASSERT(_spriteBatch);
    GP_ASSERT(_spriteBatch->getStateBlock());

    switch (textureBlending)
    {
        case BLEND_OPAQUE:
            _spriteBatch->getStateBlock()->setBlend(false);
            break;
        case BLEND_TRANSPARENT:
            _spriteBatch->getStateBlock()->setBlend(true);
            _spriteBatch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
            _spriteBatch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
            break;
        case BLEND_ADDITIVE:
            _spriteBatch->getStateBlock()->setBlend(true);
            _spriteBatch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
            _spriteBatch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE);
            break;
        case BLEND_MULTIPLIED:
            _spriteBatch->getStateBlock()->setBlend(true);
            _spriteBatch->getStateBlock()->setBlendSrc(RenderState::BLEND_ZERO);
            _spriteBatch->getStateBlock()->setBlendDst(RenderState::BLEND_SRC_COLOR);
            break;
        default:
            GP_ERROR("Unsupported texture blending mode (%d).", textureBlending);
            break;
    }
}
예제 #9
0
void RenderState::StateBlock::setState(const char* name, const char* value)
{
    GP_ASSERT(name);

    if (strcmp(name, "blend") == 0)
    {
        setBlend(parseBoolean(value));
    }
    else if (strcmp(name, "blendSrc") == 0 || strcmp(name, "srcBlend") == 0 )   // Leaving srcBlend for backward compat.
    {
        setBlendSrc(parseBlend(value));
    }
    else if (strcmp(name, "blendDst") == 0 || strcmp(name, "dstBlend") == 0)    // // Leaving dstBlend for backward compat.
    {
        setBlendDst(parseBlend(value));
    }
    else if (strcmp(name, "cullFace") == 0)
    {
        setCullFace(parseBoolean(value));
    }
    else if (strcmp(name, "depthTest") == 0)
    {
        setDepthTest(parseBoolean(value));
    }
    else if (strcmp(name, "depthWrite") == 0)
    {
        setDepthWrite(parseBoolean(value));
    }
    else
    {
        GP_ERROR("Unsupported render state string '%s'.", name);
    }
}
예제 #10
0
/**
 * Creates a triangle mesh with vertex colors.
 */
static Mesh* createTriangleMesh()
{
    // Calculate the vertices of the equilateral triangle.
    float a = 0.5f;     // length of the side
    Vector2 p1(0.0f,       a / sqrtf(3.0f));
    Vector2 p2(-a / 2.0f, -a / (2.0f * sqrtf(3.0f)));
    Vector2 p3( a / 2.0f, -a / (2.0f * sqrtf(3.0f)));

    // Create 3 vertices. Each vertex has position (x, y, z) and color (red, green, blue)
    float vertices[] =
    {
        p1.x, p1.y, 0.0f,     1.0f, 0.0f, 0.0f,
        p2.x, p2.y, 0.0f,     0.0f, 1.0f, 0.0f,
        p3.x, p3.y, 0.0f,     0.0f, 0.0f, 1.0f,
    };
    unsigned int vertexCount = 3;
    VertexFormat::Element elements[] =
    {
        VertexFormat::Element(VertexFormat::POSITION, 3),
        VertexFormat::Element(VertexFormat::COLOR, 3)
    };
    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
    if (mesh == NULL)
    {
        GP_ERROR("Failed to create mesh.");
        return NULL;
    }
    mesh->setPrimitiveType(Mesh::TRIANGLES);
    mesh->setVertexData(vertices, 0, vertexCount);
    return mesh;
}
예제 #11
0
static Mesh* createLineStripMesh()
{
    float a = 0.1f;
    float vertices[] = 
    {
        0,  0,  0,    1, 0, 0,
        a,  0, -a,    0, 1, 0,
        0, -a,  a,    0, 0, 1,
       -a,  0, -a,    1, 0, 1,
        0,  a,  a,    0, 1, 1,
    };

    unsigned int vertexCount = 5;
    VertexFormat::Element elements[] =
    {
        VertexFormat::Element(VertexFormat::POSITION, 3),
        VertexFormat::Element(VertexFormat::COLOR, 3)
    };
    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
    if (mesh == NULL)
    {
        GP_ERROR("Failed to create mesh.");
        return NULL;
    }
    mesh->setPrimitiveType(Mesh::LINE_STRIP);
    mesh->setVertexData(vertices, 0, vertexCount);
    return mesh;
}
예제 #12
0
void ParticleEmitter::setBlendMode(BlendMode blendMode)
{
    GP_ASSERT(_spriteBatch);
    GP_ASSERT(_spriteBatch->getStateBlock());

    switch (blendMode)
    {
        case BLEND_NONE:
            _spriteBatch->getStateBlock()->setBlend(false);
            break;
        case BLEND_ALPHA:
            _spriteBatch->getStateBlock()->setBlend(true);
            _spriteBatch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
            _spriteBatch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
            break;
        case BLEND_ADDITIVE:
            _spriteBatch->getStateBlock()->setBlend(true);
            _spriteBatch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
            _spriteBatch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE);
            break;
        case BLEND_MULTIPLIED:
            _spriteBatch->getStateBlock()->setBlend(true);
            _spriteBatch->getStateBlock()->setBlendSrc(RenderState::BLEND_ZERO);
            _spriteBatch->getStateBlock()->setBlendDst(RenderState::BLEND_SRC_COLOR);
            break;
        default:
            GP_ERROR("Unsupported blend mode (%d).", blendMode);
            break;
    }

    _spriteBlendMode = blendMode;
}
예제 #13
0
파일: Mesh.cpp 프로젝트: 03050903/GamePlay
Mesh* Mesh::createQuadFullscreen()
{
    float x = -1.0f;
    float y = -1.0f;
    float x2 = 1.0f;
    float y2 = 1.0f;

    float vertices[] =
    {
        x, y2,   0, 1,
        x, y,    0, 0,
        x2, y2,  1, 1,
        x2, y,   1, 0
    };

    VertexFormat::Element elements[] =
    {
        VertexFormat::Element(VertexFormat::POSITION, 2),
        VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
    };
    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), 4, false);
    if (mesh == NULL)
    {
        GP_ERROR("Failed to create mesh.");
        return NULL;
    }

    mesh->_primitiveType = TRIANGLE_STRIP;
    mesh->setVertexData(vertices, 0, 4);

    return mesh;
}
예제 #14
0
파일: Mesh.cpp 프로젝트: 03050903/GamePlay
Mesh* Mesh::createQuad(float x, float y, float width, float height, float s1, float t1, float s2, float t2)
{
    float x2 = x + width;
    float y2 = y + height;

    float vertices[] =
    {
        x, y2, 0,   0, 0, 1,    s1, t2,
        x, y, 0,    0, 0, 1,    s1, t1,
        x2, y2, 0,  0, 0, 1,    s2, t2,
        x2, y, 0,   0, 0, 1,    s2, t1,
    };

    VertexFormat::Element elements[] =
    {
        VertexFormat::Element(VertexFormat::POSITION, 3),
        VertexFormat::Element(VertexFormat::NORMAL, 3),
        VertexFormat::Element(VertexFormat::TEXCOORD0, 2)
    };
    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 3), 4, false);
    if (mesh == NULL)
    {
        GP_ERROR("Failed to create mesh.");
        return NULL;
    }

    mesh->_primitiveType = TRIANGLE_STRIP;
    mesh->setVertexData(vertices, 0, 4);

    return mesh;
}
예제 #15
0
파일: Mesh.cpp 프로젝트: 03050903/GamePlay
Mesh* Mesh::createLines(Vector3* points, unsigned int pointCount)
{
    GP_ASSERT(points);
    GP_ASSERT(pointCount);

    float* vertices = new float[pointCount*3];
    memcpy(vertices, points, pointCount*3*sizeof(float));

    VertexFormat::Element elements[] =
    {
        VertexFormat::Element(VertexFormat::POSITION, 3)
    };
    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 1), pointCount, false);
    if (mesh == NULL)
    {
        GP_ERROR("Failed to create mesh.");
        SAFE_DELETE_ARRAY(vertices);
        return NULL;
    }

    mesh->_primitiveType = LINE_STRIP;
    mesh->setVertexData(vertices, 0, pointCount);

    SAFE_DELETE_ARRAY(vertices);
    return mesh;
}
예제 #16
0
static Mesh* createPointsMesh()
{
    float scale = 0.2f;
    unsigned int vertexCount = 100;

    std::vector<float> vertices;
    vertices.reserve(vertexCount * 6);
    for (unsigned int i = 0; i < vertexCount; ++i)
    {
        // x, y, z, r, g, b
        vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
        vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
        vertices.push_back(MATH_RANDOM_MINUS1_1() * scale);
        vertices.push_back(MATH_RANDOM_0_1());
        vertices.push_back(MATH_RANDOM_0_1());
        vertices.push_back(MATH_RANDOM_0_1()); 
    }
    
    VertexFormat::Element elements[] =
    {
        VertexFormat::Element(VertexFormat::POSITION, 3),
        VertexFormat::Element(VertexFormat::COLOR, 3)
    };
    Mesh* mesh = Mesh::createMesh(VertexFormat(elements, 2), vertexCount, false);
    if (mesh == NULL)
    {
        GP_ERROR("Failed to create mesh.");
        return NULL;
    }
    mesh->setPrimitiveType(Mesh::POINTS);
    mesh->setVertexData(&vertices[0], 0, vertexCount);
    return mesh;
}
예제 #17
0
bool Material::loadTechnique(Material* material, Properties* techniqueProperties)
{
    GP_ASSERT(material);
    GP_ASSERT(techniqueProperties);

    // Create a new technique.
    Technique* technique = new Technique(techniqueProperties->getId(), material);

    // Go through all the properties and create passes under this technique.
    techniqueProperties->rewind();
    Properties* passProperties = NULL;
    while ((passProperties = techniqueProperties->getNextNamespace()))
    {
        if (strcmp(passProperties->getNamespace(), "pass") == 0)
        {
            // Create and load passes.
            if (!loadPass(technique, passProperties))
            {
                GP_ERROR("Failed to create pass for technique.");
                SAFE_RELEASE(technique);
                return false;
            }
        }
    }

    // Load uniform value parameters for this technique.
    loadRenderState(technique, techniqueProperties);

    // Add the new technique to the material.
    material->_techniques.push_back(technique);

    return true;
}
예제 #18
0
bool Material::loadPass(Technique* technique, Properties* passProperties)
{
    GP_ASSERT(passProperties);
    GP_ASSERT(technique);

    // Fetch shader info required to create the effect of this technique.
    const char* vertexShaderPath = passProperties->getString("vertexShader");
    GP_ASSERT(vertexShaderPath);
    const char* fragmentShaderPath = passProperties->getString("fragmentShader");
    GP_ASSERT(fragmentShaderPath);
    const char* defines = passProperties->getString("defines");

    // Create the pass.
    Pass* pass = Pass::create(passProperties->getId(), technique, vertexShaderPath, fragmentShaderPath, defines);
    if (!pass)
    {
        GP_ERROR("Failed to create pass for technique.");
        return false;
    }

    // Load render state.
    loadRenderState(pass, passProperties);

    // Add the new pass to the technique.
    technique->_passes.push_back(pass);

    return true;
}
예제 #19
0
void Matrix::createPerspective(float fieldOfView, float aspectRatio,
                                     float zNearPlane, float zFarPlane, Matrix* dst)
{
    GP_ASSERT(dst);
    GP_ASSERT(zFarPlane != zNearPlane);

    float f_n = 1.0f / (zFarPlane - zNearPlane);
    float theta = MATH_DEG_TO_RAD(fieldOfView) * 0.5f;
    if (fabs(fmod(theta, MATH_PIOVER2)) < MATH_EPSILON)
    {
        GP_ERROR("Invalid field of view value (%d) causes attempted calculation tan(%d), which is undefined.", fieldOfView, theta);
        return;
    }
    float divisor = tan(theta);
    GP_ASSERT(divisor);
    float factor = 1.0f / divisor;

    memset(dst, 0, MATRIX_SIZE);

    GP_ASSERT(aspectRatio);
    dst->m[0] = (1.0f / aspectRatio) * factor;
    dst->m[5] = factor;
    dst->m[10] = (-(zFarPlane + zNearPlane)) * f_n;
    dst->m[11] = -1.0f;
    dst->m[14] = -2.0f * zFarPlane * zNearPlane * f_n;
}
예제 #20
0
void MeshPart::setIndexData(void* indexData, unsigned int indexStart, unsigned int indexCount)
{
    GL_ASSERT( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer) );

    unsigned int indexSize = 0;
    switch (_indexFormat)
    {
    case Mesh::INDEX8:
        indexSize = 1;
        break;
    case Mesh::INDEX16:
        indexSize = 2;
        break;
    case Mesh::INDEX32:
        indexSize = 4;
        break;
    default:
        GP_ERROR("Unsupported index format (%d).", _indexFormat);
        return;
    }

    if (indexStart == 0 && indexCount == 0)
    {
        GL_ASSERT( glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * _indexCount, indexData, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) );
    }
    else
    {
        if (indexCount == 0)
        {
            indexCount = _indexCount - indexStart;
        }

        GL_ASSERT( glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, indexStart * indexSize, indexCount * indexSize, indexData) );
    }
}
예제 #21
0
static bool parseFlipFlags(const char* str, Sprite::FlipFlags* flip)
{
    GP_ASSERT(flip);

    if (!str)
    {
        *flip = Sprite::FLIP_NONE;
        return false;
    }

    if (strcmp(str, "FLIP_VERTICAL") == 0)
    {
        *flip = Sprite::FLIP_VERTICAL;
    }
    else if (strcmp(str, "FLIP_HORIZONTAL") == 0)
    {
        *flip = Sprite::FLIP_HORIZONTAL;
    }
    else if (strcmp(str, "FLIP_VERTICAL_HORIZONTAL") == 0)
    {
        *flip = (Sprite::FlipFlags)(Sprite::FLIP_VERTICAL | Sprite::FLIP_HORIZONTAL);
    }
    else if (strcmp(str, "FLIP_NONE") != 0)
    {
        GP_ERROR("Failed to get corresponding sprite flip flag for unsupported value '%s'.", str);
        *flip = Sprite::FLIP_NONE;
        return false;
    }
    else
    {
        *flip = Sprite::FLIP_NONE;
    }

    return true;
}
예제 #22
0
static RenderState::Blend parseBlend(const char* value)
{
    GP_ASSERT(value);

    // Convert the string to uppercase for comparison.
    std::string upper(value);
    std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
    if (upper == "ZERO")
        return RenderState::BLEND_ZERO;
    else if (upper == "ONE")
        return RenderState::BLEND_ONE;
    else if (upper == "SRC_ALPHA")
        return RenderState::BLEND_SRC_ALPHA;
    else if (upper == "ONE_MINUS_SRC_ALPHA")
        return RenderState::BLEND_ONE_MINUS_SRC_ALPHA;
    else if (upper == "DST_ALPHA")
        return RenderState::BLEND_DST_ALPHA;
    else if (upper == "ONE_MINUS_DST_ALPHA")
        return RenderState::BLEND_ONE_MINUS_DST_ALPHA;
    else if (upper == "CONSTANT_ALPHA")
        return RenderState::BLEND_CONSTANT_ALPHA;
    else if (upper == "ONE_MINUS_CONSTANT_ALPHA")
        return RenderState::BLEND_ONE_MINUS_CONSTANT_ALPHA;
    else if (upper == "SRC_ALPHA_SATURATE")
        return RenderState::BLEND_SRC_ALPHA_SATURATE;
    else
    {
        GP_ERROR("Unsupported blend value (%s). (Will default to BLEND_ONE if errors are treated as warnings)", value);
        return RenderState::BLEND_ONE;
    }
}
예제 #23
0
void Sprite::setBlendMode(BlendMode mode)
{
    switch (mode)
    {
    case BLEND_NONE:
        _batch->getStateBlock()->setBlend(false);
        break;
    case BLEND_ALPHA:
        _batch->getStateBlock()->setBlend(true);
        _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
        _batch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE_MINUS_SRC_ALPHA);
        break;
    case BLEND_ADDITIVE:
        _batch->getStateBlock()->setBlend(true);
        _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_SRC_ALPHA);
        _batch->getStateBlock()->setBlendDst(RenderState::BLEND_ONE);
        break;
    case BLEND_MULTIPLIED:
        _batch->getStateBlock()->setBlend(true);
        _batch->getStateBlock()->setBlendSrc(RenderState::BLEND_ZERO);
        _batch->getStateBlock()->setBlendDst(RenderState::BLEND_SRC_COLOR);
        break;
    default:
        GP_ERROR("Unsupported blend mode (%d).", mode);
        break;
    }
}
예제 #24
0
ParticleEmitter* ParticleEmitter::create(const char* textureFile, TextureBlending textureBlending, unsigned int particleCountMax)
{
    Texture* texture = NULL;
    texture = Texture::create(textureFile, false);

    if (!texture)
    {
        GP_ERROR("Failed to create texture for particle emitter.");
        return NULL;
    }
    GP_ASSERT(texture->getWidth());
    GP_ASSERT(texture->getHeight());

    // Use default SpriteBatch material.
    SpriteBatch* batch =  SpriteBatch::create(texture, NULL, particleCountMax);
    texture->release(); // batch owns the texture.
    GP_ASSERT(batch);

    ParticleEmitter* emitter = new ParticleEmitter(batch, particleCountMax);
    GP_ASSERT(emitter);

    // By default assume only one frame which uses the entire texture.
    emitter->setTextureBlending(textureBlending);
    emitter->_spriteTextureWidth = texture->getWidth();
    emitter->_spriteTextureHeight = texture->getHeight();
    emitter->_spriteTextureWidthRatio = 1.0f / (float)texture->getWidth();
    emitter->_spriteTextureHeightRatio = 1.0f / (float)texture->getHeight();

    Rectangle texCoord((float)texture->getWidth(), (float)texture->getHeight());
    emitter->setSpriteFrameCoords(1, &texCoord);

    return emitter;
}
예제 #25
0
static bool parseBlendMode(const char* str, Sprite::BlendMode* blend)
{
    GP_ASSERT(blend);

    if (!str)
    {
        *blend = Sprite::BLEND_NONE;
        return false;
    }

    if (strcmp(str, "BLEND_ALPHA") == 0)
    {
        *blend = Sprite::BLEND_ALPHA;
    }
    else if (strcmp(str, "BLEND_ADDITIVE") == 0)
    {
        *blend = Sprite::BLEND_ADDITIVE;
    }
    else if (strcmp(str, "BLEND_MULTIPLIED") == 0)
    {
        *blend = Sprite::BLEND_MULTIPLIED;
    }
    else if (strcmp(str, "BLEND_NONE") != 0)
    {
        GP_ERROR("Failed to get corresponding sprite blend mode for unsupported value '%s'.", str);
        *blend = Sprite::BLEND_NONE;
        return false;
    }
    else
    {
        *blend = Sprite::BLEND_NONE;
    }

    return true;
}
예제 #26
0
파일: Light.cpp 프로젝트: dtbinh/Game3D
Light* Light::clone(NodeCloneContext &context)
{
    Light* lightClone = NULL;
    switch (_type)
    {
    case DIRECTIONAL:
        lightClone = createDirectional(getColor());
        break;
    case POINT:
        lightClone = createPoint(getColor(), getRange());
        break;
    case SPOT:
        lightClone = createSpot(getColor(), getRange(), getInnerAngle(), getOuterAngle());
        break;
    default:
        GP_ERROR("Unsupported light type (%d).", _type);
        return NULL;
    }
    GP_ASSERT(lightClone);

    if (Node* node = context.findClonedNode(getNode()))
    {
        lightClone->setNode(node);
    }
    return lightClone;
}
예제 #27
0
static RenderState::DepthFunction parseDepthFunc(const char* value)
{
    GP_ASSERT(value);

    // Convert string to uppercase for comparison
    std::string upper(value);
    std::transform(upper.begin(), upper.end(), upper.begin(), (int(*)(int))toupper);
    if (upper == "NEVER")
        return RenderState::DEPTH_NEVER;
    else if (upper == "LESS")
        return RenderState::DEPTH_LESS;
    else if (upper == "EQUAL")
        return RenderState::DEPTH_EQUAL;
    else if (upper == "LEQUAL")
        return RenderState::DEPTH_LEQUAL;
    else if (upper == "GREATER")
        return RenderState::DEPTH_GREATER;
    else if (upper == "NOTEQUAL")
        return RenderState::DEPTH_NOTEQUAL;
    else if (upper == "GEQUAL")
        return RenderState::DEPTH_GEQUAL;
    else if (upper == "ALWAYS")
        return RenderState::DEPTH_ALWAYS;
    else
    {
        GP_ERROR("Unsupported depth function value (%s). Will default to DEPTH_LESS if errors are treated as warnings)", value);
        return RenderState::DEPTH_LESS;
    }
}
예제 #28
0
Container::Scroll Container::getScroll(const char* scroll)
{
    if (!scroll)
        return Container::SCROLL_NONE;

    if (strcmp(scroll, "SCROLL_NONE") == 0)
    {
        return Container::SCROLL_NONE;
    }
    else if (strcmp(scroll, "SCROLL_HORIZONTAL") == 0)
    {
        return Container::SCROLL_HORIZONTAL;
    }
    else if (strcmp(scroll, "SCROLL_VERTICAL") == 0)
    {
        return Container::SCROLL_VERTICAL;
    }
    else if (strcmp(scroll, "SCROLL_BOTH") == 0)
    {
        return Container::SCROLL_BOTH;
    }
    else
    {
        GP_ERROR("Failed to get corresponding scroll state for unsupported value '%s'.", scroll);
    }

    return Container::SCROLL_NONE;
}
예제 #29
0
void MaterialParameter::bind(Effect* effect)
{
    GP_ASSERT(effect);

    // If we had a Uniform cached that is not from the passed in effect,
    // we need to update our uniform to point to the new effect's uniform.
    if (!_uniform || _uniform->getEffect() != effect)
    {
        _uniform = effect->getUniform(_name.c_str());

        if (!_uniform)
        {
            // This parameter was not found in the specified effect, so do nothing.
            GP_WARN("Warning: Material parameter '%s' not found in effect '%s'.", _name.c_str(), effect->getId());
            return;
        }
    }

    switch (_type)
    {
    case MaterialParameter::FLOAT:
        effect->setValue(_uniform, _value.floatValue);
        break;
    case MaterialParameter::FLOAT_ARRAY:
        effect->setValue(_uniform, _value.floatPtrValue, _count);
        break;
    case MaterialParameter::INT:
        effect->setValue(_uniform, _value.intValue);
        break;
    case MaterialParameter::INT_ARRAY:
        effect->setValue(_uniform, _value.intPtrValue, _count);
        break;
    case MaterialParameter::VECTOR2:
        effect->setValue(_uniform, reinterpret_cast<Vector2*>(_value.floatPtrValue), _count);
        break;
    case MaterialParameter::VECTOR3:
        effect->setValue(_uniform, reinterpret_cast<Vector3*>(_value.floatPtrValue), _count);
        break;
    case MaterialParameter::VECTOR4:
        effect->setValue(_uniform, reinterpret_cast<Vector4*>(_value.floatPtrValue), _count);
        break;
    case MaterialParameter::MATRIX:
        effect->setValue(_uniform, reinterpret_cast<Matrix*>(_value.floatPtrValue), _count);
        break;
    case MaterialParameter::SAMPLER:
        effect->setValue(_uniform, _value.samplerValue);
        break;
    case MaterialParameter::SAMPLER_ARRAY:
        effect->setValue(_uniform, _value.samplerArrayValue, _count);
        break;
    case MaterialParameter::METHOD:
        GP_ASSERT(_value.method);
        _value.method->setValue(effect);
        break;
    default:
        GP_ERROR("Unsupported material parameter type (%d).", _type);
        break;
    }
}
예제 #30
0
AudioSource* AudioSource::create(Properties* properties)
{
    // Check if the properties is valid and has a valid namespace.
    GP_ASSERT(properties);
    if (!properties || !(strcmp(properties->getNamespace(), "audio") == 0))
    {
        GP_ERROR("Failed to load audio source from properties object: must be non-null object and have namespace equal to 'audio'.");
        return NULL;
    }

    std::string path;
    if (!properties->getPath("path", &path))
    {
        GP_ERROR("Audio file failed to load; the file path was not specified.");
        return NULL;
    }

    // Create the audio source.
    AudioSource* audio = AudioSource::create(path.c_str());
    if (audio == NULL)
    {
        GP_ERROR("Audio file '%s' failed to load properly.", path.c_str());
        return NULL;
    }

    // Set any properties that the user specified in the .audio file.
    if (properties->exists("looped"))
    {
        audio->setLooped(properties->getBool("looped"));
    }
    if (properties->exists("gain"))
    {
        audio->setGain(properties->getFloat("gain"));
    }
    if (properties->exists("pitch"))
    {
        audio->setPitch(properties->getFloat("pitch"));
    }
    Vector3 v;
    if (properties->getVector3("velocity", &v))
    {
        audio->setVelocity(v);
    }

    return audio;
}