8 Replies - 253 Views - Last Post: 01 January 2013 - 01:55 PM Rate Topic: -----

#1 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 197
  • Joined: 23-May 09

Opengl Lighting and Textures

Posted 01 January 2013 - 04:18 AM

Okay, so everything was going fine until i decided to add textures and lighting to my program.
It is supposed to draw a square grid. Each square in the grid is made of two triangles

The texture is being applied to both sides of the mesh.
Lighting acts really weirldly. Both sides of the mesh is being lit.

I suppose its as if one set of triangles is faceing one way and the other the oposite.
I'm not sure if I'm calculating normals correctly either.

The only reason I could think of thats causing all this, is that my coordinate system has been messed up.

SpaceCamera.h and objectloader.h control the camera and list #includes respectivly. so I haven't posted them below.

CTextures.h
#ifndef CTEXTURES_H
#define CTEXTURES_H

#include "objectloader.h"

class CTexture {
private:
public:
	GLuint texture;			
    SDL_Surface *surface;	
    GLenum texture_format;
    GLint  nOfColors;

	void createtexture(std::string filename) {
		        if ((surface = SDL_LoadBMP(filename.c_str())) ) {  
	        if ( (surface->w & (surface->w - 1)) != 0 ) {
		        printf("warning: image.bmp's width is not a power of 2\n");
	        } 
	        if ( (surface->h & (surface->h - 1)) != 0 ) {
		        printf("warning: image.bmp's height is not a power of 2\n");
	    }
 
        nOfColors = surface->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
                if (surface->format->Rmask == 0x000000ff)
                        texture_format = GL_RGBA;
                else
                        texture_format = GL_BGRA;
        } else if (nOfColors == 3)     // no alpha channel
        {
                if (surface->format->Rmask == 0x000000ff)
                        texture_format = GL_RGB;
                else
                        texture_format = GL_BGR;
        } else {
                printf("warning: the image is not truecolor..  this will probably break\n");
                // this error should not go unhandled
        }
 
		glGenTextures( 1, &texture ); 
		glBindTexture( GL_TEXTURE_2D, texture ); 
	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	    
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

		glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
                      texture_format, GL_UNSIGNED_BYTE, surface->pixels );
        } 
else {
	printf("SDL could not load image.bmp: %s\n", SDL_GetError());
	//SDL_Quit();
	
}    
 
// Free the SDL_Surface only if it was successfully created
if ( surface ) { 
	SDL_FreeSurface( surface );
}
    }
	void usetexture() {
		glBindTexture( GL_TEXTURE_2D, texture );
	}
};

#endif


Grid.h
#ifndef GRID_H
#define GRID_H

#include <iostream>
#include "CTextures.h"

class CPoint {
private:
    float x;
    float y;
    float z;

public:

    void setX(float newx) { x=newx; }
    void setY(float newy) { y=newy; }
    void setZ(float newz) { z=newz; }
    float getX()  { return x; }
    float getY()  { return y; }
    float getZ()  { return z; }

    void setvalues(float newx, float newy, float newz) { x=newx; y=newy; z=newz; }
};

class CTriangle {
private:
public:

    CPoint pointtri[3];
	CPoint normaltri[2];
	CPoint averagenormal[1];
    
	void CalculateNormal(int i, int u, int v) {

        float ia = pointtri[u].getY()*pointtri[v].getZ(); 
        float ib = pointtri[u].getZ()*pointtri[v].getY();

        // j values
        float ja = pointtri[u].getX()*pointtri[v].getZ(); 
        float jb = pointtri[u].getZ()*pointtri[v].getX();

        // k values
        float ka = pointtri[u].getX()*pointtri[v].getY(); 
        float kb = pointtri[u].getY()*pointtri[v].getX();

        float iAB = (ia-ib);
        float jAB = (ja-jb)*-1;
        float kAB = (kb-ka);

        normaltri[i].setvalues(iAB,jAB,kAB);

		std::cout << "NORMALS: " << std::endl;
		std::cout << "ia-ib: " << ia << ", " << ib << " = " << iAB << std::endl;
		std::cout << "ja-jb: " << ja << ", " << jb << " = " << jAB << std::endl;
		std::cout << "ka-kb: " << ka << ", " << kb << " = " << kAB << std::endl;
    }

    void AverageNormals() {

        averagenormal[0].setX((normaltri[0].getX()+normaltri[1].getX())/2);
        averagenormal[0].setY((normaltri[0].getY()+normaltri[1].getY())/2);
        averagenormal[0].setZ((normaltri[0].getZ()+normaltri[1].getZ())/2);
    }

};

class CSquare {
private:
    int coorx;
    int coory;

	float pointx;
	float pointy;
public:
    
    void setcoorX(int newx) { coorx =newx; }
    void setcoorY(int newy) { coory =newy; }
    
