inline GLint Program::UniformLocation(const char *name) { GL_ASSERT(m_id > 0); GL_ASSERT(name != NULL); return glGetUniformLocation(m_id, name); }
inline void Program::Uniform(GLint location, GLsizei count, GLboolean transpose, const glm::mat4 *value) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniformMatrix4fv(location, count, transpose, glm::value_ptr(*value)); }
inline bool Program::AddShader(GLuint shader_id) { GL_ASSERT(m_id > 0); GL_ASSERT(shader_id > 0); glAttachShader(m_id, shader_id); }
inline void Program::Uniform(GLint location, GLsizei count, const GLint *value) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniform1iv(location, count, value); }
inline void Program::Uniform(GLint location, GLsizei count, const glm::ivec4 *value) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniform4iv(location, count, glm::value_ptr(*value)); }
inline void Program::Uniform(GLint location, GLint v0, GLint v1) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniform2i(location, v0, v1); }
inline void Program::Uniform(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniform3i(location, v0, v2, v3); }
bool Texture::create(int width, int height) { // Check if texture parameters are valid before creating it if ((width == 0) || (height == 0)) { GUY_ERROR("Failed to create texture, invalid size (%dx%d)\n", width, height); return false; } // All the validity checks passed, we can store the new texture settings m_size.x = width; m_size.y = height; // Create the OpenGL texture if it doesn't exist yet if (!m_id) { GLuint texture; GL_ASSERT(glGenTextures(1, &texture)); m_id = texture; } // Initialize the texture GL_ASSERT(glBindTexture(GL_TEXTURE_2D, m_id)); GL_ASSERT(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x, m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)); return true; }
void Texture::setData(const unsigned char* data) { // Don't work with any compressed or cached textures GP_ASSERT( data ); GP_ASSERT( (!_compressed) ); GP_ASSERT( (!_cached) ); GL_ASSERT( glBindTexture((GLenum)_type, _handle) ); if (_type == Texture::TEXTURE_2D) { GL_ASSERT( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, _internalFormat, _texelType, data) ); } else { // Get texture size unsigned int textureSize = _width * _height; textureSize *= _bpp; // Texture Cube for (unsigned int i = 0; i < 6; i++) { GL_ASSERT( glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _width, _height, _internalFormat, _texelType, &data[i * textureSize]) ); } } if (_mipmapped) { generateMipmaps(); } // Restore the texture id GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) ); }
bool Shader::Compile(const char *src) { GL_ASSERT(m_id != 0); GL_ASSERT(src != NULL); int len[1]; len[0] = (int)strlen(src); GL_ASSERT(len[0] > 0); glShaderSource(m_id, 1, &src, len); glCompileShader(m_id); GLint status; glGetShaderiv(m_id, GL_COMPILE_STATUS, &status); if (status == GL_TRUE) return true; GLsizei length; GLchar info_log[256] = { 0 }; glGetShaderInfoLog(m_id, sizeof(info_log) - 1, &length, info_log); m_info_log = info_log; return false; }
bool Shader::compile() const { GLint status; GL_ASSERT(glCompileShader(m_id)); GL_ASSERT(glGetShaderiv(m_id, GL_COMPILE_STATUS, &status)); return status == GL_TRUE; }
void Mesh::setVertexData(const void* vertexData, unsigned int vertexStart, unsigned int vertexCount) { GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer) ); if (vertexStart == 0 && vertexCount == 0) { GL_ASSERT( glBufferData(GL_ARRAY_BUFFER, _vertexFormat.getVertexSize() * _vertexCount, vertexData, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) ); } else { if (vertexCount == 0) { vertexCount = _vertexCount - vertexStart; } else if (vertexCount > _vertexCount || vertexStart == 0 && vertexCount < _vertexCount) { _vertexCount = vertexCount; GL_ASSERT(glBufferData(GL_ARRAY_BUFFER, _vertexFormat.getVertexSize() * _vertexCount, vertexData, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW)); } else { GL_ASSERT(glBufferSubData(GL_ARRAY_BUFFER, vertexStart * _vertexFormat.getVertexSize(), vertexCount * _vertexFormat.getVertexSize(), vertexData)); } } }
inline void Program::Uniform(GLint location, GLfloat v0) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniform1f(location, v0); }
inline void Program::Uniform(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { GL_ASSERT(m_id > 0); GL_ASSERT(location >= 0); glUniform3f(location, v0, v1, v2); }
void Engine::Texture::updateData( void* data ) { GL_ASSERT(glBindTexture(target, m_textureId)); switch (target) { case GL_TEXTURE_1D: { GL_ASSERT(glTexImage1D(target, 0, internalFormat, m_width, 0, m_format, dataType, data)); } case GL_TEXTURE_2D: { GL_ASSERT(glTexImage2D(target, 0, internalFormat, m_width, m_height, 0, m_format, dataType, data)); } break; case GL_TEXTURE_3D: { GL_ASSERT(glTexImage3D(target, 0, internalFormat, m_width, m_height, m_depth, 0, m_format, dataType, data)); } break; default: { CORE_ASSERT( 0, "Dafuck ?" ); } break; } }
static bool drawWireframe(Mesh* mesh) { switch (mesh->getPrimitiveType()) { case Mesh::TRIANGLES: { unsigned int vertexCount = mesh->getVertexCount(); for (unsigned int i = 0; i < vertexCount; i += 3) { GL_ASSERT( glDrawArrays(GL_LINE_LOOP, i, 3) ); } } return true; case Mesh::TRIANGLE_STRIP: { unsigned int vertexCount = mesh->getVertexCount(); for (unsigned int i = 2; i < vertexCount; ++i) { GL_ASSERT( glDrawArrays(GL_LINE_LOOP, i-2, 3) ); } } return true; default: // not supported return false; } }
void GLshader::print_subroutines() { int maxSub,maxSubU,countActiveSU; char name[256]; int len, numCompS; GL_ASSERT(glGetIntegerv(GL_MAX_SUBROUTINES, &maxSub)); GL_ASSERT(glGetIntegerv(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, &maxSubU)); printf("Max Subroutines: %d Max Subroutine Uniforms: %d\n", maxSub,maxSubU); GL_ASSERT(glGetProgramStageiv(program, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &countActiveSU)); for (int i = 0; i < countActiveSU; ++i) { glGetActiveSubroutineUniformName(program, GL_VERTEX_SHADER, i, 256, &len, name); printf("Suroutine Uniform: %d name: %s\n", i,name); glGetActiveSubroutineUniformiv(program, GL_VERTEX_SHADER, i, GL_NUM_COMPATIBLE_SUBROUTINES, &numCompS); int *s = (int *) malloc(sizeof(int) * numCompS); glGetActiveSubroutineUniformiv(program, GL_VERTEX_SHADER, i, GL_COMPATIBLE_SUBROUTINES, s); printf("Compatible Subroutines:\n"); for (int j=0; j < numCompS; ++j) { glGetActiveSubroutineName(program, GL_VERTEX_SHADER, s[j], 256, &len, name); printf("\t%d - %s\n", s[j],name); } printf("\n"); free(s); } }
void MeshPart::setIndexData(void* indexData, unsigned int indexStart, unsigned int indexCount) { GL_ASSERT( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer) ); unsigned int indexSize = 0; switch (_indexFormat) { case Mesh::INDEX8: indexSize = 1; break; case Mesh::INDEX16: indexSize = 2; break; case Mesh::INDEX32: indexSize = 4; break; default: GP_ERROR("Unsupported index format (%d).", _indexFormat); return; } if (indexStart == 0 && indexCount == 0) { GL_ASSERT( glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * _indexCount, indexData, _dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) ); } else { if (indexCount == 0) { indexCount = _indexCount - indexStart; } GL_ASSERT( glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, indexStart * indexSize, indexCount * indexSize, indexData) ); } }
Texture* Texture::create(Format format, unsigned int width, unsigned int height, unsigned char* data, bool generateMipmaps) { // Load our texture. GLuint textureId; GL_ASSERT( glGenTextures(1, &textureId) ); GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) ); if (format == DEPTH) { // <type> must be UNSIGNED_SHORT or UNSIGNED_INT for a format of DEPTH_COMPONENT. GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_INT, data) ); } else { GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) ); } // Set initial minification filter based on whether or not mipmaping was enabled GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, generateMipmaps ? GL_NEAREST_MIPMAP_LINEAR : GL_LINEAR) ); Texture* texture = new Texture(); texture->_handle = textureId; texture->_width = width; texture->_height = height; if (generateMipmaps) { texture->generateMipmaps(); } return texture; }
Texture* Texture::create(Format format, unsigned int width, unsigned int height, unsigned char* data, bool generateMipmaps) { // Create and load the texture. GLuint textureId; GL_ASSERT( glGenTextures(1, &textureId) ); GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) ); GL_ASSERT( glPixelStorei(GL_UNPACK_ALIGNMENT, 1) ); GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) ); // Set initial minification filter based on whether or not mipmaping was enabled. GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, generateMipmaps ? GL_NEAREST_MIPMAP_LINEAR : GL_LINEAR) ); Texture* texture = new Texture(); texture->_handle = textureId; texture->_format = format; texture->_width = width; texture->_height = height; if (generateMipmaps) { texture->generateMipmaps(); texture->_mipmapped = true; } return texture; }
Mesh* Mesh::createMesh(const VertexFormat& vertexFormat, unsigned int vertexCount, bool dynamic) { GLuint vbo; GL_ASSERT( glGenBuffers(1, &vbo) ); if (GL_LAST_ERROR()) { return NULL; } GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, vbo) ); if (GL_LAST_ERROR()) { glDeleteBuffers(1, &vbo); return NULL; } GL_CHECK( glBufferData(GL_ARRAY_BUFFER, vertexFormat.getVertexSize() * vertexCount, NULL, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) ); if (GL_LAST_ERROR()) { glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &vbo); return NULL; } Mesh* mesh = new Mesh(vertexFormat); mesh->_vertexCount = vertexCount; mesh->_vertexBuffer = vbo; mesh->_dynamic = dynamic; return mesh; }
void VertexAttributeBinding::unbind() { if (_handle) { // Hardware mode GL_ASSERT( glBindVertexArray(0) ); } else { // Software mode if (_mesh) { GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, 0) ); } GP_ASSERT(_attributes); for (unsigned int i = 0; i < __maxVertexAttribs; ++i) { if (_attributes[i].enabled) { GL_ASSERT( glDisableVertexAttribArray(i) ); } } } }
void VertexAttributeBinding::bind() { if (_handle) { // Hardware mode GL_ASSERT( glBindVertexArray(_handle) ); } else { // Software mode if (_mesh) { GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, _mesh->getVertexBuffer()) ); } else { GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, 0) ); } GP_ASSERT(_attributes); for (unsigned int i = 0; i < __maxVertexAttribs; ++i) { VertexAttribute& a = _attributes[i]; if (a.enabled) { GL_ASSERT( glVertexAttribPointer(i, a.size, a.type, a.normalized, a.stride, a.pointer) ); GL_ASSERT( glEnableVertexAttribArray(i) ); } } } }
void Texture::Sampler::bind() { GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _texture->_handle) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)_wrapS) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)_wrapT) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)_minFilter) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)_magFilter) ); }
unsigned int Model::draw(bool wireframe) { GP_ASSERT(_mesh); unsigned int partCount = _mesh->getPartCount(); if (partCount == 0) { // No mesh parts (index buffers). if (_material) { Technique* technique = _material->getTechnique(); GP_ASSERT(technique); unsigned int passCount = technique->getPassCount(); for (unsigned int i = 0; i < passCount; ++i) { Pass* pass = technique->getPassByIndex(i); GP_ASSERT(pass); pass->bind(); GL_ASSERT( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) ); if (!wireframe || !drawWireframe(_mesh)) { GL_ASSERT( glDrawArrays(_mesh->getPrimitiveType(), 0, _mesh->getVertexCount()) ); } pass->unbind(); } } } else { for (unsigned int i = 0; i < partCount; ++i) { MeshPart* part = _mesh->getPart(i); GP_ASSERT(part); // Get the material for this mesh part. Material* material = getMaterial(i); if (material) { Technique* technique = material->getTechnique(); GP_ASSERT(technique); unsigned int passCount = technique->getPassCount(); for (unsigned int j = 0; j < passCount; ++j) { Pass* pass = technique->getPassByIndex(j); GP_ASSERT(pass); pass->bind(); GL_ASSERT( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, part->_indexBuffer) ); if (!wireframe || !drawWireframe(part)) { GL_ASSERT( glDrawElements(part->getPrimitiveType(), part->getIndexCount(), part->getIndexFormat(), 0) ); } pass->unbind(); } } } } return partCount; }
void Engine::Texture::bind( int unit ) { if (unit >= 0) { GL_ASSERT(glActiveTexture(GL_TEXTURE0 + unit)); } GL_ASSERT(glBindTexture(target, m_textureId)); }
void Texture::setFilterMode(Filter minificationFilter, Filter magnificationFilter) { GLint currentTextureId; GL_ASSERT( glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTextureId) ); GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _handle) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLenum)minificationFilter) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLenum)magnificationFilter) ); GL_ASSERT( glBindTexture(GL_TEXTURE_2D, (GLuint)currentTextureId) ); }
void Texture::setWrapMode(Wrap wrapS, Wrap wrapT) { GLint currentTextureId; GL_ASSERT( glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTextureId) ); GL_ASSERT( glBindTexture(GL_TEXTURE_2D, _handle) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (GLenum)wrapS) ); GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (GLenum)wrapT) ); GL_ASSERT( glBindTexture(GL_TEXTURE_2D, (GLuint)currentTextureId) ); }
void GLshader::term() { GL_ASSERT(glDetachShader(program, vs)); GL_ASSERT(glDetachShader(program, fs)); for (auto s : shader_objects) { GL_ASSERT(glDeleteShader(s)); } }
MeshPart* MeshPart::create(Mesh* mesh, unsigned int meshIndex, Mesh::PrimitiveType primitiveType, Mesh::IndexFormat indexFormat, unsigned int indexCount, bool dynamic) { // Create a VBO for our index buffer. GLuint vbo; GL_ASSERT( glGenBuffers(1, &vbo) ); if (GL_LAST_ERROR()) { GP_ERROR("Failed to create VBO for index buffer with OpenGL error %d.", GL_LAST_ERROR()); return NULL; } GL_ASSERT( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo) ); if (GL_LAST_ERROR()) { GP_ERROR("Failed to bind VBO for index buffer with OpenGL error %d.", GL_LAST_ERROR()); glDeleteBuffers(1, &vbo); return NULL; } unsigned int indexSize = 0; switch (indexFormat) { case Mesh::INDEX8: indexSize = 1; break; case Mesh::INDEX16: indexSize = 2; break; case Mesh::INDEX32: indexSize = 4; break; default: GP_ERROR("Unsupported index format (%d).", indexFormat); glDeleteBuffers(1, &vbo); return NULL; } GL_CHECK( glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * indexCount, NULL, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW) ); if (GL_LAST_ERROR()) { GP_ERROR("Failed to load VBO with index data with OpenGL error %d.", GL_LAST_ERROR()); glDeleteBuffers(1, &vbo); return NULL; } MeshPart* part = new MeshPart(); part->_mesh = mesh; part->_meshIndex = meshIndex; part->_primitiveType = primitiveType; part->_indexFormat = indexFormat; part->_indexCount = indexCount; part->_indexBuffer = vbo; part->_dynamic = dynamic; return part; }