wip: practica1
This commit is contained in:
		
							
								
								
									
										147
									
								
								src/shader.cpp
									
									
									
									
									
								
							
							
						
						
									
										147
									
								
								src/shader.cpp
									
									
									
									
									
								
							| @@ -3,41 +3,134 @@ | ||||
| #include <vector> | ||||
| #include <fstream> | ||||
| #include <sstream> | ||||
| #include <iostream> | ||||
|  | ||||
| #include "../lib/glew/GL/glew.h" | ||||
| #include "../lib/glfw/glfw3.h" | ||||
|  | ||||
| namespace { | ||||
| 	std::string readShaderFile(const std::string& filename) { | ||||
| 		std::ifstream file(filename); | ||||
| 		if (!file) | ||||
| 			throw std::runtime_error("Failed to open shader file: " + filename); | ||||
| 		std::stringstream buffer; | ||||
| 		buffer << file.rdbuf(); | ||||
| 		return buffer.str(); | ||||
| 	} | ||||
| } // namespace | ||||
| #include "vertex.h" | ||||
|  | ||||
| Shader::Shader(const std::string& vertexPath, const std::string& fragmentPath) | ||||
| { | ||||
| 	std::string vertexCode = readShaderFile(vertexPath); | ||||
| 	std::string fragmentCode = readShaderFile(fragmentPath); | ||||
| 	const char* vShaderCode = vertexCode.c_str(); | ||||
| 	const char* fShaderCode = fragmentCode.c_str(); | ||||
| 	const uint32_t vshader = CompileShader(GL_VERTEX_SHADER, vertexPath); | ||||
| 	const uint32_t fshader = CompileShader(GL_FRAGMENT_SHADER, fragmentPath); | ||||
|  | ||||
| 	const uint32_t vertex = glCreateShader(GL_VERTEX_SHADER); | ||||
| 	glShaderSource(vertex, 1, &vShaderCode, NULL); | ||||
| 	glCompileShader(vertex); | ||||
| 	if (vshader == 0 || fshader == 0) { | ||||
| 		program_id_ = 0; | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	const uint32_t fragment = glCreateShader(GL_FRAGMENT_SHADER); | ||||
| 	glShaderSource(fragment, 1, &fShaderCode, NULL); | ||||
| 	glCompileShader(fragment); | ||||
| 	program_id_ = glCreateProgram(); | ||||
| 	glAttachShader(program_id_, vshader); | ||||
| 	glAttachShader(program_id_, fshader); | ||||
| 	glLinkProgram(program_id_); | ||||
|  | ||||
| 	program = glCreateProgram(); | ||||
| 	glAttachShader(program, vertex); | ||||
| 	glAttachShader(program, fragment); | ||||
| 	glLinkProgram(program); | ||||
| 	// Error handling | ||||
| 	int ret; | ||||
| 	glGetProgramiv(program_id_, GL_LINK_STATUS, &ret); | ||||
| 	if (ret == GL_FALSE) { | ||||
| 		char buffer[1024]; | ||||
| 		glGetProgramInfoLog(program_id_, sizeof(buffer), nullptr, buffer); | ||||
| 		error_ = buffer; | ||||
| 		glDeleteProgram(program_id_); | ||||
| 		program_id_ = 0; | ||||
| 	} | ||||
|  | ||||
| 	glDeleteShader(vertex); | ||||
| 	glDeleteShader(fragment); | ||||
| } | ||||
| 	glDeleteShader(vshader); | ||||
| 	glDeleteShader(fshader); | ||||
| } | ||||
|  | ||||
| void Shader::Use() const | ||||
| { | ||||
| 	if (program_id_ != 0) | ||||
| 		glUseProgram(program_id_); | ||||
| } | ||||
|  | ||||
| void Shader::SetupAttribs() const | ||||
| { | ||||
| 	int loc = glGetAttribLocation(program_id_, "vpos"); | ||||
| 	if (loc != -1) { | ||||
| 		glEnableVertexAttribArray(loc); | ||||
| 		glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const void*>(offsetof(Vertex, position))); | ||||
| 	} | ||||
|  | ||||
| 	loc = glGetAttribLocation(program_id_, "vcolor"); | ||||
| 	if (loc != -1) { | ||||
| 		glEnableVertexAttribArray(loc); | ||||
| 		glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const void*>(offsetof(Vertex, color))); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int Shader::getLocation(const char* key) const | ||||
| { | ||||
| 	return glGetUniformLocation(program_id_, key); | ||||
| } | ||||
|  | ||||
| void Shader::setInt(int loc, int value) | ||||
| { | ||||
| 	if (loc != -1) | ||||
| 		glUniform1i(loc, value); | ||||
| } | ||||
|  | ||||
| void Shader::setFloat(int loc, float value) | ||||
| { | ||||
| 	if (loc != -1) | ||||
| 		glUniform1f(loc, value); | ||||
| } | ||||
|  | ||||
| void Shader::setVec3(int loc, const glm::vec3& value) | ||||
| { | ||||
| 	if (loc != -1) | ||||
| 		glUniform3fv(loc, 1, &value[0]); | ||||
| } | ||||
|  | ||||
| void Shader::setVec4(int loc, const glm::vec4& value) | ||||
| { | ||||
| 	if (loc != -1) | ||||
| 		glUniform4fv(loc, 1, &value[0]); | ||||
| } | ||||
|  | ||||
| void Shader::setMat4(int loc, const glm::mat4& value) | ||||
| { | ||||
| 	if (loc != -1) | ||||
| 		glUniformMatrix4fv(loc, 1, GL_FALSE, &value[0][0]); | ||||
| } | ||||
|  | ||||
| std::string Shader::ReadShaderFile(const std::string& filename) | ||||
| { | ||||
| 	std::ifstream file(filename); | ||||
| 	if (!file) { | ||||
| 		error_ = "Failed to open shader file: " + filename + "\n"; | ||||
| 		return std::string{0}; | ||||
| 	} | ||||
|  | ||||
| 	std::stringstream buffer; | ||||
| 	buffer << file.rdbuf(); | ||||
| 	return buffer.str(); | ||||
| } | ||||
|  | ||||
| uint32_t Shader::CompileShader(uint32_t type, const std::string& source_path) | ||||
| { | ||||
| 	std::string source = ReadShaderFile(source_path); | ||||
| 	if (source.empty()) | ||||
| 		return 0; | ||||
|  | ||||
| 	const uint32_t shader = glCreateShader(type); | ||||
| 	const char* shader_code = source.c_str(); | ||||
|  | ||||
| 	glShaderSource(shader, 1, &shader_code, nullptr); | ||||
| 	glCompileShader(shader); | ||||
|  | ||||
| 	// Error handling | ||||
| 	int ret; | ||||
| 	glGetShaderiv(shader, GL_COMPILE_STATUS, &ret); | ||||
| 	if (ret == GL_FALSE) { | ||||
| 		char buffer[1024]; | ||||
| 		glGetShaderInfoLog(shader, sizeof(buffer), nullptr, buffer); | ||||
| 		error_ = buffer; | ||||
| 		glDeleteShader(shader); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	return shader; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 izenynn
					izenynn