📄 ball.cpp
字号:
//------------------------------------------------------------------------------
// File: Ball.cpp
//
// Desc: DirectShow sample code. This sample illustrates a simple source
// filter that produces decompressed images showing a ball bouncing
// around. Each movement of the ball is done by generating a new image.
// We use the CSource and CSourceStream base classes to manage a source
// filter - we are a live source and so do not support any seeking.
//
// The image stream is never-ending, with the ball color dependent on
// bit depth of the current display device. 32, 24, 16 (555 and 565),
// and 8 bit palettized types can be supplied.
//
// In implementation, the CSource and CSourceStream base classes from
// the SDK are used to implement some of the more tedious effort
// associated with source filters. In particular, the starting and
// stopping of worker threads based upon overall activation/stopping
// is facilitated. A worker thread sits in a loop asking for buffers
// and then calls the PURE virtual FillBuffer method when it has a
// buffer available to fill.
//
// The sample also has a simple quality management implementation in
// the filter. With the exception of renderers (which normally initiate
// it), this is controlled through IQualityControl. In each frame it
// is called for status. Due to the straightforward nature of the
// filter, spacing of samples sent downward can be controlled so that
// any CPU used runs flat out.
//
// Demonstration instructions:
//
// Start GraphEdit, which is available in the SDK DXUtils folder. Click
// on the Graph menu and select "Insert Filters." From the dialog box,
// double click on "DirectShow filters," then "Bouncing ball" and then
// dismiss the dialog. Go to the output pin of the filter box and
// right click, selecting "Render." A video renderer will be inserted
// and connected up (on some displays there may be a color space
// convertor put between them to get the pictures into a suitable
// format). Then click "run" on GraphEdit and see the ball bounce
// around the window...
//
// Files:
//
// ball.cpp Looks after drawing a moving bouncing ball
// ball.h Class definition for the ball drawing object
// ball.rc Version and title information resources
// fball.cpp The real filter class implementation
// fball.h Class definition for the main filter object
// resource.h A couple of identifiers for our resources
//
// Base classes used:
//
// CSource Base class for a generic source filter
// CSourceStream A base class for a source filters stream
//
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include <streams.h>
#include "ball.h"
//------------------------------------------------------------------------------
// Name: CBall::CBall(()
// Desc: Constructor for the ball class. The default arguments provide a
// reasonable image and ball size.
//------------------------------------------------------------------------------
CBall::CBall(int iImageWidth, int iImageHeight, int iBallSize) :
m_iImageWidth(iImageWidth),
m_iImageHeight(iImageHeight),
m_iBallSize(iBallSize),
m_iAvailableWidth(iImageWidth - iBallSize),
m_iAvailableHeight(iImageHeight - iBallSize),
m_x(0),
m_y(0),
m_xDir(RIGHT),
m_yDir(UP)
{
// Check we have some (arbitrary) space to bounce in.
ASSERT(iImageWidth > 2*iBallSize);
ASSERT(iImageHeight > 2*iBallSize);
// Random position for showing off a video mixer
m_iRandX = rand();
m_iRandY = rand();
} // (Constructor)
// Added by HQ Tech
void CBall::SetImageSize(int inWidth, int inHeight)
{
m_iImageWidth = inWidth;
m_iImageHeight = inHeight;
}
//------------------------------------------------------------------------------
// Name: CBall::PlotBall()
// Desc: Positions the ball on the memory buffer.
// Assumes the image buffer is arranged as Row 1,Row 2,...,Row n
// in memory and that the data is contiguous.
//------------------------------------------------------------------------------
void CBall::PlotBall(BYTE pFrame[], BYTE BallPixel[], int iPixelSize)
{
ASSERT(m_x >= 0);
ASSERT(m_x <= m_iAvailableWidth);
ASSERT(m_y >= 0);
ASSERT(m_y <= m_iAvailableHeight);
ASSERT(pFrame != NULL);
ASSERT(BallPixel != NULL);
// The current byte of interest in the frame
BYTE *pBack;
pBack = pFrame;
// Plot the ball into the correct location
BYTE *pBall = pFrame + ( m_y * m_iImageWidth * iPixelSize) + m_x * iPixelSize;
for(int row = 0; row < m_iBallSize; row++)
{
for(int col = 0; col < m_iBallSize; col++)
{
// For each byte fill its value from BallPixel[]
for(int i = 0; i < iPixelSize; i++)
{
if(WithinCircle(col, row))
{
*pBall = BallPixel[i];
}
pBall++;
}
}
pBall += m_iAvailableWidth * iPixelSize;
}
} // PlotBall
//------------------------------------------------------------------------------
// CBall::BallPosition()
//
// Returns the 1-dimensional position of the ball at time t millisecs
// (note that millisecs runs out after about a month!)
//------------------------------------------------------------------------------
int CBall::BallPosition(int iPixelTime, // Millisecs per pixel
int iLength, // Distance between the bounce points
int time, // Time in millisecs
int iOffset) // For a bit of randomness
{
// Calculate the position of an unconstrained ball (no walls)
// then fold it back and forth to calculate the actual position
int x = time / iPixelTime;
x += iOffset;
x %= 2 * iLength;
// check it is still in bounds
if(x > iLength)
{
x = 2*iLength - x;
}
return x;
} // BallPosition
//------------------------------------------------------------------------------
// CBall::MoveBall()
//
// Set (m_x, m_y) to the new position of the ball. move diagonally
// with speed m_v in each of x and y directions.
// Guarantees to keep the ball in valid areas of the frame.
// When it hits an edge the ball bounces in the traditional manner!.
// The boundaries are (0..m_iAvailableWidth, 0..m_iAvailableHeight)
//
//------------------------------------------------------------------------------
void CBall::MoveBall(CRefTime rt)
{
m_x = BallPosition(10, m_iAvailableWidth, rt.Millisecs(), m_iRandX);
m_y = BallPosition(10, m_iAvailableHeight, rt.Millisecs(), m_iRandY);
} // MoveBall
//------------------------------------------------------------------------------
// CBall:WithinCircle()
//
// Return TRUE if (x,y) is within a circle radius S/2, center (S/2, S/2)
// where S is m_iBallSize else return FALSE
//------------------------------------------------------------------------------
inline BOOL CBall::WithinCircle(int x, int y)
{
unsigned int r = m_iBallSize / 2;
if((x-r)*(x-r) + (y-r)*(y-r) < r*r)
{
return TRUE;
}
else
{
return FALSE;
}
} // WithinCircle
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -