#include "gx/gll/GLVertexArray.h" #include "gx/gll/GLDevice.h" bool GLVertexArray::s_VertexArrayEnable = false; GLVertexArray::GLVertexArray(bool a2) { // TODO } void GLVertexArray::FindVertexArray(GLDevice* a1, GLVertexArray& a2) { if (GLVertexArray::s_VertexArrayEnable) { // TODO } a2.ApplyVertexFormat(a1); } void GLVertexArray::ApplyGLStates(GLStates::VertexArrayObject& vao) { GLDevice* device = GLDevice::Get(); device->BindVertexArray(this); for (int32_t i = 0; i < kMAX_VERTEX_ATTRIBS; i++) { auto& attrib = vao.vertexAttribs[i]; if (attrib.enable) { glBindBuffer(attrib.buffer->m_Type, attrib.buffer->m_BufferID); glVertexAttribPointerARB( i, attrib.size, attrib.type, attrib.normalized, attrib.stride, reinterpret_cast(attrib.offset) ); glEnableVertexAttribArrayARB(i); } else { glDisableVertexAttribArrayARB(i); } } if (vao.position.enable) { glBindBuffer(vao.position.buffer->m_Type, vao.position.buffer->m_BufferID); glVertexPointer(vao.position.size, vao.position.type, vao.position.stride, vao.position.offset); glEnableClientState(GL_VERTEX_ARRAY); } else { glDisableClientState(GL_VERTEX_ARRAY); } if (vao.normal.enable) { glBindBuffer(vao.normal.buffer->m_Type, vao.normal.buffer->m_BufferID); glNormalPointer(vao.normal.type, vao.normal.stride, vao.normal.offset); glEnableClientState(GL_NORMAL_ARRAY); } else { glDisableClientState(GL_NORMAL_ARRAY); } if (vao.color0.enable) { glBindBuffer(vao.color0.buffer->m_Type, vao.color0.buffer->m_BufferID); glColorPointer(vao.color0.size, vao.color0.type, vao.color0.stride, vao.color0.offset); glEnableClientState(GL_COLOR_ARRAY); } else { glDisableClientState(GL_COLOR_ARRAY); } if (vao.color1.enable) { glBindBuffer(vao.color1.buffer->m_Type, vao.color1.buffer->m_BufferID); glColorPointer(vao.color1.size, vao.color1.type, vao.color1.stride, vao.color1.offset); glEnableClientState(GL_SECONDARY_COLOR_ARRAY); } else { glDisableClientState(GL_SECONDARY_COLOR_ARRAY); } for (int32_t i = 0; i < 8; i++) { glClientActiveTextureARB(GL_TEXTURE0 + i); if (vao.texCoord[i].enable) { glBindBuffer(vao.texCoord[i].buffer->m_Type, vao.texCoord[0].buffer->m_BufferID); glTexCoordPointer(vao.texCoord[i].size, vao.texCoord[i].type, vao.texCoord[i].stride, vao.texCoord[i].offset); glEnableClientState(GL_TEXTURE_COORD_ARRAY); } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } glBindBuffer(GL_ARRAY_BUFFER, vao.buffers[0]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao.buffers[1]); glBindBuffer(GL_PIXEL_PACK_BUFFER, vao.buffers[2]); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, vao.buffers[3]); this->m_GLStates = vao; } void GLVertexArray::ApplyVertexFormat(GLDevice* device) { if (GLVertexArray::s_VertexArrayEnable) { device->BindVertexArray(this); } auto indexBuffer = this->m_Properties.m_IndexBuffer; uint32_t indexBufferID = indexBuffer ? indexBuffer->m_BufferID : 0; if (this->m_GLStates.buffers[1] != indexBufferID) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID); this->m_GLStates.buffers[1] = indexBufferID; } BLIZZARD_ASSERT(this->GetProperties().m_VertexBufferFormat != nullptr); auto& properties = this->GetProperties(); bool attribEnable[16] = {}; bool useVertexShader = device->GetShader(GLShader::eVertexShader) != nullptr; for (int32_t index = 0; index < this->GetProperties().m_VertexBufferFormat->m_Size; index++) { BLIZZARD_ASSERT(index < kMAX_VERTEX_ATTRIBS); auto& attrib = this->GetProperties().m_VertexBufferFormat->m_Attribs[index]; BLIZZARD_ASSERT(attrib.type != GLVT_INVALID); BLIZZARD_ASSERT(attrib.type < GLVT_NUM_VERTEX_TYPES); auto vertexBuffer = this->GetProperties().m_VertexBuffer[attrib.stream]; if (useVertexShader || attrib.slot - 1 > 1) { if (this->m_GLStates.buffers[0] != vertexBuffer->m_BufferID) { glBindBuffer(vertexBuffer->m_Type, vertexBuffer->m_BufferID); this->m_GLStates.buffers[0] = vertexBuffer->m_BufferID; } attribEnable[attrib.slot] = 1; int32_t stride = properties.m_VertexBufferStride[attrib.stream]; int32_t offset = attrib.offset + properties.m_VertexBufferOffset[attrib.stream] + properties.m_VertexBase * stride; if (useVertexShader) { glVertexAttribPointerARB( attrib.slot, k_VertexTypeInfo[attrib.type].m_Size, k_VertexTypeInfo[attrib.type].m_Type, k_VertexTypeInfo[attrib.type].m_Normalized, stride, reinterpret_cast(offset) ); } else { // TODO } } } for (int32_t s = 0; s < 16; s++) { bool* prevAttribEnable; if (useVertexShader) { prevAttribEnable = &this->m_GLStates.vertexAttribs[s].enable; } else { // TODO } if (*prevAttribEnable != attribEnable[s]) { if (attribEnable[s]) { if (useVertexShader) { glEnableVertexAttribArrayARB(s); } else { // TODO } } else { if (useVertexShader) { glDisableVertexAttribArrayARB(s); } else { // TODO } } *prevAttribEnable = attribEnable[s]; } } } GLVertexArray::Properties& GLVertexArray::GetProperties() { return this->m_Properties; } void GLVertexArray::ReleaseObject() { // TODO }