shaderPhong.cpp 7.93 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-2011, 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.u-strasbg.fr/                                         *
Sylvain Thery's avatar
Sylvain Thery committed
21 22 23 24 25
* Contact information: cgogn@unistra.fr                                        *
*                                                                              *
*******************************************************************************/

#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 33
namespace Utils
{

Sylvain Thery's avatar
Sylvain Thery committed
34
std::string ShaderPhong::vertexShaderText =
Sylvain Thery's avatar
Sylvain Thery committed
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
"ATTRIBUTE vec3 VertexPosition, VertexNormal;\n"
"#ifdef WITH_COLOR\n"
"ATTRIBUTE vec3 VertexColor;\n"
"#endif\n"
"uniform mat4 ModelViewProjectionMatrix;\n"
"uniform mat4 ModelViewMatrix;\n"
"uniform mat4 NormalMatrix;\n"
"uniform vec3 lightPosition;\n"
"VARYING_VERT vec3 EyeVector, Normal, LightDir;\n"
"#ifdef WITH_COLOR\n"
"VARYING_VERT vec3 Color;\n"
"#endif\n"
"INVARIANT_POS;\n"
"void main ()\n"
"{\n"
"	Normal = vec3 (NormalMatrix * vec4 (VertexNormal, 0.0));\n"
" 	vec3 Position = vec3 (ModelViewMatrix * vec4 (VertexPosition, 1.0));\n"
"	LightDir = lightPosition - Position;\n"
"	EyeVector = -Position;\n"
"	#ifdef WITH_COLOR\n"
55
"	Color = VertexColor;\n"
Sylvain Thery's avatar
Sylvain Thery committed
56 57 58 59 60
"	#endif\n"
"	gl_Position = ModelViewProjectionMatrix * vec4 (VertexPosition, 1.0);\n"
"}";


Sylvain Thery's avatar
Sylvain Thery committed
61
std::string ShaderPhong::fragmentShaderText =
Sylvain Thery's avatar
Sylvain Thery committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
"PRECISON;\n"
"VARYING_FRAG vec3 EyeVector, Normal, LightDir;\n"
"#ifdef WITH_COLOR\n"
"VARYING_FRAG vec3 Color;\n"
"#endif\n"
"uniform vec4 materialDiffuse;\n"
"uniform vec4 materialSpecular;\n"
"uniform vec4 materialAmbient;\n"
"uniform float shininess;\n"
"FRAG_OUT_DEF;\n"
"void main()\n"
"{\n"
"	vec3 N = normalize (Normal);\n"
"	vec3 L = normalize (LightDir);\n"
"	float lambertTerm = dot(N,L);\n"

"	vec4 finalColor = materialAmbient;\n"
79 80 81 82 83 84 85 86 87
"	#ifdef DOUBLE_SIDED\n"
"	if (lambertTerm < 0.0)\n"
"	{\n"
"		N = -1.0*N;\n"
"		lambertTerm = -1.0*lambertTerm;\n"
"	}\n"
"	#else\n"
"	if (lambertTerm > 0.0)\n"
"	#endif\n"
Sylvain Thery's avatar
Sylvain Thery committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
"	{\n"
"		#ifndef WITH_COLOR\n"
"		finalColor += materialDiffuse * lambertTerm;\n"
"		#else\n"
"		finalColor += vec4((Color*lambertTerm),0.0) ;\n"
"		#endif\n"
"		vec3 E = normalize(EyeVector);\n"
"		vec3 R = reflect(-L, N);\n"
"		float specular = pow( max(dot(R, E), 0.0), shininess );\n"
"		finalColor += materialSpecular * specular;\n"
"	}\n"
"	gl_FragColor=finalColor;\n"
"}";


103
ShaderPhong::ShaderPhong(bool doubleSided):
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
104 105 106 107 108
	m_with_color(false),
	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),
109 110 111 112
	m_lightPos(Geom::Vec3f(10.0f,10.0f,1000.0f)),
	m_vboPos(NULL),
	m_vboNormal(NULL),
	m_vboColor(NULL)
