Пример #1
0
	GLWindow(const char *name = "SDL GL Window", const Size &s = Size(800,600), unsigned int flags = 0) throw(GLException)
		: SDLWindow(name,s,SDL_WINDOW_OPENGL|flags)
	{

		context = SDL_GL_CreateContext(getSDLWindow());

		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
		SDL_GL_SetAttribute(SDL_GL_RED_SIZE,5);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,6);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,5);
		SDL_GL_SetSwapInterval(1);

		GLenum glew_status = glewInit();
		if(GLEW_OK != glew_status)
		{
			throw(GLException(reinterpret_cast<const char*>(glewGetErrorString(glew_status))));
		}
		if(!GLEW_VERSION_2_0)
		{
			/* TODO:
			 * in this case use old OpenGL */
			throw(GLException("No support for OpenGL 2.0 found"));
		}

		glClearColor(0, 0, 0, 0);
		glViewport(0,0,s.w,s.h);
	}
Пример #2
0
AssimpModel::AssimpModel ( const std::string& fileName )
{
    m_scene = m_importer.ReadFile ( fileName.c_str(), aiProcess_Triangulate );
    if ( !m_scene ) {
        throw GLException("Load model failed");
    }

    if (m_scene->HasTextures()) {
        throw GLException("AssimpModel::LoadGLTextures failed");
    }

    loadTextures(fileName);
}
Пример #3
0
 IndexSlot operator[](int index) {
   if(index >= m_indexCount) {
     logError("[IndexSet] Index <", index, "> out of bounds!");
     throw GLException("[IndexSet] Index out of bounds");
   }
   return std::move(IndexSlot(*(m_buffer + index)));
 }
Пример #4
0
void debugGLError( const std::string& when, const GLenum error,
                   const char* file, const int line )
{
    LBWARN << lunchbox::disableFlush << "Got " << glError( error ) << ' '
           << when << " in " << file << ':' << line << std::endl
           << lunchbox::backtrace << lunchbox::enableFlush << std::endl;
    throw GLException( error );
}
Пример #5
0
void 
CheckForGLError( const std::string &situation  )
{
	GLenum errorCode = glGetError();
	if (errorCode != GL_NO_ERROR) {
		const char *string = (const char *)gluErrorString(errorCode);
		_THROW_ GLException( TO_STRING( situation << " : " << string ) );
	}
}
Пример #6
0
void GLSLProgram::setUniform(const char* uniformName, T& value) {
	if (!m_linked) {
		SAFE_THROW(GLException(E_BADSTATE, "GLSL program must be linked before binding uniforms"));
	}
	int loc = glGetUniformLocation(m_progID, uniformName);
	// the uniform could either not exist or be inactive (e.g. removed by the glsl compiler as it was not used)
	if (loc != -1) {
		this->setUniform(loc, value);
	}
}
Пример #7
0
    GLBuffer::GLBuffer() {
        GLuint id = 0;

        try {
            GLError::clearAll();
            glGenBuffers(1, &id);
            setID(id);

            GLError::throwExceptionOnError();
        }
        catch (GLException& e) {
            glDeleteBuffers(1, &id);
            throw GLException(string("Couldn't create buffer: ") + string(e.what()));
        }
    }
Пример #8
0
		GLTexture::GLTexture() : MioObject()
		{			
			glGetError();
			glGenTextures(1, &texID_);			
			GLint error = glGetError();
			if (error != GL_NO_ERROR)
				throw GLException("GLException: cannot generate new texture");

			components_ = 4;
			format_ = GL_RGBA;
			type_ = GL_UNSIGNED_BYTE;
			width_ = 0;
			height_ = 0;

			mag_filter_ = GL_LINEAR;
			min_filter_ = GL_LINEAR;
			wrap_s_ = GL_REPEAT;
			wrap_t_ = GL_REPEAT;

			mipmapBuilt_ = false;
		}
