예제 #1
0
void Shader::Init(const char* vertexShaderPath, const char* fragmentShaderPath)
{
	_vertexProgram = glCreateShader(GL_VERTEX_SHADER);
	_fragmentProgram = glCreateShader(GL_FRAGMENT_SHADER);

	std::string vertexShaderText;
	std::string fragmentShaderText;
	if (!ReadShader(vertexShaderPath, vertexShaderText) || !ReadShader(fragmentShaderPath, fragmentShaderText))
	{
		std::cerr << "Either vertex shader or fragment shader file not found." << std::endl;
		return;
	}
	const char* constVST = vertexShaderText.c_str();
	const char* constFST = fragmentShaderText.c_str();

	glShaderSource(_vertexProgram, 1, &constVST, 0);
	glShaderSource(_fragmentProgram, 1, &constFST, 0);

	glCompileShader(_vertexProgram);
	ValidateShader(_vertexProgram, vertexShaderPath);
	glCompileShader(_fragmentProgram);
	ValidateShader(_fragmentProgram, fragmentShaderPath);

	_id = glCreateProgram();
	glAttachShader(_id, _vertexProgram);
	glAttachShader(_id, _fragmentProgram);
	glLinkProgram(_id);
	ValidateProgram(_id);
}
예제 #2
0
파일: shader.cpp 프로젝트: 0x2A/glslplus
	void Shader::Compile()
	{
		Preprocessor p(m_ShaderSource, m_VsEntry, m_PsEntry, m_Defines);
		p.Process(m_ShaderFileName, m_ShaderPath);
		
		std::string vsCode = p.GetVSCode();
		std::string psCode = p.GetPSCode();
		
		m_VSObject = glCreateShader(GL_VERTEX_SHADER);
		m_FSObject = glCreateShader(GL_FRAGMENT_SHADER);
		
		GLchar const* filesVS[]{ vsCode.c_str() };
		GLchar const* filesFS[]{ psCode.c_str() };

		glShaderSource(m_VSObject, 1, filesVS, 0);
		glShaderSource(m_FSObject, 1, filesFS, 0);

		glCompileShader(m_VSObject);
		ValidateShader(m_VSObject);
		
		glCompileShader(m_FSObject);
		ValidateShader(m_FSObject);

		m_ShaderObject = glCreateProgram();
		glAttachShader(m_ShaderObject, m_VSObject);
		glAttachShader(m_ShaderObject, m_FSObject);

		glLinkProgram(m_ShaderObject);
		ValidateProgram(m_ShaderObject);
		

		m_Compiled = true;
	}
