Skip to content

Instantly share code, notes, and snippets.

@alanhaugen
Created September 5, 2020 15:31
Show Gist options
  • Save alanhaugen/556b7ce50945f9c8ab543b18cde81283 to your computer and use it in GitHub Desktop.
Save alanhaugen/556b7ce50945f9c8ab543b18cde81283 to your computer and use it in GitHub Desktop.
#include "gles2drawable.h"
#include "core/x-platform/typedefs.h"
#include "core/x-platform/pixmap.h"
GLES2Drawable::GLES2Drawable(
Array<IDrawable::Vertex> &vertices,
Array<unsigned int> &indices,
Array<String> &shaders,
Array<Pixmap *> *textures)
: shader(),
texture()
{
if (textures)
{
texture.Load(*textures[0]);
}
// Ensure weights for skinning add up to 1 (very important)
// TODO: Do not do this for meshes without skins
for (unsigned int i = 0; i < vertices.Size(); i++)
{
float weightsSum = vertices[i].weights.x + vertices[i].weights.y + vertices[i].weights.z + vertices[i].weights.w;
if (weightsSum != 1.0f)
{
float missing = 1.0f - weightsSum;
vertices[i].weights.x += missing / 4;
vertices[i].weights.y += missing / 4;
vertices[i].weights.z += missing / 4;
vertices[i].weights.w += missing / 4;
}
}
vao = 0;
vbo = 0;
ibo = 0;
indicesQuantity = indices.Size();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.Size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned int),
&indices[0], GL_STATIC_DRAW);
// vertex positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
// vertex colours
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, color));
// vertex normals
//glEnableVertexAttribArray(2);
//glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));
// texture coordinates
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, textureCoordinates));
// weights for skinning
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, weights));
// joints for skinning
glEnableVertexAttribArray(5);
glVertexAttribIPointer(5, 4, GL_INT, sizeof(Vertex), (void*)offsetof(Vertex, joints));
glBindVertexArray(0);
DeActivate();
shader.LoadGLSL(GL_VERTEX_SHADER, shaders[VERTEX_SHADER].ToChar());
shader.LoadGLSL(GL_FRAGMENT_SHADER, shaders[FRAGMENT_SHADER].ToChar());
shader.Compile();
}
GLES2Drawable::~GLES2Drawable()
{
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ibo);
}
void GLES2Drawable::Activate(const glm::mat4& projViewMatrix)
{
glUseProgram(shader.program);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); // Due to a bug on some cards, this is included
texture.Activate();
// TODO: Loop through all uniforms and update their values for the shader
glm::mat4 mvp = projViewMatrix * matrix;
Uniform("MVP", static_cast<glm::mat4&>(mvp));
Uniform("colorTint", static_cast<glm::vec4>(colorTint));
if (animatedMatrices != NULL)
{
Uniform("animatedMatrices", static_cast<glm::mat4&>(animatedMatrices[0]), MAX_JOINTS);
}
if (this->texture.textureID)
{
Uniform("uEnableTexture", static_cast<glm::int32>(1));
// Set the sampler texture unit to 0
//textureSamplerLocation = glGetUniformLocation(shader.program, "textureSampler");
//glUniform1i(textureSamplerLocation, 0);
}
else
{
Uniform("uEnableTexture", static_cast<glm::int32>(0));
}
}
void GLES2Drawable::DeActivate()
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
}
/*void GLES2Drawable::UploadBuffer(datatype, elements, data, offset)
{
glEnableVertexAttribArray(index);
glVertexAttribPointer(index, elements, datatype, GL_FALSE, sizeof(Vertex), (void*)offsetof(data, offset));
index++;
}*/
int GLES2Drawable::GetUniform(String location)
{
int uniformLocation;
if (uniforms.Find(location) == NULL)
{
uniformLocation = glGetUniformLocation(shader.program, location.ToChar());
uniforms.Insert(location, uniformLocation);
}
else
{
uniformLocation = uniforms.Find(location)->data_;
}
return uniformLocation;
}
void GLES2Drawable::Uniform(String location, glm::f32 uniform)
{
glUniform1f(GetUniform(location), uniform);
}
void GLES2Drawable::Uniform(String location, glm::vec2 uniform)
{
glUniform2f(GetUniform(location), uniform.x, uniform.y);
}
void GLES2Drawable::Uniform(String location, glm::vec3 uniform)
{
glUniform3f(GetUniform(location), uniform.x, uniform.y, uniform.z);
}
void GLES2Drawable::Uniform(String location, glm::vec4 uniform)
{
glUniform4f(GetUniform(location), uniform.x, uniform.y, uniform.z, uniform.w);
}
void GLES2Drawable::Uniform(String location, glm::int32 uniform)
{
glUniform1i(GetUniform(location), uniform);
}
void GLES2Drawable::Uniform(String location, glm::ivec2 uniform)
{
glUniform2i(GetUniform(location), uniform.x, uniform.y);
}
void GLES2Drawable::Uniform(String location, glm::ivec3 uniform)
{
glUniform3i(GetUniform(location), uniform.x, uniform.y, uniform.z);
}
void GLES2Drawable::Uniform(String location, glm::ivec4 uniform)
{
glUniform4i(GetUniform(location), uniform.x, uniform.y, uniform.z, uniform.w);
}
void GLES2Drawable::Uniform(String location, glm::uint uniform)
{
glUniform1ui(GetUniform(location), uniform);
}
void GLES2Drawable::Uniform(String location, glm::uvec2 uniform)
{
glUniform2ui(GetUniform(location), uniform.x, uniform.y);
}
void GLES2Drawable::Uniform(String location, glm::uvec3 uniform)
{
glUniform3ui(GetUniform(location), uniform.x, uniform.y, uniform.z);
}
void GLES2Drawable::Uniform(String location, glm::uvec4 uniform)
{
glUniform4ui(GetUniform(location), uniform.x, uniform.y, uniform.z, uniform.w);
}
void GLES2Drawable::Uniform(String location, glm::f32 &uniform)
{
glUniform1fv(GetUniform(location), 1, &uniform);
}
void GLES2Drawable::Uniform(String location, glm::vec2 &uniform)
{
glUniform2fv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::vec3 &uniform)
{
glUniform3fv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::vec4 &uniform)
{
glUniform4fv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::int32 &uniform)
{
glUniform1iv(GetUniform(location), 1, &uniform);
}
void GLES2Drawable::Uniform(String location, glm::ivec2 &uniform)
{
glUniform2iv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::ivec3 &uniform)
{
glUniform3iv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::ivec4 &uniform)
{
glUniform4iv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::uint &uniform)
{
glUniform1uiv(GetUniform(location), 1, &uniform);
}
void GLES2Drawable::Uniform(String location, glm::uvec2 &uniform)
{
glUniform2uiv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::uvec3 &uniform)
{
glUniform3uiv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::uvec4 &uniform)
{
glUniform4uiv(GetUniform(location), 1, &uniform[0]);
}
void GLES2Drawable::Uniform(String location, glm::mat2 &uniform)
{
glUniformMatrix2fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat3 &uniform)
{
glUniformMatrix3fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat4 &uniform, int arraySize)
{
glUniformMatrix4fv(GetUniform(location), arraySize, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat2x3 &uniform)
{
glUniformMatrix4fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat3x2 &uniform)
{
glUniformMatrix3x2fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat2x4 &uniform)
{
glUniformMatrix2x4fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat4x2 &uniform)
{
glUniformMatrix4x2fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat3x4 &uniform)
{
glUniformMatrix3x4fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
void GLES2Drawable::Uniform(String location, glm::mat4x3 &uniform)
{
glUniformMatrix4x3fv(GetUniform(location), 1, GL_FALSE, &uniform[0][0]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment