我正在用 Java 开发 Android 应用程序。我想绘制动态图像,如附件(非常旧的 DOS 程序的打印屏幕)。我认为是水波。
谁能解释一下我该如何做这份工作?我不知道这些照片是如何绘制的。
谢谢!
ps 可能是可压缩流体中的行波?
已编辑:带有所需动画的屏幕记录:http ://www.youtube.com/watch?v=_zeSQX_8grY
EDITED2:我在这里找到了这个视频效果的来源。有一个针对 DOS 的编译程序(可以在 DOS 框中运行)和 ASM 中的源。文件夹“PART3”包含所需视频效果的来源(文件 WPLASMA.ASM)。不幸的是,我不知道 Turbo Assembler。有人可以帮我理解这个程序是如何绘制这个视频效果的吗?我在这里发布了 WPLASMA.ASM 的内容。
EDITED3:我已将大部分代码移植到 C。但我不知道 VGA 模式是如何工作的。我对 PutBmp 函数有困难。
#include <cmath>
#include <ctime>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <opencv2/highgui/highgui.hpp>
struct RGB {
char red, green, blue;
};
#define MAXH 60 // horiz wave length.
#define MAXVW 64 // vert wave length.
#define MAXHW 32 // max horiz wave amount.
#define MAXV (80 + MAXHW) // vert wave length.
static void UpdHWaves( char* HWave1, char* HWave2,
int& HWavPos1, int& HWavPos2,
int HWavInc1 ) // Updates the Horiz Waves.
{
for( int i = 0; i < MAXH - 1; ++i ) {
HWave1[ i ] = HWave1[ i + 1 ];
}
int8_t val = 127 * std::sin( HWavPos1 * M_PI / 180.0 );
HWave1[ MAXH - 1 ] = val >> 1;
HWavPos1 += HWavInc1;
if( HWavPos1 >= 360 ) {
HWavPos1 -= 360;
}
for( int i = 0; i < MAXH; ++i ) {
val = 127 * std::sin( ( HWavPos2 + i * 4 ) * M_PI / 180.0 );
val = ( val >> 1 ) + HWave1[ i ];
HWave2[ i ] = ( val >> 3 ) + 16;
}
HWavPos2 += 4;
if( HWavPos2 >= 360 ) {
HWavPos2 -= 360;
}
}
static void UpdVWaves( char *VWave1, char* VWave2,
int& VWavPos1, int& VWavPos2,
int VWavInc1 )
{
for( int i = 0; i < MAXV - 1; ++i ) {
VWave1[ i ] = VWave1[ i + 1 ];
}
int8_t val = 127 * std::sin( VWavPos1 * M_PI / 180.0 );
VWave1[ MAXV - 1 ] = val >> 1;
VWavPos1 += VWavInc1;
if( VWavPos1 >= 360 ) {
VWavPos1 -= 360;
}
for( int i = 0; i < MAXV; ++i ) {
val = 127 * std::sin( ( VWavPos2 + i * 3 ) * M_PI / 180.0 );
val = ( val >> 1 ) + VWave1[ i ];
VWave2[ i ] = ( val >> 2 ) + 32;
}
++VWavPos2;
if( VWavPos2 >= 360 ) {
VWavPos2 -= 360;
}
}
static void UpdBmp( char *Bitmap, const char *VWave2 ) // Updates the Plasma bitmap.
{
for( int k = 0; k < MAXV; ++k ) {
char al = VWave2[ k ];
int i = 0;
for( int l = 0; l < MAXH; ++l ) {
++al;
Bitmap[ i ] = al;
i += 256;
}
++Bitmap;
}
}
static void PutBmp( const RGB* palete,
const char* BitMap,
const char* HWave2 ) // Puts into the screen the Plasma bitmap.
{
RGB screen[320*200];
memset( screen, 0, sizeof( screen ) );
RGB *screenPtr = screen;
const char *dx = BitMap;
const char *si = HWave2;
for( int i = 0; i < MAXH; ++i ) {
char ax = *si;
++si;
const char *si2 = ax + dx;
for( int j = 0; j < 40; ++j ) {
assert( *si2 < MAXH + MAXVW );
*screenPtr = palete[ *si2 ];
++screenPtr;
++si2;
assert( *si2 < MAXH + MAXVW );
*screenPtr = palete[ *si2 ];
++screenPtr;
++si2;
}
dx += 256;
}
static cv::VideoWriter writer( "test.avi", CV_FOURCC('M','J','P','G'), 15, cv::Size( 320, 200 ) );
cv::Mat image( 200, 320, CV_8UC3 );
for( int i = 0; i < 200; ++i ) {
for( int j = 0; j < 320; ++j ) {
image.at<cv::Vec3b>(i, j )[0] = screen[ 320 * i + j ].blue;
image.at<cv::Vec3b>(i, j )[1] = screen[ 320 * i + j ].green;
image.at<cv::Vec3b>(i, j )[2] = screen[ 320 * i + j ].red;
}
}
writer.write( image );
}
int main( )
{
RGB palete[256];
// generation of the plasma palette.
palete[ 0 ].red = 0;
palete[ 0 ].green = 0;
palete[ 0 ].blue = 0;
RGB *ptr = palete + 1;
int ah = 0;
int bl = 2;
for( int i = 0; i < MAXH + MAXVW; ++i ) {
ptr->red = 32 - ( ah >> 1 );
ptr->green = 16 - ( ah >> 2 );
ptr->blue = 63 - ( ah >> 2 );
ah += bl;
if( ah >= 64 ) {
bl = - bl;
ah += 2 * bl;
}
ptr += 1;
}
//setup wave parameters.
int HWavPos1 = 0; // horiz waves pos.
int HWavPos2 = 0;
int VWavPos1 = 0; // vert waves pos.
int VWavPos2 = 0;
int HWavInc1 = 1; // horiz wave speed.
int VWavInc1 = 7; // vert wave speed.
char HWave1[ MAXH ]; // horiz waves.
char HWave2[ MAXH ];
char VWave1[ MAXV ]; // vert waves.
char VWave2[ MAXV ];
char Bitmap[ 256 * MAXH + MAXV ];
memset( Bitmap, 0, sizeof( Bitmap ) );
//use enough steps to update all the waves entries.
for( int i = 0; i < MAXV; ++i ) {
UpdHWaves( HWave1, HWave2, HWavPos1, HWavPos2, HWavInc1 );
UpdVWaves( VWave1, VWave2, VWavPos1, VWavPos2, VWavInc1 );
}
std::srand(std::time(0));
for( int i = 0; i < 200; ++i ) {
UpdHWaves( HWave1, HWave2, HWavPos1, HWavPos2, HWavInc1 );
UpdVWaves( VWave1, VWave2, VWavPos1, VWavPos2, VWavInc1 );
UpdBmp( Bitmap, VWave2 );
PutBmp( palete, Bitmap, HWave2 );
//change wave's speed.
HWavInc1 = ( std::rand( ) & 7 ) + 3;
VWavInc1 = ( std::rand( ) & 3 ) + 5;
}
return 0;
}