Advertisement

Blending and Lighting don't play well together...

Started by June 22, 2003 04:49 PM
3 comments, last by FunkyB 21 years, 8 months ago
Hi, i''ve been having problems with enabling lighting on my scene that uses blending. Without lights the transparent polygons are drawn correctly yet as soon as I enable lighting all polygons are totally opaque, regardless of alpha value. I have included the source of my project, its just something simple that I''m playing with to learn gl and it has loads of rubbish in it but it should work and yet doesn''t Interestingly if I use GL_ONE instead of GL_ONE_MINUS_SRC_ALPHA for the blending function then everything becomes transparent and I can''t stop it. Hmm If someone could help me with this I would be very grateful Thanks

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#include <gl\glut.h>

#define ESCAPE 27
#define ARRMAX 40
#define SCALE 20
#define GRAVITY 60
#define BOUNCE 1.0
#define CAMINT 0.9


GLuint texture[2];

////////////////////////////////

//Texture Initialisation Code //

////////////////////////////////


//Loads the image

AUX_RGBImageRec *LoadBMP(char *Filename) 
{
	FILE *File=NULL;						//Create a file handle


	if(!Filename)							//Make sure filename was given

		return NULL;						//It wasn''t so b0rk


	File=fopen(Filename, "r");				//Check if exists


	if(File)
	{
		fclose(File);
		return auxDIBImageLoad(Filename);	//Load and return a pointer

	}
	
	return NULL;
}

//Load BMPs and convert to textures

int LoadGLTextures(int NoOfTex, char**FNames)
{
	int Status=TRUE;
	AUX_RGBImageRec *TextureImage[1];			//Storage for the texture


	//Clear the image record to make sure its empty

	memset(TextureImage,0,sizeof(void *)*1);	//Set pointer to NULL


	//Load the bitmaps, check for errors

	for (int i=0; i<NoOfTex; i++)
	{
		if(!(TextureImage[i]=LoadBMP(FNames[i])))
		{
			Status = FALSE;
		}
	}

	if(!Status) return FALSE;

	for (i=0; i<NoOfTex; i++)
	{
		//Now that bmp loaded need to convert to texture

		//Number of textures, Where to store textures (declared above)

		glGenTextures(1, &texture[i]);			//Create the texture


		//Tell OpenGL memory is available at &texture[0] for a texture

		glBindTexture(GL_TEXTURE_2D, texture[i]);

		//Create the actual texture

		glTexImage2D(GL_TEXTURE_2D, 
					0,						//Levels of detail

					3,						//Components (RGB)

					TextureImage[i]->sizeX,	//Get X size from the loaded data

					TextureImage[i]->sizeY, 
					0,						//Border

					GL_RGB,					//Data type

					GL_UNSIGNED_BYTE,		//Representation

					TextureImage[i]->data);	//Data


		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);


		//Garbage collection

		if(TextureImage[i])
		{
			if(TextureImage[i]->data)
			{
				free(TextureImage[i]->data);
			}
			free(TextureImage[i]);
		}

	}

	return Status;
}





// GL Initialisation Code

// Here we will put variables which we wish to be global

///////////////////////////////////////////////////////////


GLint window; // The number of our GLUT window

GLint Xsize=500;
GLint Ysize=500;

int MatrixStylee = 0, AutoRot = 0;
float cam_angle = 0, cam_pitch = 0;

GLfloat LightAmbient[] = { 0.5, 0.5, 0.5, 0.5 };  
GLfloat LightDiffuse[] = { 1.0, 1.0, 1.0, 0.5 };  
GLfloat LightPosition[] = { 0.0, 0.0, 2.0, 1.0 };    /* position */

GLfloat parray[ARRMAX][7];
	// 0 = X pos

	// 1 = Y pos

	// 2 = Z pos

	// 3 = X velocity

	// 4 = Y velocity

	// 5 = Z velocity

	// 6 = radius



//Called by the window resize code

//Sets the viewport perspective and stuff

GLvoid Transform(GLfloat Width, GLfloat Height)
{
	glViewport(0, 0, Width, Height);				// Set the viewport

	glMatrixMode(GL_PROJECTION);					// Select the projection matrix

	glLoadIdentity();								// Reset The Projection Matrix

	//gluPerspective(FOV, Aspect, Near Clip, Far Clip)

	gluPerspective(45.0,Width/Height,2,1000.0);	// Calculate The Aspect Ratio Of The Window

	glMatrixMode(GL_MODELVIEW);						// Switch back to the modelview matrix

}


// The function called when our window is resized

// Sets vars then calls Transform

GLvoid ReSizeGLScene(GLint Width, GLint Height)
{
	if (Height==0) Height=1;						// Sanity checks

	if (Width ==0) Width=1;
	Transform( Width , Height );					// Perform the transformation

}


// A general OpenGL initialization function. Sets all of the initial parameters

// Called by main() before jumping into the GLUT loop

GLvoid InitGL(GLfloat Width, GLfloat Height)	
{
	char * FNArray[2] ={"crate.bmp", "check2.bmp"};
	
	glClearColor(0.0, 0.0, 0.0, 0.5);				// Clear The Background Colour To Black

	glClearDepth(1.0f);									// Depth Buffer Setup


	glPointSize(2.0);
	glLineWidth(1.0);
	glShadeModel(GL_SMOOTH);

	glDepthFunc(GL_LESS);
	glEnable(GL_DEPTH_TEST);

	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);			// Really Nice Perspective Calculations


	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	//glBlendFunc( GL_SRC_ALPHA, GL_ONE);

	glEnable(GL_BLEND);

	glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);		//  add lighting. (ambient)	

	glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);		//  add lighting. (diffuse)

	glLightfv(GL_LIGHT0, GL_POSITION,LightPosition);	//  set light position.		

	glEnable(GL_LIGHT0);								//  turn light 0 on.		

	glEnable(GL_LIGHTING);

	if(!LoadGLTextures(2, FNArray))
	{
		//Something went wrong

		MessageBox(NULL, "Couldn''t load textures", "Texture Load Error", MB_OK|MB_ICONEXCLAMATION);
	}	
	
	Transform( Width, Height );						// Perform the transformation

}



float gettime(){
  static clock_t t_old = 0;
  clock_t t_new, elapsed;

  t_new = clock();

  elapsed = t_new - t_old;

  t_old = t_new;
  
  return (float) elapsed / CLOCKS_PER_SEC;
}


//The main drawing function. This is the function which will be 

//called when a "redisplay" is requested.


GLvoid DrawGLScene()
{
	int i =0;
	float R;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear screen & depth buffer

	glPushMatrix();
	glLoadIdentity();
	
	//Global scene modifiers

	glTranslatef(0.0,-40.0,-175.0);
	glRotatef(cam_angle, 0.0, 1.0, 0.0);
	glRotatef(cam_pitch, 1.0, 0.0, 0.0);

	glColor4f(1.0, 1.0, 1.0, 1.0);

	//Draw the floor

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[0]);		//Select floor texture

	glBegin(GL_QUADS);
		glNormal3f( 0.0f, 5.0f, 0.0f);	
		glTexCoord2f(0.0f, 0.0f);
		glVertex3f(-70.0, 0, -70.0);
		glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-70.0, 0, 70.0);
		glTexCoord2f(1.0f, 1.0f);
		glVertex3f(70.0, 0, 70.0);
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f(70.0, 0, -70.0);
	glEnd();
	glDisable(GL_TEXTURE_2D);


	//Draw the objects

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[1]);
	for(i=0; i<ARRMAX; i++)
	{
		glPushMatrix();
			glTranslatef(parray[i][0], parray[i][1], parray[i][2]);
			//glutSolidSphere(parray[6],20,20);
</font>
			<font color=gray>//glutSolidCube(parray[6]);
</font>

			R = parray[<font color=purple>i</font>][<font color=purple>6</font>];

			glBegin(GL_QUADS);
				<font color=gray>// Front Face
</font>
				glNormal3f( 0.0f, 0.0f, 1.0f);
				glTexCoord2f(0.0f, 0.0f); glVertex3f(-R, -R,  R);
				glTexCoord2f(1.0f, 0.0f); glVertex3f( R, -R,  R);
				glTexCoord2f(1.0f, 1.0f); glVertex3f( R,  R,  R);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(-R,  R,  R);
				<font color=gray>// Back Face
</font>
				glNormal3f( 0.0f, 0.0f,-1.0f);
				glTexCoord2f(1.0f, 0.0f); glVertex3f(-R, -R, -R);
				glTexCoord2f(1.0f, 1.0f); glVertex3f(-R,  R, -R);
				glTexCoord2f(0.0f, 1.0f); glVertex3f( R,  R, -R);
				glTexCoord2f(0.0f, 0.0f); glVertex3f( R, -R, -R);
				<font color=gray>// Top Face
</font>
				glNormal3f( 0.0f, 1.0f, 0.0f);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(-R,  R, -R);
				glTexCoord2f(0.0f, 0.0f); glVertex3f(-R,  R,  R);
				glTexCoord2f(1.0f, 0.0f); glVertex3f( R,  R,  R);
				glTexCoord2f(1.0f, 1.0f); glVertex3f( R,  R, -R);
				<font color=gray>// Bottom Face
</font>
				glNormal3f( 0.0f,-1.0f, 0.0f);
				glTexCoord2f(1.0f, 1.0f); glVertex3f(-R, -R, -R);
				glTexCoord2f(0.0f, 1.0f); glVertex3f( R, -R, -R);
				glTexCoord2f(0.0f, 0.0f); glVertex3f( R, -R,  R);
				glTexCoord2f(1.0f, 0.0f); glVertex3f(-R, -R,  R);
				<font color=gray>// Right face
</font>
				glNormal3f( 1.0f, 0.0f, 0.0f);
				glTexCoord2f(1.0f, 0.0f); glVertex3f( R, -R, -R);
				glTexCoord2f(1.0f, 1.0f); glVertex3f( R,  R, -R);
				glTexCoord2f(0.0f, 1.0f); glVertex3f( R,  R,  R);
				glTexCoord2f(0.0f, 0.0f); glVertex3f( R, -R,  R);
				<font color=gray>// Left Face
</font>
				glNormal3f(-1.0f, 0.0f, 0.0f);
				glTexCoord2f(0.0f, 0.0f); glVertex3f(-R, -R, -R);
				glTexCoord2f(1.0f, 0.0f); glVertex3f(-R, -R,  R);
				glTexCoord2f(1.0f, 1.0f); glVertex3f(-R,  R,  R);
				glTexCoord2f(0.0f, 1.0f); glVertex3f(-R,  R, -R);
			glEnd();
		glPopMatrix();
	}
	glDisable(GL_TEXTURE_2D);


	<font color=gray>//Draw the walls
</font>
	<font color=gray>//Walls are transparent so draw last. Draw back faces first.
</font>
	<font color=gray>//Keep depth buffer ENABLED, no cheating
</font>
	<font color=gray>//Counter clockwise for objects facing us
</font>
	glColor4f(0.0, 0.6, 0.3, 0.35);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texture[<font color=purple>1</font>]);
	glBegin(GL_QUADS);
		<font color=gray>//Back wall
</font>
		glNormal3f(0.0f, 0.0f, 1.0f);
		glVertex3f(-70, 15, -70);
		glVertex3f(-70, 0, -70);
		glVertex3f(70, 0, -70);
		glVertex3f(70, 15, -70);

		<font color=gray>//Left wall
</font>
		glNormal3f(1.0f, 0.0f, 0.0f);
		glVertex3f(-70, 15, 70);
		glVertex3f(-70, 0, 70);
		glVertex3f(-70, 0, -70);
		glVertex3f(-70, 15, -70);

		<font color=gray>//Right wall
</font>
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glVertex3f(70, 15, 70);
		glVertex3f(70, 0, 70);
		glVertex3f(70, 0, -70);
		glVertex3f(70, 15, -70);

		<font color=gray>//Front wall
