1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
26 // File: vogl_light_state.cpp
27 #include "vogl_light_state.h"
29 vogl_light_state::vogl_light_state()
35 vogl_light_state::~vogl_light_state()
40 bool vogl_light_state::snapshot(const vogl_context_info &context_info)
48 bool any_gl_errors = false;
50 m_lights.resize(context_info.get_max_lights());
51 for (uint light = 0; light < context_info.get_max_lights(); light++)
53 #define GET_FLOAT(light, pname) \
56 float values[4] = { 0, 0, 0, 0 }; \
57 GL_ENTRYPOINT(glGetLightfv)(get_light_enum(light), pname, values); \
58 if (vogl_check_gl_error()) \
59 any_gl_errors = true; \
60 m_lights[light].insert(pname, 0, values, sizeof(values[0])); \
62 GET_FLOAT(light, GL_CONSTANT_ATTENUATION);
63 GET_FLOAT(light, GL_LINEAR_ATTENUATION);
64 GET_FLOAT(light, GL_QUADRATIC_ATTENUATION);
65 GET_FLOAT(light, GL_SPOT_EXPONENT);
66 GET_FLOAT(light, GL_SPOT_CUTOFF);
67 GET_FLOAT(light, GL_AMBIENT);
68 GET_FLOAT(light, GL_DIFFUSE);
69 GET_FLOAT(light, GL_SPECULAR);
70 GET_FLOAT(light, GL_POSITION);
71 GET_FLOAT(light, GL_SPOT_DIRECTION);
79 vogl_error_printf("%s: GL error while enumerating light params\n", VOGL_METHOD_NAME);
89 bool vogl_light_state::set_light_parameter(uint light, GLenum pname) const
93 GLenum light_enum = get_light_enum(light);
95 const vogl_state_data *pData = m_lights[light].find(pname);
103 if (pData->get_num_elements() > cMaxElements)
109 if ((pData->get_data_type() == cSTFloat) || (pData->get_data_type() == cSTDouble))
111 float fvals[cMaxElements];
112 pData->get_float(fvals);
113 if (pData->get_num_elements() == 1)
114 GL_ENTRYPOINT(glLightf)(light_enum, pname, fvals[0]);
116 GL_ENTRYPOINT(glLightfv)(light_enum, pname, fvals);
120 int ivals[cMaxElements];
121 pData->get_int(ivals);
122 if (pData->get_num_elements() == 1)
123 GL_ENTRYPOINT(glLighti)(light_enum, pname, ivals[0]);
125 GL_ENTRYPOINT(glLightiv)(light_enum, pname, ivals);
128 return !vogl_check_gl_error();
131 bool vogl_light_state::restore(const vogl_context_info &context_info) const
140 const uint num_lights = math::minimum<uint>(m_lights.size(), context_info.get_max_lights());
141 if (m_lights.size() > context_info.get_max_lights())
143 vogl_warning_printf("%s: Object has %u lights, but the context only supports %u lights!\n", VOGL_METHOD_NAME, m_lights.size(), context_info.get_max_lights());
146 for (uint light = 0; light < num_lights; light++)
148 #define SET_FLOAT(light, pname) set_light_parameter(light, pname)
149 SET_FLOAT(light, GL_CONSTANT_ATTENUATION);
150 SET_FLOAT(light, GL_LINEAR_ATTENUATION);
151 SET_FLOAT(light, GL_QUADRATIC_ATTENUATION);
152 SET_FLOAT(light, GL_SPOT_EXPONENT);
153 SET_FLOAT(light, GL_SPOT_CUTOFF);
154 SET_FLOAT(light, GL_AMBIENT);
155 SET_FLOAT(light, GL_DIFFUSE);
156 SET_FLOAT(light, GL_SPECULAR);
157 SET_FLOAT(light, GL_POSITION);
158 SET_FLOAT(light, GL_SPOT_DIRECTION);
162 return !vogl_check_gl_error();
165 void vogl_light_state::clear()
171 bool vogl_light_state::serialize(json_node &node, vogl_blob_manager &blob_manager) const
181 json_node &light_array_node = node.add_array("lights");
182 for (uint i = 0; i < m_lights.size(); i++)
183 if (!m_lights[i].serialize(light_array_node.add_object(), blob_manager))
189 bool vogl_light_state::deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
195 const json_node *pLight_array_node = node.find_child_array("lights");
196 if (!pLight_array_node)
198 if (!pLight_array_node->are_all_children_objects())
201 m_lights.resize(pLight_array_node->size());
203 for (uint i = 0; i < m_lights.size(); i++)
205 if (!m_lights[i].deserialize(*pLight_array_node->get_child(i), blob_manager))