| 1081 | } |
| 1082 | |
| 1083 | void GLInstancingRenderer::updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY) |
| 1084 | { |
| 1085 | B3_PROFILE("updateTexture"); |
| 1086 | if ((textureIndex >= 0) && (textureIndex < m_data->m_textureHandles.size())) |
| 1087 | { |
| 1088 | glActiveTexture(GL_TEXTURE0); |
| 1089 | b3Assert(glGetError() == GL_NO_ERROR); |
| 1090 | InternalTextureHandle& h = m_data->m_textureHandles[textureIndex]; |
| 1091 | glBindTexture(GL_TEXTURE_2D, h.m_glTexture); |
| 1092 | b3Assert(glGetError() == GL_NO_ERROR); |
| 1093 | |
| 1094 | if (flipPixelsY) |
| 1095 | { |
| 1096 | B3_PROFILE("flipPixelsY"); |
| 1097 | //textures need to be flipped for OpenGL... |
| 1098 | b3AlignedObjectArray<unsigned char> flippedTexels; |
| 1099 | flippedTexels.resize(h.m_width * h.m_height * 3); |
| 1100 | |
| 1101 | for (int j = 0; j < h.m_height; j++) |
| 1102 | { |
| 1103 | for (int i = 0; i < h.m_width; i++) |
| 1104 | { |
| 1105 | flippedTexels[(i + j * h.m_width) * 3] = texels[(i + (h.m_height - 1 - j) * h.m_width) * 3]; |
| 1106 | flippedTexels[(i + j * h.m_width) * 3 + 1] = texels[(i + (h.m_height - 1 - j) * h.m_width) * 3 + 1]; |
| 1107 | flippedTexels[(i + j * h.m_width) * 3 + 2] = texels[(i + (h.m_height - 1 - j) * h.m_width) * 3 + 2]; |
| 1108 | } |
| 1109 | } |
| 1110 | |
| 1111 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, h.m_width, h.m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, &flippedTexels[0]); |
| 1112 | } |
| 1113 | else |
| 1114 | { |
| 1115 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, h.m_width, h.m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, &texels[0]); |
| 1116 | } |
| 1117 | b3Assert(glGetError() == GL_NO_ERROR); |
| 1118 | if (h.m_enableFiltering) |
| 1119 | { |
| 1120 | B3_PROFILE("glGenerateMipmap"); |
| 1121 | glGenerateMipmap(GL_TEXTURE_2D); |
| 1122 | } |
| 1123 | b3Assert(glGetError() == GL_NO_ERROR); |
| 1124 | } |
| 1125 | } |
| 1126 | |
| 1127 | void GLInstancingRenderer::activateTexture(int textureIndex) |
| 1128 | { |
no test coverage detected