Matei: the proper tag to use is [ source ][ /source ] so you don''t make the forum scroll left to right
.
private int [] pixels; private MemoryImageSource imageSource; private Image backBuffer; private int [] left = new int [2000]; // store the x value of the pixel on the left side of the triangle at a given y value.</font> private int [] right = new int [2000]; // ditto for the right side</font> private void createMemoryImage() { // should be called after you set/change your window size</font> this .pixels = new int [displayWidth*displayHeight]; this .imageSource = new MemoryImageSource(displayWidth, displayHeight, pixels, 0, displayWidth); imageSource.setAnimated(true ); this .backBuffer = Toolkit.getDefaultToolkit().createImage(imageSource); } /* Given a line, calculate its x coordinates for each y value and place them into dest. My example uses some fixed-point math, which is not the best way; you can make it use doubles or use a true integer line-scanning algorithm; I''ll post a real one when I implement it myself - right now this was just needed to get things working, and it does work fairly well. */</font> private void getLineXVals(int x1, int y1, int x2, int y2, int [] dest) { if (y1 > y2) { // swap so y1 is on top</font> int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; } else if (y1 == y2) { // horizontal</font> return ; } int dx, dy; dy = y2 - y1; dx = x2 - x1; int gi = (dx*2048) / dy; // multiplies and divides by 2048 should get optimized to shifts by the compiler.</font> int xi = (x1*2048); for (int y = y1; y < y2; y++) { dest[y] = (xi/2048); xi += gi; } } private void rasterizeTriangle(ProcessedPrimitive p) { // p is just a class that contains the vertices of the triangle in *counterclockwise* order (important!)</font> // they are stored as doubles, so we cast them here; if you''re really adventurous you can look for a moe</font> // precise line-drawing algorithm that actually uses doubles rather than ints and make the </font> // appropriate changes.</font> int x0 = (int ) p.x[0]; int x1 = (int ) p.x[1]; int x2 = (int ) p.x[2]; int y0 = (int ) p.y[0]; int y1 = (int ) p.y[1]; int y2 = (int ) p.y[2]; int yMin = y0; int yMax = y0; if (y1 < yMin) yMin = y1; else if (y1 > yMax) yMax = y1; if (y2 < yMin) yMin = y2; else if (y2 > yMax) yMax = y2; // use the fact that the vertices are in counterclockwise order to determine whether</font> // the edges are left or right edges.</font> getLineXVals(x0, y0, x1, y1, (y0>y1 ? left : right)); getLineXVals(x1, y1, x2, y2, (y1>y2 ? left : right)); getLineXVals(x0, y0, x2, y2, (y2>y0 ? left : right)); int col = p.color.getRGB(); for (int y = yMin; y < yMax; y++) { int l = left[y]; int r = right[y]; int w = r - l; if (w<0) continue ; int from = y*displayWidth + l; int to = from+w; Arrays.fill(pixels, from, to, col); // fast way to fill a continuous segment;</font> // if you want to do other calculations for each pixel (maybe Gouraud shading or texturing?), use</font> // a manual fill as follows:</font> // int pos = y*displayWidth + l;</font> // for(int i=0; i<w; i++) {</font> // pixels[pos] = col;</font> // pos++;</font> // }</font> } } public void paint(Graphics g) { // clear background to black:</font> int max = displayWidth*displayHeight; for (int p=0; p<max; p++) { pixels[p] = 0xff000000; // alpha=255, r=0, g=0, b=0</font> } // for each triangle, rasterizeTriangle(t);</font> // now draw the raster image onto the screen</font> imageSource.newPixels(); g.drawImage(backBuffer, 0, 0, null); }
First make it work, then make it fast. --Brian Kernighan
The problems of this world cannot possibly be solved by skeptics or cynics whose horizons are limited by the obvious realities. We need men and women who can dream of things that never were. - John Fitzgerald Kennedy(35th US President)
Do not interrupt your enemy when he is making a mistake. - Napolean Bonaparte