// SetOffset bool Gradient::SetOffset(int32 index, float offset) { BGradient::ColorStop* step = ColorAt(index); if (step && step->offset != offset) { step->offset = offset; Notify(); return true; } return false; }
// SetColor bool Gradient::SetColor(int32 index, const rgb_color& color) { if (BGradient::ColorStop* step = ColorAt(index)) { if ((uint32&)step->color != (uint32&)color) { step->color = color; Notify(); return true; } } return false; }
// // LoadAEArtFile // Purpose: Loads a .AEArt file and places it into the table of image files // IMAGE *LoadAEArtFile( const char *folder, const char *fileName ) { FILE *fp; IMAGE *image = NULL; // Allocate space to concatenate the folder and the fileName together int size = strlen( folder ) + strlen( fileName ) + 2; char *pathName = (char *)malloc( size ); // Copy the folder and fileName into the pathName array strcpy_s( pathName, size, folder ); strcat_s( pathName, size, fileName ); fopen_s( &fp, pathName, "r" ); if(fp) // read image contents in file { int x, y; CHAR *thisChar; COL *thisColor; AE_COORD bottomRight = { 0 }; fscanf_s( fp, "%d", &bottomRight.x_ ); fscanf_s( fp, "%d", &bottomRight.y_ ); image = AllocateImage( fileName, bottomRight.x_, bottomRight.y_ ); for(y = 0; y < bottomRight.y_; ++y) { for(x = 0; x < bottomRight.x_; ++x) { int copy = 0; thisChar = CharAt( image, x, y ); fscanf_s( fp, "%d", © ); *thisChar = (char)copy; } } for(y = 0; y < bottomRight.y_; ++y) { for(x = 0; x < bottomRight.x_; ++x) { int copy = 0; thisColor = ColorAt( image, x, y ); fscanf_s( fp, "%d", © ); *thisColor = (char)copy; } } fclose( fp ); } return image; }
// SetColor bool Gradient::SetColor(int32 index, const BGradient::ColorStop& color) { if (BGradient::ColorStop* step = ColorAt(index)) { if (*step != color) { step->color = color.color; step->offset = color.offset; Notify(); return true; } } return false; }
// PrintToStream void Gradient::PrintToStream() const { printf("Gradient: type: %s, interpolation: %s, inherits transform: %d\n", string_for_type(fType), string_for_interpolation(fInterpolation), fInheritTransformation); for (int32 i = 0; BGradient::ColorStop* step = ColorAt(i); i++) { printf(" %" B_PRId32 ": offset: %.1f -> color(%d, %d, %d, %d)\n", i, step->offset, step->color.red, step->color.green, step->color.blue, step->color.alpha); } }
// Archive status_t Gradient::Archive(BMessage* into, bool deep) const { status_t ret = BArchivable::Archive(into, deep); // transformation if (ret == B_OK) { int32 size = Transformable::matrix_size; double matrix[size]; StoreTo(matrix); ret = into->AddData("transformation", B_DOUBLE_TYPE, matrix, size * sizeof(double)); } // color steps if (ret >= B_OK) { for (int32 i = 0; BGradient::ColorStop* step = ColorAt(i); i++) { ret = into->AddInt32("color", (const uint32&)step->color); if (ret < B_OK) break; ret = into->AddFloat("offset", step->offset); if (ret < B_OK) break; } } // gradient and interpolation type if (ret >= B_OK) ret = into->AddInt32("type", (int32)fType); if (ret >= B_OK) ret = into->AddInt32("interpolation", (int32)fInterpolation); if (ret >= B_OK) ret = into->AddBool("inherit transformation", fInheritTransformation); // finish off if (ret >= B_OK) ret = into->AddString("class", "Gradient"); return ret; }
// MakeGradient void Gradient::MakeGradient(uint32* colors, int32 count) const { BGradient::ColorStop* from = ColorAt(0); if (!from) return; // find the step with the lowest offset for (int32 i = 0; BGradient::ColorStop* step = ColorAt(i); i++) { if (step->offset < from->offset) from = step; } // current index into "colors" array int32 index = (int32)floorf(count * from->offset + 0.5); if (index < 0) index = 0; if (index > count) index = count; // make sure we fill the entire array if (index > 0) { uint8* c = (uint8*)&colors[0]; for (int32 i = 0; i < index; i++) { c[0] = from->color.red; c[1] = from->color.green; c[2] = from->color.blue; c[3] = from->color.alpha; c += 4; } } // put all steps that we need to interpolate to into a list BList nextSteps(fColors.CountItems() - 1); for (int32 i = 0; BGradient::ColorStop* step = ColorAt(i); i++) { if (step != from) nextSteps.AddItem((void*)step); } // interpolate "from" to "to" while (!nextSteps.IsEmpty()) { // find the step with the next offset BGradient::ColorStop* to = NULL; float nextOffsetDist = 2.0; for (int32 i = 0; BGradient::ColorStop* step = (BGradient::ColorStop*)nextSteps.ItemAt(i); i++) { float d = step->offset - from->offset; if (d < nextOffsetDist && d >= 0) { to = step; nextOffsetDist = d; } } if (!to) break; nextSteps.RemoveItem((void*)to); // interpolate int32 offset = (int32)floorf((count - 1) * to->offset + 0.5); if (offset >= count) offset = count - 1; int32 dist = offset - index; if (dist >= 0) { uint8* c = (uint8*)&colors[index]; #if GAMMA_BLEND uint16 fromRed = kGammaTable[from->color.red]; uint16 fromGreen = kGammaTable[from->color.green]; uint16 fromBlue = kGammaTable[from->color.blue]; uint16 toRed = kGammaTable[to->color.red]; uint16 toGreen = kGammaTable[to->color.green]; uint16 toBlue = kGammaTable[to->color.blue]; for (int32 i = index; i <= offset; i++) { float f = (float)(offset - i) / (float)(dist + 1); if (fInterpolation == INTERPOLATION_SMOOTH) f = gauss(1.0 - f); float t = 1.0 - f; c[0] = kInverseGammaTable[(uint16)floor(fromBlue * f + toBlue * t + 0.5)]; c[1] = kInverseGammaTable[(uint16)floor(fromGreen * f + toGreen * t + 0.5)]; c[2] = kInverseGammaTable[(uint16)floor(fromRed * f + toRed * t + 0.5)]; c[3] = (uint8)floor(from->color.alpha * f + to->color.alpha * t + 0.5); c += 4; } #else // GAMMA_BLEND for (int32 i = index; i <= offset; i++) { float f = (float)(offset - i) / (float)(dist + 1); if (fInterpolation == INTERPOLATION_SMOOTH) f = gauss(1.0 - f); float t = 1.0 - f; c[0] = (uint8)floor(from->color.red * f + to->color.red * t + 0.5); c[1] = (uint8)floor(from->color.green * f + to->color.green * t + 0.5); c[2] = (uint8)floor(from->color.blue * f + to->color.blue * t + 0.5); c[3] = (uint8)floor(from->color.alpha * f + to->color.alpha * t + 0.5); c += 4; } #endif // GAMMA_BLEND } index = offset + 1; // the current "to" will be the "from" in the next interpolation from = to; } // make sure we fill the entire array if (index < count) { uint8* c = (uint8*)&colors[index]; for (int32 i = index; i < count; i++) { c[0] = from->color.red; c[1] = from->color.green; c[2] = from->color.blue; c[3] = from->color.alpha; c += 4; } } }
bool Mesh::Load(const GLfloat* positions, const GLfloat* colors, const GLfloat* normals, const GLfloat* texCoords, const GLuint* indices, int numVertices, int numIndices, GLenum drawMode, StorageType storageType ) { if (!positions || numVertices <= 0) { return false; } mDrawMode = drawMode; mStorageType = storageType; mNumVertices = numVertices; mNumIndices = (numIndices <= 0 || indices == nullptr) ? numVertices : numIndices; mHasColors = (colors != nullptr); mHasNormals = (normals != nullptr); mHasTexCoord = (texCoords != nullptr); mVertexSize = 3 + 3*mHasColors + 3*mHasNormals + 2*mHasTexCoord; mVertices = new GLfloat [mVertexSize * mNumVertices]; mIndices = new GLuint [mNumIndices]; if (mStorageType == kTightlyPacked) { // Initialize vertices buffer array. for (int i = 0; i < mNumVertices; i++) { float* position = PositionAt(i); float* texCoord = TexCoordAt(i); float* normal = NormalAt(i); float* color = ColorAt(i); memcpy(position, positions + 3*i, sizeof(GLfloat)*3); if (HasColors()) { memcpy(color, colors + 3*i, sizeof(GLfloat)*3); } if (HasNormals()) { memcpy(normal, normals + 3*i, sizeof(GLfloat)*3); } if (HasTexCoord()) { memcpy(texCoord, texCoords + 2*i, sizeof(GLfloat)*2); } } } else { GLfloat* dest = mVertices; memcpy(dest, positions, 3*sizeof(GLfloat)*mNumVertices); dest += 3*mNumVertices; if (HasColors()) { memcpy(dest, colors, 3*sizeof(GLfloat)*mNumVertices); dest += 3*mNumVertices; } if (HasNormals()) { memcpy(dest, normals, 3*sizeof(GLfloat)*mNumVertices); dest += 3*mNumVertices; } if (HasTexCoord()) { memcpy(dest, texCoords, 2*sizeof(GLfloat)*mNumVertices); dest += 2*mNumVertices; } } // Initialize element array (indices array). if (indices) // Element array provided. { memcpy(mIndices, indices, sizeof(GLuint)*mNumIndices); } else // Element array wasn't provided -- build it up. { for (int i = 0; i < mNumIndices; i++) { mIndices[i] = i; } } mInitialized = true; Mesh::Upload(); return true; }
// Reloads the geometry. To keep some data constant, just specify nullptr. void Mesh::Reload(const GLfloat* positions, const GLfloat* colors, const GLfloat* normals, const GLfloat* texCoords ) { if (!mInitialized) { std::cerr << "ERROR The mesh must be initialized before creating buffer objects.\n"; return; } if (mStorageType == kTightlyPacked) { for (int i = 0; i < mNumVertices; i++) { float* position = PositionAt(i); float* texCoord = TexCoordAt(i); float* normal = NormalAt(i); float* color = ColorAt(i); if (positions) { memcpy(position, positions + 3*i, sizeof(GLfloat)*3); } if (colors && HasColors()) { memcpy(color, colors + 3*i, sizeof(GLfloat)*3); } if (normals && HasNormals()) { memcpy(normal, normals + 3*i, sizeof(GLfloat)*3); } if (texCoords && HasTexCoord()) { memcpy(texCoord, texCoords + 2*i, sizeof(GLfloat)*2); } } } else // Sub-buffered. { GLfloat* dest = mVertices; if (positions) { memcpy(dest, positions, 3*sizeof(GLfloat)*mNumVertices); dest += 3*mNumVertices; } if (colors && HasColors()) { memcpy(dest, colors, 3*sizeof(GLfloat)*mNumVertices); dest += 3*mNumVertices; } if (normals && HasNormals()) { memcpy(dest, normals, 3*sizeof(GLfloat)*mNumVertices); dest += 3*mNumVertices; } if (texCoords && HasTexCoord()) { memcpy(dest, texCoords, 2*sizeof(GLfloat)*mNumVertices); dest += 2*mNumVertices; } } Mesh::Upload(); }