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);
							 | 
						||
| 
								 | 
							
								}
							 |