Пример #9
0
void Program::create(VShader& vs, FShader& fs) {
  auto program = glCreateProgram();

  // attach both shaders
  glAttachShader(program, vs.getHandle());
  glAttachShader(program, fs.getHandle());

  // link program
  glLinkProgram(program);

  // check for errors
  GLint linkStatus;
  glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
  if(linkStatus != GL_TRUE) {
    // obtain error message
    GLint logLength;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
    vector<char> compileLog(logLength);
    glGetShaderInfoLog(program, logLength, nullptr, compileLog.data());
    logError("[Program] Could not link shaders <", vs.getFilename(),
             ", ", fs.getFilename(), "> ->");
    logError("[Program] ", compileLog.data());
    throw GLException("Could not link shaders");
  }
  log("[Program] Shaders <", vs.getFilename(), ", ", fs.getFilename(),
      "> were successfully linked.");

  // detach shaders (TODO: is this a good idea?)
  glDetachShader(program, vs.getHandle());
  glDetachShader(program, fs.getHandle());

  // check for any error
  checkGLError("[Program] GL error while linking program <", GLERR, ">!");

  // linking was successful: commit changes
  m_handle = program;
}
Пример #10
0
void GLSLProgram::setUniform(const String& uniformName, T& value) {
	if (!m_linked) {
		SAFE_THROW(GLException(E_BADSTATE, "GLSL program must be linked before binding uniforms"));
	}
	this->setUniform(uniformName.c_str(), value);
}
Пример #11
0
void ShaderGenerator::generateShaders(Material& mat, const RenderState& rs, const VertexFormat& vf, const FogParameters fogParams) {

	bool hasNormalMap = false;
	bool hasParallaxMap = false;

	ctemplate::TemplateDictionary vertexShaderDict("vertexShader");
	ctemplate::TemplateDictionary fragmentShaderDict("fragmentShader");

	ctemplate::TemplateDictionary* vertexIoDict = vertexShaderDict.AddIncludeDictionary("VERTEX_INPUTS");
	vertexIoDict->SetFilename("shader_templates/ft_vertex_inout.tpl");

	ctemplate::TemplateDictionary* fragmentOutDict = vertexShaderDict.AddIncludeDictionary("FRAGMENT_INPUTS");
	fragmentOutDict->SetFilename("shader_templates/ft_fragment_inout.tpl");
	fragmentOutDict->ShowSection("OUT_DIRECTION");

	ctemplate::TemplateDictionary* uniformsDict = vertexShaderDict.AddIncludeDictionary("UNIFORMS");
	uniformsDict->SetFilename("shader_templates/uniforms.tpl");

	// emit the fog uniforms if necessary
	if (fogParams.m_fogMode != FOG_NONE) {
		uniformsDict->ShowSection("FOG");
	}

	// use lighting when material uses shading and we have normals
	bool useLighting = !mat.m_shadeless && vf.getAttributeBySemantic(Vertex_Normal);
	if (useLighting) {
		uniformsDict->ShowSection("USE_LIGHTING");
	}

	if (vf.getAttributeBySemantic(Vertex_Normal)) {
		vertexShaderDict.ShowSection("HAS_NORMALS");
		vertexShaderDict.ShowSection("NORMALIZE_NORMALS");

		vertexIoDict->ShowSection("HAS_NORMALS");
		vertexIoDict->ShowSection("NORMALIZE_NORMALS");

		fragmentOutDict->ShowSection("HAS_NORMALS");

		uniformsDict->ShowSection("HAS_NORMALS");
	}

	if (vf.getAttributeBySemantic(Vertex_Tangent)) {
		fragmentOutDict->ShowSection("HAS_TANGENTS");
		vertexIoDict->ShowSection("HAS_TANGENTS");
	}

	if (vf.getAttributeBySemantic(Vertex_BiNormal)) {
		fragmentOutDict->ShowSection("HAS_BINORMALS");
		vertexIoDict->ShowSection("HAS_BINORMALS");
	}

	if (vf.getAttributeBySemantic(Vertex_Color)) {
		vertexShaderDict.ShowSection("HAS_COLORS");
		vertexIoDict->ShowSection("HAS_COLORS");
		fragmentOutDict->ShowSection("HAS_COLORS");
	}

	// indicates if the tex coords generation functions declarations template has already been
	// included in the vertex shader template
	bool texGenDeclIncluded = false;

	// number of active texture units
	uint activeTextures = 0;

	ctemplate::TemplateDictionary* texGenDict = vertexShaderDict.AddIncludeDictionary("TEX_COORDS_GEN");
	texGenDict->SetFilename("shader_templates/ft_tex_coords_gen.tpl");

	// Loops over all material textures and performs the following:
	//	1. Declares a respective uniform sampler object which will be named as u_sampler#,
	//     where # is the active texture index.
	//  2. Emits code for any texture coordinates generation scheme, if not simple UV.

	ctemplate::TemplateDictionary* parallaxMapDict = 0;

	for (int i = 0; i < MAX_TEXTURES_STACK; i++) {
		TexturePtr tex = mat.m_texStack->textures[i];
		if (tex) {
			// for the fragment shader, here we can fill in the dictionary for the texture application section
			// that takes into account the texture's mapTo, environment color, uvset, etc.
			ctemplate::TemplateDictionary* texUnitDict = fragmentShaderDict.AddIncludeDictionary(
					"SINGLE_TEXTURE_STACK_ENTRY");
			texUnitDict->SetFilename("shader_templates/ft_tex_stack_application.tpl");

			ctemplate::TemplateDictionary* alphaMapDict = 0;
			ctemplate::TemplateDictionary* tangentNormalMapDict = 0;
			ctemplate::TemplateDictionary* offsetMappingDict = 0;

			// depending on the texture's mapTo, we will emit different sections in the template
			ctemplate::TemplateDictionary* texMapToDict = 0;
			switch (mat.m_texStack->texOutputs[i].mapTo) {
			case TexMapTo_Diffuse:
				texMapToDict = texUnitDict->AddSectionDictionary("TEX_MAP_TO_DIFFUSE");
				break;
			case TexMapTo_CSpecular:
				texMapToDict = texUnitDict->AddSectionDictionary("TEX_MAP_TO_SPECULAR");
				break;
			case TexMapTo_Shininess:
				texMapToDict = texUnitDict->AddSectionDictionary("TEX_MAP_TO_SHININESS");
				break;
			case TexMapTo_Alpha:
				alphaMapDict = fragmentShaderDict.AddSectionDictionary("ALPHA_MAP_APPLICATION");
				break;
			case TexMapTo_Normal:
				tangentNormalMapDict = fragmentShaderDict.AddIncludeDictionary("TANGENT_SPACE_NORMAL_MAP");
				tangentNormalMapDict->SetFilename(TANGENT_SPACE_NMAP_TPL);
				parallaxMapDict = tangentNormalMapDict;
				hasNormalMap = true;
				break;
			case TexMapTo_Parallax:
				/* IMPORTANT: Parallax maps must come after the normal maps */
				if (parallaxMapDict) {
					offsetMappingDict = parallaxMapDict->AddSectionDictionary("PARALLAX_OFFSET_MAPPING");
				}
				hasParallaxMap = true;
				break;
			default:
				SAFE_THROW(GLException(E_NOTIMPL, "Unimplemented texture output mapping mode"))
			}

			texUnitDict->SetIntValue(TEX_INDEX, activeTextures);
			texUnitDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);

			if (alphaMapDict) {
				alphaMapDict->SetIntValue(TEX_INDEX, activeTextures);
				alphaMapDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			}

			if (tangentNormalMapDict) {
				tangentNormalMapDict->SetIntValue(TEX_INDEX, activeTextures);
				tangentNormalMapDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			}
			if (offsetMappingDict) {
				offsetMappingDict->SetIntValue(TEX_INDEX, activeTextures);
				offsetMappingDict->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			}

			switch (mat.m_texStack->texOutputs[i].blendOp) {
			case TexBlendOp_Mix:
				texUnitDict->ShowSection("TEX_BLENDOP_BLEND");
				break;
			case TexBlendOp_Add:
				texUnitDict->ShowSection("TEX_BLENDOP_ADD");
				break;
			case TexBlendOp_Multiply:
				texUnitDict->ShowSection("TEX_BLENDOP_MULTIPLY");
				break;
			case TexBlendOp_Decal:
				texUnitDict->ShowSection("TEX_BLENDOP_DECAL");
				break;
			default:
				SAFE_THROW(GLException(E_NOTIMPL, "Unimplemented texture blending mode"))
			}

			// this is the dictionary for a single uniform sampler declaration
			ctemplate::TemplateDictionary* samplerDict = uniformsDict->AddSectionDictionary("SINGLE_SAMPLER_DECL");
			samplerDict->SetIntValue(TEX_INDEX, activeTextures);

			const char* samplerToken;
			const char* coordsToken;
			switch (tex->getTextureTarget()) {
			case GL_TEXTURE_1D:
				samplerToken = "sampler1D";
				coordsToken = S_COORD;
				break;
			case GL_TEXTURE_CUBE_MAP:
				samplerToken = "samplerCube";
				coordsToken = STP_COORDS;
				break;
			case GL_TEXTURE_2D:
			default:
				samplerToken = "sampler2D";
				coordsToken = ST_COORDS;
				break;
			}

			samplerDict->SetValue("SAMPLER_SPEC", samplerToken);
			texUnitDict->SetValue(TEX_COORDS, coordsToken);

			if (alphaMapDict) {
				alphaMapDict->SetValue(TEX_COORDS, coordsToken);
			}
			if (tangentNormalMapDict) {
				tangentNormalMapDict->SetValue(TEX_COORDS, coordsToken);
			}
			if (offsetMappingDict) {
				offsetMappingDict->SetValue(TEX_COORDS, coordsToken);
			}

			// When a special texture coordinate generation system is used, we have to include
			// the TEX_COORDS_GEN_DECL template which contains function declarations for the various
			// tex gen systems. Then for each texture unit that uses custom tex gen, we need to
			// instantiate a SINGLE_TEX_COORDS_GEN section with an appropriately initialized dictionary
			ctemplate::TemplateDictionary* singleTexGen = texGenDict->AddSectionDictionary("SINGLE_TEXCOORDS_ASSIGN");
			singleTexGen->SetIntValue(UV_SET_INDEX, mat.m_texStack->texInputs[i].uvSet);
			singleTexGen->SetValue(TEX_COORDS, coordsToken);

			TexMapInput inputMapping = mat.m_texStack->texInputs[i].mapping;
			if (inputMapping != TexMapInput_UV) {
				if (!texGenDeclIncluded) {
					ctemplate::TemplateDictionary* texGenDecl = vertexShaderDict.AddIncludeDictionary(
							"TEX_COORDS_GEN_DECL");
					texGenDecl->SetFilename("shader_templates/ft_tex_coords_gen_decl.tpl");
					texGenDeclIncluded = true;
				}
				switch (inputMapping) {
				case TexMapInput_Normal:
					singleTexGen->ShowSection("NORMAL_TEXGEN");
					break;
				case TexMapInput_Refl:
					singleTexGen->ShowSection("REFLECTION_TEXGEN");
					break;
				case TexMapInput_Spherical:
					singleTexGen->ShowSection("SPHERE_TEXGEN");
					break;
				case TexMapInput_EyeSpace:
					singleTexGen->ShowSection("EYE_TEXGEN");
					break;
				case TexMapInput_ObjectSpace:
					singleTexGen->ShowSection("OBJECT_TEXGEN");
					break;
				case TexMapInput_Cube:
					singleTexGen->ShowSection("CUBE_TEXGEN");
					break;
				default:
					SAFE_THROW(GLException(E_NOTIMPL, "Unimplemented texture mapping mode"))
				}
			} else {
				singleTexGen->ShowSection("UV_MAPPING");
			}

			++activeTextures;
		}
	}
