Skip to content
Snippets Groups Projects
Select Git revision
  • 41771aa81124b3ae424d40d275403fe55a930db5
  • master default
2 results

list tuple.py

Blame
  • OpenGLWrapper.cpp 12.93 KiB
    #include "OpenGLWrapper.h"
    #include "ShaderType.h"
    #include "ResourceLoader.h"
    
    // settings
    const unsigned int _SCR_WIDTH = 800;
    const unsigned int _SCR_HEIGHT = 600;
    
    // lighting
    glm::vec3 _lightPos(1.2f, 20.0f, 2.0f);
    
    Mesh::Mesh(GLuint _nVertex, GLuint _VAO, GLuint *_VBOs)
    {
    	nVertex = _nVertex;
    	VAO = _VAO;
    	VBOs = _VBOs;
    }
    
    GLuint Mesh::get_vertex_count()
    {
    	return nVertex;
    }
    GLuint Mesh::get_VAO()
    {
    	return VAO;
    }
    GLuint *Mesh::get_VBOs()
    {
    	return VBOs;
    }
    
    void draw_mesh(Mesh &mesh)
    {
    	glBindVertexArray(mesh.get_VAO());
    
    	glDrawArrays(GL_TRIANGLES, 0, mesh.get_vertex_count());
    
    	glBindVertexArray(0);
    }
    
    Material::Material(GLuint _prog, GLuint _diffuseMap, GLuint _specularMap)
    {
    	prog = _prog;
    
    	diffuseMap = _diffuseMap;
    	specularMap = _specularMap;
    }
    
    GLuint Material::get_program()
    {
    	return prog;
    }
    GLuint Material::get_diffuseMap()
    {
    	return diffuseMap;
    }
    GLuint Material::get_specularMap()
    {
    	return specularMap;
    }
    
    RenderObject::RenderObject(Mesh * _mesh)
    {
    	translate = glm::vec3(0.0f, 0.0f, 0.0f);
    	rotate = glm::vec3(0.0f, 0.0f, 0.0f);
    	scale = glm::vec3(1.0f, 1.0f, 1.0f);
    
    	mesh = _mesh;
    
    	update_model_matrix();
    	update_directional_vector();
    }
    
    Material *RenderObject::get_material()
    {
    	return material;
    }
    
    GLuint RenderObject::get_vertex_count()
    {
    	return mesh->get_vertex_count();
    }
    
    glm::mat4 RenderObject::get_model_matrix()
    {
    	return model;
    }
    
    void RenderObject::update_model_matrix()
    {
    	model = glm::mat4(1.0f);
    	model = glm::translate(model, translate);
    
    	model = glm::rotate(model, glm::radians(rotate.x), glm::vec3(1.0f, 0.0f, 0.0f));
    	model = glm::rotate(model, glm::radians(rotate.y), glm::vec3(0.0f, 1.0f, 0.0f));
    	model = glm::rotate(model, glm::radians(rotate.z), glm::vec3(0.0f, 0.0f, 1.0f));
    
    	model = glm::scale(model, scale);
    }
    
    void RenderObject::update_directional_vector()
    {
    	glm::vec3 front;
    	glm::vec3 up;
    	glm::vec3 right;
    
    	glm::vec3 _front;
    	front.x = cos(glm::radians(rotate.y)) * cos(glm::radians(rotate.x));
    	front.y = sin(glm::radians(rotate.x));
    	front.z = sin(glm::radians(rotate.y)) * cos(glm::radians(rotate.x));
    	front = glm::normalize(_front);
    
    	right = glm::normalize(glm::cross(front, glm::vec3(0, 1, 0)));
    
    	up = glm::normalize(glm::cross(right, front));
    }
    
    void RenderObject::set_translate(glm::vec3 _translate)
    {
    	translate = _translate;
    
    	update_model_matrix();
    	update_directional_vector();
    }
    
    void RenderObject::set_rotate(glm::vec3 _rotate)
    {
    	rotate = _rotate;
    
    	update_model_matrix();
    	update_directional_vector();
    }
    
    void RenderObject::set_scale(glm::vec3 _scale)
    {
    	scale = _scale;
    
    	update_model_matrix();
    }
    
    void RenderObject::move(glm::vec3 _delta)
    {
    	translate += _delta;
    
    	update_model_matrix();
    	update_directional_vector();
    }
    
    void RenderObject::move(glm::vec3 _direction, glm::vec1 _velocity)
    {
    	translate += glm::vec3(_velocity *_direction.x, _velocity *_direction.y, _velocity *_direction.z);
    
    	update_model_matrix();
    }
    
    void RenderObject::set_material(Material *_material)
    {
    	material = _material;
    }
    
    void RenderObject::render(Camera &camera)
    {
    	auto prog = material->get_program();
    	glUseProgram(prog);
    
    	set_uniform_value(prog, "light.position", _lightPos);
    	set_uniform_value(prog, "viewPos", camera.Position);
    
    	glm::vec3 a = { 0.2f, 0.2f, 0.2f };
    	glm::vec3 d = { 0.5f, 0.5f, 0.5f };
    	glm::vec3 f = { 1.0f, 1.0f, 1.0f };
    	set_uniform_value(prog, "light.ambient", a);
    	set_uniform_value(prog, "light.diffuse", d);
    	set_uniform_value(prog, "light.specular", f);
    
    	set_uniform_value(prog, "material.shininess", glm::fvec1{ 64.0f });
    
    	glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)_SCR_WIDTH / (float)_SCR_HEIGHT, 0.1f, 500.0f);
    	glm::mat4 view = camera.GetViewMatrix();
    	set_uniform_value(prog, "projection", projection);
    	set_uniform_value(prog, "view", view);
    	set_uniform_value(prog, "model", model);
    
    	{
    		glActiveTexture(GL_TEXTURE0);
    		glBindTexture(GL_TEXTURE_2D, material->get_diffuseMap());
    	}
    
    	{
    		glActiveTexture(GL_TEXTURE1);
    		glBindTexture(GL_TEXTURE_2D, material->get_specularMap());
    	}
    
    	draw_mesh(*mesh);
    
    	glUseProgram(0);
    }
    
    void RenderObject::projective_render(Camera &camera)
    {
    	glm::mat4 bias = { 0.5f, 0.0f, 0.0f, 0.5f,
    							0.0f, 0.5f, 0.0f, 0.5f,
    							0.0f, 0.0f, 0.5f, 0.5f,
    							0.0f, 0.0f, 0.0f, 1.0f };
    
    	glm::mat4 projector_view = glm::lookAt(camera.Position, camera.Position + camera.Front, camera.Up);
    	glm::mat4 projector_projection = glm::perspective(glm::radians(camera.Zoom), 1.0f, 0.1f, 100.0f);
    
    	auto prog = material->get_program();
    	glUseProgram(prog);
    
    	set_uniform_value(prog, "light.position", _lightPos);
    	set_uniform_value(prog, "viewPos", camera.Position);
    
    	glm::vec3 a = { 0.2f, 0.2f, 0.2f };
    	glm::vec3 d = { 0.5f, 0.5f, 0.5f };
    	glm::vec3 f = { 1.0f, 1.0f, 1.0f };
    	set_uniform_value(prog, "light.ambient", a);
    	set_uniform_value(prog, "light.diffuse", d);
    	set_uniform_value(prog, "light.specular", f);
    
    	set_uniform_value(prog, "material.shininess", glm::fvec1{ 64.0f });
    
    	glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)_SCR_WIDTH / (float)_SCR_HEIGHT, 0.1f, 500.0f);
    	glm::mat4 view = camera.GetViewMatrix();
    
    	set_uniform_value(prog, "projectorBias", bias);
    	set_uniform_value(prog, "projectorProjection", projector_projection);
    	set_uniform_value(prog, "projectorView", projector_view);
    
    	set_uniform_value(prog, "projection", projection);
    	set_uniform_value(prog, "view", view);
    	set_uniform_value(prog, "model", model);
    
    	{
    		set_uniform_value(prog, "material.diffuse", glm::ivec1{ 0 });
    		glActiveTexture(GL_TEXTURE0);
    		glBindTexture(GL_TEXTURE_2D, material->get_diffuseMap());
    	}
    
    	{
    		set_uniform_value(prog, "material.specular", glm::ivec1{ 1 });
    		glActiveTexture(GL_TEXTURE1);
    		glBindTexture(GL_TEXTURE_2D, material->get_specularMap());
    	}
    
    	{
    		set_uniform_value(prog, "projImage", glm::ivec1{ 2 });
    		glActiveTexture(GL_TEXTURE2);
    		glBindTexture(GL_TEXTURE_2D, material->get_specularMap());
    	}
    
    	draw_mesh(*mesh);
    
    	glUseProgram(0);
    }
    
    RenderObject *make_render_object(Mesh *mesh)
    {
    	RenderObject *ro = new RenderObject(mesh);
    
    	return ro;
    };
    
    GLuint build_program(const std::string name)
    {
    	std::string shaderSources[5];
    	shaderSources[0] = FileSystem::read_file("../Shaders/" + name + "/" + name + ".vert");
    	shaderSources[1] = FileSystem::read_file("../Shaders/" + name + "/" + name + ".frag");
    
    	std::vector<GLint> shaderIDs;
    	compile_shaders(&shaderIDs, shaderSources);
    
    	auto programID = glCreateProgram();
    	for (auto i : shaderIDs)
    	{
    		glAttachShader(programID, i);
    	}
    	glLinkProgram(programID);
    	for (auto i : shaderIDs)
    	{
    		glDeleteShader(i);
    	}
    
    	return programID;
    }
    
    void compile_shaders(std::vector<GLint> *shaderIDs, const std::string *shaderSources)
    {
    	shaderIDs->push_back(compile_shader(GL_VERTEX_SHADER, &shaderSources[0]));
    	shaderIDs->push_back(compile_shader(GL_FRAGMENT_SHADER, &shaderSources[1]));
    }
    
    GLint compile_shader(const GLint shaderType, const std::string *shaderSource)
    {
    	GLuint shaderID;
    	switch (shaderType)
    	{
    	case (GL_VERTEX_SHADER): shaderID = glCreateShader(GL_VERTEX_SHADER); break;
    	case (GL_FRAGMENT_SHADER): shaderID = glCreateShader(GL_FRAGMENT_SHADER); break;
    	default:
    		GLchar infoLog[512];
    		log_error(infoLog, "SHADER::CAN'T_FIND_SHADER_TYPE");
    
    		break;
    	}
    
    	const char *c_str = (*shaderSource).c_str();
    	glShaderSource(shaderID, 1, &c_str, NULL);
    	glCompileShader(shaderID);
    
    	GLint success;
    	glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
    	if (!success)
    	{
    		GLchar infoLog[512];
    		glGetShaderInfoLog(shaderID, 512, NULL, infoLog);
    
    		log_error(infoLog, "SHADER::" + parse_shaderType(shaderType) + "::COMPILATION_ERROR");
    	}
    
    	return shaderID;
    }
    
    GLint link_program(const GLint *shaderIDs)
    {
    	auto programID = glCreateProgram();
    	glAttachShader(programID, shaderIDs[0]);
    	glAttachShader(programID, shaderIDs[1]);
    	glLinkProgram(programID);
    
    	GLint success;
    	glGetProgramiv(programID, GL_LINK_STATUS, &success);
    	if (!success)
    	{
    		GLchar infoLog[512];
    		log_error(infoLog, "PROGRAM::LINK_FAILED");
    	}
    
    	glDeleteShader(shaderIDs[0]);
    	glDeleteShader(shaderIDs[1]);
    
    	return programID;
    }
    
    void set_uniform_value(GLuint &prog, const char *name, glm::vec1 value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform1fv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::ivec1 value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform1iv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::vec2 &value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform2fv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::ivec2 &value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform2iv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::vec3 &value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform3fv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::ivec3 &value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform3iv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::vec4 value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform4fv(uniform, 1, &value.x);
    }
    void set_uniform_value(GLuint &prog, const char *name, glm::ivec4 value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniform4iv(uniform, 1, &value.x);
    }
    
    void set_uniform_value(GLuint &prog, const char *name, glm::mat4 &value)
    {
    	auto uniform = glGetUniformLocation(prog, name);
    	glUniformMatrix4fv(uniform, 1, GL_FALSE, &value[0][0]);
    }
    
    GLuint allocate_VBO(const GLuint attribIndex, std::vector<glm::vec3> *VBO)
    {
    	GLuint VBOIndex = 0;
    
    	glGenBuffers(1, &VBOIndex);
    	glBindBuffer(GL_ARRAY_BUFFER, VBOIndex);
    	glBufferData(GL_ARRAY_BUFFER, VBO->size() * sizeof(glm::vec3), &(VBO->front()), GL_STATIC_DRAW);
    
    	glEnableVertexAttribArray(attribIndex);
    	glVertexAttribPointer(attribIndex, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    	return VBOIndex;
    }
    
    GLuint allocate_VBO(const GLuint attribIndex, std::vector<glm::vec2> *VBO)
    {
    	GLuint VBOIndex = 0;
    
    	glGenBuffers(1, &VBOIndex);
    	glBindBuffer(GL_ARRAY_BUFFER, VBOIndex);
    	glBufferData(GL_ARRAY_BUFFER, VBO->size() * sizeof(glm::vec2), &(VBO->front()), GL_STATIC_DRAW);
    
    	glEnableVertexAttribArray(attribIndex);
    	glVertexAttribPointer(attribIndex, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
    
    	glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    	return VBOIndex;
    }
    
    GLuint *allocate_VBOs(GLuint VAO, std::vector<std::vector<glm::vec3> *> &vertexInfoVec3, std::vector<std::vector<glm::vec2> *> &vertexInfoVec2)
    {
    	auto size = vertexInfoVec3.size() + vertexInfoVec2.size();
    	GLuint *VBOindicies = new GLuint[size];
    
    	glBindVertexArray(VAO);
    
    	GLuint i = 0;
    	for (i = 0; i < vertexInfoVec3.size(); i++)
    	{
    		VBOindicies[i] = allocate_VBO(i, vertexInfoVec3.at(i));
    	}
    	for (i = vertexInfoVec3.size(); i < size; i++)
    	{
    		VBOindicies[i] = allocate_VBO(i, vertexInfoVec2.at(i - vertexInfoVec3.size()));
    	}
    
    	glBindVertexArray(0);
    
    	return VBOindicies;
    }
    
    GLuint allocate_VAO()
    {
    	GLuint VAO = 0;
    
    	glGenVertexArrays(1, &VAO);
    
    	return VAO;
    }
    
    Mesh *make_mesh(const std::string fileName)
    {
    	std::vector<glm::vec3> vertices;
    	std::vector<glm::vec2> vertexTexCoord;
    	std::vector<glm::vec3> vertexNormals;
    
    	const std::string ext = get_extension(fileName);
    	if (ext.compare("obj") == 0)
    	{
    		openObj(fileName, vertices, vertexTexCoord, vertexNormals);
    	}
    	else
    	{
    		std::cout << "Can't Open " + fileName + " Extension." << std::endl;
    	}
    
    	std::vector<std::vector<glm::vec3> *> vertexInfoVec3;
    	std::vector<std::vector<glm::vec2> *> vertexInfoVec2;
    
    	vertexInfoVec3.push_back(&vertices);
    	if (vertexTexCoord.size() > 0)
    	{
    		vertexInfoVec2.push_back(&vertexTexCoord);
    	}
    	if (vertexNormals.size() > 0)
    	{
    		vertexInfoVec3.push_back(&vertexNormals);
    	}
    
    	auto VAO = allocate_VAO();
    	auto VBOs = allocate_VBOs(VAO, vertexInfoVec3, vertexInfoVec2);
    
    	Mesh *m = new Mesh(vertices.size(), VAO, VBOs);
    
    	return m;
    }
    
    GLuint load_texture(const std::string fileName)
    {
    	return load_image(fileName, ImageType::REPEAT);
    }
    
    GLuint load_image(const std::string fileName, const ImageType type)
    {
    	int width, height, nrChannels;
    	GLuint textureID;
    
    	Image *tex = make_Image(fileName, &width, &height, &nrChannels);
    	if (tex != NULL && tex->getData() != NULL)
    	{
    		GLenum format;
    		if (nrChannels == 1)
    			format = GL_RED;
    		else if (nrChannels == 3)
    			format = GL_RGB;
    		else if (nrChannels == 4)
    			format = GL_RGBA;
    
    		glGenTextures(1, &textureID);
    		glBindTexture(GL_TEXTURE_2D, textureID);
    
    		if (type == ImageType::REPEAT)
    		{
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    		}
    		else if (type == ImageType::CLAMP)
    		{
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    		}
    
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    		glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, tex->getData());
    		glGenerateMipmap(GL_TEXTURE_2D);
    	}
    
    	free_image(tex);
    
    	return textureID;
    }