OsdGLPtexMipmapTexture * OsdGLPtexMipmapTexture::Create(PtexTexture * reader, int maxLevels) { OsdGLPtexMipmapTexture * result = NULL; GLint maxNumPages = 0; glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxNumPages); // Read the ptexture data and pack the texels OsdPtexMipmapTextureLoader loader(reader, maxNumPages, maxLevels); // Setup GPU memory int numFaces = loader.GetNumFaces(); GLuint layout = genTextureBuffer(GL_R16I, numFaces * 6 * sizeof(GLshort), loader.GetLayoutBuffer()); GLenum format, type; switch (reader->dataType()) { case Ptex::dt_uint16 : type = GL_UNSIGNED_SHORT; break; case Ptex::dt_float : type = GL_FLOAT; break; case Ptex::dt_half : type = GL_HALF_FLOAT; break; default : type = GL_UNSIGNED_BYTE; break; } switch (reader->numChannels()) { case 1 : format = GL_RED; break; case 2 : format = GL_RG; break; case 3 : format = GL_RGB; break; case 4 : format = GL_RGBA; break; default: format = GL_RED; break; } // actual texels texture array GLuint texels; glGenTextures(1, &texels); glBindTexture(GL_TEXTURE_2D_ARRAY, texels); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, (type == GL_FLOAT) ? GL_RGBA32F : GL_RGBA, loader.GetPageWidth(), loader.GetPageHeight(), loader.GetNumPages(), 0, format, type, loader.GetTexelBuffer()); // loader.ClearBuffers(); // Return the Osd Ptexture object result = new OsdGLPtexMipmapTexture; result->_width = loader.GetPageWidth(); result->_height = loader.GetPageHeight(); result->_depth = loader.GetNumPages(); result->_format = format; result->_layout = layout; result->_texels = texels; return result; }
OsdGLPtexTexture * OsdGLPtexTexture::Create(PtexTexture * reader, unsigned long int targetMemory, int gutterWidth, int pageMargin) { OsdGLPtexTexture * result = NULL; // Read the ptexture data and pack the texels OsdPtexTextureLoader ldr(reader, gutterWidth, pageMargin); unsigned long int nativeSize = ldr.GetNativeUncompressedSize(), targetSize = targetMemory; if (targetSize != 0 && targetSize != nativeSize) ldr.OptimizeResolution(targetSize); GLint maxnumpages = 0; glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxnumpages); ldr.OptimizePacking(maxnumpages); if (!ldr.GenerateBuffers()) return result; // Setup GPU memory unsigned long int nfaces = ldr.GetNumBlocks(); GLuint pages = genTextureBuffer(GL_R32I, nfaces * sizeof(GLint), ldr.GetIndexBuffer()); GLuint layout = genTextureBuffer(GL_RGBA32F, nfaces * 4 * sizeof(GLfloat), ldr.GetLayoutBuffer()); GLenum format, type; switch (reader->dataType()) { case Ptex::dt_uint16 : type = GL_UNSIGNED_SHORT; break; case Ptex::dt_float : type = GL_FLOAT; break; case Ptex::dt_half : type = GL_HALF_FLOAT; break; default : type = GL_UNSIGNED_BYTE; break; } switch (reader->numChannels()) { case 1 : format = GL_RED; break; case 2 : format = GL_RG; break; case 3 : format = GL_RGB; break; case 4 : format = GL_RGBA; break; default: format = GL_RED; break; } // actual texels texture array GLuint texels; glGenTextures(1, &texels); glBindTexture(GL_TEXTURE_2D_ARRAY, texels); // XXXX for the time being, filtering is off - once cross-patch filtering // is in place, we will use glGenSamplers to dynamically access these settings. if (gutterWidth > 0) { glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, (type == GL_FLOAT) ? GL_RGBA32F : GL_RGBA, ldr.GetPageSize(), ldr.GetPageSize(), ldr.GetNumPages(), 0, format, type, ldr.GetTexelBuffer()); ldr.ClearBuffers(); // Return the Osd Ptexture object result = new OsdGLPtexTexture; result->_width = ldr.GetPageSize(); result->_height = ldr.GetPageSize(); result->_depth = ldr.GetNumPages(); result->_format = format; result->_pages = pages; result->_layout = layout; result->_texels = texels; return result; }
D3D11PtexTexture * D3D11PtexTexture::Create(ID3D11DeviceContext *deviceContext, PtexTexture * reader, unsigned long int targetMemory, int gutterWidth, int pageMargin) { D3D11PtexTexture * result = NULL; // Read the ptex data and pack the texels PtexTextureLoader ldr(reader, gutterWidth, pageMargin); unsigned long int nativeSize = ldr.GetNativeUncompressedSize(), targetSize = targetMemory; if (targetSize != 0 && targetSize != nativeSize) ldr.OptimizeResolution(targetSize); int maxnumpages = D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; ldr.OptimizePacking(maxnumpages); if (!ldr.GenerateBuffers()) return result; // Setup GPU memory unsigned long int nfaces = ldr.GetNumBlocks(); ID3D11Buffer *pages = genTextureBuffer(deviceContext, nfaces * sizeof(int), ldr.GetIndexBuffer()); ID3D11Buffer *layout = genTextureBuffer(deviceContext, nfaces * 4 * sizeof(float), ldr.GetLayoutBuffer()); DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; int bpp = 0; int numChannels = reader->numChannels(); switch (reader->dataType()) { case Ptex::dt_uint16: switch (numChannels) { case 1: format = DXGI_FORMAT_R16_UINT; break; case 2: format = DXGI_FORMAT_R16G16_UINT; break; case 3: assert(false); break; case 4: format = DXGI_FORMAT_R16G16B16A16_UINT; break; } bpp = numChannels * 2; break; case Ptex::dt_float: switch (numChannels) { case 1: format = DXGI_FORMAT_R32_FLOAT; break; case 2: format = DXGI_FORMAT_R32G32_FLOAT; break; case 3: format = DXGI_FORMAT_R32G32B32_FLOAT; break; case 4: format = DXGI_FORMAT_R32G32B32A32_FLOAT; break; } bpp = numChannels * 4; break; case Ptex::dt_half: switch (numChannels) { case 1: format = DXGI_FORMAT_R16_FLOAT; break; case 2: format = DXGI_FORMAT_R16G16_FLOAT; break; case 3:assert(false); break; case 4: format = DXGI_FORMAT_R16G16B16A16_FLOAT; break; } bpp = numChannels * 2; break; default: switch (numChannels) { case 1: format = DXGI_FORMAT_R8_UINT; break; case 2: format = DXGI_FORMAT_R8G8_UINT; break; case 3: assert(false); break; case 4: format = DXGI_FORMAT_R8G8B8A8_UINT; break; } bpp = numChannels; break; } // actual texels texture array D3D11_TEXTURE2D_DESC desc; desc.Width = ldr.GetPageSize(); desc.Height = ldr.GetPageSize(); desc.MipLevels = 1; desc.ArraySize = ldr.GetNumPages(); desc.Format = format; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = ldr.GetTexelBuffer(); initData.SysMemPitch = ldr.GetPageSize() * bpp; initData.SysMemSlicePitch = ldr.GetPageSize() * ldr.GetPageSize() * bpp; ID3D11Device *device; ID3D11Texture2D *texels; deviceContext->GetDevice(&device); HRESULT hr = device->CreateTexture2D(&desc, &initData, &texels); ldr.ClearBuffers(); // Return the Osd PtexTexture object result = new D3D11PtexTexture; result->_width = ldr.GetPageSize(); result->_height = ldr.GetPageSize(); result->_depth = ldr.GetNumPages(); result->_format = format; result->_pages = pages; result->_layout = layout; result->_texels = texels; return result; }