示例#1
0
void Shader::link()
{
    for( int i = 0; i < mSeparatedTransformFeedbackVarying.size(); i++ ){
        const char *attrib[] = { mSeparatedTransformFeedbackVarying[i].c_str() };
        glTransformFeedbackVaryingsEXT( getHandle(), 1, attrib, GL_SEPARATE_ATTRIBS_EXT );
    }
    
    if( mInterleavedTransformFeedbackVarying.size() ){
        const char* attribs[mInterleavedTransformFeedbackVarying.size()];
        for( int i = 0; i < mInterleavedTransformFeedbackVarying.size(); i++ ){
            attribs[i] = mInterleavedTransformFeedbackVarying[i].c_str();
        }
        glTransformFeedbackVaryingsEXT( getHandle(), mInterleavedTransformFeedbackVarying.size(), attribs, GL_INTERLEAVED_ATTRIBS_EXT );
    }
    
	glLinkProgram( mObj->mHandle );
    
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTTransformFeedback_nglTransformFeedbackVaryingsEXT(JNIEnv *env, jclass clazz, jint program, jint count, jobject varyings, jint varyings_position, jint bufferMode, jlong function_pointer) {
	const GLchar *varyings_address = ((const GLchar *)(*env)->GetDirectBufferAddress(env, varyings)) + varyings_position;
	unsigned int _str_i;
	GLchar *_str_address;
	GLchar **varyings_str = (GLchar **) malloc(count * sizeof(GLchar *));
	glTransformFeedbackVaryingsEXTPROC glTransformFeedbackVaryingsEXT = (glTransformFeedbackVaryingsEXTPROC)((intptr_t)function_pointer);
	_str_i = 0;
	_str_address = (GLchar *)varyings_address;
	while ( _str_i < count ) {
		varyings_str[_str_i++] = _str_address;
		_str_address += strlen(_str_address) + 1;
	}
	glTransformFeedbackVaryingsEXT(program, count, (const GLchar **)varyings_str, bufferMode);
	free(varyings_str);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTTransformFeedback_nglTransformFeedbackVaryingsEXT(JNIEnv *__env, jclass clazz, jint program, jint count, jlong varyingsAddress, jint bufferMode) {
    glTransformFeedbackVaryingsEXTPROC glTransformFeedbackVaryingsEXT = (glTransformFeedbackVaryingsEXTPROC)tlsGetFunction(1830);
    intptr_t varyings = (intptr_t)varyingsAddress;
    UNUSED_PARAM(clazz)
    glTransformFeedbackVaryingsEXT(program, count, varyings, bufferMode);
}
示例#4
0
WSProgram* WCShaderManager::ParseProgram(xercesc::DOMElement *element, const bool &verbose) {
	char *tmpChars;
	std::string tmpStr;

	//Create program object
	WSProgram *program = new WSProgram();
	program->_id = glCreateProgram();
	//Get the program name
	program->_name = WCSerializeableObject::GetStringAttrib(element, "name");

	//Process all shaders
	xercesc::DOMNode *tmpNode;
	std::map<std::string,WSShader*>::iterator iter;
	XMLCh *xmlString = xercesc::XMLString::transcode("shader");
	xercesc::DOMNodeList *nodeList = element->getElementsByTagName(xmlString);
	xercesc::XMLString::release(&xmlString);
	int numShaders = nodeList->getLength();
	xercesc::DOMElement *tmpElement;
	//Loop through all shaders and process
	for (int index=0; index < numShaders; index++) {
		tmpElement = (xercesc::DOMElement*)nodeList->item(index);
		//Get the value node
		tmpNode = tmpElement->getFirstChild();
		//Find the shader name
		tmpChars = xercesc::XMLString::transcode(tmpNode->getNodeValue());
		tmpStr = std::string(tmpChars);
		xercesc::XMLString::release(&tmpChars);
		//Look up in map
		iter = this->_shaderMap.find(tmpStr);
		//Is a shader found at all
		if (iter == this->_shaderMap.end()) { 
			CLOGGER_ERROR(WCLogManager::RootLogger(), "WCShaderManager::ParseProgram - " << tmpStr << " not found."); 
			delete program;
			return NULL;
		}
		//Is the shader valid
		if ((*iter).second->_id == 0) {
			CLOGGER_INFO(WCLogManager::RootLogger(), "WCShaderManager::ParseProgram - " << tmpStr << " requires excluding this program.");
			delete program;
			return NULL;
		}
		//Attach shader
		glAttachShader(program->_id, (*iter).second->_id);
		//Add shader to shader list
		program->_shaders.push_back( (*iter).second );
	}

	//Process transform feedback
	xmlString = xercesc::XMLString::transcode("transform_feedback");
	nodeList = element->getElementsByTagName(xmlString);
	xercesc::XMLString::release(&xmlString);
	if (nodeList->getLength() == 1) {
		//Found a transform feedback
		tmpElement = (xercesc::DOMElement*)nodeList->item(0);
		//Get type attribute
		std::string typeStr = WCSerializeableObject::GetStringAttrib(tmpElement, "type");
		GLenum type;
		//Convert string to enum
		if (typeStr == "GL_INTERLEAVED_ATTRIBS_EXT") type = GL_INTERLEAVED_ATTRIBS_EXT;
		else if (typeStr == "GL_SEPARATE_ATTRIBS_EXT") type = GL_SEPARATE_ATTRIBS_EXT;
		else { 
			CLOGGER_ERROR(WCLogManager::RootLogger(), "WCShaderManager::ParseProgram - Unknown transform feedback type(" << typeStr << "."); 
			delete program;
			return NULL;
		}

		//Get list of varyings
		xmlString = xercesc::XMLString::transcode("varying");
		nodeList = tmpElement->getElementsByTagName(xmlString);
		xercesc::XMLString::release(&xmlString);
		GLint varyingCount = nodeList->getLength();
		const GLchar** varyings = new const GLchar*[varyingCount];
		//Process varyings
		for (int index=0; index<varyingCount; index++) {
			//Get the varying element
			tmpElement = (xercesc::DOMElement*)nodeList->item(index);
			//Get the value node
			tmpNode = tmpElement->getFirstChild();
			//Get the name of the varying and put into array
			varyings[index] = xercesc::XMLString::transcode(tmpNode->getNodeValue());
		}
		//Set up the transform feedback for the program
		glTransformFeedbackVaryingsEXT(program->_id, varyingCount, varyings, type);
		//Delete all of the varyings
		for (int j=0; j<varyingCount; j++) {
			//Do null value check
			if (varyings[j]) delete varyings[j];
		}
		//Delete the array
		if (varyings) delete varyings;
	}

	//Process geometry shader params (if present)
	xmlString = xercesc::XMLString::transcode("geometry_shader");
	nodeList = element->getElementsByTagName(xmlString);
	xercesc::XMLString::release(&xmlString);
	if (nodeList->getLength() == 1) {
		//Found a geometry shader
		tmpElement = (xercesc::DOMElement*)nodeList->item(0);		
		//Get input type
		std::string inputTypeStr = WCSerializeableObject::GetStringAttrib(tmpElement, "inputType");
		std::string outputTypeStr = WCSerializeableObject::GetStringAttrib(tmpElement, "outputType");
		GLint vertexOut = (GLint)WCSerializeableObject::GetFloatAttrib(tmpElement, "vertsOut");
		//Set the attributes
		GLenum inputType = ConvertGLTypeStringToEnum(inputTypeStr);
		GLenum outputType = ConvertGLTypeStringToEnum(outputTypeStr);
		//Set the program parameters
		glProgramParameteriEXT(program->_id, GL_GEOMETRY_INPUT_TYPE_EXT, inputType);
		glProgramParameteriEXT(program->_id, GL_GEOMETRY_VERTICES_OUT_EXT, vertexOut);
		glProgramParameteriEXT(program->_id, GL_GEOMETRY_OUTPUT_TYPE_EXT, outputType);
	}

	//Link the program
	glLinkProgram(program->_id);
	GLint linked;
	glGetProgramiv(program->_id, GL_OBJECT_LINK_STATUS_ARB, &linked);
	//Check the link status
	if (!linked) {
		char temp[256] = "";
		//If not, print out compilation errors
		glGetProgramInfoLog(program->_id, 256, NULL, temp);
		CLOGGER_WARN(WCLogManager::RootLogger(), "WCShaderManager::ParseProgram - Program Link failed:\n" << temp);
		delete program; 
		program = NULL; 
	}
	else {
		if (verbose) CLOGGER_DEBUG(WCLogManager::RootLogger(), "Program " << program->_id << " successfully linked: " << program->_name);
	}
	//Return the program object
	return program;
}