| 148 | } |
| 149 | |
| 150 | GLuint MakeTextureArray(std::map<unsigned int, Texture> &textures, bool repeatable) { |
| 151 | ASSERT(textures.size() < MAX_TEXTURE_ARRAY_SIZE, "Configured maximum texture array size of " << MAX_TEXTURE_ARRAY_SIZE << " has been exceeded."); |
| 152 | |
| 153 | size_t max_width =0, max_height = 0; |
| 154 | GLuint texture_name; |
| 155 | |
| 156 | glGenTextures(1, &texture_name); |
| 157 | glBindTexture(GL_TEXTURE_2D_ARRAY, texture_name); |
| 158 | |
| 159 | // Find the maximum width and height, so we can avoid overestimating with blanket values (256x256) and thereby scale UV's uneccesarily |
| 160 | for(auto &texture: textures){ |
| 161 | if(texture.second.width > max_width) max_width = texture.second.width; |
| 162 | if(texture.second.height > max_height) max_height = texture.second.height; |
| 163 | } |
| 164 | |
| 165 | std::vector<uint32_t> clear_data(max_width * max_height, 0); |
| 166 | |
| 167 | LOG(INFO) << "Creating texture array with " << (int) textures.size() << " textures, max texture width " << max_width << ", max texture height " << max_height; |
| 168 | glTexStorage3D(GL_TEXTURE_2D_ARRAY, 3, GL_RGBA8, max_width, max_height, MAX_TEXTURE_ARRAY_SIZE); // I should really call this on textures.size(), but the layer numbers are not linear up to textures.size(). HS Bloats tex index up over 2048. |
| 169 | |
| 170 | for (auto &texture : textures) { |
| 171 | ASSERT(texture.second.width <= max_width, "Texture " << texture.second.texture_id << " exceeds maximum specified texture size (" << max_width << ") for Array"); |
| 172 | ASSERT(texture.second.height <= max_height, "Texture " << texture.second.texture_id << " exceeds maximum specified texture size (" << max_height << ") for Array"); |
| 173 | // Set the whole texture to transparent (so min/mag filters don't find bad data off the edge of the actual image data) |
| 174 | glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, hsStockTextureIndexRemap(texture.first), max_width, max_height, 1, GL_RGBA, GL_UNSIGNED_BYTE, &clear_data[0]); |
| 175 | glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, hsStockTextureIndexRemap(texture.first), texture.second.width, texture.second.height, 1, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid *) texture.second.texture_data); |
| 176 | |
| 177 | texture.second.min_u = 0.00; |
| 178 | texture.second.min_v = 0.00; |
| 179 | texture.second.layer = hsStockTextureIndexRemap(texture.first); |
| 180 | texture.second.max_u = (texture.second.width / static_cast<float>(max_width )) - 0.005f; // Attempt to remove potential for sampling texture from transparent area |
| 181 | texture.second.max_v = (texture.second.height / static_cast<float>(max_height)) - 0.005f; |
| 182 | texture.second.texture_id = texture_name; |
| 183 | |
| 184 | } |
| 185 | |
| 186 | if (repeatable) { |
| 187 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| 188 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| 189 | } else { |
| 190 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 191 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 192 | } |
| 193 | |
| 194 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| 195 | glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| 196 | glGenerateMipmap(GL_TEXTURE_2D_ARRAY); |
| 197 | |
| 198 | //Unbind texture |
| 199 | glBindTexture(GL_TEXTURE_2D_ARRAY, 0); |
| 200 | |
| 201 | return texture_name; |
| 202 | } |
| 203 | |
| 204 | std::vector<glm::vec2> nfsUvGenerate(NFSVer tag, EntityType mesh_type, uint32_t textureFlags, Texture gl_texture) { |
| 205 | std::bitset<32> textureAlignment(textureFlags); |
no test coverage detected