Пример #12
0
	void GLProgram::build( const char* vertsrc, const char* fragsrc, const char* geomsrc )
	{
		GLuint vs = 0, fs = 0, gs = 0;
		GLint status = GL_TRUE;
		GLint loglen;
		std::string logbuf;

		if( !vertsrc || !fragsrc )
			throw GLException( "Verter/Fragment shader source missing!\n" );

		vs = glCreateShader( GL_VERTEX_SHADER );
		if( !vs )
			throw GLException("Vertex-Shader creation failed!\n");

		glShaderSource( vs, 1, &vertsrc, NULL );
		glCompileShader( vs );
		glGetShaderiv( vs, GL_COMPILE_STATUS, &status );
		if( status == GL_FALSE ) {
			glGetShaderiv( vs, GL_INFO_LOG_LENGTH, &loglen );
			logbuf.resize( loglen );
			glGetShaderInfoLog( vs, loglen, &loglen, &logbuf[ 0 ]  );
			glDeleteShader(vs);
			throw GLException("Vertex-Shader compilation error\n", logbuf );
		}

		fs = glCreateShader( GL_FRAGMENT_SHADER );
		if( !fs ) {
			glDeleteShader( vs );
			throw GLException("Fragment-Shader creation failed!\n");
		}

		glShaderSource( fs, 1, &fragsrc, NULL );
		glCompileShader( fs );
		glGetShaderiv( fs, GL_COMPILE_STATUS, &status );
		if( status == GL_FALSE ) {
			glGetShaderiv( fs, GL_INFO_LOG_LENGTH, &loglen );
			logbuf.resize( loglen );
			glGetShaderInfoLog( fs, loglen, &loglen, &logbuf[ 0 ] );
			glDeleteShader(fs);
			glDeleteShader(vs);
			throw GLException("Fragment-Shader compilation error\n", logbuf );
		}

		if( geomsrc ) {
			gs = glCreateShader( GL_GEOMETRY_SHADER );
			if( !gs ) {
				glDeleteShader( vs );
				throw GLException("Geometry-Shader creation failed!\n");
			}

			glShaderSource( gs, 1, &geomsrc, NULL );
			glCompileShader( gs );
			glGetShaderiv( gs, GL_COMPILE_STATUS, &status );
			if( status == GL_FALSE ) {
				glGetShaderiv( gs, GL_INFO_LOG_LENGTH, &loglen );
				logbuf.resize( loglen );
				glGetShaderInfoLog( gs, loglen, &loglen, &logbuf[ 0 ] );
				glDeleteShader( fs );
				glDeleteShader( vs );
				glDeleteShader( gs );
				throw GLException("Geometry-Shader compilation error\n", logbuf );
			}
		}

		glAttachShader( program, fs );
		glAttachShader( program, vs );

		if( gs )
			glAttachShader( program, gs );

		/* shaders are now referenced by programm, delete them*/
		glDeleteShader( vs );
		glDeleteShader( fs );
		if( gs )
			glDeleteShader( gs );

		glLinkProgram( program );
		glGetProgramiv( program, GL_LINK_STATUS, &status );
		if(status == GL_FALSE) {
			glGetProgramiv( program, GL_INFO_LOG_LENGTH, &loglen );
			logbuf.resize( loglen );
			glGetProgramInfoLog( program, loglen, &loglen, &logbuf[ 0 ] );
			throw GLException("Shader link error\n", logbuf );
		}
	}