mirror of
https://github.com/arduino/Arduino.git
synced 2024-11-30 11:24:12 +01:00
1296 lines
33 KiB
Java
1296 lines
33 KiB
Java
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
|
|
/*
|
|
Part of the Processing project - http://processing.org
|
|
|
|
Copyright (c) 2004-06 Ben Fry and Casey Reas
|
|
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General
|
|
Public License along with this library; if not, write to the
|
|
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
package processing.core;
|
|
|
|
|
|
/**
|
|
* Code for rendering lines.
|
|
* <P>
|
|
* This code will soon be removed.
|
|
* Written by Carlos Rocha.
|
|
*/
|
|
public class PLine implements PConstants
|
|
{
|
|
private int[] m_pixels;
|
|
private float[] m_zbuffer;
|
|
//private int[] m_stencil;
|
|
|
|
private int m_index;
|
|
|
|
static final int R_COLOR = 0x1;
|
|
static final int R_ALPHA = 0x2;
|
|
static final int R_SPATIAL = 0x8;
|
|
static final int R_THICK = 0x4;
|
|
static final int R_SMOOTH = 0x10;
|
|
|
|
private int SCREEN_WIDTH;
|
|
private int SCREEN_HEIGHT;
|
|
private int SCREEN_WIDTH1;
|
|
private int SCREEN_HEIGHT1;
|
|
|
|
public boolean INTERPOLATE_RGB;
|
|
public boolean INTERPOLATE_ALPHA;
|
|
public boolean INTERPOLATE_Z;
|
|
public boolean INTERPOLATE_THICK;
|
|
|
|
// antialias
|
|
private boolean SMOOTH;
|
|
|
|
// blender
|
|
//private boolean BLENDER;
|
|
|
|
// stroke color
|
|
private int m_stroke;
|
|
|
|
// draw flags
|
|
public int m_drawFlags;
|
|
|
|
// vertex coordinates
|
|
private float[] x_array;
|
|
private float[] y_array;
|
|
private float[] z_array;
|
|
|
|
// vertex intensity
|
|
private float[] r_array;
|
|
private float[] g_array;
|
|
private float[] b_array;
|
|
private float[] a_array;
|
|
|
|
// vertex offsets
|
|
private int o0;
|
|
private int o1;
|
|
|
|
// start values
|
|
private float m_r0;
|
|
private float m_g0;
|
|
private float m_b0;
|
|
private float m_a0;
|
|
private float m_z0;
|
|
|
|
// deltas
|
|
private float dz;
|
|
|
|
// rgba deltas
|
|
private float dr;
|
|
private float dg;
|
|
private float db;
|
|
private float da;
|
|
|
|
private PGraphics parent;
|
|
|
|
|
|
public PLine(PGraphics g) {
|
|
INTERPOLATE_Z = false;
|
|
|
|
x_array = new float[2];
|
|
y_array = new float[2];
|
|
z_array = new float[2];
|
|
r_array = new float[2];
|
|
g_array = new float[2];
|
|
b_array = new float[2];
|
|
a_array = new float[2];
|
|
|
|
this.parent = g;
|
|
}
|
|
|
|
|
|
public void reset() {
|
|
// reset these in case PGraphics was resized
|
|
SCREEN_WIDTH = parent.width;
|
|
SCREEN_HEIGHT = parent.height;
|
|
SCREEN_WIDTH1 = SCREEN_WIDTH-1;
|
|
SCREEN_HEIGHT1 = SCREEN_HEIGHT-1;
|
|
|
|
m_pixels = parent.pixels;
|
|
//m_stencil = parent.stencil;
|
|
m_zbuffer = parent.zbuffer;
|
|
|
|
// other things to reset
|
|
|
|
INTERPOLATE_RGB = false;
|
|
INTERPOLATE_ALPHA = false;
|
|
//INTERPOLATE_Z = false;
|
|
m_drawFlags = 0;
|
|
m_index = 0;
|
|
//BLENDER = false;
|
|
}
|
|
|
|
|
|
public void setVertices(float x0, float y0, float z0,
|
|
float x1, float y1, float z1) {
|
|
// [rocha] fixed z drawing, so whenever a line turns on
|
|
// z interpolation, all the lines are z interpolated
|
|
if (z0 != z1 || z0!=0.0f || z1!=0.0f || INTERPOLATE_Z) {
|
|
INTERPOLATE_Z = true;
|
|
m_drawFlags |= R_SPATIAL;
|
|
} else {
|
|
INTERPOLATE_Z = false;
|
|
m_drawFlags &= ~R_SPATIAL;
|
|
}
|
|
|
|
z_array[0] = z0;
|
|
z_array[1] = z1;
|
|
|
|
x_array[0] = x0;
|
|
x_array[1] = x1;
|
|
|
|
y_array[0] = y0;
|
|
y_array[1] = y1;
|
|
}
|
|
|
|
public void setIntensities(float r0, float g0, float b0, float a0,
|
|
float r1, float g1, float b1, float a1) {
|
|
a_array[0] = (a0 * 253f + 1.0f) * 65536f;
|
|
a_array[1] = (a1 * 253f + 1.0f) * 65536f;
|
|
|
|
// check if we need alpha or not?
|
|
if ((a0 != 1.0f) || (a1 != 1.0f)) {
|
|
INTERPOLATE_ALPHA = true;
|
|
m_drawFlags |= R_ALPHA;
|
|
} else {
|
|
INTERPOLATE_ALPHA = false;
|
|
m_drawFlags &= ~R_ALPHA;
|
|
}
|
|
|
|
// extra scaling added to prevent color "overflood" due to rounding errors
|
|
r_array[0] = (r0 * 253f + 1.0f) * 65536f;
|
|
r_array[1] = (r1 * 253f + 1.0f) * 65536f;
|
|
|
|
g_array[0] = (g0 * 253f + 1.0f) * 65536f;
|
|
g_array[1] = (g1 * 253f + 1.0f) * 65536f;
|
|
|
|
b_array[0] = (b0 * 253f + 1.0f) * 65536f;
|
|
b_array[1] = (b1 * 253f + 1.0f) * 65536f;
|
|
|
|
// check if we need to interpolate the intensity values
|
|
if (r0 != r1) {
|
|
INTERPOLATE_RGB = true;
|
|
m_drawFlags |= R_COLOR;
|
|
|
|
} else if (g0 != g1) {
|
|
INTERPOLATE_RGB = true;
|
|
m_drawFlags |= R_COLOR;
|
|
|
|
} else if (b0 != b1) {
|
|
INTERPOLATE_RGB = true;
|
|
m_drawFlags |= R_COLOR;
|
|
|
|
} else {
|
|
// when plain we use the stroke color of the first vertex
|
|
m_stroke = 0xFF000000 |
|
|
((int)(255*r0) << 16) | ((int)(255*g0) << 8) | (int)(255*b0);
|
|
INTERPOLATE_RGB = false;
|
|
m_drawFlags &= ~R_COLOR;
|
|
}
|
|
}
|
|
|
|
|
|
public void setIndex(int index) {
|
|
m_index = index;
|
|
//BLENDER = false;
|
|
if (m_index != -1) {
|
|
//BLENDER = true;
|
|
} else {
|
|
m_index = 0;
|
|
}
|
|
}
|
|
|
|
|
|
public void draw() {
|
|
int xi;
|
|
int yi;
|
|
int length;
|
|
boolean visible = true;
|
|
|
|
if (parent.smooth) {
|
|
SMOOTH = true;
|
|
m_drawFlags |= R_SMOOTH;
|
|
|
|
} else {
|
|
SMOOTH = false;
|
|
m_drawFlags &= ~R_SMOOTH;
|
|
}
|
|
|
|
// line hack
|
|
if (parent.hints[NO_FLYING_POO]) {
|
|
float nwidth2 = -SCREEN_WIDTH;
|
|
float nheight2 = -SCREEN_HEIGHT;
|
|
float width2 = SCREEN_WIDTH * 2;
|
|
float height2 = SCREEN_HEIGHT * 2;
|
|
if ((x_array[1] < nwidth2) ||
|
|
(x_array[1] > width2) ||
|
|
(x_array[0] < nwidth2) ||
|
|
(x_array[0] > width2) ||
|
|
(y_array[1] < nheight2) ||
|
|
(y_array[1] > height2) ||
|
|
(y_array[0] < nheight2) ||
|
|
(y_array[0] > height2)) {
|
|
return; // this is a bad line
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
// line clipping
|
|
visible = lineClipping();
|
|
if (!visible) {
|
|
return;
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
// calculate line values
|
|
int shortLen;
|
|
int longLen;
|
|
boolean yLonger;
|
|
int dt;
|
|
|
|
yLonger = false;
|
|
|
|
// HACK for drawing lines left-to-right for rev 0069
|
|
// some kind of bug exists with the line-stepping algorithm
|
|
// that causes strange patterns in the anti-aliasing.
|
|
// [040228 fry]
|
|
//
|
|
// swap rgba as well as the coords.. oops
|
|
// [040712 fry]
|
|
//
|
|
if (x_array[1] < x_array[0]) {
|
|
float t;
|
|
|
|
t = x_array[1]; x_array[1] = x_array[0]; x_array[0] = t;
|
|
t = y_array[1]; y_array[1] = y_array[0]; y_array[0] = t;
|
|
t = z_array[1]; z_array[1] = z_array[0]; z_array[0] = t;
|
|
|
|
t = r_array[1]; r_array[1] = r_array[0]; r_array[0] = t;
|
|
t = g_array[1]; g_array[1] = g_array[0]; g_array[0] = t;
|
|
t = b_array[1]; b_array[1] = b_array[0]; b_array[0] = t;
|
|
t = a_array[1]; a_array[1] = a_array[0]; a_array[0] = t;
|
|
}
|
|
|
|
// important - don't change the casts
|
|
// is needed this way for line drawing algorithm
|
|
longLen = (int)x_array[1] - (int)x_array[0];
|
|
shortLen = (int)y_array[1] - (int)y_array[0];
|
|
|
|
if (Math.abs(shortLen) > Math.abs(longLen)) {
|
|
int swap = shortLen;
|
|
shortLen = longLen;
|
|
longLen = swap;
|
|
yLonger = true;
|
|
}
|
|
|
|
// now we sort points so longLen is always positive
|
|
// and we always start drawing from x[0], y[0]
|
|
if (longLen < 0) {
|
|
// swap order
|
|
o0 = 1;
|
|
o1 = 0;
|
|
|
|
xi = (int) x_array[1];
|
|
yi = (int) y_array[1];
|
|
|
|
length = -longLen;
|
|
|
|
} else {
|
|
o0 = 0;
|
|
o1 = 1;
|
|
|
|
xi = (int) x_array[0];
|
|
yi = (int) y_array[0];
|
|
|
|
length = longLen;
|
|
}
|
|
|
|
// calculate dt
|
|
if (length == 0) {
|
|
dt = 0;
|
|
} else {
|
|
dt = (shortLen << 16) / longLen;
|
|
}
|
|
|
|
m_r0 = r_array[o0];
|
|
m_g0 = g_array[o0];
|
|
m_b0 = b_array[o0];
|
|
|
|
if (INTERPOLATE_RGB) {
|
|
dr = (r_array[o1] - r_array[o0]) / length;
|
|
dg = (g_array[o1] - g_array[o0]) / length;
|
|
db = (b_array[o1] - b_array[o0]) / length;
|
|
} else {
|
|
dr = 0;
|
|
dg = 0;
|
|
db = 0;
|
|
}
|
|
|
|
m_a0 = a_array[o0];
|
|
|
|
if (INTERPOLATE_ALPHA) {
|
|
da = (a_array[o1] - a_array[o0]) / length;
|
|
} else {
|
|
da = 0;
|
|
}
|
|
|
|
m_z0 = z_array[o0];
|
|
//z0 += -0.001f; // [rocha] ugly fix for z buffer precision
|
|
|
|
if (INTERPOLATE_Z) {
|
|
dz = (z_array[o1] - z_array[o0]) / length;
|
|
} else {
|
|
dz = 0;
|
|
}
|
|
|
|
// draw thin points
|
|
if (length == 0) {
|
|
if (INTERPOLATE_ALPHA) {
|
|
drawPoint_alpha(xi, yi);
|
|
} else {
|
|
drawPoint(xi, yi);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
// draw antialias polygon lines for non stroked polygons
|
|
if (BLENDER && SMOOTH) {
|
|
// fix for endpoints not being drawn
|
|
// [rocha]
|
|
drawPoint_alpha((int)x_array[0], (int)x_array[0]);
|
|
drawPoint_alpha((int)x_array[1], (int)x_array[1]);
|
|
|
|
drawline_blender(x_array[0], y_array[0], x_array[1], y_array[1]);
|
|
return;
|
|
}
|
|
*/
|
|
|
|
// draw normal strokes
|
|
if (SMOOTH) {
|
|
drawLine_smooth(xi, yi, dt, length, yLonger);
|
|
|
|
} else {
|
|
if (m_drawFlags == 0) {
|
|
drawLine_plain(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == R_ALPHA) {
|
|
drawLine_plain_alpha(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == R_COLOR) {
|
|
drawLine_color(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == (R_COLOR + R_ALPHA)) {
|
|
drawLine_color_alpha(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == R_SPATIAL) {
|
|
drawLine_plain_spatial(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == (R_SPATIAL + R_ALPHA)) {
|
|
drawLine_plain_alpha_spatial(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == (R_SPATIAL + R_COLOR)) {
|
|
drawLine_color_spatial(xi, yi, dt, length, yLonger);
|
|
|
|
} else if (m_drawFlags == (R_SPATIAL + R_COLOR + R_ALPHA)) {
|
|
drawLine_color_alpha_spatial(xi, yi, dt, length, yLonger);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public boolean lineClipping() {
|
|
// new cohen-sutherland clipping code, as old one was buggy [toxi]
|
|
// get the "dips" for the points to clip
|
|
int code1 = lineClipCode(x_array[0], y_array[0]);
|
|
int code2 = lineClipCode(x_array[1], y_array[1]);
|
|
int dip = code1 | code2;
|
|
|
|
if ((code1 & code2)!=0) {
|
|
|
|
return false;
|
|
|
|
} else if (dip != 0) {
|
|
|
|
// now calculate the clipped points
|
|
float a0 = 0, a1 = 1, a = 0;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
if (((dip>>i)%2)==1){
|
|
a = lineSlope(x_array[0], y_array[0], x_array[1], y_array[1], i+1);
|
|
if (((code1 >> i) % 2) == 1) {
|
|
a0 = (a>a0)?a:a0; // max(a,a0)
|
|
} else {
|
|
a1 = (a<a1)?a:a1; // min(a,a1)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (a0 > a1) {
|
|
return false;
|
|
} else {
|
|
float xt = x_array[0];
|
|
float yt = y_array[0];
|
|
|
|
x_array[0] = xt + a0 * (x_array[1] - xt);
|
|
y_array[0] = yt + a0 * (y_array[1] - yt);
|
|
x_array[1] = xt + a1 * (x_array[1] - xt);
|
|
y_array[1] = yt + a1 * (y_array[1] - yt);
|
|
|
|
// interpolate remaining parameters
|
|
if (INTERPOLATE_RGB) {
|
|
float t = r_array[0];
|
|
r_array[0] = t + a0 * (r_array[1] - t);
|
|
r_array[1] = t + a1 * (r_array[1] - t);
|
|
t = g_array[0];
|
|
g_array[0] = t + a0 * (g_array[1] - t);
|
|
g_array[1] = t + a1 * (g_array[1] - t);
|
|
t = b_array[0];
|
|
b_array[0] = t + a0 * (b_array[1] - t);
|
|
b_array[1] = t + a1 * (b_array[1] - t);
|
|
}
|
|
|
|
if (INTERPOLATE_ALPHA) {
|
|
float t = a_array[0];
|
|
a_array[0] = t + a0 * (a_array[1] - t);
|
|
a_array[1] = t + a1 * (a_array[1] - t);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
private int lineClipCode(float xi, float yi) {
|
|
int xmin = 0;
|
|
int ymin = 0;
|
|
int xmax = SCREEN_WIDTH1;
|
|
int ymax = SCREEN_HEIGHT1;
|
|
|
|
//return ((yi < ymin ? 8 : 0) | (yi > ymax ? 4 : 0) |
|
|
// (xi < xmin ? 2 : 0) | (xi > xmax ? 1 : 0));
|
|
//(int) added by ewjordan 6/13/07 because otherwise we sometimes clip last pixel when it should actually be displayed.
|
|
//Currently the min values are okay because values less than 0 should not be rendered; however, bear in mind that
|
|
//(int) casts towards zero, so without this clipping, values between -1+eps and +1-eps would all be rendered as 0.
|
|
return ((yi < ymin ? 8 : 0) | ((int)yi > ymax ? 4 : 0) |
|
|
(xi < xmin ? 2 : 0) | ((int)xi > xmax ? 1 : 0));
|
|
}
|
|
|
|
|
|
private float lineSlope(float x1, float y1, float x2, float y2, int border) {
|
|
int xmin = 0;
|
|
int ymin = 0;
|
|
int xmax = SCREEN_WIDTH1;
|
|
int ymax = SCREEN_HEIGHT1;
|
|
|
|
switch (border) {
|
|
case 4: return (ymin-y1)/(y2-y1);
|
|
case 3: return (ymax-y1)/(y2-y1);
|
|
case 2: return (xmin-x1)/(x2-x1);
|
|
case 1: return (xmax-x1)/(x2-x1);
|
|
}
|
|
return -1f;
|
|
}
|
|
|
|
|
|
private void drawPoint(int x0, int y0) {
|
|
float iz = m_z0;
|
|
int offset = y0 * SCREEN_WIDTH + x0;
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
m_pixels[offset] = m_stroke;
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
}
|
|
|
|
|
|
private void drawPoint_alpha(int x0, int y0) {
|
|
int ia = (int) a_array[0];
|
|
int pr = m_stroke & 0xFF0000;
|
|
int pg = m_stroke & 0xFF00;
|
|
int pb = m_stroke & 0xFF;
|
|
float iz = m_z0;
|
|
int offset = y0 * SCREEN_WIDTH + x0;
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = ia >> 16;
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0 &= 0xFF0000;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
//m_zbuffer[offset] = iz;
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_plain(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
// new "extremely fast" line code
|
|
// adapted from http://www.edepot.com/linee.html
|
|
// first version modified by [toxi]
|
|
// simplified by [rocha]
|
|
// length must be >= 0
|
|
|
|
//assert length>=0:length;
|
|
|
|
int offset = 0;
|
|
|
|
if (vertical) {
|
|
// vertical
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
m_pixels[offset] = m_stroke;
|
|
m_zbuffer[offset] = m_z0;
|
|
j+=dt;
|
|
}
|
|
|
|
} else {
|
|
// horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
m_pixels[offset] = m_stroke;
|
|
//m_zbuffer[offset] = m_z0;
|
|
j+=dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_plain_alpha(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
|
|
int pr = m_stroke & 0xFF0000;
|
|
int pg = m_stroke & 0xFF00;
|
|
int pb = m_stroke & 0xFF;
|
|
|
|
int ia = (int) (m_a0);
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
|
|
int alpha = ia >> 16;
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0 &= 0xFF0000;
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = m_z0;
|
|
|
|
ia += da;
|
|
j += dt;
|
|
}
|
|
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
|
|
int alpha = ia >> 16;
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = m_z0;
|
|
|
|
ia += da;
|
|
j += dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_color(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
|
|
int ir = (int) m_r0;
|
|
int ig = (int) m_g0;
|
|
int ib = (int) m_b0;
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
m_pixels[offset] = 0xFF000000 |
|
|
((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16));
|
|
m_zbuffer[offset] = m_z0;
|
|
ir += dr;
|
|
ig += dg;
|
|
ib += db;
|
|
j +=dt;
|
|
}
|
|
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
m_pixels[offset] = 0xFF000000 |
|
|
((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16));
|
|
m_zbuffer[offset] = m_z0;
|
|
ir += dr;
|
|
ig += dg;
|
|
ib += db;
|
|
j += dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_color_alpha(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
|
|
int ir = (int) m_r0;
|
|
int ig = (int) m_g0;
|
|
int ib = (int) m_b0;
|
|
int ia = (int) m_a0;
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
|
|
int pr = ir & 0xFF0000;
|
|
int pg = (ig >> 8) & 0xFF00;
|
|
int pb = (ib >> 16);
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
|
|
int alpha = ia >> 16;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = m_z0;
|
|
|
|
ir+= dr;
|
|
ig+= dg;
|
|
ib+= db;
|
|
ia+= da;
|
|
j+=dt;
|
|
}
|
|
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
|
|
int pr = ir & 0xFF0000;
|
|
int pg = (ig >> 8) & 0xFF00;
|
|
int pb = (ib >> 16);
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
|
|
int alpha = ia >> 16;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = m_z0;
|
|
|
|
ir+= dr;
|
|
ig+= dg;
|
|
ib+= db;
|
|
ia+= da;
|
|
j+=dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_plain_spatial(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
float iz = m_z0;
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
if (iz <= m_zbuffer[offset]) {
|
|
m_pixels[offset] = m_stroke;
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
iz+=dz;
|
|
j+=dt;
|
|
}
|
|
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
if (iz <= m_zbuffer[offset]) {
|
|
m_pixels[offset] = m_stroke;
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
iz+=dz;
|
|
j+=dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_plain_alpha_spatial(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
float iz = m_z0;
|
|
|
|
int pr = m_stroke & 0xFF0000;
|
|
int pg = m_stroke & 0xFF00;
|
|
int pb = m_stroke & 0xFF;
|
|
|
|
int ia = (int) m_a0;
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = ia >> 16;
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0 &= 0xFF0000;
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
//m_zbuffer[offset] = iz;
|
|
}
|
|
iz +=dz;
|
|
ia += da;
|
|
j += dt;
|
|
}
|
|
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = ia >> 16;
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
//m_zbuffer[offset] = iz;
|
|
}
|
|
iz += dz;
|
|
ia += da;
|
|
j += dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_color_spatial(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
float iz = m_z0;
|
|
|
|
int ir = (int) m_r0;
|
|
int ig = (int) m_g0;
|
|
int ib = (int) m_b0;
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
m_pixels[offset] = 0xFF000000 |
|
|
((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16));
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
iz +=dz;
|
|
ir += dr;
|
|
ig += dg;
|
|
ib += db;
|
|
j += dt;
|
|
}
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
if (iz <= m_zbuffer[offset]) {
|
|
m_pixels[offset] = 0xFF000000 |
|
|
((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16));
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
iz += dz;
|
|
ir += dr;
|
|
ig += dg;
|
|
ib += db;
|
|
j += dt;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
private void drawLine_color_alpha_spatial(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int offset = 0;
|
|
float iz = m_z0;
|
|
|
|
int ir = (int) m_r0;
|
|
int ig = (int) m_g0;
|
|
int ib = (int) m_b0;
|
|
int ia = (int) m_a0;
|
|
|
|
if (vertical) {
|
|
length += y0;
|
|
for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) {
|
|
offset = y0 * SCREEN_WIDTH + (j>>16);
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int pr = ir & 0xFF0000;
|
|
int pg = (ig >> 8) & 0xFF00;
|
|
int pb = (ib >> 16);
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
|
|
int alpha = ia >> 16;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
iz+=dz;
|
|
ir+= dr;
|
|
ig+= dg;
|
|
ib+= db;
|
|
ia+= da;
|
|
j+=dt;
|
|
}
|
|
|
|
} else { // horizontal
|
|
length += x0;
|
|
for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) {
|
|
offset = (j>>16) * SCREEN_WIDTH + x0;
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int pr = ir & 0xFF0000;
|
|
int pg = (ig >> 8) & 0xFF00;
|
|
int pb = (ib >> 16);
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0 &= 0xFF0000;
|
|
|
|
int alpha = ia >> 16;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
iz += dz;
|
|
ir += dr;
|
|
ig += dg;
|
|
ib += db;
|
|
ia += da;
|
|
j += dt;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void drawLine_smooth(int x0, int y0, int dt,
|
|
int length, boolean vertical) {
|
|
int xi, yi; // these must be >=32 bits
|
|
int offset = 0;
|
|
int temp;
|
|
int end;
|
|
|
|
float iz = m_z0;
|
|
|
|
int ir = (int) m_r0;
|
|
int ig = (int) m_g0;
|
|
int ib = (int) m_b0;
|
|
int ia = (int) m_a0;
|
|
|
|
if (vertical) {
|
|
xi = x0 << 16;
|
|
yi = y0 << 16;
|
|
|
|
end = length + y0;
|
|
|
|
while ((yi >> 16) < end) {
|
|
|
|
offset = (yi>>16) * SCREEN_WIDTH + (xi>>16);
|
|
|
|
int pr = ir & 0xFF0000;
|
|
int pg = (ig >> 8) & 0xFF00;
|
|
int pb = (ib >> 16);
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = (((~xi >> 8) & 0xFF) * (ia >> 16)) >> 8;
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
|
|
// this if() makes things slow. there shoudl be
|
|
// a better way to check if the second pixel is
|
|
// withing the image array [rocha]
|
|
temp = ((xi>>16)+1);
|
|
if (temp >= SCREEN_WIDTH) {
|
|
xi += dt;
|
|
yi += (1 << 16);
|
|
continue;
|
|
}
|
|
|
|
offset = (yi>>16) * SCREEN_WIDTH + temp;
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = (((xi >> 8) & 0xFF) * (ia >> 16)) >> 8;
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0 &= 0xFF0000;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
|
|
xi += dt;
|
|
yi += (1 << 16);
|
|
|
|
iz+=dz;
|
|
ir+= dr;
|
|
ig+= dg;
|
|
ib+= db;
|
|
ia+= da;
|
|
}
|
|
|
|
} else { // horizontal
|
|
xi = x0 << 16;
|
|
yi = y0 << 16;
|
|
end = length + x0;
|
|
|
|
while ((xi >> 16) < end) {
|
|
offset = (yi>>16) * SCREEN_WIDTH + (xi>>16);
|
|
|
|
int pr = ir & 0xFF0000;
|
|
int pg = (ig >> 8) & 0xFF00;
|
|
int pb = (ib >> 16);
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = (((~yi >> 8) & 0xFF) * (ia >> 16)) >> 8;
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0 &= 0xFF0000;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
|
|
// see above [rocha]
|
|
temp = ((yi>>16)+1);
|
|
if (temp >= SCREEN_HEIGHT) {
|
|
xi += (1 << 16);
|
|
yi += dt;
|
|
continue;
|
|
}
|
|
|
|
offset = temp * SCREEN_WIDTH + (xi>>16);
|
|
|
|
if (iz <= m_zbuffer[offset]) {
|
|
int alpha = (((yi >> 8) & 0xFF) * (ia >> 16)) >> 8;
|
|
|
|
int r0 = m_pixels[offset];
|
|
int g0 = r0 & 0xFF00;
|
|
int b0 = r0 & 0xFF;
|
|
r0&=0xFF0000;
|
|
|
|
r0 = r0 + (((pr - r0) * alpha) >> 8);
|
|
g0 = g0 + (((pg - g0) * alpha) >> 8);
|
|
b0 = b0 + (((pb - b0) * alpha) >> 8);
|
|
|
|
m_pixels[offset] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
m_zbuffer[offset] = iz;
|
|
}
|
|
|
|
xi += (1 << 16);
|
|
yi += dt;
|
|
|
|
iz+=dz;
|
|
ir+= dr;
|
|
ig+= dg;
|
|
ib+= db;
|
|
ia+= da;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Special "blender" line code by sami,
|
|
* used for anti-aliasing polygon edges
|
|
*/
|
|
/*
|
|
private void drawline_blender(double x0, double y0, double x1, double y1)
|
|
{
|
|
double tmp;
|
|
double dx = x1-x0;
|
|
double dy = y1-y0;
|
|
double adx = (dx >= 0) ? dx : -dx;
|
|
double ady = (dy >= 0) ? dy : -dy;
|
|
|
|
// VERY small line --> skip
|
|
if (adx < 0.0001d && ady < 0.0001d)
|
|
return;
|
|
|
|
// pixel color
|
|
int pxl;
|
|
|
|
// vaakaviiva
|
|
if (adx > ady) {
|
|
// flip if x0 > x1
|
|
if (x0 > x1) {
|
|
tmp = x0;
|
|
x0 = x1;
|
|
x1 = tmp;
|
|
tmp = y0;
|
|
y0 = y1;
|
|
y1 = tmp;
|
|
dx = x1-x0;
|
|
dy = y1-y0;
|
|
}
|
|
|
|
// add interpolation params here
|
|
double addy = dy / dx;
|
|
|
|
int ix0 = (int) (x0 + PIXEL_CENTER);
|
|
if (ix0 < 0)
|
|
ix0 = 0;
|
|
|
|
int ix1 = (int) (x1 + PIXEL_CENTER);
|
|
if (ix1 > SCREEN_WIDTH)
|
|
ix1 = SCREEN_WIDTH;
|
|
|
|
double delta = (ix0 + PIXEL_CENTER) - x0;
|
|
double ys = y0 + delta * addy;
|
|
|
|
for (int a = ix0; a < ix1; a++,ys+=addy) {
|
|
int iy = (int) (ys - PIXEL_CENTER);
|
|
if ((iy >= 0) && (iy < SCREEN_HEIGHT1)) {
|
|
int ofs1 = iy * SCREEN_WIDTH + a;
|
|
int ofs2 = ofs1 + SCREEN_WIDTH;
|
|
|
|
if (m_stencil[ofs1] == m_index) {
|
|
pxl = m_pixels[ofs1];
|
|
} else if (m_stencil[ofs2] == m_index) {
|
|
pxl = m_pixels[ofs2];
|
|
} else {
|
|
//m_pixels[ofs1] = 0xFFFFFF;
|
|
//m_pixels[ofs2] = 0xFFFFFF;
|
|
continue;
|
|
}
|
|
|
|
double frcf = ys - PIXEL_CENTER;
|
|
|
|
int frac1 = ((int) (frcf * 256f) & 0xFF);
|
|
int frac2 = 255 - frac1;
|
|
int pr = (pxl & 0xFF0000);
|
|
int pg = (pxl & 0xFF00);
|
|
int pb = (pxl & 0xFF);
|
|
|
|
int r0 = m_pixels[ofs1];
|
|
int g0 = (r0 & 0xFF00);
|
|
int b0 = (r0 & 0xFF);
|
|
r0 = (r0 & 0xFF0000);
|
|
r0 = r0 + (((pr - r0) * frac2) >> 8);
|
|
g0 = g0 + (((pg - g0) * frac2) >> 8);
|
|
b0 = b0 + (((pb - b0) * frac2) >> 8);
|
|
m_pixels[ofs1] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
|
|
r0 = m_pixels[ofs2];
|
|
g0 = (r0 & 0xFF00);
|
|
b0 = (r0 & 0xFF);
|
|
r0 = (r0 & 0xFF0000);
|
|
r0 = r0 + (((pr - r0) * frac1) >> 8);
|
|
g0 = g0 + (((pg - g0) * frac1) >> 8);
|
|
b0 = b0 + (((pb - b0) * frac1) >> 8);
|
|
m_pixels[ofs2] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
|
|
//m_pixels[ofs1] = 0xFF00FF;
|
|
//m_pixels[ofs2] = 0xFFFF00;
|
|
}
|
|
}
|
|
} else { // pystyviiva
|
|
// flip if y1 > y0
|
|
if (y0 > y1) {
|
|
tmp = x0;
|
|
x0 = x1;
|
|
x1 = tmp;
|
|
tmp = y0;
|
|
y0 = y1;
|
|
y1 = tmp;
|
|
dx = x1-x0;
|
|
dy = y1-y0;
|
|
}
|
|
|
|
double addx = dx / dy;
|
|
int iy0 = (int) (y0 + PIXEL_CENTER);
|
|
if (iy0 < 0)
|
|
iy0 = 0;
|
|
int iy1 = (int) (y1 + PIXEL_CENTER);
|
|
if (iy1 > SCREEN_HEIGHT)
|
|
iy1 = SCREEN_HEIGHT;
|
|
|
|
double delta = (iy0 + PIXEL_CENTER) - y0;
|
|
double xs = x0 + delta * addx;
|
|
|
|
iy0*=SCREEN_WIDTH;
|
|
iy1*=SCREEN_WIDTH;
|
|
for (int a = iy0; a < iy1; a+=SCREEN_WIDTH,xs+=addx) {
|
|
int ix = (int) (xs - PIXEL_CENTER);
|
|
if ((ix >= 0) && (ix < SCREEN_WIDTH1)) {
|
|
int ofs1 = a + ix;
|
|
int ofs2 = ofs1+1;
|
|
|
|
if (m_stencil[ofs1] == m_index) {
|
|
pxl = m_pixels[ofs1];
|
|
} else if (m_stencil[ofs2] == m_index) {
|
|
pxl = m_pixels[ofs2];
|
|
} else {
|
|
//m_pixels[ofs1] = 0xFFFFFF;
|
|
//m_pixels[ofs2] = 0xFFFFFF;
|
|
continue;
|
|
}
|
|
|
|
int pr = (pxl & 0xFF0000);
|
|
int pg = (pxl & 0xFF00);
|
|
int pb = (pxl & 0xFF);
|
|
|
|
double frcf = xs - PIXEL_CENTER;
|
|
int frac1 = ((int) (frcf * 256f) & 0xFF);
|
|
int frac2 = 255 - frac1;
|
|
|
|
int r0 = m_pixels[ofs1];
|
|
int g0 = (r0 & 0xFF00);
|
|
int b0 = (r0 & 0xFF);
|
|
r0 = (r0 & 0xFF0000);
|
|
r0 = r0 + (((pr - r0) * frac2) >> 8);
|
|
g0 = g0 + (((pg - g0) * frac2) >> 8);
|
|
b0 = b0 + (((pb - b0) * frac2) >> 8);
|
|
m_pixels[ofs1] = 0xFF000000 |
|
|
(r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF);
|
|
|
|
r0 = m_pixels[ofs2];
|
|
g0 = (r0 & 0xFF00);
|
|
b0 = (r0 & 0xFF);
|
|
r0 = (r0 & 0xFF0000);
|
|
r0 = r0 + (((pr - r0) * frac1) >> 8);
|
|
g0 = g0 + (((pg - g0) * frac1) >> 8);
|
|
b0 = b0 + (((pb - b0) * frac1) >> 8);
|
|
|
|
//m_pixels[ofs1] = 0x0000FF;
|
|
//m_pixels[ofs2] = 0x00FFFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|