mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-16 01:55:21 +03:00
317 lines
9.8 KiB
C++
317 lines
9.8 KiB
C++
#include "gx/gll/GLVertexArray.h"
|
|
#include "gx/gll/GLDevice.h"
|
|
#include <bc/Debug.hpp>
|
|
|
|
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<void*>(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 || static_cast<uint32_t>(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<void*>(offset)
|
|
);
|
|
} else {
|
|
switch (attrib.slot) {
|
|
case 0: {
|
|
glVertexPointer(
|
|
k_VertexTypeInfo[attrib.type].m_Size,
|
|
k_VertexTypeInfo[attrib.type].m_Type,
|
|
stride,
|
|
reinterpret_cast<void*>(offset)
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 3: {
|
|
glNormalPointer(
|
|
k_VertexTypeInfo[attrib.type].m_Type,
|
|
stride,
|
|
reinterpret_cast<void*>(offset)
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 4: {
|
|
glColorPointer(
|
|
k_VertexTypeInfo[attrib.type].m_Size,
|
|
k_VertexTypeInfo[attrib.type].m_Type,
|
|
stride,
|
|
reinterpret_cast<void*>(offset)
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 5: {
|
|
glSecondaryColorPointer(
|
|
k_VertexTypeInfo[attrib.type].m_Size,
|
|
k_VertexTypeInfo[attrib.type].m_Type,
|
|
stride,
|
|
reinterpret_cast<void*>(offset)
|
|
);
|
|
|
|
break;
|
|
}
|
|
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13: {
|
|
auto tmu = attrib.slot - 6;
|
|
auto texCoordIndex = device->m_States.fixedFunc.texCoordIndex[tmu];
|
|
glClientActiveTextureARB(GL_TEXTURE0 + texCoordIndex);
|
|
glTexCoordPointer(
|
|
k_VertexTypeInfo[attrib.type].m_Size,
|
|
k_VertexTypeInfo[attrib.type].m_Type,
|
|
stride,
|
|
reinterpret_cast<void*>(offset)
|
|
);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int32_t s = 0; s < 16; s++) {
|
|
// Shader
|
|
if (useVertexShader) {
|
|
auto prevAttribEnable = &this->m_GLStates.vertexAttribs[s].enable;
|
|
|
|
if (*prevAttribEnable != attribEnable[s]) {
|
|
if (attribEnable[s]) {
|
|
glEnableVertexAttribArrayARB(s);
|
|
} else {
|
|
glDisableVertexAttribArrayARB(s);
|
|
}
|
|
}
|
|
|
|
*prevAttribEnable = attribEnable[s];
|
|
|
|
// FFP
|
|
} else {
|
|
bool* prevAttribEnable = nullptr;
|
|
GLenum glArray = GL_NONE;
|
|
|
|
switch (s) {
|
|
case 0: {
|
|
prevAttribEnable = &this->m_GLStates.position.enable;
|
|
glArray = GL_VERTEX_ARRAY;
|
|
|
|
break;
|
|
}
|
|
|
|
case 3: {
|
|
prevAttribEnable = &this->m_GLStates.normal.enable;
|
|
glArray = GL_NORMAL_ARRAY;
|
|
|
|
break;
|
|
}
|
|
|
|
case 4: {
|
|
prevAttribEnable = &this->m_GLStates.color0.enable;
|
|
glArray = GL_COLOR_ARRAY;
|
|
|
|
break;
|
|
}
|
|
|
|
case 5: {
|
|
prevAttribEnable = &this->m_GLStates.color1.enable;
|
|
glArray = GL_SECONDARY_COLOR_ARRAY;
|
|
|
|
break;
|
|
}
|
|
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13: {
|
|
auto tmu = s - 6;
|
|
auto texCoordIndex = device->m_States.fixedFunc.texCoordIndex[tmu];
|
|
|
|
prevAttribEnable = &this->m_GLStates.texCoord[texCoordIndex].enable;
|
|
glArray = GL_TEXTURE_COORD_ARRAY;
|
|
|
|
glClientActiveTextureARB(GL_TEXTURE0 + texCoordIndex);
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (prevAttribEnable) {
|
|
if (*prevAttribEnable != attribEnable[s]) {
|
|
if (attribEnable[s]) {
|
|
glEnableClientState(glArray);
|
|
} else {
|
|
glDisableClientState(glArray);
|
|
}
|
|
}
|
|
|
|
*prevAttribEnable = attribEnable[s];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!useVertexShader) {
|
|
// TODO device->SetColorMaterial(this->m_GLStates.color0.enable);
|
|
}
|
|
}
|
|
|
|
GLVertexArray::Properties& GLVertexArray::GetProperties() {
|
|
return this->m_Properties;
|
|
}
|
|
|
|
void GLVertexArray::ReleaseObject() {
|
|
// TODO
|
|
}
|