Sylvain Thery's avatar
Sylvain Thery committed
113
{
114 115 116 117 118

	m_nameVS = "ShaderPhong_vs";
	m_nameFS = "ShaderPhong_fs";
	m_nameGS = "ShaderPhong_gs";

Sylvain Thery's avatar
Sylvain Thery committed
119 120 121 122 123
	// get choose GL defines (2 or 3)
	// ans compile shaders
	std::string glxvert(*GLSLShader::DEFINES_GL);
	glxvert.append(vertexShaderText);
	std::string glxfrag(*GLSLShader::DEFINES_GL);
124 125 126
	// Use double sided lighting if set
	if (doubleSided)
		glxfrag.append("#define DOUBLE_SIDED\n");
Sylvain Thery's avatar
Sylvain Thery committed
127 128 129 130 131 132 133 134 135 136
	glxfrag.append(fragmentShaderText);

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

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

Sylvain Thery's avatar
Sylvain Thery committed
137
void ShaderPhong::getLocations()
Sylvain Thery's avatar
Sylvain Thery committed
138
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
139 140 141 142 143
	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 Thery's avatar
Sylvain Thery committed
144 145
}

Sylvain Thery's avatar
Sylvain Thery committed
146
void ShaderPhong::sendParams()
Sylvain Thery's avatar
Sylvain Thery committed
147 148 149 150 151 152 153 154
{
	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());
}

Sylvain Thery's avatar
Sylvain Thery committed
155
void ShaderPhong::setAmbiant(const Geom::Vec4f& ambiant)
Sylvain Thery's avatar
Sylvain Thery committed
156 157 158 159 160 161
{
	this->bind();
	glUniform4fv(m_unif_ambiant,1, ambiant.data());
	m_ambiant = ambiant;
}

Sylvain Thery's avatar
Sylvain Thery committed
162
void ShaderPhong::setDiffuse(const Geom::Vec4f& diffuse)
Sylvain Thery's avatar
Sylvain Thery committed
163 164 165 166 167 168
{
	this->bind();
	glUniform4fv(m_unif_diffuse,1, diffuse.data());
	m_diffuse = diffuse;
}

Sylvain Thery's avatar
Sylvain Thery committed
169
void ShaderPhong::setSpecular(const Geom::Vec4f& specular)
Sylvain Thery's avatar
Sylvain Thery committed
170 171 172 173 174 175
{
	this->bind();
	glUniform4fv(m_unif_specular,1,specular.data());
	m_specular = specular;
}

Sylvain Thery's avatar
Sylvain Thery committed
176
void ShaderPhong::setShininess(float shininess)
Sylvain Thery's avatar
Sylvain Thery committed
177 178 179 180 181 182
{
	this->bind();
	glUniform1f (m_unif_shininess, shininess);
	m_shininess = shininess;
}

Sylvain Thery's avatar
Sylvain Thery committed
183
void ShaderPhong::setLightPosition( Geom::Vec3f lightPos)
Sylvain Thery's avatar
Sylvain Thery committed
184 185 186 187 188 189
{
	this->bind();
	glUniform3fv(m_unif_lightPos,1,lightPos.data());
	m_lightPos = lightPos;
}

Sylvain Thery's avatar
Sylvain Thery committed
190
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
191 192 193 194 195 196 197 198 199 200
{
	m_ambiant = ambiant;
	m_diffuse = diffuse;
	m_specular = specular;
	m_shininess = shininess;
	m_lightPos = lightPos;
	bind();
	sendParams();
}

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

		// and treat uniforms
		bind();
		getLocations();
		sendParams();
	}
	// bind th VA with WBO
222
	return bindVA_VBO("VertexColor", vbo);
Sylvain Thery's avatar
Sylvain Thery committed
223 224
}

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

void ShaderPhong::restoreUniformsAttribs()
{
	getLocations();
249 250

	bind();
251
	sendParams();
Sylvain Thery's avatar
Sylvain Thery committed
252

253 254 255 256
	bindVA_VBO("VertexPosition", m_vboPos);
	bindVA_VBO("VertexNormal", m_vboNormal);
	if (m_vboColor)
		bindVA_VBO("VertexColor", m_vboColor);
257
	unbind();
Sylvain Thery's avatar
Sylvain Thery committed
258 259
}

260 261
unsigned int ShaderPhong::setAttributePosition(VBO* vbo)
{
Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
262
	m_vboPos = vbo;
263 264 265 266 267 268 269 270 271
	return bindVA_VBO("VertexPosition", vbo);
}

unsigned int ShaderPhong::setAttributeNormal(VBO* vbo)
{
	m_vboNormal = vbo;
	return bindVA_VBO("VertexNormal", vbo);
}

Pierre Kraemer's avatar
merge..  
Pierre Kraemer committed
272
} // namespace Utils
273

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