]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_material_state.cpp
Initial vogl checkin
[vogl] / src / voglcommon / vogl_material_state.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 // File: vogl_material_state.cpp
27 #include "vogl_material_state.h"
28
29 vogl_material_state::vogl_material_state()
30     : m_valid(false)
31 {
32     VOGL_FUNC_TRACER
33 }
34
35 vogl_material_state::~vogl_material_state()
36 {
37     VOGL_FUNC_TRACER
38 }
39
40 bool vogl_material_state::snapshot(const vogl_context_info &context_info)
41 {
42     VOGL_FUNC_TRACER
43
44     VOGL_NOTE_UNUSED(context_info);
45
46     clear();
47
48     VOGL_CHECK_GL_ERROR;
49
50     bool any_gl_errors = false;
51
52 #define GET_FLOAT(side, pname)                                         \
53     do                                                                 \
54     {                                                                  \
55         float values[4] = { 0, 0, 0, 0 };                              \
56         GL_ENTRYPOINT(glGetMaterialfv)(get_face(side), pname, values); \
57         if (vogl_check_gl_error())                                      \
58             any_gl_errors = true;                                      \
59         m_params[side].insert(pname, 0, values, sizeof(values[0]));    \
60     } while (0)
61     for (uint s = 0; s < cTotalSides; s++)
62     {
63         GET_FLOAT(s, GL_AMBIENT);
64         GET_FLOAT(s, GL_DIFFUSE);
65         GET_FLOAT(s, GL_SPECULAR);
66         GET_FLOAT(s, GL_EMISSION);
67         GET_FLOAT(s, GL_SHININESS);
68         GET_FLOAT(s, GL_COLOR_INDEXES);
69     }
70 #undef GET_FLOAT
71
72     if (any_gl_errors)
73     {
74         clear();
75
76         vogl_error_printf("%s: GL error while enumerating material params\n", VOGL_METHOD_NAME);
77         return false;
78     }
79
80     m_valid = true;
81
82     return true;
83 }
84
85 bool vogl_material_state::set_material_parameter(uint side, GLenum pname) const
86 {
87     VOGL_FUNC_TRACER
88
89     const GLenum face = get_face(side);
90
91     const vogl_state_data *pData = m_params[side].find(pname);
92     if (!pData)
93     {
94         VOGL_ASSERT_ALWAYS;
95         return false;
96     }
97
98     enum
99     {
100         cMaxElements = 4
101     };
102     if (pData->get_num_elements() > cMaxElements)
103     {
104         VOGL_ASSERT_ALWAYS;
105         return false;
106     }
107
108     if ((pData->get_data_type() == cSTFloat) || (pData->get_data_type() == cSTDouble))
109     {
110         float fvals[cMaxElements];
111         pData->get_float(fvals);
112         if (pData->get_num_elements() == 1)
113             GL_ENTRYPOINT(glMaterialf)(face, pname, fvals[0]);
114         else
115             GL_ENTRYPOINT(glMaterialfv)(face, pname, fvals);
116     }
117     else
118     {
119         int ivals[cMaxElements];
120         pData->get_int(ivals);
121         if (pData->get_num_elements() == 1)
122             GL_ENTRYPOINT(glMateriali)(face, pname, ivals[0]);
123         else
124             GL_ENTRYPOINT(glMaterialiv)(face, pname, ivals);
125     }
126
127     return !vogl_check_gl_error();
128 }
129
130 bool vogl_material_state::restore(const vogl_context_info &context_info) const
131 {
132     VOGL_FUNC_TRACER
133
134     VOGL_NOTE_UNUSED(context_info);
135
136     if (!m_valid)
137     {
138         VOGL_ASSERT_ALWAYS;
139         return false;
140     }
141
142     VOGL_CHECK_GL_ERROR;
143
144 #define SET_FLOAT(side, pname) set_material_parameter(side, pname)
145     for (uint s = 0; s < cTotalSides; s++)
146     {
147         SET_FLOAT(s, GL_AMBIENT);
148         SET_FLOAT(s, GL_DIFFUSE);
149         SET_FLOAT(s, GL_SPECULAR);
150         SET_FLOAT(s, GL_EMISSION);
151         SET_FLOAT(s, GL_SHININESS);
152         SET_FLOAT(s, GL_COLOR_INDEXES);
153     }
154 #undef GET_FLOAT
155
156     return !vogl_check_gl_error();
157 }
158
159 void vogl_material_state::clear()
160 {
161     VOGL_FUNC_TRACER
162
163     for (uint i = 0; i < cTotalSides; i++)
164         m_params[i].clear();
165
166     m_valid = false;
167 }
168
169 bool vogl_material_state::serialize(json_node &node, vogl_blob_manager &blob_manager) const
170 {
171     VOGL_FUNC_TRACER
172
173     if (!m_params[cFront].serialize(node.add_object("front"), blob_manager) || !m_params[cBack].serialize(node.add_object("back"), blob_manager))
174         return false;
175
176     return true;
177 }
178
179 bool vogl_material_state::deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
180 {
181     VOGL_FUNC_TRACER
182
183     clear();
184
185     if (!m_params[cFront].deserialize("front", node, blob_manager) || !m_params[cBack].deserialize("back", node, blob_manager))
186     {
187         clear();
188         return false;
189     }
190
191     m_valid = true;
192
193     return true;
194 }
195
196 vogl_state_vector *vogl_material_state::get_state_vector(int side)
197 {
198     VOGL_FUNC_TRACER
199
200     if (side < 0 || side >= cTotalSides)
201     {
202         return NULL;
203     }
204
205     return &(m_params[side]);
206 }
207
208 const vogl_state_vector *vogl_material_state::get_state_vector(int side) const
209 {
210     VOGL_FUNC_TRACER
211
212     if (side < 0 || side >= cTotalSides)
213     {
214         return NULL;
215     }
216
217     return &(m_params[side]);
218 }