1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/math.h"
#include "tetraedge/te/te_light_opengl.h"
#include "tetraedge/te/te_color.h"
#include "tetraedge/te/te_quaternion.h"
#include "tetraedge/te/te_vector3f32.h"
#include "graphics/opengl/system_headers.h"
namespace Tetraedge {
static inline uint _toGlLight(uint lightno) {
return GL_LIGHT0 + lightno;
}
TeLightOpenGL::TeLightOpenGL() {
}
void TeLightOpenGL::disable(uint lightno) {
glDisable(_toGlLight(lightno));
}
void TeLightOpenGL::enable(uint lightno) {
if (_colDiffuse.r() == 0 && _colDiffuse.g() == 0 && _colDiffuse.b() == 0)
glDisable(_toGlLight(lightno));
else
glEnable(_toGlLight(lightno));
}
/*static*/
void TeLightOpenGL::disableAll() {
glDisable(GL_LIGHTING);
}
/*static*/
void TeLightOpenGL::enableAll() {
glEnable(GL_LIGHTING);
}
void TeLightOpenGL::draw(TeCamera &camera) {
error("TODO: Finish TeLightOpenGL::draw");
}
void TeLightOpenGL::update(uint lightno) {
if (lightno > GL_MAX_LIGHTS)
error("Invalid light no %d", lightno);
const uint glLight = _toGlLight(lightno);
const float ambient[4] = {_colAmbient.r() / 255.0f, _colAmbient.g() / 255.0f,
_colAmbient.b() / 255.0f, 1.0};
glLightfv(glLight, GL_AMBIENT, ambient);
const float diff[4] = {_colDiffuse.r() / 255.0f, _colDiffuse.g() / 255.0f,
_colDiffuse.b() / 255.0f, 1.0};
glLightfv(glLight, GL_DIFFUSE, diff);
// WORKAROUND: Original game sets 0.01 as threshold here to avoid enabling
// the "shadow" light. However, Syberia CitStation/31130 has shadowlight with
// values (4, 0, 0) which means it gets enabled and everything is dark.
if (diff[0] < 0.02f && diff[1] < 0.02f && diff[2] < 0.02f)
glDisable(glLight);
const float spec[4] = {_colSpecular.r() / 255.0f, _colSpecular.g() / 255.0f,
_colSpecular.b() / 255.0f, 1.0};
glLightfv(glLight, GL_SPECULAR, spec);
if (_type == LightTypeSpot || _type == LightTypePoint) {
const float pos[4] = {_position3d.x(), _position3d.y(), _position3d.z(), 1.0f};
glLightfv(glLight, GL_POSITION, pos);
glLightf(glLight, GL_CONSTANT_ATTENUATION, _constAtten);
glLightf(glLight, GL_LINEAR_ATTENUATION, _linearAtten);
glLightf(glLight, GL_QUADRATIC_ATTENUATION, _quadraticAtten);
}
if (_type == LightTypeDirectional) {
float cosx = cosf(_positionRadial.getX());
float cosy = cosf(_positionRadial.getY());
float sinx = sinf(_positionRadial.getX());
float siny = sinf(_positionRadial.getY());
const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
glLightfv(glLight, GL_POSITION, pos);
}
if (_type == LightTypeSpot) {
float cosx = cosf(_positionRadial.getX());
float cosy = cosf(_positionRadial.getY());
float sinx = sinf(_positionRadial.getX());
float siny = sinf(_positionRadial.getY());
const float pos[4] = {cosx * cosy, siny, sinx * cosy, 0.0f};
glLightfv(glLight, GL_SPOT_DIRECTION, pos);
glLightf(glLight, GL_SPOT_CUTOFF, (_cutoff * 180.0) / M_PI);
glLightf(glLight, GL_SPOT_EXPONENT, _exponent);
} else {
glLightf(glLight, GL_SPOT_CUTOFF, 180.0);
}
}
/*static*/
void TeLightOpenGL::updateGlobal() {
const TeColor globalAmbient(_globalAmbientColor);
const float col[4] = {globalAmbient.r() / 255.0f,
globalAmbient.g() / 255.0f, globalAmbient.b() / 255.0f, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
}
} // end namespace Tetraedge
|