我知道如何用drawTexturePath在任何角度上旋转图像
int displayWidth = Display.getWidth();
int displayHeight = Display.getHeight();
int[] x = new int[] { 0, displayWidth, displayWidth, 0 };
int[] x = new int[] { 0, 0, displayHeight, displayHeight };
int angle = Fixed32.toFP( 45 );
int dux = Fixed32.cosd(angle );
int dvx = -Fixed32.sind( angle );
int duy = Fixed32.sind( angle );
int dvy = Fixed32.cosd( angle );
graphics.drawTexturedPath( x, y, null, null, 0, 0, dvx, dux, dvy, duy, image);但我需要的是一个具有3d转换的简单图像的3d projection (类似于this)
你能建议我如何用drawTexturedPath做到这一点吗(我几乎肯定这是可能的)?
还有别的选择吗?
发布于 2009-08-07 13:42:26
此函数使用的方法(2个漫游向量)与用于著名的“旋转变焦”效果的旧代码技巧相同。rotozoomer example video
此方法是旋转、缩放和倾斜图像的一种非常快速的方式。旋转只需旋转漫游向量即可。缩放只需缩放漫游向量即可。倾斜是通过相对于彼此旋转漫游向量来完成的(例如,它们不再形成90度角)。
任天堂已经在他们的SNES中制作了硬件,以便在任何精灵和/或背景上使用相同的效果。这为一些非常酷的效果让路。
这种技术的一大缺点是不能透视性地扭曲纹理。要做到这一点,每一条新的水平线,漫游向量都应该稍微改变一下。(没有图画很难解释)。
在snes上,他们通过改变每条扫描线来克服这一点(在那个时代,当显示器绘制任何扫描线时,人们可以设置一个中断)。这种模式后来被称为MODE 7 (因为它的行为方式类似于一种新的虚拟图形模式)。使用这种模式的最著名的游戏是马里奥卡丁车和F-zero。
因此,为了在黑莓上工作,你必须绘制你的图像"displayHeight“次(例如,每次图像的一条扫描线)。这是达到预期效果的唯一方法。(这无疑会影响您的性能,因为您现在使用新值多次调用drawTexturedPath函数,而不是只调用一次)。
我猜想,通过一点谷歌搜索,你可以找到一些公式(甚至是一个实现),如何计算不同的走向量。用一点纸(考虑到你的数学不是很差),你自己也可以推断出来。当我为Gameboy Advance制作游戏时,我自己也做过,所以我知道这是可以做到的。
一定要预先计算所有东西!速度就是一切(特别是在像手机这样速度很慢的机器上)
编辑:为你做了一些谷歌搜索。下面是如何创建mode7效果的详细说明。这将帮助您实现与黑莓功能相同的功能。Mode 7 implementation
发布于 2009-08-04 18:53:31
使用以下代码,您可以倾斜您的图像,并获得类似透视的效果:
int displayWidth = Display.getWidth();
int displayHeight = Display.getHeight();
int[] x = new int[] { 0, displayWidth, displayWidth, 0 };
int[] y = new int[] { 0, 0, displayHeight, displayHeight };
int dux = Fixed32.toFP(-1);
int dvx = Fixed32.toFP(1);
int duy = Fixed32.toFP(1);
int dvy = Fixed32.toFP(0);
graphics.drawTexturedPath( x, y, null, null, 0, 0, dvx, dux, dvy, duy, image);这将使你的图像倾斜45度角,如果你想要一个特定的角度,你只需要使用一些三角来确定你的向量的长度。
发布于 2009-08-16 11:08:28
感谢你的回答和指导,+1对你们所有人。
模式7是我选择实现3D转换的方式,但不幸的是我不能让drawTexturedPath来调整扫描线的大小……所以我最终选择了简单的drawImage。
假设您有一个位图inBmp (输入纹理),创建新的位图outBmp (输出纹理)。
Bitmap mInBmp = Bitmap.getBitmapResource("map.png");
int inHeight = mInBmp.getHeight();
int inWidth = mInBmp.getWidth();
int outHeight = 0;
int outWidth = 0;
int outDrawX = 0;
int outDrawY = 0;
Bitmap mOutBmp = null;
public Scr() {
super();
mOutBmp = getMode7YTransform();
outWidth = mOutBmp.getWidth();
outHeight = mOutBmp.getHeight();
outDrawX = (Display.getWidth() - outWidth) / 2;
outDrawY = Display.getHeight() - outHeight;
}在代码中的某处为outBmp创建一个图形outBmpGraphics。
然后在从开始y到(纹理高度)*y转换因子的迭代中执行以下操作:
1.为一行创建一个位图lineBmp = new位图(宽度,1
2.从lineBmp创建图形lineBmpGraphics
3.绘制纹理到lineBmpGraphics的线条
4.将lineBmp编码为EncodedImage img
5.根据模式7缩放img
6.将img绘制为outBmpGraphics
备注: Richard Puckett's PNGEncoder BB port used in my code
private Bitmap getMode7YTransform() {
Bitmap outBmp = new Bitmap(inWidth, inHeight / 2);
Graphics outBmpGraphics = new Graphics(outBmp);
for (int i = 0; i < inHeight / 2; i++) {
Bitmap lineBmp = new Bitmap(inWidth, 1);
Graphics lineBmpGraphics = new Graphics(lineBmp);
lineBmpGraphics.drawBitmap(0, 0, inWidth, 1, mInBmp, 0, 2 * i);
PNGEncoder encoder = new PNGEncoder(lineBmp, true);
byte[] data = null;
try {
data = encoder.encode(true);
} catch (IOException e) {
e.printStackTrace();
}
EncodedImage img = PNGEncodedImage.createEncodedImage(data,
0, -1);
float xScaleFactor = ((float) (inHeight / 2 + i))
/ (float) inHeight;
img = scaleImage(img, xScaleFactor, 1);
int startX = (inWidth - img.getScaledWidth()) / 2;
int imgHeight = img.getScaledHeight();
int imgWidth = img.getScaledWidth();
outBmpGraphics.drawImage(startX, i, imgWidth, imgHeight, img,
0, 0, 0);
}
return outBmp;
}然后只需在paint()中绘制它
protected void paint(Graphics graphics) {
graphics.drawBitmap(outDrawX, outDrawY, outWidth, outHeight, mOutBmp,
0, 0);
}为了进行扩展,我做了一些类似于Resizing a Bitmap using .scaleImage32 instead of .setScale中描述的方法
private EncodedImage scaleImage(EncodedImage image, float ratioX,
float ratioY) {
int currentWidthFixed32 = Fixed32.toFP(image.getWidth());
int currentHeightFixed32 = Fixed32.toFP(image.getHeight());
double w = (double) image.getWidth() * ratioX;
double h = (double) image.getHeight() * ratioY;
int width = (int) w;
int height = (int) h;
int requiredWidthFixed32 = Fixed32.toFP(width);
int requiredHeightFixed32 = Fixed32.toFP(height);
int scaleXFixed32 = Fixed32.div(currentWidthFixed32,
requiredWidthFixed32);
int scaleYFixed32 = Fixed32.div(currentHeightFixed32,
requiredHeightFixed32);
EncodedImage result = image.scaleImage32(scaleXFixed32, scaleYFixed32);
return result;
}另请参阅
J2ME Mode 7 Floor Renderer -如果你正在写一个3D游戏,那就是更详细、更激动人心的东西!
https://stackoverflow.com/questions/1212651
复制相似问题