1 ////////////////////////////////////////////////////////////////////////////////
2 //    Scorched3D (c) 2000-2011
3 //
4 //    This file is part of Scorched3D.
5 //
6 //    Scorched3D is free software; you can redistribute it and/or modify
7 //    it under the terms of the GNU General Public License as published by
8 //    the Free Software Foundation; either version 2 of the License, or
9 //    (at your option) any later version.
10 //
11 //    Scorched3D is distributed in the hope that it will be useful,
12 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //    GNU General Public License for more details.
15 //
16 //    You should have received a copy of the GNU General Public License along
17 //    with this program; if not, write to the Free Software Foundation, Inc.,
18 //    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20 
21 #include <GLSL/GLSLShader.h>
22 #include <GLEXT/GLStateExtension.h>
23 #include <common/Defines.h>
24 #include <string>
25 
GLSLShader(const char * filename,Type stype,const defines_list & dl)26 GLSLShader::GLSLShader(const char *filename, Type stype,
27 					   const defines_list& dl) :
28 	id_(0)
29 {
30 	DIALOG_ASSERT(GLStateExtension::hasShaders());
31 
32 	switch (stype)
33 	{
34 	case VERTEX:
35 		id_ = glCreateShaderObjectARB(GL_VERTEX_SHADER);
36 		break;
37 	case FRAGMENT:
38 		id_ = glCreateShaderObjectARB(GL_FRAGMENT_SHADER);
39 		break;
40 	default:
41 		DIALOG_ASSERT(0); // ("invalid shader type");
42 	}
43 
44 	DIALOG_ASSERT(id_); // runtime_error("can't create glsl shader");
45 
46 	// the program as string
47 	std::string prg;
48 
49 	// add defines to top of list for preprocessor
50 	for (defines_list::const_iterator it = dl.begin(); it != dl.end(); ++it) {
51 		prg += std::string("#define ") + *it + "\n";
52 	}
53 
54 	// read lines.
55 	FILE *in = fopen(filename, "rb");
56 	if (!in) S3D::dialogExit("GLSLShader",
57 		S3D::formatStringBuffer("ERROR: Cannot find shader file \"%s\"", filename));
58 
59 	char buffer[256];
60 	while (fgets(buffer, 256, in) != 0)
61 	{
62 		prg += buffer;
63 	}
64 	fclose(in);
65 
66 	const char* prg_cstr = prg.c_str();
67 	glShaderSourceARB(id_, 1, &prg_cstr, 0);
68 
69 	glCompileShaderARB(id_);
70 
71 	GLint compiled = GL_FALSE;
72 	glGetObjectParameterivARB(id_, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
73 	if (compiled == GL_FALSE)
74 	{
75 		// get compile log
76 		GLint maxlength = 0;
77 		glGetObjectParameterivARB(id_, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxlength);
78 		std::string logText(maxlength+1, ' ');
79 		GLsizei length = 0;
80 		glGetInfoLogARB(id_, maxlength, &length, &logText[0]);
81 
82 		S3D::dialogExit("GLSLShader",
83 			S3D::formatStringBuffer("Shader compiling failed %s : %s", filename, logText.c_str()));
84 	}
85 }
86 
~GLSLShader()87 GLSLShader::~GLSLShader()
88 {
89 	glDeleteObjectARB(id_);
90 }
91