</font>
		glNormal3f(0.0f, 0.0f, -1.0f);
		glVertex3f(-70, 15, 70);
		glVertex3f(-70, 0, 70);
		glVertex3f(70, 0, 70);
		glVertex3f(70, 15, 70);
	glEnd();
	glDisable(GL_TEXTURE_2D);


	glPopMatrix();
	glFlush();
	glutSwapBuffers();	<font color=gray>//Double buffer swapover
</font>

}


<font color=gray>// Timer function, called every 40ms, will redraw if passed a 1
</font>
<font color=gray>// Passes its argument to itself. Arg comes from the Viz func below
</font>
GLvoid Timer( <font color=blue>int</font> value )
{
	<font color=blue>if</font>( value ) glutPostRedisplay();
	glutTimerFunc(40,Timer,value);
}


GLvoid Animate(<font color=blue>int</font> t)
{
	<font color=blue>int</font> i = 0;
	<font color=blue>float</font> time_step, bfact;

	time_step = gettime();

	<font color=blue>if</font> (AutoRot)
	{
		cam_angle = cam_angle + CAMINT;
		<font color=blue>if</font> (cam_angle &gt; 360) cam_angle = 0;
	}

	<font color=blue>if</font> (!MatrixStylee)
	{
		<font color=blue>for</font> (i = 0; i&lt;ARRMAX; i++)
		{

			parray[<font color=purple>i</font>][<font color=purple>0</font>] += parray[<font color=purple>i</font>][<font color=purple>3</font>]*time_step;;
			parray[<font color=purple>i</font>][<font color=purple>1</font>] += parray[<font color=purple>i</font>][<font color=purple>4</font>]*time_step;;
			parray[<font color=purple>i</font>][<font color=purple>2</font>] += parray[<font color=purple>i</font>][<font color=purple>5</font>]*time_step;;
			parray[<font color=purple>i</font>][<font color=purple>4</font>] = parray[<font color=purple>i</font>][<font color=purple>4</font>] -(GRAVITY*time_step);

			
			<font color=gray>//Code to make the balls bounce
</font>

			<font color=gray>//Floor
</font>
			<font color=blue>if</font> (parray[<font color=purple>i</font>][<font color=purple>1</font>]-parray[<font color=purple>i</font>][<font color=purple>6</font>] &lt; 0)
			{
				<font color=gray>//Apply a random scaling factor to the bounce coefficient
</font>
				bfact = (<font color=blue>float</font>(rand())/131070) + 0.75;
				parray[<font color=purple>i</font>][<font color=purple>4</font>] = parray[<font color=purple>i</font>][<font color=purple>4</font>] * -(BOUNCE * bfact);
				parray[<font color=purple>i</font>][<font color=purple>1</font>] = parray[<font color=purple>i</font>][<font color=purple>6</font>];
			}	

			<font color=gray>//Left
</font>
			<font color=blue>if</font> (parray[<font color=purple>i</font>][<font color=purple>0</font>]-parray[<font color=purple>i</font>][<font color=purple>6</font>] &lt; -70)
			{
				parray[<font color=purple>i</font>][<font color=purple>3</font>] = -parray[<font color=purple>i</font>][<font color=purple>3</font>];
				parray[<font color=purple>i</font>][<font color=purple>0</font>] = -70 + parray[<font color=purple>i</font>][<font color=purple>6</font>];
			}

			<font color=gray>//Right
</font>
			<font color=blue>if</font> (parray[<font color=purple>i</font>][<font color=purple>0</font>]+parray[<font color=purple>i</font>][<font color=purple>6</font>] &gt; 70)
			{
				parray[<font color=purple>i</font>][<font color=purple>3</font>] = -parray[<font color=purple>i</font>][<font color=purple>3</font>];
				parray[<font color=purple>i</font>][<font color=purple>0</font>] = 70 - parray[<font color=purple>i</font>][<font color=purple>6</font>];
			}

			<font color=gray>//Back
</font>
			<font color=blue>if</font> (parray[<font color=purple>i</font>][<font color=purple>2</font>]-parray[<font color=purple>i</font>][<font color=purple>6</font>] &lt; -70)
			{
				parray[<font color=purple>i</font>][<font color=purple>5</font>] = -parray[<font color=purple>i</font>][<font color=purple>5</font>];
				parray[<font color=purple>i</font>][<font color=purple>2</font>] = -70 + parray[<font color=purple>i</font>][<font color=purple>6</font>];
			}

			<font color=gray>//Front
</font>
			<font color=blue>if</font> (parray[<font color=purple>i</font>][<font color=purple>2</font>]+parray[<font color=purple>i</font>][<font color=purple>6</font>] &gt; 70)
			{
				parray[<font color=purple>i</font>][<font color=purple>5</font>] = -parray[<font color=purple>i</font>][<font color=purple>5</font>];
				parray[<font color=purple>i</font>][<font color=purple>2</font>] = 70 - parray[<font color=purple>i</font>][<font color=purple>6</font>];
			}


		}
	}

	glutTimerFunc(40,Animate,1);
}

<font color=gray>//Called when visibility status changes
</font>
<font color=gray>//Sets the value passed by the timer
</font>
GLvoid Viz(<font color=blue>int</font> state)
{
	<font color=blue>switch</font> (state)
	{
		<font color=blue>case</font> GLUT_VISIBLE:
             Timer(1);
             <font color=blue>break</font>;
		<font color=blue>case</font> GLUT_NOT_VISIBLE:
             Timer(0);
             <font color=blue>break</font>;
		<font color=blue>default</font>:
             <font color=blue>break</font>;
	}
}


<font color=gray>//Called when a key is pressed
</font>
<font color=gray>//X and Y are coords of mouse at keypress
</font>
<font color=blue>void</font> NormalKey(GLubyte key, GLint x, GLint y) 
{
	<font color=blue>int</font> i = 0;
	<font color=blue>float</font> f,g,h,radius;

    <font color=blue>switch</font> (key)
	{ 
	<font color=blue>case</font> ESCAPE :
		glutDestroyWindow(window);	<font color=gray>// Kill window
</font>
		exit(0); 					<font color=gray>// Very dirty exit
</font>
		<font color=blue>break</font>;

	<font color=blue>case</font> ''g'' :
		<font color=gray>//Seed the random generator
</font>
		srand(time(0)); 

		<font color=gray>//Populate the array with particles
</font>
		<font color=blue>for</font> (i = 0; i &lt; ARRMAX; i++)
		{
			<font color=gray>//Random float between -1 and 1
</font>
			f = (<font color=blue>float</font>(rand())/16383.5) - 1 ;
			g = (<font color=blue>float</font>(rand())/16383.5);
			h = (<font color=blue>float</font>(rand())/16383.5) - 1 ;

			<font color=gray>//Apply scaling factor to velocities
</font>
			f=f*SCALE; g=g*SCALE; h=h*SCALE;

			radius = (<font color=blue>float</font>(rand())/16383.5) + 1;

			parray[<font color=purple>i</font>][<font color=purple>0</font>] = 0.0;
			parray[<font color=purple>i</font>][<font color=purple>1</font>] = 12.0;
			parray[<font color=purple>i</font>][<font color=purple>2</font>] = 0.0;
			parray[<font color=purple>i</font>][<font color=purple>3</font>] = f;
			parray[<font color=purple>i</font>][<font color=purple>4</font>] = g;
			parray[<font color=purple>i</font>][<font color=purple>5</font>] = h;
			parray[<font color=purple>i</font>][<font color=purple>6</font>] = radius;
		}
		<font color=blue>break</font>;

	<font color=blue>case</font> ''m'' :
		<font color=blue>if</font> (MatrixStylee)
			MatrixStylee = 0;
		<font color=blue>else</font>
			MatrixStylee = 1;
		<font color=blue>break</font>;

	<font color=blue>case</font> ''r'' :
		<font color=blue>if</font> (AutoRot)
			AutoRot = 0;
		<font color=blue>else</font>
			AutoRot = 1;
		<font color=blue>break</font>;

	<font color=blue>default</font>:
		<font color=blue>break</font>;
	}
}

<font color=blue>void</font> SpecialKey(<font color=blue>int</font> key, <font color=blue>int</font> x, <font color=blue>int</font> y){
  <font color=blue>switch</font>(key){
  <font color=blue>case</font> GLUT_KEY_RIGHT:
      cam_angle-=5;
	  <font color=blue>if</font>(cam_angle&lt;0)
		cam_angle=360;
    <font color=blue>break</font>;

  <font color=blue>case</font> GLUT_KEY_LEFT:
      cam_angle+=5;
	  <font color=blue>if</font>(cam_angle&gt;360)
		cam_angle=0;
    <font color=blue>break</font>;

  <font color=blue>case</font> GLUT_KEY_UP:
      cam_pitch-=1;
	  <font color=blue>if</font>(cam_pitch&lt;0)
		cam_pitch=360;
    <font color=blue>break</font>;

  <font color=blue>case</font> GLUT_KEY_DOWN:
      cam_pitch+=1;
	  <font color=blue>if</font>(cam_pitch&gt;360)
		cam_pitch=0;
    <font color=blue>break</font>;

  <font color=blue>default</font>:
	<font color=blue>break</font>;
  }

  <font color=blue>return</font>;
}


<font color=gray>//        Main Code
</font>
<font color=gray>//————————
</font>


<font color=blue>int</font> WINAPI WinMain(HINSTANCE hInstance,
			HINSTANCE hPrevInstance,
			LPSTR lpCmdLine,
			<font color=blue>int</font> nCmdShow) 
{  
<font color=gray>// Initialisation and window creation
</font>
	<font color=gray>//glutInit(&argc, argv);               // Initialize GLUT state.
</font>

	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);  <font color=gray>// RGB and Alpha, Single buffer, Z buffer (depth)
</font>
	
	glutInitWindowSize(Xsize,Ysize);     <font color=gray>// set initial window size.
</font>
	glutInitWindowPosition(0,0);         <font color=gray>// upper left corner of the screen.
</font>
	window = glutCreateWindow(<font color=darkred>"OpenGL"</font>);  <font color=gray>// Open a window with a title.
</font>
	InitGL(Xsize,Ysize);                 <font color=gray>// Initialize our window.
</font>

<font color=gray>// Now register the various callback functions
</font>
	glutDisplayFunc(DrawGLScene);        <font color=gray>// Function to do all our OpenGL drawing.
</font>
	glutReshapeFunc(ReSizeGLScene);		 <font color=gray>// Called when window is resized
</font>
	glutKeyboardFunc(NormalKey);         <font color=gray>// Normal key is pressed
</font>
	glutSpecialFunc(SpecialKey);		 <font color=gray>// ''Special'' key is pressed
</font>
	<font color=gray>//glutIdleFunc(DrawGLScene);         // What to call when there''s spare time
</font>
	glutTimerFunc(40,Timer,1);			 <font color=gray>// Call Timer in 40 ms
</font>
	glutTimerFunc(400,Animate,1);
	glutVisibilityFunc(Viz);			 <font color=gray>// Call Viz if visibility changes
</font>


<font color=gray>// Now drop into the event loop from which we never return
</font>
	glutMainLoop();                      <font color=gray>// Start Event Processing Engine
</font>
	<font color=blue>return</font> 1;
}



</pre><!–ENDSCRIPT–>    
Why not disable lighting while you draw your blended objects?
Advertisement
I believe that when lighting is enabled, all glColorxx() calls are tossed out. Lighting uses glMaterialxx() functions instead. I''m not sure about the alpha value of the glColorxx() functions though, that might still be used.

---
K-1 Productions: Come visit us here.
---K-1 Productions: Come visit us here.
Hi,
You should set to 0.0f the alpha value in ambient light and set to 1.0f the value in diffuse light. Lighting can modify the vertex in alpha if you don''t care!
Ronan
Thanks for all the suggestions guys. My internet access has been destroyed by my phone company making me check this at college and so I can''t feedback which of these ideas worked but thanks for your time, I''ll go try em now.

This topic is closed to new replies.

Advertisement