// 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;
}
Ejemplo n.º 3
0
//
// 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", &copy );
        *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", &copy );
        *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();
}