예제 #3
0
// Same as above but for not-separated build
GLuint GSShaderOGL::CompileShader(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel)
{
	ASSERT(glsl_h_code != NULL);

	GLuint shader = 0;

	// Note it is better to separate header and source file to have the good line number
	// in the glsl compiler report
	const int shader_nb = 3;
	const char* sources[shader_nb];

	std::string header = GenGlslHeader(entry, type, macro_sel);

	sources[0] = header.c_str();
	sources[1] = common_header_glsl;
	sources[2] = glsl_h_code;

	shader =  glCreateShader(type);
	glShaderSource(shader, shader_nb, sources, NULL);
	glCompileShader(shader);

	bool status = ValidateShader(shader);

	if (!status) {
		// print extra info
		fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), shader);
		fprintf(stderr, "\n%s", macro_sel.c_str());
		fprintf(stderr, "\n");
	}

	m_shad_to_delete.push_back(shader);

	return shader;
}
예제 #4
0
GLuint GSShaderOGL::Compile(const std::string& glsl_file, const std::string& entry, GLenum type, const char* glsl_h_code, const std::string& macro_sel)
{
	ASSERT(glsl_h_code != NULL);

	GLuint program = 0;

#ifndef ENABLE_GLES
	if (type == GL_GEOMETRY_SHADER && !GLLoader::found_geometry_shader) {
		return program;
	}
#endif

	// Note it is better to separate header and source file to have the good line number
	// in the glsl compiler report
	const char* sources[2];

	std::string header = GenGlslHeader(entry, type, macro_sel);
	int shader_nb = 1;
#if 1
	sources[0] = header.c_str();
	sources[1] = glsl_h_code;
	shader_nb++;
#else
	sources[0] = header.append(glsl_h_code).c_str();
#endif

	if (GLLoader::found_GL_ARB_separate_shader_objects) {
#ifndef ENABLE_GLES
		program = gl_CreateShaderProgramv(type, shader_nb, sources);
#endif
	} else {
		program = gl_CreateShader(type);
		gl_ShaderSource(program, shader_nb, sources, NULL);
		gl_CompileShader(program);
	}

	bool status;
	if (GLLoader::found_GL_ARB_separate_shader_objects)
		status = ValidateProgram(program);
	else
		status = ValidateShader(program);

	if (!status) {
		// print extra info
		fprintf(stderr, "%s (entry %s, prog %d) :", glsl_file.c_str(), entry.c_str(), program);
		fprintf(stderr, "\n%s", macro_sel.c_str());
		fprintf(stderr, "\n");
	}
	return program;
}
//Since we're precompiling the shaders, we dont need all the extra parameters
//Assume this is a function within the renderer thus we have access to private render members
Shader* CreateShader(
	const std::string& name,
	const std::string& vsFile,
	const std::string& psFile,
	const std::string& gsFile = "")
{
	Shader newShader = new Shader(name);
	ID3D11ShaderReflection *vsReflect(nullptr);
	ID3D11ShaderReflection *psReflect(nullptr);
	ID3D11ShaderReflection *gsReflect(nullptr);

	if(!vsFile.empty()) {
		auto vsFileRes = new WhaleFile(vsFile);
		if(!vsFileRes) {
			log_sxerror("Shader", "Error opening VS file %s. Cannot continue", vsFile.c_str());
			delete newShader;
			return nullptr;
		}
		auto vsFilePtr = vsFileRes->GetMem();
		HRESULT result = 
			device->CreateVertexShader(vsFilePtr, vsFileRes.Size(), NULL, &newShader->vertexShader);
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not create Vertex shader from %s. Cannot continue!", vsFile.c_str());
			//Clean up after ourselves before returning
			delete vsFileRes;
			delete newShader;
			return nullptr;
		}
		//Grab the input signature from the vertex shader
		result = D3DGetInputSignatureBlob(vsFilePtr, vsFileRes.Size(), &newShader->inputSignature);	
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not get Input signature from %s. Cannot continue!", vsFile.c_str());
			delete vsFileRes;
			delete newShader;
			return nullptr;
		}
		result = D3DReflect(vsFilePtr, vsFileRes.Size(), IID_ID3D11ShaderReflection, (void **)&vsReflect);
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not get Reflection Interface from %s. Cannot continue!", vsFile.c_str());
			delete vsFileRes;
			delete newShader;
			return nullptr;
		}
		delete vsFileRes;
	}
	if(!psFile.empty()) {
		auto psFileRes = new WhaleFile(psFile);
		if(!psFileRes) {
			log_sxerror("Shader", "Error opening PS file %s. Cannot continue!", psFile.c_str());
			delete newShader;
			SAFE_RELEASE(vsReflect);
			return nullptr;
		}
		auto psFilePtr = psFileRes->GetMem();
		HRESULT result =
			device->CreatePixelShader(psFilePtr, psFileRes.Size(), NULL, &newShader->pixelShader);
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not create Pixel shader from %s. Cannot continue!", psFile.c_str());
			delete psFileRes;
			SAFE_RELEASE(vsReflect);
			delete newShader;
			return nullptr;
		}
		result = D3DReflect(psFilePtr, psFileRes.Size(), IID_ID3D11ShaderReflection, (void **)&psReflect);
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not get Reflection Interface from %s. Cannot continue!", psFile.c_str());
			delete psFileRes;
			SAFE_RELEASE(vsReflect);
			delete newShader;
			return nullptr;
		}
		delete psFileRes;
	}
	if(!gsFile.empty()) {
		auto gsFileRes = new WhaleFile(gsFile);
		if(!gsFileRes) {
			log_sxerror("Shader", "Error opening PS file %s. Cannot continue!", gsFile.c_str());
			delete newShader;
			SAFE_RELEASE(vsReflect);
			return nullptr;
		}
		auto gsFilePtr = gsFileRes->GetMem();
		HRESULT result =
			device->CreatePixelShader(gsFilePtr, gsFileRes.Size(), NULL, &newShader->geometryShader);
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not create Pixel shader from %s. Cannot continue!", gsFile.c_str());
			delete gsFileRes;
			SAFE_RELEASE(vsReflect);
			SAFE_RELEASE(psReflect);
			delete newShader;
			return nullptr;
		}
		result = D3DReflect(gsFilePtr, gsFileRes.Size(), IID_ID3D11ShaderReflection, (void **)&gsReflect);
		if(FAILED(result)) {
			log_sxerror("Shader", "Could not get Reflection Interface from %s. Cannot continue!", gsFile.c_str());
			delete gsFileRes;
			SAFE_RELEASE(psReflect);
			SAFE_RELEASE(vsReflect);
			delete newShader;
			return nullptr;
		}
		delete gsFileRes;
	}
	bool res = GenerateShaderConstants(newShader, vsReflect, psReflect, gsReflect);
	if(!res) {
		log_sxerror("Shader", "Error Generating shader constants for shader %s.", name.c_str());
		SAFE_RELEASE(vsReflect);
		SAFE_RELEASE(psReflect);
		SAFE_RELEASE(gsReflect);
		delete newShader;
		return nullptr;
	}
	res = GenerateShaderSamplers(newShader, vsReflect, psReflect, gsReflect);
	if(!res) {
		log_sxerror("Shader", "Error Generating shader samplers for shader %s.", name.c_str());
		SAFE_RELEASE(vsReflect);
		SAFE_RELEASE(psReflect);
		SAFE_RELEASE(gsReflect);
		delete newShader;
		return nullptr;
	}
	res = ValidateShader(newShader, vsReflect, psReflect, gsReflect);
	if(!res) {
		log_sxerror("Shader", "Error validating shader %s", name.c_str());
		delete newShader;
		newShader = nullptr;	
	}
	SAFE_RELEASE(vsReflect);
	SAFE_RELEASE(psReflect);
	SAFE_RELEASE(gsReflect);
	return newShader;
}
예제 #6
0
int main() 
{
    try {

    // Camera settings
	Camera camera;
	glm::vec3 vrp(0.0f, 0.0f, 10.0f);
	glm::vec3 vpn(0.0f, 0.0f, 1.0f);
	glm::vec3 vup(0.0f, 1.0f, 0.0f);
	glm::vec3 prp(0.0f, 0.0f, 100.0f);
	float F = 10.0f;
	float B = -80.0f;
	glm::vec2 lower_left(-20.0f, -20.0f);
	glm::vec2 upper_right(20.0f, 20.0f);
	camera = Camera(vrp, vpn, vup, prp, lower_left, upper_right, F, B);
	
	// Examples
	int curves = 4;    // Amount of examples
	BezierRow G[curves];
	G[0] = BezierRow(glm::vec3(-15.0f, -15.0f, 0.0f),
					 glm::vec3(-10.0f, 25.0f, 0.0f),
					 glm::vec3(10.0f, 25.0f, 0.0f),
					 glm::vec3(15.0f, -15.0f, 0.0f));
	G[1] = BezierRow(glm::vec3(-20.0f, 0.0f, 0.0f),
					 glm::vec3(-1.0f, 55.0f, 0.0f),
					 glm::vec3(1.0f, -55.0f, 0.0f),
					 glm::vec3(20.0f, 0.0f, 0.0f));
	G[2] = BezierRow(glm::vec3(-1.0f, -5.0f, 0.0f),
					 glm::vec3(-60.0f, 5.0f, 0.0f),
					 glm::vec3(60.0f,  5.0f, 0.0f),
					 glm::vec3(1.0f,  -5.0f, 0.0f));
	G[3] = BezierRow(glm::vec3(-10.0f, -5.0f, 0.0f),
					 glm::vec3(60.0f,   5.0f, 0.0f),
					 glm::vec3(-60.0f,  5.0f, 0.0f),
					 glm::vec3(10.0f,  -5.0f, 0.0f));

	int currentfigure = 3; // Set figure between 4 different examples

	// Decide whether to use sampling or subdivision
	int decider = 1;

	int Npoint = 0;
	std::vector<glm::vec3> points;

	// Sampling
	if(decider == 0){
	float t = 0.0f;
	float step = 12.0f;
	sampling(G[currentfigure], t, step, points);
	Npoint = step*2;
	}

	// Subdivision
	else if(decider == 1){
	DLB /= 8.0f;	
	DRB /= 8.0f;
	int n = 3; 				// Amount of curves (smoothness)
 	int npow = pow(2, n+1); // Amount of points
	subdivide(G[currentfigure], n, points);
	Npoint = npow;
	}
	else{
		printf("No method chosen\n"); return 1;
	}




	glm::mat4x4 CTM = camera.CurrentTransformationMatrix();
	std::cout << "CTM = " << std::endl << CTM << std::endl;


	// Initialize the graphics
	InitializeGLFW();
	GLFWwindow* Window = CreateWindow(WindowWidth, WindowHeight, WindowTitle.c_str());
	InitializeGLEW();
	InitializeOpenGL();
	glfwSwapBuffers(Window);

	// Read and Compile the vertex program vertextransform.vert
	GLuint vertexprogID = CreateGpuProgram("vertextransform.vert", GL_VERTEX_SHADER);

        // Read and Compile the fragment program linefragment.frag
	GLuint linefragmentprogID = CreateGpuProgram("linefragment.frag", GL_FRAGMENT_SHADER);

	// Create a lineshader program and Link it with the vertex and linefragment programs
	GLuint lineshaderID = CreateShaderProgram(vertexprogID, linefragmentprogID);
	
	// Now comes the OpenGL core part

	// This is where the curve is initialized
        // User data is in the global variable curveVertices, and the number of entries
	// is in Ncurvevertices

    // Make a VertexArrayObject - it is used by the VertexArrayBuffer, and it must be declared!
	GLuint CurveVertexArrayID;
	glGenVertexArrays(1, &CurveVertexArrayID);
	glBindVertexArray(CurveVertexArrayID);

	// Make a curvevertexbufferObject - it uses the previous VertexArrayBuffer!
	GLuint curvevertexbuffer;
	glGenBuffers(1, &curvevertexbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, curvevertexbuffer);




	// Give our vertices to OpenGL.
	glBufferData(GL_ARRAY_BUFFER, Npoint * 3 * sizeof(float), &points[0], GL_STATIC_DRAW);
	

    // Validate the shader program
	ValidateShader(lineshaderID, "Validating the lineshader");

	// Get locations of Uniforms
	GLuint curvevertextransform   = glGetUniformLocation(lineshaderID, "CTM");
	GLuint curvefragmentcolor     = glGetUniformLocation(lineshaderID, "Color");	




	// Initialize Attributes
	GLuint curvevertexattribute = glGetAttribLocation(lineshaderID, "VertexPosition");
	glVertexAttribPointer(curvevertexattribute, 3, GL_FLOAT, GL_FALSE, 0, 0);

	// The main loop
	while (!glfwWindowShouldClose(Window)) {
	    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	    glUseProgram(lineshaderID);
		glm::mat4x4 CTM = camera.CurrentTransformationMatrix();
		glUniformMatrix4fv(curvevertextransform, 1, GL_FALSE, &CTM[0][0]);
		glUniform3f(curvefragmentcolor, 0.2f, 0.2f, 0.2f);

		glEnableVertexAttribArray(curvevertexattribute);
		glBindVertexArray(CurveVertexArrayID);  // This is very important! There are two "binds"!
		glDrawArrays(GL_LINES, 0, Npoint);

		glDisableVertexAttribArray(curvevertexattribute);
	    glUseProgram(0);

	    glfwSwapBuffers(Window);
	    std::stringstream errormessage;
	    errormessage << "End of loop: " << "assignment5.cpp" << ": " << __LINE__ << ": ";
	    ErrorCheck(errormessage.str());

	    glfwPollEvents();
	}
    }
    catch (std::exception const& exception) {
	std::cerr << "Exception: " << exception.what() << std::endl;
    }

    glfwTerminate();

    return 0;
}
예제 #7
0
bool InitializeShader(Shader_T *s, const char *vsfile, const char *fsfile)
{
	bool success = true;
	GLuint vertexShader;
	GLuint fragmentShader;
	GLint vShaderCompiled = GL_FALSE;
	GLint fShaderCompiled = GL_FALSE;
	GLint programSuccess = GL_TRUE;
	GLchar *txt;
	unsigned long len;	
	//Generate program
	s->id = glCreateProgram();
	s->vertex_attrib = -1;
	s->uv_attrib = -1;
	//Create vertex shader
	vertexShader = glCreateShader( GL_VERTEX_SHADER );
	//Set vertex source
	LoadShaderSource(vsfile, &txt, &len);
	glShaderSource( vertexShader, 1, &txt, NULL );
	//Compile vertex source
	glCompileShader( vertexShader );
	ValidateShader(vertexShader, vsfile);
	UnloadShaderSource(&txt);
	//Check vertex shader for errors
	glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &vShaderCompiled );
	if( vShaderCompiled != GL_TRUE )
	{
		printf( "Unable to compile vertex shader %d!\n", vertexShader );
		printShaderLog( vertexShader );
        success = false;
	}
	else
	{
		//Attach vertex shader to program
		glAttachShader( s->id, vertexShader );
		//Create fragment shader
		LoadShaderSource(fsfile, &txt, &len);
		fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
		//Set fragment source
		glShaderSource( fragmentShader, 1, &txt, NULL );
		//Compile fragment source
		glCompileShader( fragmentShader );
		ValidateShader(fragmentShader, fsfile);
		UnloadShaderSource(&txt);
		//Check fragment shader for errors
		glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &fShaderCompiled );
		if( fShaderCompiled != GL_TRUE )
		{
			printf( "Unable to compile fragment shader %d!\n", fragmentShader );
			printShaderLog( fragmentShader );
			success = false;
		}
		else
		{
			//Attach fragment shader to program
			glAttachShader( s->id, fragmentShader );
			//Link program
			glLinkProgram( s->id );
			//Check for errors
			glGetProgramiv( s->id, GL_LINK_STATUS, &programSuccess );
			if( programSuccess != GL_TRUE )
			{
				printf( "Error linking program %d!\n", s->id );
				printProgramLog( s->id );
				success = false;
			}
			else
			{
				//Get vertex attribute location
				s->uv_attrib = glGetAttribLocation( s->id, "vertexUV" );
				s->vertex_attrib = glGetAttribLocation( s->id, "vertexPosition" );
				if( s->vertex_attrib == -1 )
				{
					printf( "vertexPosition is not a valid glsl program variable!\n" );
					success = false;
				}
				if(s->uv_attrib == -1 )
				{
					printf( "vertexTex is not a valid glsl program variable!\n" );
					success = false;
				}
			}
		}
	}
	return success;
}