    void setcoord(int newx, int newy) { coorx =newx; coory =newy; }

    int getcoorX() { return coorx; }
    int getcoorY() { return coory; }



    void setpointX(float newx) { pointx =newx; }
    void setpointY(float newy) { pointy =newy; }
    
    void setpoint(float newx, float newy) { pointx =newx; pointy =newy; }

    int getpointX() { return pointx; }
    int getpointY() { return pointy; }
  


    CTriangle ctriangle[2];
};

class CGrid {
private:
   int gridwidth;
   int gridheight;

   int fullwidth;
   int halfwidth;
public:
	CGrid() {
	    
	}
    CSquare csquare[65536];
	CTexture ctexture[3];
	
    void setgridwidth(int newgridwidth)   { gridwidth  = newgridwidth;  }
    void setgridheight(int newgridheight) { gridheight = newgridheight; }
    
    int getgridwidth()  { return gridwidth;  }
    int getgridheight() { return gridheight; }

    void setfullwidth(int newfullwidth) { fullwidth = newfullwidth; }
    void sethalfwidth(int newhalfwidth) { halfwidth = newhalfwidth; }

    int  getfullwidth() { return fullwidth; }
    int  gethalfwidth() { return halfwidth; }

	void setGrid(float fullwidth, float height, float width) {
	    setfullwidth(fullwidth);
        sethalfwidth(fullwidth/2.0);

        setgridheight(height);
        setgridwidth(width);

    
	    std::vector<float> yheight;
	    int numberofvert = getgridheight()*getgridwidth();
	    for(int i=0;i<numberofvert;i++) {
	        //srand(time(NULL));
	        float randomnumber = rand() % 4;
	        yheight.push_back(randomnumber);
	        std::cout << "Random Number: " << i << ") " << yheight[i] << std::endl;
	    }   
    
        int tilecounter=0;
        
		for(int k=0; k<numberofvert; k++) {
			csquare[k].ctriangle[0].pointtri[0].setY(0);
			csquare[k].ctriangle[0].pointtri[1].setY(0);
			csquare[k].ctriangle[0].pointtri[2].setY(0);

			csquare[k].ctriangle[1].pointtri[0].setY(0);
			csquare[k].ctriangle[1].pointtri[1].setY(0);
			csquare[k].ctriangle[1].pointtri[2].setY(0);
		}

        for(float k=0; k<getgridheight(); k++) {
            for(float i=0; i<getgridwidth(); i++) {
                csquare[tilecounter].setcoord(i,k);
                csquare[tilecounter].setpoint(i*getfullwidth(),k*getfullwidth());

                csquare[tilecounter].ctriangle[0].pointtri[0].setvalues(csquare[tilecounter].getpointX()-gethalfwidth(),csquare[tilecounter-1].ctriangle[1].pointtri[1].getY(),csquare[tilecounter].getpointY()-gethalfwidth());
                csquare[tilecounter].ctriangle[0].pointtri[1].setvalues(csquare[tilecounter].getpointX()-gethalfwidth(),csquare[tilecounter-1].ctriangle[1].pointtri[0].getY(),csquare[tilecounter].getpointY()+gethalfwidth());
                csquare[tilecounter].ctriangle[0].pointtri[2].setvalues(csquare[tilecounter].getpointX()+gethalfwidth(),yheight[tilecounter],csquare[tilecounter].getpointY()+gethalfwidth());

                csquare[tilecounter].ctriangle[1].pointtri[0].setvalues(csquare[tilecounter].getpointX()+gethalfwidth(),yheight[tilecounter],csquare[tilecounter].getpointY()+gethalfwidth());
				if(tilecounter-getgridwidth()<0) {
					csquare[tilecounter].ctriangle[1].pointtri[1].setvalues(csquare[tilecounter].getpointX()+gethalfwidth(),0,csquare[tilecounter].getpointY()-gethalfwidth());
                }
				if(tilecounter-getgridwidth()>=0) {
					csquare[tilecounter].ctriangle[1].pointtri[1].setvalues(csquare[tilecounter].getpointX()+gethalfwidth(),csquare[tilecounter-getgridwidth()].ctriangle[0].pointtri[2].getY(),csquare[tilecounter].getpointY()-gethalfwidth());
                }
                csquare[tilecounter].ctriangle[1].pointtri[2].setvalues(csquare[tilecounter].getpointX()-gethalfwidth(),csquare[tilecounter-1].ctriangle[1].pointtri[1].getY(),csquare[tilecounter].getpointY()-gethalfwidth());
			
			    csquare[tilecounter].ctriangle[0].CalculateNormal(0,0,1);
	            csquare[tilecounter].ctriangle[0].CalculateNormal(1,2,1);                
	            csquare[tilecounter].ctriangle[0].AverageNormals();    
	            csquare[tilecounter].ctriangle[1].CalculateNormal(0,0,1);
				csquare[tilecounter].ctriangle[1].CalculateNormal(1,2,1);	            
	            csquare[tilecounter].ctriangle[1].AverageNormals();		
                
				tilecounter++;
            }
        }
    }

