Reply To: rutt etra….

Home Forums v002 v002 QC Plugins Support rutt etra…. Reply To: rutt etra….

#4176
vade
Keymaster

The v002 Shader code has some assumptions regarding having to have both a vertex and a fragment (you can have just one or the other). However for a geometry shader, you have to have a vertex program. The following is, I think, pretty tight. You will also have to clean up your 3 shaders after linking to a program.

As for the source issue, I was just curious. Its more of a half regret sometimes releasing source, I get very little out of it, and others get quite a lot, so it feels a bit odd sometimes.

Anyway, try this out.

CGLContextObj cgl_ctx = context;

		// create our shaders from the source
		if(vertexShaderSource != NULL)
		{
			vertexProgram = glCreateShader(GL_VERTEX_SHADER);
			glCheckForErrors;

			glShaderSource(vertexProgram, 1, &vertexShaderSource, NULL);
			glCheckForErrors;
			glCompileShader(vertexProgram);
			glCheckForErrors;
		}

		if(fragmentShaderSource != NULL)
		{
			fragmentProgram = glCreateShader(GL_FRAGMENT_SHADER);
			glCheckForErrors;

			glShaderSource(fragmentProgram, 1, &fragmentShaderSource, NULL);
			glCheckForErrors;
			glCompileShader(fragmentProgram);
			glCheckForErrors;
		}

		if(geometryShaderSource != NULL)
		{
			geometryProgram = glCreateShader(GL_GEOMETRY_SHADER_EXT);
			glCheckForErrors;

			glShaderSource(geometryProgram, 1, &geometryShaderSource, NULL);
			glCheckForErrors;
			glCompileShader(geometryProgram);
			glCheckForErrors;
		}

		// now that we have our shaders, we have to create a program and attach them all
		programObject = glCreateProgram();
		glCheckForErrors;

		if(vertexProgram && programObject)
		{
			glAttachShader(programObject,vertexProgram);
			glCheckForErrors;

			// check log for errors, print if necessary
			[self printShaderInfoLog:vertexProgram];
		}

		if(fragmentProgram && programObject)
		{
			glAttachShader(programObject,fragmentProgram);
			glCheckForErrors;

			// check log for errors, print if necessary
			[self printShaderInfoLog:fragmentProgram];
		}

		if(geometryProgram && programObject)
		{
			glAttachShader(programObject,geometryProgram);
			glCheckForErrors;

			glProgramParameteriEXT(programObject,GL_GEOMETRY_INPUT_TYPE_EXT, [[attributes valueForKey:kNIGLSLShaderGeomInputPrimitive] unsignedIntValue]);
			glCheckForErrors;
			glProgramParameteriEXT(programObject,GL_GEOMETRY_OUTPUT_TYPE_EXT, [[attributes valueForKey:kNIGLSLShaderGeomOutputPrimitive] unsignedIntValue]);
			glCheckForErrors;

			// TODO: make this an input variable, as specifying max emitabble vertices is poor form and poor for performance

			GLint temp;
			if(![[attributes valueForKey:kNIGLSLShaderGeomMaxPoints] unsignedIntValue] || [[attributes valueForKey:kNIGLSLShaderGeomMaxPoints] unsignedIntegerValue] == 0)
			{
				glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &temp);
				glCheckForErrors;
			}
			else
				temp = [[attributes valueForKey:kNIGLSLShaderGeomMaxPoints] intValue];

			glProgramParameteriEXT(programObject,GL_GEOMETRY_VERTICES_OUT_EXT,temp);
			glCheckForErrors;

			// check log for errors, print if necessary
			[self printShaderInfoLog:geometryProgram];

		}

		glLinkProgram(programObject);
		glCheckForErrors;