101 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			101 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | #include "ogl.h"
 | ||
|  | 
 | ||
|  | #include <Kore/Graphics3/Graphics.h>
 | ||
|  | #include <Kore/Graphics3/Light.h>
 | ||
|  | #include <Kore/Math/Core.h>
 | ||
|  | 
 | ||
|  | using namespace Kore; | ||
|  | 
 | ||
|  | // OpenGL man pages for "glLight" function:
 | ||
|  | // see https://www.opengl.org/sdk/docs/man2/xhtml/glLight.xml
 | ||
|  | 
 | ||
|  | LightImpl::LightImpl() | ||
|  |     : myType(DirectionalLight), myAmbient(0, 0, 0, 1), myDiffuse(1, 1, 1, 1), mySpecular(1, 1, 1, 1), myPositionOrDirection(0, 0, 1, 0), | ||
|  |       mySpotDirection(0, 0, 1), // default point in +Z direction
 | ||
|  |       mySpotExponent(0.0f), mySpotCutoff(180.0f), myConstAttn(1.0f), myLinearAttn(0.0f), myQuadricAttn(0.0f) {} | ||
|  | 
 | ||
|  | LightImpl::~LightImpl() {} | ||
|  | 
 | ||
|  | void Light::setType(LightType type) { | ||
|  | 	// Set new light type
 | ||
|  | 	myType = type; | ||
|  | 
 | ||
|  | 	// Update position/directior vector
 | ||
|  | 	myPositionOrDirection[3] = (myType == DirectionalLight ? 0.0f : 1.0f); | ||
|  | } | ||
|  | 
 | ||
|  | void Light::setColors(const vec4 &ambient, const vec4 &diffuse, const vec4 &specular) { | ||
|  | 	// Store light colors
 | ||
|  | 	myAmbient = ambient; | ||
|  | 	myDiffuse = diffuse; | ||
|  | 	mySpecular = specular; | ||
|  | } | ||
|  | 
 | ||
|  | void Light::setPosition(const vec3 &position) { | ||
|  | 	// Store position point (x, y, z, 1)
 | ||
|  | 	myPositionOrDirection = vec4(position, 1); | ||
|  | } | ||
|  | 
 | ||
|  | void Light::setDirection(const vec3 &direction) { | ||
|  | 	if (myType == SpotLight) { | ||
|  | 		// Store spot direction vector (x, y, z)
 | ||
|  | 		mySpotDirection = direction; | ||
|  | 	} | ||
|  | 	else { | ||
|  | 		// Store direction vector (x, y, z, 0)
 | ||
|  | 		myPositionOrDirection = vec4(direction, 0); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | void Light::setSpot(float exponent, float cutoff) { | ||
|  | 	mySpotExponent = exponent; | ||
|  | 	mySpotCutoff = cutoff; | ||
|  | } | ||
|  | 
 | ||
|  | void Light::setAttenuation(float constAttn, float linearAttn, float quadricAttn) { | ||
|  | 	myConstAttn = constAttn; | ||
|  | 	myLinearAttn = linearAttn; | ||
|  | 	myQuadricAttn = quadricAttn; | ||
|  | } | ||
|  | 
 | ||
|  | /*
 | ||
|  |                                     1 | ||
|  | GL Light Intensity = ----------------------------------- | ||
|  |                      constant + d*linear + d^2*quadratic | ||
|  | */ | ||
|  | void Light::setAttenuationRadius(float radius) { | ||
|  | 	setAttenuation(1.0f, 1.0f / radius, 1.0f / radius); | ||
|  | } | ||
|  | 
 | ||
|  | void LightImpl::submitLightParamsToGL(GLenum lightID) const { | ||
|  | 	// Submit colors
 | ||
|  | 	glLightfv(lightID, GL_AMBIENT, myAmbient.values); | ||
|  | 	glLightfv(lightID, GL_DIFFUSE, myDiffuse.values); | ||
|  | 	glLightfv(lightID, GL_SPECULAR, mySpecular.values); | ||
|  | 
 | ||
|  | 	// Submit attenuation
 | ||
|  | 	glLightf(lightID, GL_CONSTANT_ATTENUATION, myConstAttn); | ||
|  | 	glLightf(lightID, GL_LINEAR_ATTENUATION, myLinearAttn); | ||
|  | 	glLightf(lightID, GL_QUADRATIC_ATTENUATION, myQuadricAttn); | ||
|  | 
 | ||
|  | 	// Submit spot parameters
 | ||
|  | 	glLightfv(lightID, GL_SPOT_DIRECTION, mySpotDirection.values); | ||
|  | 	glLightf(lightID, GL_SPOT_EXPONENT, mySpotExponent); | ||
|  | 	glLightf(lightID, GL_SPOT_CUTOFF, mySpotCutoff); | ||
|  | } | ||
|  | 
 | ||
|  | void LightImpl::submitLightTransformToGL(GLenum lightID) const { | ||
|  | 	glLightfv(lightID, GL_POSITION, myPositionOrDirection.values); | ||
|  | } | ||
|  | 
 | ||
|  | Light::Light(LightType type) : LightImpl() { | ||
|  | 	setType(type); | ||
|  | } | ||
|  | 
 | ||
|  | void Light::_set(int num) { | ||
|  | 	GLenum lightID = GL_LIGHT0 + num; | ||
|  | 	glEnable(lightID); | ||
|  | 	submitLightParamsToGL(lightID); | ||
|  | 	submitLightTransformToGL(lightID); | ||
|  | } |