    void setTriangles() {  
        int tilecounter=0;
        for(int k=0; k<getgridheight(); k++) {
            for(int i=0; i<getgridwidth(); i++) {
                int average = (csquare[tilecounter].ctriangle[0].pointtri[0].getY() + csquare[tilecounter].ctriangle[0].pointtri[1].getY() + csquare[tilecounter].ctriangle[0].pointtri[2].getY() + csquare[tilecounter].ctriangle[1].pointtri[0].getY() + csquare[tilecounter].ctriangle[1].pointtri[1].getY() + csquare[tilecounter].ctriangle[1].pointtri[2].getY())/6;    

			    if(average<0) { 
                    ctexture[0].usetexture();
			    }
			    if((average>=0) && (average<2)) {
                    ctexture[1].usetexture();
			    }
			    if((average>=2) && (average<9)){
                    ctexture[2].usetexture();
			    }

			    glBegin(GL_TRIANGLES);
                    //glColor3f(0.0,1.0,1.0);
				    glNormal3f(csquare[tilecounter].ctriangle[0].averagenormal[0].getX(),csquare[tilecounter].ctriangle[0].averagenormal[0].getY(),csquare[tilecounter].ctriangle[0].averagenormal[0].getZ());
                    glTexCoord2f(0.0,0.0); glVertex3f(csquare[tilecounter].ctriangle[0].pointtri[0].getX(),csquare[tilecounter].ctriangle[0].pointtri[0].getY(),csquare[tilecounter].ctriangle[0].pointtri[0].getZ());
                    glTexCoord2f(0.0,1.0); glVertex3f(csquare[tilecounter].ctriangle[0].pointtri[1].getX(),csquare[tilecounter].ctriangle[0].pointtri[1].getY(),csquare[tilecounter].ctriangle[0].pointtri[1].getZ());
                    glTexCoord2f(1.0,1.0); glVertex3f(csquare[tilecounter].ctriangle[0].pointtri[2].getX(),csquare[tilecounter].ctriangle[0].pointtri[2].getY(),csquare[tilecounter].ctriangle[0].pointtri[2].getZ());
                glEnd();
                
                glBegin(GL_TRIANGLES);
                    //glColor3f(0.0,1.0,1.0);
					glNormal3f(csquare[tilecounter].ctriangle[1].averagenormal[0].getX(),csquare[tilecounter].ctriangle[1].averagenormal[0].getY(),csquare[tilecounter].ctriangle[1].averagenormal[0].getZ());
                    glTexCoord2f(0.0,0.0); glVertex3f(csquare[tilecounter].ctriangle[1].pointtri[0].getX(),csquare[tilecounter].ctriangle[1].pointtri[0].getY(),csquare[tilecounter].ctriangle[1].pointtri[0].getZ());
                    glTexCoord2f(0.0,1.0); glVertex3f(csquare[tilecounter].ctriangle[1].pointtri[1].getX(),csquare[tilecounter].ctriangle[1].pointtri[1].getY(),csquare[tilecounter].ctriangle[1].pointtri[1].getZ());
                    glTexCoord2f(1.0,1.0); glVertex3f(csquare[tilecounter].ctriangle[1].pointtri[2].getX(),csquare[tilecounter].ctriangle[1].pointtri[2].getY(),csquare[tilecounter].ctriangle[1].pointtri[2].getZ());
                glEnd();
                
		        tilecounter++;	
            }
        }
    }
};

#endif


main file

#include <time.h>
#include "objectloader.h"
#include "SpaceCamera.h"
#include "Grid.h"

SpaceCamera spacecamera;
CGrid cgrid;

bool mousein=false;

void init() {
	glClearColor(0.0,0.0,0.0,1.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45,640.0/480.0,1.0,10240.0);   

	glMatrixMode(GL_MODELVIEW);
	glEnable(GL_DEPTH_TEST);
	
	glEnable(GL_NORMALIZE);
	
    glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glShadeModel(GL_SMOOTH);   

	cgrid.ctexture[0].createtexture("water.bmp");
	cgrid.ctexture[1].createtexture("sand.bmp");
	cgrid.ctexture[2].createtexture("grass.bmp");	
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	spacecamera.Control(0.2,0.2,mousein);	//calculate the position, and rotate the camera
	spacecamera.UpdateCamera();	            //move the camera to the new location
	 
	float DiffuseLight[] = {1.0, 1.0, 1.0};
	glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); 

	float LightPosition[] = {0.0, 1.0, 0.0};
	glLightfv (GL_LIGHT0, GL_POSITION, LightPosition); 

	float AmbientLight[] = {1.2, 1.2, 1.2}; 
    glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight); 
	
    //glDisable(GL_LIGHTING);
    
	glPushMatrix();
	    glEnable(GL_TEXTURE_2D);
        //glCullFace(GL_BACK);
	    glTranslatef(0.0,0.0,0.0);
		//glPolygonMode(GL_FRONT, GL_LINE);
        //glPolygonMode(GL_BACK, GL_LINE);
        cgrid.setTriangles();	
		glDisable(GL_TEXTURE_2D);
	glPopMatrix(); 
}

