Results 1 to 7 of 7

Thread: Lighting a Triangle Fan

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    4

    Lighting a Triangle Fan

    So, I have been building a dynamic terrain renderer, and it was going well until I needed to add lighting. I am new to OpenGL, and I have no idea what is causing the problem, but I have a few ideas.

    Here is my code so far, it is written in Java using LWJGL.
    <div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
    Code :
    package geekygenius.nutrality;
     
    import static org.lwjgl.opengl.GL11.*;
    import static org.lwjgl.util.glu.GLU.*;
     
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
     
    import org.lwjgl.opengl.GL11;
     
    public class DeafultMapRenderer implements MapRenderer {
    	private final float HEIGHT_MOD = .5f;
     
    	public void initilizeRenderer(Map map, int width, int height) {
    		glMatrixMode(GL11.GL_PROJECTION);
    		glLoadIdentity();
    		gluPerspective(80f, (float) width / height, .1f, 100f);
    		//glOrtho(0, width, height, 0, .1, 1000);
    		glMatrixMode(GL11.GL_MODELVIEW);
    		glRotatef(-30, 1.0f, 0.0f, 0.0f);
    		glTranslatef(-(width / 64), 0, -10);
     
    		setUpLighting(width, height);
     
    		// Debug crap
    		map.setHeightRange(10, 5, 2, 2, 2);
    		map.setType(10, 5, BlockType.SEA);
     
    		// Wire frame mode
    		//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    	}
     
    	public void render(Map map) {
    		// Clear the screen and depth buffer
    		glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
     
    		// set the color of the quad (R,G,B,A)
    		glColor3f(0.1f, 0.8f, 0.1f); // Green
     
    		// Allocate some memory for the verticies
    		float[][] verticies = new float[6][3];
    		float[] normal = new float[3];
     
    		for (int x = 0; x < map.getWidth(); x++) {
    			for (int y = 0; y < map.getHeight(); y++) {
    				// TODO replace with ctual textures/shaders
    				if (map.getType(x, y) == BlockType.LAND) {
    					glColor3f(0.1f, 0.8f, 0.1f); // Green
    				} else if (map.getType(x, y) == BlockType.SEA) {
    					glColor3f(0.1f, 0.1f, 0.8f); // Blue
    				}
     
    				// Calculate verticies now, so we don't have to re calculate
    				// when finding normals
    				verticies[0] = new float[] {x + .5f,y + .5f,average(map.getHeight(x, y), map.getHeight(x + 1, y),
                                             map.getHeight(x, y + 1),map.getHeight(x + 1, y + 1))* HEIGHT_MOD };
    				verticies[1] = new float[] { x, y,map.getHeight(x, y) * HEIGHT_MOD };
    				verticies[2] = new float[] { x + 1, y,map.getHeight(x + 1, y) * HEIGHT_MOD };
    				verticies[3] = new float[] { x + 1, y + 1,map.getHeight(x + 1, y + 1) * HEIGHT_MOD };
    				verticies[4] = new float[] { x, y + 1,map.getHeight(x, y + 1) * HEIGHT_MOD };
    				verticies[5] = verticies[1];// Wrap it around
     
    				glBegin(GL_TRIANGLE_FAN);
    				glVertex3f(verticies[0][0], verticies[0][1], verticies[0][2]);
    				glVertex3f(verticies[1][0], verticies[1][1], verticies[1][2]);
    				for (int v = 2; v < 6; v++) {// v for vertex
    					glVertex3f(verticies[v][0], verticies[v][1],verticies[v][2]);
     
    					normal = getNormal(verticies[0][0], verticies[v - 1][0],verticies[v][0],
    							verticies[0][1],verticies[v - 1][1], verticies[v][1],
    							verticies[0][2], verticies[v - 1][2],verticies[v][2]);// Normal for top section
     
    					//normal = new float [] {0.0f, 0.0f, 1.0f};
    					glNormal3f(normal[0], normal[1], normal[2]);
    				}
    				glEnd();
    			}
    		}
    	}
     
    	private void setUpLighting(int width, int height) {
    		glShadeModel(GL_FLAT);
     
    		glEnable(GL_LIGHTING);
     
    		float lightPosition[] = { height, 0f, 4f, 0.0f };
    		FloatBuffer lPos = ByteBuffer.allocateDirect(16).order(ByteOrder.nativeOrder()).asFloatBuffer();
        	lPos.put(lightPosition).flip();
     
        	/*
    		FloatBuffer lightColor = ByteBuffer.allocateDirect(16).asFloatBuffer();
    		lightColor.mark();
    		lightColor.put(new float[] { .5f, .5f, .5f, 1f });
    		lightColor.reset();
    		*/
        	float lightDiffuse[] = { .2f, .2f, .2f, 1.0f };
    		FloatBuffer lDif = ByteBuffer.allocateDirect(16).order(ByteOrder.nativeOrder()).asFloatBuffer();
        	lPos.put(lightDiffuse).flip();
    		glLight(GL_LIGHT0, GL_DIFFUSE, lDif);
     
    		FloatBuffer position = ByteBuffer.allocateDirect(16).asFloatBuffer();
    		position.mark();
    		position.put(new float[] { height, 0f, 4f, 0.0f });
    		position.reset();
    		glLight(GL_LIGHT0, GL_POSITION, lPos);
    		glEnable(GL_LIGHT0);
     
     
    		//GL11.glLight(GL11.GL_LIGHT0, GL11.GL_AMBIENT, ambient);
     
    		//glLight(GL_LIGHT1, GL_DIFFUSE, ambient);
    		//glLight(GL_LIGHT1, GL_SPECULAR, ambient);
     
     
    		//glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5f);
    		//glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5f);
    		//glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2f);
     
    		//glLightModel(GL_LIGHT_MODEL_AMBIENT, lDif);
    		//glLightModeli(GL11.GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);		
     
    	}
     
    	private float average(int a, int b, int c, int d) {
    		return (a + b + c + d) / 4;
    	}
     
    	private float[] getNormal(float x1, float x2, float x3, float y1, float y2,
    			float y3, float z1, float z2, float z3) {
    		float nx1 = (y3 - y1) * (z2 - z1) - (y2 - y1) * (z3 - z1);
    		float ny1 = (z3 - z1) * (x2 - x1) - (z2 - z1) * (x3 - x1);
    		float nz1 = (x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1);
    		float fac1 = (float) Math.sqrt((nx1 * nx1) + (ny1 * ny1) + (nz1 * nz1));
    		nx1 /= fac1;
    		ny1 /= fac1;
    		nz1 /= fac1;
    		return new float[] { nx1, ny1, nz1 };
    	}
    }
    [/QUOTE]</div>

    Essentially what is does is renders triangle fan squares to try and get an end result similar to Transport tycoon. If I enable wire-frame mode, and disable lighting, I get this next image, which is the target result as far as meshes go. [IMAGE1]

    However, if I turn on lighting, I get a dimly lit mesh, or plane (depending if wire-frame is on or not). It looks something like this: [IMAGE2] The bottom half has been brightened so the rendered portion without lighting can be seen easier.

    I don't know what is causing this, I've probably forgot something obvious that I didn't know existed yet. I have tried tinkering with a few different things, and left them commented, but I can't guarentee every combination was tried. Anyways, thanks for taking the time to read my post and post an answer if you did!

    -geekygenius

  2. #2
    Senior Member Regular Contributor
    Join Date
    Jun 2009
    Location
    FL , USA
    Posts
    192

    Re: Lighting a Triangle Fan

    In your TRIANGLE_FAN rendering code,

    compute the normals first and do glNormal() followed by glVertex() and check.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    4

    Re: Lighting a Triangle Fan

    I still get the same results as before. Maybe something is wrong with my lighting?

  4. #4
    Senior Member Regular Contributor
    Join Date
    Jun 2009
    Location
    FL , USA
    Posts
    192

    Re: Lighting a Triangle Fan

    Are you calling to set up lighting before rendering your triangle fan?

    Your code only describes the class methods. Just check the sequence used to call your methods.

    Also, call glNormal() before glVertex to assign normals to the vertices.

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    4

    Re: Lighting a Triangle Fan

    I got textures to work properly, and I think they are applied the same way as normals, before the vertex. Yes, I checked, and the methods are being called at the appropriate times.

  6. #6
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,161

    Re: Lighting a Triangle Fan

    There are several reasons why fixed function lighting can go wrong.
    Firstly the polygon winding may be wrong for some of the vertices and this may be flipping the normals.
    Secondly the mesh may not be tessellated enough for lighting.
    Thirdly your lighting setup may be wrong and the most common cause of issues is not calling glLightv immediately after setting the modelview matrix (ie after glulookat)

  7. #7
    Junior Member Newbie
    Join Date
    Jan 2012
    Posts
    4

    Re: Lighting a Triangle Fan

    So, I re-ordered the gl calls, according to the way you described earlier, and it works lust how it should! Thanks!

Similar Threads

  1. An alternative to triangle strips and triangle fans
    By vincoof in forum OpenGL: General
    Replies: 8
    Last Post: 10-26-2012, 04:04 AM
  2. Replies: 3
    Last Post: 10-09-2012, 09:39 PM
  3. triangle strip with a LINE triangle display error
    By Samme in forum OpenGL: Windows
    Replies: 22
    Last Post: 11-20-2008, 07:50 PM
  4. OT: fastest ray-triangle line -triangle intersection algo
    By V-man in forum OpenGL: Advanced Coding
    Replies: 23
    Last Post: 08-28-2002, 02:18 AM
  5. Triangle strips vs triangle fans
    By zeraiam in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 12-17-2001, 11:06 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean