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); }
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; }
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); }
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 }
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; }
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; }
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; }
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; } }
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); } }
/** * 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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) ); } }
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; }
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; } }
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; } }
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; }
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; }
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; }
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; } }
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; }
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; } }
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; }