int main(int argc, char **argv)
{
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_Surface* screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE|SDL_OPENGL);
	bool running=true;
	Uint32 start;
	SDL_Event event;
	init();

	cgrid.setGrid(8,4,4);
    
	while(running){
		start=SDL_GetTicks();
		while(SDL_PollEvent(&event)) {
			switch(event.type) {				
				case SDL_QUIT:
					running=false;
					break;
				case SDL_MOUSEBUTTONDOWN:
					mousein=true;
					SDL_ShowCursor(SDL_DISABLE);
					break;
				case SDL_KEYDOWN:					
					if(event.key.keysym.sym==SDLK_p) {
						mousein=false;
						SDL_ShowCursor(SDL_ENABLE);
						break;
					}
					if(event.key.keysym.sym==SDLK_ESCAPE) {
						running=false;
						break;
					}
			}
		}		
		display();

		SDL_GL_SwapBuffers();
		
		if(1000/30>(SDL_GetTicks()-start))
			SDL_Delay(1000/30-(SDL_GetTicks()-start));
	}
	SDL_Quit();	
	return 0;	
}


Is This A Good Question/Topic? 0
  • +

Replies To: Opengl Lighting and Textures

#2 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 197
  • Joined: 23-May 09

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 05:21 AM

if I multiply the y value for the seecond normal3f by -1

glNormal3f(csquare[tilecounter].ctriangle[1].averagenormal[0].getX(),[b](csquare[tilecounter].ctriangle[1].averagenormal[0].getY())*-1[/b],csquare[tilecounter].ctriangle[1].averagenormal[0].getZ()); 


and then this to a -y value

float LightPosition[] = {0.0, -2.0, 0.0, 1.0};
	glLightfv (GL_LIGHT0, GL_POSITION, LightPosition);


I get this,

Posted Image

But for some reason the first tile where the light source is located is blacked out. This works if I change the first
glNormal3f() to be multiplyeed by -1 instead of the second one, but the y position for the light to positive.

This post has been edited by xnewix: 01 January 2013 - 05:24 AM

Was This Post Helpful? 0
  • +
  • -

#3 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: -4
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 08:33 AM

Just before you call the code you need to check that lighting is actually enabled with glIsEnabled(GL_LIGHT0);. It might not be enabled.

This post has been edited by ButchDean: 01 January 2013 - 08:37 AM

Was This Post Helpful? 0
  • +
  • -

#4 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 197
  • Joined: 23-May 09

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 09:32 AM

Hum, I think I have the Lighting working now, it's just the first two triangles at the top that arn't getting any light.
They get drawn like the rest of the grid if i diable lighting, but don't if i do. It doesn't matter where I put the light, those two triangles never get any. I'm perplexed.
Was This Post Helpful? 0
  • +
  • -

#5 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: -4
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 11:27 AM

What you are saying is hinting to me that the normals you have for the squares not being lit are pointing in the opposite direction to those that are, this would cause a problem like the one you're seeing.

There are some debugging tools out there that can help you visualize what's going in.

https://www.opengl.o...Debugging_Tools
Was This Post Helpful? 0
  • +
  • -

#6 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 197
  • Joined: 23-May 09

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 12:47 PM

Yes it was normals, well I'v just finished rearranging my normal code, everything is drawn correctly.

A 2D surface looks good, 3D still a little blocky, but ehh.

Posted Image

This post has been edited by xnewix: 01 January 2013 - 12:48 PM

Was This Post Helpful? 0
  • +
  • -

#7 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: -4
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 12:55 PM

Awesome. The reason why it's looking like that is because your terrain has a low poly count. Up it a bit and it will look better.
Was This Post Helpful? 0
  • +
  • -

#8 xnewix  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 2
  • View blog
  • Posts: 197
  • Joined: 23-May 09

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 01:01 PM

Thanks! But, think I'll leave the increase in polycount till another day.
Was This Post Helpful? 0
  • +
  • -

#9 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: -4
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Opengl Lighting and Textures

Posted 01 January 2013 - 01:55 PM

Cool. Good work! :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1