Thread: Basis for a software-based 3d renderer

Page 3 of 3 FirstFirst 123
Results 21 to 27 of 27
  1. #21  
    Retired. Stop PMing me.


    Galkon's Avatar
    Join Date
    Nov 2007
    Age
    17
    Posts
    7,526
    Thanks given
    1,805
    Thanks received
    2,830
    Rep Power
    5000
    Cool shit. Make this something I can put in a swing panel
    Reply With Quote  
     

  2. #22  
    Rune Synergy


    Dane's Avatar
    Join Date
    Jan 2007
    Posts
    189
    Thanks given
    110
    Thanks received
    337
    Rep Power
    2323
    Quote Originally Posted by Galkon View Post
    Cool shit. Make this something I can put in a swing panel
    boom i made a thing

    Reply With Quote  
     

  3. Thankful user:


  4. #23  
    ???

    funkE's Avatar
    Join Date
    Feb 2008
    Posts
    2,612
    Thanks given
    255
    Thanks received
    989
    Rep Power
    1366
    Quote Originally Posted by Dane View Post
    I simplified fillTriangle because all those if's and repeating code were just to properly interpolate if the points weren't in top, middle, bottom order and if it was inverted horizontally or not.

    Code:
    	public void fillTriangle(int xA, int yA, int xB, int yB, int xC, int yC, int color) {
    		if (yC < yA) {
    			int a = yA;
    			yA = yC;
    			yC = a;
    
    			a = xA;
    			xA = xC;
    			xC = a;
    		}
    
    		if (yB < yA) {
    			int a = yA;
    			yA = yB;
    			yB = a;
    
    			a = xA;
    			xA = xB;
    			xB = a;
    		}
    
    		if (yC < yB) {
    			int a = yB;
    			yB = yC;
    			yC = a;
    
    			a = xB;
    			xB = xC;
    			xC = a;
    		}
    
    		// the top point is off screen
    		if (yA >= bottom) return;
    
    		// clamp points on screen
    		if (yB > bottom) yB = bottom;
    		if (yC > bottom) yC = bottom;
    
    		int mAB = 0;
    		int mBC = 0;
    		int mCA = 0;
    
    		// calculate inverted slopes (this is because Y+ goes down)
    		if (yB != yA) mAB = ((xB - xA) << 16) / (yB - yA);
    		if (yC != yB) mBC = ((xC - xB) << 16) / (yC - yB);
    		if (yC != yA) mCA = ((xA - xC) << 16) / (yA - yC);
    
    		// our X positions along our edges
    		int x0 = xA << 16;
    		int x1 = x0;
    		int x2 = xB << 16;
    
    		// A is above the screen
    		if (yA < 0) {
    			x0 -= mCA * yA;
    			x1 -= mAB * yA;
    			yA = 0;
    		}
    
    		// B is above the screen
    		if (yB < 0) {
    			x2 -= mBC * yB;
    			yB = 0;
    		}
    		
    		int heightA = yB - yA;
    		int heightB = yC - yB;
    		int offset = offsets[yA];
    
    		while (--heightA >= 0) {
    			drawScanline(offset, x0 >> 16, x1 >> 16, color);
    
    			x0 += mCA;
    			x1 += mAB;
    
    			offset += width;
    		}
    
    		while (--heightB >= 0) {
    			drawScanline(offset, x0 >> 16, x2 >> 16, color);
    
    			x0 += mCA;
    			x2 += mBC;
    
    			offset += width;
    		}
    	}
    
    	private void drawScanline(int offset, int xA, int xB, int rgb) {
    		if (xA == xB) return;
    
    		// invert
    		if (xA >= xB) {
    			int a = xA;
    			xA = xB;
    			xB = a;
    		}
    
    		// clamp
    		if (xB > right) xB = right;
    		if (xA < left) xA = left;
    
    		int length = xB - xA;
    		offset += xA;
    
    		while (--length >= 0) {
    			data[offset++] = rgb;
    		}
    	}
    Here's a simplified fillGradientTriangle using the HSL table



    Code:
    	public void fillGradientTriangle(int xA, int yA, int colorA, int xB, int yB, int colorB, int xC, int yC, int colorC) {
    		if (yC < yA) {
    			int a = yA;
    			yA = yC;
    			yC = a;
    
    			a = xA;
    			xA = xC;
    			xC = a;
    
    			a = colorA;
    			colorA = colorC;
    			colorC = a;
    		}
    
    		if (yB < yA) {
    			int a = yA;
    			yA = yB;
    			yB = a;
    
    			a = xA;
    			xA = xB;
    			xB = a;
    
    			a = colorA;
    			colorA = colorB;
    			colorB = a;
    		}
    
    		if (yC < yB) {
    			int a = yB;
    			yB = yC;
    			yC = a;
    
    			a = xB;
    			xB = xC;
    			xC = a;
    
    			a = colorB;
    			colorB = colorC;
    			colorC = a;
    		}
    
    		// the top point is off screen
    		if (yA >= bottom) return;
    
    		// clamp points on screen
    		if (yB > bottom) yB = bottom;
    		if (yC > bottom) yC = bottom;
    
    		int mAB = 0;
    		int mBC = 0;
    		int mCA = 0;
    
    		int mCAB = 0;
    		int mCBC = 0;
    		int mCCA = 0;
    
    		if (yB != yA) {
    			mAB = ((xB - xA) << 16) / (yB - yA);
    			mCAB = ((colorB - colorA) << 16) / (yB - yA);
    		}
    
    		if (yC != yB) {
    			mBC = ((xC - xB) << 16) / (yC - yB);
    			mCBC = ((colorC - colorB) << 16) / (yC - yB);
    		}
    
    		if (yC != yA) {
    			mCA = ((xA - xC) << 16) / (yA - yC);
    			mCCA = ((colorA - colorC) << 16) / (yA - yC);
    		}
    
    		int x0 = xA << 16;
    		int x1 = x0;
    		int x2 = xB << 16;
    
    		int rgb0 = colorA << 16;
    		int rgb1 = rgb0;
    		int rgb2 = colorB << 16;
    
    		// A is above the screen
    		if (yA < 0) {
    			x0 -= mCA * yA; // A -> C
    			x1 -= mAB * yA; // A -> B
    
    			rgb0 -= mCCA * yA;
    			rgb1 -= mCAB * yA;
    
    			yA = 0;
    		}
    
    		// B is above the screen
    		if (yB < 0) {
    			x2 -= mBC * yB; // B -> C
    			rgb2 -= mCBC * yB;
    			yB = 0;
    		}
    
    		int heightA = yB - yA;
    		int heightB = yC - yB;
    		int offset = offsets[yA];
    
    		while (--heightA >= 0) {
    			drawGradientScanline(offset, x0 >> 16, x1 >> 16, rgb0, rgb1);
    
    			x0 += mCA;
    			x1 += mAB;
    
    			rgb0 += mCCA;
    			rgb1 += mCAB;
    
    			offset += width;
    		}
    
    		while (--heightB >= 0) {
    			drawGradientScanline(offset, x0 >> 16, x2 >> 16, rgb0, rgb2);
    
    			x0 += mCA;
    			x2 += mBC;
    
    			rgb0 += mCCA;
    			rgb2 += mCBC;
    
    			offset += width;
    		}
    	}
    
    	private void drawGradientScanline(int offset, int xA, int xB, int colorA, int colorB) {
    		if (xA == xB) return;
    
    		// flip if inverted
    		if (xA > xB) {
    			int a = xB;
    			xB = xA;
    			xA = a;
    
    			a = colorB;
    			colorB = colorA;
    			colorA = a;
    		}
    
    		int m = (colorB - colorA) / (xB - xA);
    
    		if (xB > right) {
    			xB = right;
    		}
    
    		if (xA < left) {
    			colorA -= xA * m;
    			xA = 0;
    		}
    
    		int length = xB - xA;
    		offset += xA;
    
    		while (--length >= 0) {
    			data[offset++] = Graphics3D.palette[colorA >> 16];
    			colorA += m;
    		}
    	}
    affine texture mapping



    Code:
    	public void fillAffineTexturedTriangle(Bitmap bitmap, int xA, int yA, int uA, int vA, int xB, int yB, int uB, int vB, int xC, int yC, int uC, int vC) {
    		if (yC < yA) {
    			int a = yA;
    			yA = yC;
    			yC = a;
    
    			a = xA;
    			xA = xC;
    			xC = a;
    
    			a = uA;
    			uA = uC;
    			uC = a;
    
    			a = vA;
    			vA = vC;
    			vC = a;
    		}
    
    		if (yB < yA) {
    			int a = yA;
    			yA = yB;
    			yB = a;
    
    			a = xA;
    			xA = xB;
    			xB = a;
    
    			a = uA;
    			uA = uB;
    			uB = a;
    
    			a = vA;
    			vA = vB;
    			vB = a;
    		}
    
    		if (yC < yB) {
    			int a = yB;
    			yB = yC;
    			yC = a;
    
    			a = xB;
    			xB = xC;
    			xC = a;
    
    			a = uB;
    			uB = uC;
    			uC = a;
    
    			a = vB;
    			vB = vC;
    			vC = a;
    		}
    
    		// the top point is off screen
    		if (yA >= bottom) return;
    
    		// clamp points on screen
    		if (yB > bottom) yB = bottom;
    		if (yC > bottom) yC = bottom;
    
    		int mAB = 0;
    		int mBC = 0;
    		int mCA = 0;
    
    		int mUAB = 0;
    		int mVAB = 0;
    
    		int mUBC = 0;
    		int mVBC = 0;
    
    		int mUCA = 0;
    		int mVCA = 0;
    
    		if (yB != yA) {
    			mAB = ((xB - xA) << 16) / (yB - yA);
    			mUAB = ((uB - uA) << 16) / (yB - yA);
    			mVAB = ((vB - vA) << 16) / (yB - yA);
    		}
    
    		if (yC != yB) {
    			mBC = ((xC - xB) << 16) / (yC - yB);
    			mUBC = ((uC - uB) << 16) / (yC - yB);
    			mVBC = ((vC - vB) << 16) / (yC - yB);
    		}
    
    		if (yC != yA) {
    			mCA = ((xA - xC) << 16) / (yA - yC);
    			mUCA = ((uA - uC) << 16) / (yA - yC);
    			mVCA = ((vA - vC) << 16) / (yA - yC);
    		}
    
    		int x0 = xA << 16;
    		int x1 = x0;
    		int x2 = xB << 16;
    
    		int u0 = uA << 16;
    		int v0 = vA << 16;
    
    		int u1 = u0;
    		int v1 = v0;
    
    		int u2 = uB << 16;
    		int v2 = vB << 16;
    
    		// A is above the screen
    		if (yA < 0) {
    			x0 -= mCA * yA; // A -> C
    			x1 -= mAB * yA; // A -> B
    
    			u0 -= mUCA * yA;
    			v0 -= mVCA * yA;
    
    			u1 -= mUAB * yA;
    			v1 -= mVAB * yA;
    
    			yA = 0;
    		}
    
    		// B is above the screen
    		if (yB < 0) {
    			x2 -= mBC * yB; // B -> C
    			u2 -= mUBC * yB;
    			v2 -= mVBC * yB;
    			yB = 0;
    		}
    
    		int heightA = yB - yA;
    		int heightB = yC - yB;
    		int offset = offsets[yA];
    
    		while (--heightA >= 0) {
    			drawAffineTexturedScanline(offset, bitmap, x0 >> 16, u0, v0, x1 >> 16, u1, v1);
    
    			x0 += mCA;
    			x1 += mAB;
    
    			u0 += mUCA;
    			v0 += mVCA;
    
    			u1 += mUAB;
    			v1 += mVAB;
    
    			offset += width;
    		}
    
    		while (--heightB >= 0) {
    			drawAffineTexturedScanline(offset, bitmap, x0 >> 16, u0, v0, x2 >> 16, u2, v2);
    
    			x0 += mCA;
    			x2 += mBC;
    
    			u0 += mUCA;
    			v0 += mVCA;
    
    			u2 += mUBC;
    			v2 += mVBC;
    
    			offset += width;
    		}
    	}
    
    	public void drawAffineTexturedScanline(int offset, Bitmap bitmap, int xA, int uA, int vA, int xB, int uB, int vB) {
    		if (xA == xB) return;
    
    		// flip if inverted
    		if (xA > xB) {
    			int a = xB;
    			xB = xA;
    			xA = a;
    
    			a = uB;
    			uB = uA;
    			uA = a;
    
    			a = vB;
    			vB = vA;
    			vA = a;
    		}
    
    		int uM = (uB - uA) / (xB - xA);
    		int vM = (vB - vA) / (xB - xA);
    
    		if (xA < left) {
    			uA -= xA * uM;
    			vA -= xA * vM;
    			xA = 0;
    		}
    
    		if (xB > right) {
    			xB = right;
    		}
    
    		int length = xB - xA;
    		offset += xA;
    
    		uA += uM >> 1;
    		vA += vM >> 1;
    
    		while (length-- > 0) {
    			int x = uA >> 16;
    			int y = vA >> 16;
    
    			// clamp
    			if (x >= bitmap.width) x = bitmap.width - 1;
    			if (y >= bitmap.height) y = bitmap.height - 1;
    
    			int rgb = bitmap.data[x + (y * bitmap.width)];
    			if (rgb != 0) data[offset] = rgb;
    			offset++;
    
    			uA += uM;
    			vA += vM;
    		}
    	}
    I wonder if there's any reason the RS engine is done the way it is. I too have simplified a few things basically rewriting that part of the code, but I can't help but wonder why Jagex didn't do that same thing. Maybe just never thought twice about it.

    If you could provide info about how textures are mapped to triangles (and more importantly, objects) that'd be great.

    I mean, how do we easily determine at which part of an image we start mapping from? what about each point around the entire object? This is something that has kind of confused me about texture mapping even in OpenGL. I don't really feel comfortable using it because I don't understand it.

    Maybe it would be better if we used something like Point objects so we could make the render code more readable. Maybe that would help us provide a way to easily port to OpenGL. Separate the renderer code and just have the renderer figure out how it wants to do things (int vs floating point, etc.). So models and the like aren't limited by renderer design, rather the renderer is only limited by what it can accomplish.

    I'd really like to implement ground blending on a 317 just to kind of learn, and I have a feeling I have an idea how to accomplish that by re-reading this thread.
    .
    Reply With Quote  
     

  5. #24  
    Retired. Stop PMing me.


    Galkon's Avatar
    Join Date
    Nov 2007
    Age
    17
    Posts
    7,526
    Thanks given
    1,805
    Thanks received
    2,830
    Rep Power
    5000
    So did you release this? I have been ripping the 3d canvas to put in my cache suite for previews but it's a work in progress as I haven't had much time for it
    Reply With Quote  
     

  6. #25  
    Rune Synergy


    Dane's Avatar
    Join Date
    Jan 2007
    Posts
    189
    Thanks given
    110
    Thanks received
    337
    Rep Power
    2323
    Quote Originally Posted by Galkon View Post
    So did you release this? I have been ripping the 3d canvas to put in my cache suite for previews but it's a work in progress as I haven't had much time for it
    I have this I wrote awhile ago: https://github.com/thedaneeffect/RT3

    It's not the prettiest but it's the most I've done so far with rendering a 3d scene. Looking back on it now it's pretty embarrassing I wrote it but it'll do. I think I'm going to rewrite it one day.
    Reply With Quote  
     

  7. #26  
    Rune Synergy


    Dane's Avatar
    Join Date
    Jan 2007
    Posts
    189
    Thanks given
    110
    Thanks received
    337
    Rep Power
    2323
    This is C++ but I thought it would be pretty cool to some people. Check it out: 3D C/C++ tutorials - Software rendering



    Simple software renderer

    The purpose of this tutorial is to help you understand the math and algorithms behind

    multithreaded rendering
    getting number of processor cores
    creating threads
    running every thread on a different core
    setting the minimum timer resolution
    thread synchronization
    initializing, resizing and clearing color and depth buffers
    primitive assembly
    vertex shader
    triangle visibility testing using homogeneous coordinates
    triangle clipping using homogeneous coordinates
    perspective division
    front and back face triangle culling
    triangle rasterization with perspective correct z and attribute values interpolation
    depth test
    fragment shader
    nearest and bilinear texture filtering
    writing to 24-bit color buffer and 32-bit depth buffer
    2x2, 3x3 and 4x4 antialiasing
    Reply With Quote  
     

  8. #27  
    Rune Synergy


    Dane's Avatar
    Join Date
    Jan 2007
    Posts
    189
    Thanks given
    110
    Thanks received
    337
    Rep Power
    2323
    interpolating rgb values

    Code:
    	public void fillGradientTriangleRGB(int x0, int y0, int rgb0, int x1, int y1, int rgb1, int x2, int y2, int rgb2) {
    		if (y2 < y0) {
    			int tmp = x0;
    			x0 = x2;
    			x2 = tmp;
    			
    			tmp = y0;
    			y0 = y2;
    			y2 = tmp;
    			
    			tmp = rgb0;
    			rgb0 = rgb2;
    			rgb2 = tmp;
    		}
    		
    		if (y1 < y0) {
    			int tmp = x0;
    			x0 = x1;
    			x1 = tmp;
    			
    			tmp = y0;
    			y0 = y1;
    			y1 = tmp;
    			
    			tmp = rgb0;
    			rgb0 = rgb1;
    			rgb1 = tmp;
    		}
    		
    		if (y2 < y1) {
    			int tmp = x1;
    			x1 = x2;
    			x2 = tmp;
    			
    			tmp = y1;
    			y1 = y2;
    			y2 = tmp;
    			
    			tmp = rgb1;
    			rgb1 = rgb2;
    			rgb2 = tmp;
    		}
    		
    		if (y0 >= height) return;
    		
    		int r0 = (rgb0 >> 16) & 0xFF;
    		int g0 = (rgb0 >> 8) & 0xFF;
    		int b0 = rgb0 & 0xFF;
    		
    		int r1 = (rgb1 >> 16) & 0xFF;
    		int g1 = (rgb1 >> 8) & 0xFF;
    		int b1 = rgb1 & 0xFF;
    		
    		int r2 = (rgb2 >> 16) & 0xFF;
    		int g2 = (rgb2 >> 8) & 0xFF;
    		int b2 = rgb2 & 0xFF;
    		
    		int mx0 = 0, mr0 = 0, mg0 = 0, mb0 = 0;
    		int mx1 = 0, mr1 = 0, mg1 = 0, mb1 = 0;
    		int mx2 = 0, mr2 = 0, mg2 = 0, mb2 = 0;
    		
    		if (y0 != y1) {
    			int denom = y1 - y0;
    			mx0 = ((x1 - x0) << 16) / denom;
    			mr0 = ((r1 - r0) << 16) / denom;
    			mg0 = ((g1 - g0) << 16) / denom;
    			mb0 = ((b1 - b0) << 16) / denom;
    		}
    		
    		if (y1 != y2) {
    			int denom = y2 - y1;
    			mx1 = ((x2 - x1) << 16) / denom;
    			mr1 = ((r2 - r1) << 16) / denom;
    			mg1 = ((g2 - g1) << 16) / denom;
    			mb1 = ((b2 - b1) << 16) / denom;
    		}
    		
    		if (y2 != y0) {
    			int denom = y2 - y0;
    			mx2 = ((x2 - x0) << 16) / denom;
    			mr2 = ((r2 - r0) << 16) / denom;
    			mg2 = ((g2 - g0) << 16) / denom;
    			mb2 = ((b2 - b0) << 16) / denom;
    		}
    		
    		x0 <<= 16;
    		r0 <<= 16;
    		g0 <<= 16;
    		b0 <<= 16;
    		
    		x2 = x1 << 16;
    		r2 = r1 << 16;
    		g2 = g1 << 16;
    		b2 = b1 << 16;
    		
    		x1 = x0;
    		r1 = r0;
    		g1 = g0;
    		b1 = b0;
    		
    		if (y0 < 0) {
    			x0 -= mx2 * y0;
    			r0 -= mr2 * y0;
    			g0 -= mg2 * y0;
    			b0 -= mb2 * y0;
    			
    			x1 -= mx0 * y0;
    			r1 -= mr0 * y0;
    			g1 -= mg0 * y0;
    			b1 -= mb0 * y0;
    			
    			y0 = 0;
    		}
    		
    		if (y1 < 0) {
    			x2 -= mx1 * y1;
    			r2 -= mr1 * y1;
    			g2 -= mg1 * y1;
    			b2 -= mb1 * y1;
    			
    			y1 = 0;
    		}
    		
    		int remaining = y1 - y0;
    		int offset = offsets[y0];
    		
    		while (remaining-- > 0) {
    			if(y0++ >= height) return;
    			
    			drawGradientScanlineRGB(offset, x0 >> 16, r0, g0, b0, x1 >> 16, r1, g1, b1);
    			
    			x0 += mx2;
    			r0 += mr2;
    			g0 += mg2;
    			b0 += mb2;
    			
    			x1 += mx0;
    			r1 += mr0;
    			g1 += mg0;
    			b1 += mb0;
    			
    			offset += width;
    		}
    		
    		remaining = y2 - y1;
    		
    		while (remaining-- > 0) {
    			if(y0++ >= height) return;
    			
    			drawGradientScanlineRGB(offset, x0 >> 16, r0, g0, b0, x2 >> 16, r2, g2, b2);
    			
    			x0 += mx2;
    			r0 += mr2;
    			g0 += mg2;
    			b0 += mb2;
    			
    			x2 += mx1;
    			r2 += mr1;
    			g2 += mg1;
    			b2 += mb1;
    			
    			offset += width;
    		}
    	}
    	
    	private void drawGradientScanlineRGB(int offset, int x0, int r0, int g0, int b0, int x1, int r1, int g1, int b1) {
    		if (x0 == x1) return;
    		
    		if (x0 > x1) {
    			int tmp = x0;
    			x0 = x1;
    			x1 = tmp;
    			
    			tmp = r0;
    			r0 = r1;
    			r1 = tmp;
    			
    			tmp = g0;
    			g0 = g1;
    			g1 = tmp;
    			
    			tmp = b0;
    			b0 = b1;
    			b1 = tmp;
    		}
    		
    		int len = x1 - x0;
    		
    		int mr = (r1 - r0) / len;
    		int mg = (g1 - g0) / len;
    		int mb = (b1 - b0) / len;
    		
    		if (x0 < 0) {
    			r0 -= x0 * mr;
    			g0 -= x0 * mg;
    			b0 -= x0 * mb;
    			x0 = 0;
    		}
    		
    		if (x1 > width) x1 = width - 1;
    		
    		len = x1 - x0;
    		offset += x0;
    		
    		while (len-- > 0) {
    			data[offset] = (r0 & 0xFF0000) | ((g0 >> 8) & 0xFF00) | (b0 >> 16);
    			r0 += mr;
    			g0 += mg;
    			b0 += mb;
    			offset++;
    		}
    	}


    creating that hsl lookup table of any size

    Code:
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.awt.image.DataBufferInt;
    import java.io.File;
    import java.io.IOException;
    
    public final class Palette {
    
    	public static void main(String[] args) throws IOException {
    		BufferedImage image = new BufferedImage(512, 2048, BufferedImage.TYPE_INT_RGB);
    		create(((DataBufferInt) image.getRaster().getDataBuffer()).getData(), 512, 2048, 64);
    		ImageIO.write(image, "png", new File("palette.png"));
    	}
    
    	public static double getValue(double value, double a, double b) {
    		if ((6.0 * value) < 1.0) return b + ((a - b) * 6.0 * value);
    		if (2.0 * value < 1.0) return a;
    		if (3.0 * value < 2.0) return b + ((a - b) * ((2.0 / 3.0) - value) * 6.0);
    		return b;
    	}
    
    	public static int[] create(int width, int height) {
    		return create(null, width, height, 64); // the color channel normally generated has 64 hues
    	}
    
    	public static int[] create(int[] dst, int width, int height, int hueCount) {
    		int offset = 0;
    		int hueHeight = height / hueCount;
    		
    		if (dst == null) dst = new int[width * height];
    
    		for (int y = 0; y < height; y++) {
    			double fGreen = (y / hueHeight) / (double) hueCount;
    			double saturation = (y & (hueHeight - 1)) / (double) hueHeight;
    
    			for (int x = 0; x < width; x++) {
    				double lightness = x / (double) width;
    				double red = lightness;
    				double green = lightness;
    				double blue = lightness;
    
    				if (saturation != 0.0) {
    					double valueA;
    
    					if (lightness < 0.5) {
    						valueA = lightness * (1.0 + saturation);
    					} else {
    						valueA = (lightness + saturation) - (lightness * saturation);
    					}
    
    					double valueB = (2.0 * lightness) - valueA;
    					double fRed = fGreen + (1.0 / 3.0);
    					double fBlue = fGreen - (1.0 / 3.0);
    
    					if (fRed > 1.0) fRed--;
    					if (fBlue < 0.0) fBlue++;
    
    					red = getValue(fRed, valueA, valueB);
    					green = getValue(fGreen, valueA, valueB);
    					blue = getValue(fBlue, valueA, valueB);
    				}
    				dst[offset++] = ((int) (red * 256.0) << 16) | ((int) (green * 256.0) << 8) | (int) (blue * 256.0);
    			}
    		}
    		return dst;
    	}
    }
    512x2048:
    Attached image
    Reply With Quote  
     

  9. Thankful users:


Page 3 of 3 FirstFirst 123

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. equipment tab for Galkons Client Base
    By DSscape™ in forum Requests
    Replies: 0
    Last Post: 07-31-2009, 06:12 AM
  2. Sig For My New Base Rs2DB
    By Snow Cat123 in forum Requests
    Replies: 0
    Last Post: 07-01-2009, 06:11 PM
  3. Good for I/O base?
    By w::v::d in forum Snippets
    Replies: 1
    Last Post: 06-30-2009, 09:43 PM
  4. how / where is the 3d rendered
    By Clienthax in forum RS2 Client
    Replies: 7
    Last Post: 10-11-2008, 07:04 AM
  5. 3D Render Signature.
    By Mr Chainsaw in forum Showcase
    Replies: 20
    Last Post: 11-18-2007, 03:34 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •