shaderPhong.cpp 8.25 KB
Newer Older
Sylvain Thery's avatar
Sylvain Thery committed
1 2 3
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps  *
* version 0.1                                                                  *
4
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg           *
Sylvain Thery's avatar
Sylvain Thery committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
*                                                                              *
* This library is free software; you can redistribute it and/or modify it      *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your     *
* option) any later version.                                                   *
*                                                                              *
* This library 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 Lesser General Public License  *
* for more details.                                                            *
*                                                                              *
* You should have received a copy of the GNU Lesser General Public License     *
* along with this library; if not, write to the Free Software Foundation,      *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.           *
*                                                                              *
20
* Web site: http://cgogn.unistra.fr/                                           *
Sylvain Thery's avatar
Sylvain Thery committed
21 22 23
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/
Sylvain Thery's avatar
Sylvain Thery committed
24
#define CGoGN_UTILS_DLL_EXPORT 1
Sylvain Thery's avatar
Sylvain Thery committed
25
#include <GL/glew.h>
26
#include "Utils/Shaders/shaderPhong.h"
Sylvain Thery's avatar
Sylvain Thery committed
27 28 29

namespace CGoGN
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
30

Sylvain Thery's avatar
Sylvain Thery committed
31 32
namespace Utils
{
33

34 35
#include "shaderPhong.vert"
#include "shaderPhong.frag"
Sylvain Thery's avatar
Sylvain Thery committed
36 37
#include "shaderPhongClip.vert"
#include "shaderPhongClip.frag"
Sylvain Thery's avatar
Sylvain Thery committed
38 39


40
	ShaderPhong::ShaderPhong(bool withClipping, bool withEyePosition) :
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
41
	m_with_color(false),
42
	m_with_eyepos(withEyePosition),
43
	m_doubleSided(1),
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
44 45 46 47
	m_ambiant(Geom::Vec4f(0.05f,0.05f,0.1f,0.0f)),
	m_diffuse(Geom::Vec4f(0.1f,1.0f,0.1f,0.0f)),
	m_specular(Geom::Vec4f(1.0f,1.0f,1.0f,0.0f)),
	m_shininess(100.0f),
48
	m_lightPos(Geom::Vec3f(10.0f,10.0f,1000.0f)),
Sylvain Thery's avatar
Sylvain Thery committed
49
	m_backColor(0.0f,0.0f,0.0f,0.0f),
50 51
	m_vboPos(NULL),
	m_vboNormal(NULL),
Sylvain Thery's avatar
Sylvain Thery committed
52 53
	m_vboColor(NULL),
	m_planeClip(Geom::Vec4f(0.0f,0.0f,0.0f,0.0f))
Sylvain Thery's avatar
Sylvain Thery committed
54
{
55 56
	std::string glxvert(GLSLShader::defines_gl());
	std::string glxfrag(GLSLShader::defines_gl());
Sylvain Thery's avatar
Sylvain Thery committed
57 58 59 60 61 62 63 64 65

	if (withClipping)
	{
		m_nameVS = "ShaderPhongClip_vs";
		m_nameFS = "ShaderPhongClip_fs";
		if (m_with_eyepos)
			glxvert.append("#define WITH_EYEPOSITION");
		glxvert.append(vertexShaderClipText);
		// Use double sided lighting if set
66 67
		//if (doubleSided)
		//	glxfrag.append("#define DOUBLE_SIDED\n");
Sylvain Thery's avatar
Sylvain Thery committed
68 69 70 71 72 73 74 75 76 77
		glxfrag.append(fragmentShaderClipText);
	}
	else
	{
		m_nameVS = "ShaderPhong_vs";
		m_nameFS = "ShaderPhong_fs";
		if (m_with_eyepos)
			glxvert.append("#define WITH_EYEPOSITION");
		glxvert.append(vertexShaderText);
		// Use double sided lighting if set
78 79
		//if (doubleSided)
		//	glxfrag.append("#define DOUBLE_SIDED\n");
Sylvain Thery's avatar
Sylvain Thery committed
80 81
		glxfrag.append(fragmentShaderText);
	}
Sylvain Thery's avatar
Sylvain Thery committed
82 83 84 85 86 87 88 89

	loadShadersFromMemory(glxvert.c_str(), glxfrag.c_str());

	// and get and fill uniforms
	getLocations();
	sendParams();
}

90

Sylvain Thery's avatar
Sylvain Thery committed
91
void ShaderPhong::getLocations()
Sylvain Thery's avatar
Sylvain Thery committed
92
{
93
	bind();
94 95 96 97 98
	*m_unif_ambiant   = glGetUniformLocation(this->program_handler(), "materialAmbient");
	*m_unif_diffuse   = glGetUniformLocation(this->program_handler(), "materialDiffuse");
	*m_unif_specular  = glGetUniformLocation(this->program_handler(), "materialSpecular");
	*m_unif_shininess = glGetUniformLocation(this->program_handler(), "shininess");
	*m_unif_lightPos  = glGetUniformLocation(this->program_handler(), "lightPosition");
Sylvain's avatar
Sylvain committed
99 100
	if (m_with_eyepos)
		*m_unif_eyePos  = glGetUniformLocation(this->program_handler(), "eyePosition");
Sylvain Thery's avatar
Sylvain Thery committed
101 102
	*m_unif_backColor  = glGetUniformLocation(this->program_handler(), "backColor");
	*m_unif_planeClip = glGetUniformLocation(this->program_handler(), "planeClip");
103
	*m_unif_doubleSided = glGetUniformLocation(this->program_handler(), "doubleSided");
Sylvain Thery's avatar
Sylvain Thery committed
104

105
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
106 107
}

Sylvain Thery's avatar
Sylvain Thery committed
108
void ShaderPhong::sendParams()
Sylvain Thery's avatar
Sylvain Thery committed
109
{
110
	bind();
111 112 113 114 115
	glUniform4fv(*m_unif_ambiant,  1, m_ambiant.data());
	glUniform4fv(*m_unif_diffuse,  1, m_diffuse.data());
	glUniform4fv(*m_unif_specular, 1, m_specular.data());
	glUniform1f(*m_unif_shininess,    m_shininess);
	glUniform3fv(*m_unif_lightPos, 1, m_lightPos.data());
116
	glUniform1i(*m_unif_doubleSided, m_doubleSided);
Sylvain's avatar
Sylvain committed
117 118
	if (m_with_eyepos)
		glUniform3fv(*m_unif_eyePos, 1, m_eyePos.data());
Sylvain Thery's avatar
Sylvain Thery committed
119 120 121
	glUniform4fv(*m_unif_backColor,  1, m_backColor.data());
	if (*m_unif_planeClip > 0)
		glUniform4fv(*m_unif_planeClip, 1, m_planeClip.data());
122
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
123 124
}

125 126 127 128 129 130 131 132 133 134
void ShaderPhong::setDoubleSided(bool doubleSided)
{
	m_doubleSided = doubleSided;

	bind();
	glUniform1i(*m_unif_doubleSided, m_doubleSided);
	unbind();
}


Sylvain Thery's avatar
Sylvain Thery committed
135
void ShaderPhong::setAmbiant(const Geom::Vec4f& ambiant)
Sylvain Thery's avatar
Sylvain Thery committed
136
{
137
	bind();
138
	glUniform4fv(*m_unif_ambiant,1, ambiant.data());
Sylvain Thery's avatar
Sylvain Thery committed
139
	m_ambiant = ambiant;
140
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
141 142
}

Sylvain Thery's avatar
Sylvain Thery committed
143
void ShaderPhong::setDiffuse(const Geom::Vec4f& diffuse)
Sylvain Thery's avatar
Sylvain Thery committed
144
{
145
	bind();
146
	glUniform4fv(*m_unif_diffuse,1, diffuse.data());
Sylvain Thery's avatar
Sylvain Thery committed
147
	m_diffuse = diffuse;
148
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
149 150
}

Sylvain Thery's avatar
Sylvain Thery committed
151
void ShaderPhong::setSpecular(const Geom::Vec4f& specular)
Sylvain Thery's avatar
Sylvain Thery committed
152
{
153
	bind();
154
	glUniform4fv(*m_unif_specular,1,specular.data());
Sylvain Thery's avatar
Sylvain Thery committed
155
	m_specular = specular;
156
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
157 158
}

Sylvain Thery's avatar
Sylvain Thery committed
159
void ShaderPhong::setShininess(float shininess)
Sylvain Thery's avatar
Sylvain Thery committed
160
{
161
	bind();
162
	glUniform1f (*m_unif_shininess, shininess);
Sylvain Thery's avatar
Sylvain Thery committed
163
	m_shininess = shininess;
164
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
165 166
}

Sylvain Thery's avatar
Sylvain Thery committed
167 168 169 170 171 172 173 174 175
void ShaderPhong::setBackColor(const Geom::Vec4f& back)
{
	bind();
	glUniform4fv(*m_unif_backColor,1, back.data());
	m_backColor = back;
	unbind();
}


176
void ShaderPhong::setLightPosition(const Geom::Vec3f& lightPos)
Sylvain Thery's avatar
Sylvain Thery committed
177
{
178
	bind();
179
	glUniform3fv(*m_unif_lightPos,1,lightPos.data());
Sylvain Thery's avatar
Sylvain Thery committed
180
	m_lightPos = lightPos;
181
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
182 183
}

184
void ShaderPhong::setEyePosition(const Geom::Vec3f& eyePos)
Sylvain's avatar
Sylvain committed
185 186 187
{
	if (m_with_eyepos)
	{
188
		bind();
Sylvain Thery's avatar
Sylvain Thery committed
189
		glUniform3fv(*m_unif_eyePos,1,eyePos.data());
Sylvain's avatar
Sylvain committed
190
		m_eyePos = eyePos;
191
		unbind();
Sylvain's avatar
Sylvain committed
192 193 194
	}
}

Sylvain Thery's avatar
Sylvain Thery committed
195
void ShaderPhong::setParams(const Geom::Vec4f& ambiant, const Geom::Vec4f& diffuse, const Geom::Vec4f& specular, float shininess, const Geom::Vec3f& lightPos)
Sylvain Thery's avatar
Sylvain Thery committed
196 197 198 199 200 201 202 203 204
{
	m_ambiant = ambiant;
	m_diffuse = diffuse;
	m_specular = specular;
	m_shininess = shininess;
	m_lightPos = lightPos;
	sendParams();
}

205
unsigned int ShaderPhong::setAttributeColor(VBO* vbo)
Sylvain Thery's avatar
Sylvain Thery committed
206
{
207
	m_vboColor = vbo;
Sylvain Thery's avatar
Sylvain Thery committed
208 209 210 211
	if (!m_with_color)
	{
		m_with_color=true;
		// set the define and recompile shader
212
		std::string gl3vert(GLSLShader::defines_gl());
Sylvain Thery's avatar
Sylvain Thery committed
213 214
		gl3vert.append("#define WITH_COLOR 1\n");
		gl3vert.append(vertexShaderText);
215
		std::string gl3frag(GLSLShader::defines_gl());
Sylvain Thery's avatar
Sylvain Thery committed
216 217 218 219 220 221 222 223 224
		gl3frag.append("#define WITH_COLOR 1\n");
		gl3frag.append(fragmentShaderText);
		loadShadersFromMemory(gl3vert.c_str(), gl3frag.c_str());

		// and treat uniforms
		getLocations();
		sendParams();
	}
	// bind th VA with WBO
225 226 227 228
	bind();
	unsigned int id = bindVA_VBO("VertexColor", vbo);
	unbind();
	return id;
Sylvain Thery's avatar
Sylvain Thery committed
229 230
}

Sylvain Thery's avatar
Sylvain Thery committed
231
void ShaderPhong::unsetAttributeColor()
Sylvain Thery's avatar
Sylvain Thery committed
232
{
233
	m_vboColor = NULL;
Sylvain Thery's avatar
Sylvain Thery committed
234 235
	if (m_with_color)
	{
236
		m_with_color = false;
Sylvain Thery's avatar
Sylvain Thery committed
237
		// unbind the VA
238
		bind();
Sylvain Thery's avatar
Sylvain Thery committed
239
		unbindVA("VertexColor");
240
		unbind();
Sylvain Thery's avatar
Sylvain Thery committed
241
		// recompile shader
242
		std::string gl3vert(GLSLShader::defines_gl());
Sylvain Thery's avatar
Sylvain Thery committed
243
		gl3vert.append(vertexShaderText);
244
		std::string gl3frag(GLSLShader::defines_gl());
Sylvain Thery's avatar
Sylvain Thery committed
245 246 247 248 249 250
		gl3frag.append(fragmentShaderText);
		loadShadersFromMemory(gl3vert.c_str(), gl3frag.c_str());
		// and treat uniforms
		getLocations();
		sendParams();
	}
251 252
}

Sylvain Thery's avatar
Sylvain Thery committed
253 254 255 256 257 258 259 260 261 262 263
void ShaderPhong::setClippingPlane(const Geom::Vec4f& plane)
{
	if (*m_unif_planeClip > 0)
	{
		m_planeClip = plane;
		bind();
		glUniform4fv(*m_unif_planeClip, 1, plane.data());
		unbind();
	}
}

264 265 266 267
void ShaderPhong::restoreUniformsAttribs()
{
	getLocations();
	sendParams();
Sylvain Thery's avatar
Sylvain Thery committed
268

269
	bind();
270 271 272 273
	bindVA_VBO("VertexPosition", m_vboPos);
	bindVA_VBO("VertexNormal", m_vboNormal);
	if (m_vboColor)
		bindVA_VBO("VertexColor", m_vboColor);
274

275
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
276 277
}

278 279
unsigned int ShaderPhong::setAttributePosition(VBO* vbo)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
280
	m_vboPos = vbo;
281 282 283 284
	bind();
	unsigned int id = bindVA_VBO("VertexPosition", vbo);
	unbind();
	return id;
285 286 287 288 289
}

unsigned int ShaderPhong::setAttributeNormal(VBO* vbo)
{
	m_vboNormal = vbo;
290 291 292 293
	bind();
	unsigned int id = bindVA_VBO("VertexNormal", vbo);
	unbind();
	return id;
294 295
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
296
} // namespace Utils
297

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
298
} // namespace CGoGN