bool TF::Texture::SetTexels(void* texels, u32 miplevel, TextureFace face) { if ( miplevel >= mipLevels ) return false; bool success = true; u32 div = 1 << miplevel; // 2 ^ miplevel GLsizei w = width / div; if ( w == 0 ) w = 1; GLsizei h = height / div; if ( h == 0 ) h = 1; GLsizei d = depth / div; if ( d == 0 ) d = 1; // defined in Renderer.cpp void GetOpenGLParametersFromTextureFormat(TextureFormat format, GLint& glInternalFormat, GLenum& glFormat, GLenum& glType, bool& isCompressed); GLint glInternalFormat = 0; GLenum glFormat = 0; GLenum glType = 0; bool isCompressed; GetOpenGLParametersFromTextureFormat(format, glInternalFormat, glFormat, glType, isCompressed); // flip texture vertically since OpenGL starts at lower left corner... if ( type == TT_TEXTURE2D || type == TT_TEXTURECUBE ) { flipImage(texels, w, h, format); } // upload texture to pbo u32 nbBytes = ComputeTextureMemorySize(type, format, w, h, d); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, specific.pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER, nbBytes, 0, GL_STREAM_DRAW); glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, nbBytes, texels); if ( glGetError() ) { LOGWARNING("Failed to upload to PBO."); success = false; goto fail; } // send to video memory switch ( type ) { case TT_TEXTURE1D: { TF_ASSERT(format < TFMT_BC1); glBindTexture(GL_TEXTURE_1D, specific.texture); glTexImage1D(GL_TEXTURE_1D, miplevel, glInternalFormat, w, 0, glFormat, glType, 0); break; } case TT_SHADOW: case TT_TEXTURE2D: case TT_TEXTURECUBE: { GLenum target = type == TT_TEXTURECUBE ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : GL_TEXTURE_2D; glBindTexture(target, specific.texture); if ( isCompressed ) { u32 nbBytes = ComputeTextureMemorySize(type, format, w, h); glCompressedTexImage2D(target, miplevel, glInternalFormat, w, h, 0, nbBytes, 0); } else { glTexImage2D(target, miplevel, glInternalFormat, w, h, 0, glFormat, glType, 0); } break; } case TT_TEXTURE3D: { TF_ASSERT(format < TFMT_BC1); glBindTexture(GL_TEXTURE_3D, specific.texture); glTexImage3D(GL_TEXTURE_3D, miplevel, glInternalFormat, w, h, d, 0, glFormat, glType, 0); break; } } if ( glGetError() ) { LOGWARNING("Failed to upload texels."); success = false; goto fail; } glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); fail: // restore texture if ( type == TT_TEXTURE2D || type == TT_TEXTURECUBE ) { flipImage(texels, w, h, format); } return success; }
//* Creation / loading methods ******************************************** void GLTexture::createInternalResourcesImpl(void) { // Convert to nearest power-of-two size if required mWidth = GLPixelUtil::optionalPO2(mWidth); mHeight = GLPixelUtil::optionalPO2(mHeight); mDepth = GLPixelUtil::optionalPO2(mDepth); // Adjust format if required mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); // Check requested number of mipmaps size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); mNumMipmaps = mNumRequestedMipmaps; if(mNumMipmaps>maxMips) mNumMipmaps = maxMips; // Generate texture name glGenTextures( 1, &mTextureID ); // Set texture type glBindTexture( getGLTextureTarget(), mTextureID ); // This needs to be set otherwise the texture doesn't get rendered glTexParameteri( getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps ); // Set some misc default parameters so NVidia won't complain, these can of course be changed later glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // If we can do automip generation and the user desires this, do so mMipmapsHardwareGenerated = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP); // NVIDIA 175.16 drivers break hardware mip generation for non-compressed // textures - disable until fixed // Leave hardware gen on compressed textures since that's the only way we // can realistically do it since GLU doesn't support DXT // However DON'T do this on Apple, their drivers aren't subject to this // problem yet and in fact software generation appears to cause a crash // in some cases which I've yet to track down #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE if (Root::getSingleton().getRenderSystem()->getCapabilities()->getVendor() == GPU_NVIDIA && !PixelUtil::isCompressed(mFormat)) { mMipmapsHardwareGenerated = false; } #endif if((mUsage & TU_AUTOMIPMAP) && mNumRequestedMipmaps && mMipmapsHardwareGenerated) { glTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE ); } // Allocate internal buffer so that glTexSubImageXD can be used // Internal format GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); size_t width = mWidth; size_t height = mHeight; size_t depth = mDepth; if(PixelUtil::isCompressed(mFormat)) { // Compressed formats size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not // accept a 0 pointer like normal glTexImageXD // Run through this process for every mipmap to pregenerate mipmap piramid uint8 *tmpdata = new uint8[size]; memset(tmpdata, 0, size); for(size_t mip=0; mip<=mNumMipmaps; mip++) { size = PixelUtil::getMemorySize(width, height, depth, mFormat); switch(mTextureType) { case TEX_TYPE_1D: glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, width, 0, size, tmpdata); break; case TEX_TYPE_2D: glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format, width, height, 0, size, tmpdata); break; case TEX_TYPE_3D: glCompressedTexImage3DARB(GL_TEXTURE_3D, mip, format, width, height, depth, 0, size, tmpdata); break; case TEX_TYPE_CUBE_MAP: for(int face=0; face<6; face++) { glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, size, tmpdata); } break; }; if(width>1) width = width/2; if(height>1) height = height/2; if(depth>1) depth = depth/2; } delete [] tmpdata; } else { // Run through this process to pregenerate mipmap piramid for(size_t mip=0; mip<=mNumMipmaps; mip++) { // Normal formats switch(mTextureType) { case TEX_TYPE_1D: glTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case TEX_TYPE_2D: glTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case TEX_TYPE_3D: glTexImage3D(GL_TEXTURE_3D, mip, format, width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case TEX_TYPE_CUBE_MAP: for(int face=0; face<6; face++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } break; }; if(width>1) width = width/2; if(height>1) height = height/2; if(depth>1) depth = depth/2; } } _createSurfaceList(); // Get final internal format mFormat = getBuffer(0,0)->getFormat(); }
static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, int depth, char err_out[256]) { GPUTexture *tex; GLenum type, format, internalformat; void *pixels = NULL; if (depth && !GLEW_ARB_depth_texture) return NULL; tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture"); tex->w = w; tex->h = h; tex->number = -1; tex->refcount = 1; tex->target = (n == 1)? GL_TEXTURE_1D: GL_TEXTURE_2D; tex->depth = depth; glGenTextures(1, &tex->bindcode); if (!tex->bindcode) { if (err_out) { BLI_snprintf(err_out, 256, "GPUTexture: texture create failed: %d", (int)glGetError()); } else { fprintf(stderr, "GPUTexture: texture create failed: %d\n", (int)glGetError()); } GPU_texture_free(tex); return NULL; } if (!GPU_non_power_of_two_support()) { tex->w = power_of_2_max_i(tex->w); tex->h = power_of_2_max_i(tex->h); } tex->number = 0; glBindTexture(tex->target, tex->bindcode); if (depth) { type = GL_UNSIGNED_BYTE; format = GL_DEPTH_COMPONENT; internalformat = GL_DEPTH_COMPONENT; } else { type = GL_UNSIGNED_BYTE; format = GL_RGBA; internalformat = GL_RGBA8; if (fpixels) pixels = GPU_texture_convert_pixels(w*h, fpixels); } if (tex->target == GL_TEXTURE_1D) { glTexImage1D(tex->target, 0, internalformat, tex->w, 0, format, type, NULL); if (fpixels) { glTexSubImage1D(tex->target, 0, 0, w, format, type, pixels? pixels: fpixels); if (tex->w > w) GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, 1); } } else { glTexImage2D(tex->target, 0, internalformat, tex->w, tex->h, 0, format, type, NULL); if (fpixels) { glTexSubImage2D(tex->target, 0, 0, 0, w, h, format, type, pixels? pixels: fpixels); if (tex->w > w) GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h); if (tex->h > h) GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h-h); } } if (pixels) MEM_freeN(pixels); if (depth) { glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(tex->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(tex->target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); glTexParameteri(tex->target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY); } else { glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(tex->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (tex->target != GL_TEXTURE_1D) { /* CLAMP_TO_BORDER is an OpenGL 1.3 core feature */ GLenum wrapmode = (depth || tex->h == 1)? GL_CLAMP_TO_EDGE: GL_CLAMP_TO_BORDER; glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, wrapmode); glTexParameteri(tex->target, GL_TEXTURE_WRAP_T, wrapmode); #if 0 float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor); #endif } else glTexParameteri(tex->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); return tex; }
//-- void CgShaderCel::GenerateTextures() { float afBuf[256]; // [rad] Create/Generate diffuse 1D texture glGenTextures(1, &m_glIDTextureDiffuse); glBindTexture(GL_TEXTURE_1D, m_glIDTextureDiffuse); for(int iIndex = 0; iIndex < 256; iIndex++) { if(iIndex < 118) { afBuf[iIndex] = 75.0f / 255.0f; //afBuf[iIndex] = 125.0f / 255.0f; } else if(iIndex < 180) { afBuf[iIndex] = 150.0f / 255.0f; //afBuf[iIndex] = 200.0f / 255.0f; } else if(iIndex < 230) { afBuf[iIndex] = 170.0f / 255.0f; //afBuf[iIndex] = 220.0f / 255.0f; } else { afBuf[iIndex] = 250.0f / 255.0f; //afBuf[iIndex] = 250.0f / 255.0f; } } glTexImage1D(GL_TEXTURE_1D, 0, GL_INTENSITY16, 256, 0, GL_LUMINANCE, GL_FLOAT, &afBuf); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_1D, 0); // [rad] Create/Generate specular 1D texture glGenTextures(1, &m_glIDTextureSpecular); glBindTexture(GL_TEXTURE_1D, m_glIDTextureSpecular); for(int iIndex = 0; iIndex < 256; iIndex++) { //if(iIndex < 192) if(iIndex < 128) { afBuf[iIndex] = 0.0f; } else { afBuf[iIndex] = 1.0f; } } glTexImage1D(GL_TEXTURE_1D, 0, GL_INTENSITY16, 256, 0, GL_LUMINANCE, GL_FLOAT, &afBuf); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_1D, 0); // [rad] Create/Generate edge 1D texture glGenTextures(1, &m_glIDTextureOutline); glBindTexture(GL_TEXTURE_1D, m_glIDTextureOutline); for(int iIndex = 0; iIndex < 256; iIndex++) { if(iIndex < 50) { afBuf[iIndex] = 0.0f; } else { afBuf[iIndex] = 1.0f; } } glTexImage1D(GL_TEXTURE_1D, 0, GL_INTENSITY16, 256, 0, GL_LUMINANCE, GL_FLOAT, &afBuf); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_1D, 0); }
/* * @~English * @brief Load a GL texture object from a ktxStream. * * This function will unpack compressed GL_ETC1_RGB8_OES and GL_ETC2_* format * textures in software when the format is not supported by the GL context, * provided the library has been compiled with SUPPORT_SOFTWARE_ETC_UNPACK * defined as 1. * * It will also convert textures with legacy formats to their modern equivalents * when the format is not supported by the GL context, provided that the library * has been compiled with SUPPORT_LEGACY_FORMAT_CONVERSION defined as 1. * * @param [in] stream pointer to the ktxStream from which to load. * @param [in,out] pTexture name of the GL texture to load. If NULL or if * <tt>*pTexture == 0</tt> the function will generate * a texture name. The function binds either the * generated name or the name given in @p *pTexture * to the texture target returned in @p *pTarget, * before loading the texture data. If @p pTexture * is not NULL and a name was generated, the generated * name will be returned in *pTexture. * @param [out] pTarget @p *pTarget is set to the texture target used. The * target is chosen based on the file contents. * @param [out] pDimensions If @p pDimensions is not NULL, the width, height and * depth of the texture's base level are returned in the * fields of the KTX_dimensions structure to which it points. * @param [out] pIsMipmapped * If @p pIsMipmapped is not NULL, @p *pIsMipmapped is set * to GL_TRUE if the KTX texture is mipmapped, GL_FALSE * otherwise. * @param [out] pGlerror @p *pGlerror is set to the value returned by * glGetError when this function returns the error * KTX_GL_ERROR. glerror can be NULL. * @param [in,out] pKvdLen If not NULL, @p *pKvdLen is set to the number of bytes * of key-value data pointed at by @p *ppKvd. Must not be * NULL, if @p ppKvd is not NULL. * @param [in,out] ppKvd If not NULL, @p *ppKvd is set to the point to a block of * memory containing key-value data read from the file. * The application is responsible for freeing the memory. * * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_INVALID_VALUE @p target is @c NULL or the size of a mip * level is greater than the size of the * preceding level. * @exception KTX_INVALID_OPERATION @p ppKvd is not NULL but pKvdLen is NULL. * @exception KTX_UNEXPECTED_END_OF_FILE the file does not contain the * expected amount of data. * @exception KTX_OUT_OF_MEMORY Sufficient memory could not be allocated to store * the requested key-value data. * @exception KTX_GL_ERROR A GL error was raised by glBindTexture, * glGenTextures or gl*TexImage*. The GL error * will be returned in @p *glerror, if glerror * is not @c NULL. */ static KTX_error_code ktxLoadTextureS(struct ktxStream* stream, GLuint* pTexture, GLenum* pTarget, KTX_dimensions* pDimensions, GLboolean* pIsMipmapped, GLenum* pGlerror, unsigned int* pKvdLen, unsigned char** ppKvd) { GLint previousUnpackAlignment; KTX_header header; KTX_texinfo texinfo; void* data = NULL; khronos_uint32_t dataSize = 0; GLuint texname; int texnameUser; khronos_uint32_t faceLodSize; khronos_uint32_t faceLodSizeRounded; khronos_uint32_t level; khronos_uint32_t face; GLenum glFormat, glInternalFormat; KTX_error_code errorCode = KTX_SUCCESS; GLenum errorTmp; if (pGlerror) *pGlerror = GL_NO_ERROR; if (ppKvd) { *ppKvd = NULL; } if (!stream || !stream->read || !stream->skip) { return KTX_INVALID_VALUE; } if (!pTarget) { return KTX_INVALID_VALUE; } if (!stream->read(&header, KTX_HEADER_SIZE, stream->src)) { return KTX_UNEXPECTED_END_OF_FILE; } errorCode = _ktxCheckHeader(&header, &texinfo); if (errorCode != KTX_SUCCESS) { return errorCode; } if (ppKvd) { if (pKvdLen == NULL) return KTX_INVALID_OPERATION; *pKvdLen = header.bytesOfKeyValueData; if (*pKvdLen) { *ppKvd = (unsigned char*)malloc(*pKvdLen); if (*ppKvd == NULL) return KTX_OUT_OF_MEMORY; if (!stream->read(*ppKvd, *pKvdLen, stream->src)) { free(*ppKvd); *ppKvd = NULL; return KTX_UNEXPECTED_END_OF_FILE; } } } else { /* skip key/value metadata */ if (!stream->skip((long)header.bytesOfKeyValueData, stream->src)) { return KTX_UNEXPECTED_END_OF_FILE; } } if (contextProfile == 0) discoverContextCapabilities(); /* KTX files require an unpack alignment of 4 */ glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousUnpackAlignment); if (previousUnpackAlignment != KTX_GL_UNPACK_ALIGNMENT) { glPixelStorei(GL_UNPACK_ALIGNMENT, KTX_GL_UNPACK_ALIGNMENT); } texnameUser = pTexture && *pTexture; if (texnameUser) { texname = *pTexture; } else { glGenTextures(1, &texname); } glBindTexture(texinfo.glTarget, texname); // Prefer glGenerateMipmaps over GL_GENERATE_MIPMAP if (texinfo.generateMipmaps && (glGenerateMipmap == NULL)) { glTexParameteri(texinfo.glTarget, GL_GENERATE_MIPMAP, GL_TRUE); } if (texinfo.glTarget == GL_TEXTURE_CUBE_MAP) { texinfo.glTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; } glInternalFormat = header.glInternalFormat; glFormat = header.glFormat; if (!texinfo.compressed) { #if SUPPORT_LEGACY_FORMAT_CONVERSION // If sized legacy formats are supported there is no need to convert. // If only unsized formats are supported, there is no point in converting // as the modern formats aren't supported either. if (sizedFormats == _NON_LEGACY_FORMATS && supportsSwizzle) { convertFormat(texinfo.glTarget, &glFormat, &glInternalFormat); errorTmp = glGetError(); } else if (sizedFormats == _NO_SIZED_FORMATS) glInternalFormat = header.glBaseInternalFormat; #else // When no sized formats are supported, or legacy sized formats are not // supported, must change internal format. if (sizedFormats == _NO_SIZED_FORMATS || (!(sizedFormats & _LEGACY_FORMATS) && (header.glBaseInternalFormat == GL_ALPHA || header.glBaseInternalFormat == GL_LUMINANCE || header.glBaseInternalFormat == GL_LUMINANCE_ALPHA || header.glBaseInternalFormat == GL_INTENSITY))) { glInternalFormat = header.glBaseInternalFormat; } #endif } for (level = 0; level < header.numberOfMipmapLevels; ++level) { GLsizei pixelWidth = MAX(1, header.pixelWidth >> level); GLsizei pixelHeight = MAX(1, header.pixelHeight >> level); GLsizei pixelDepth = MAX(1, header.pixelDepth >> level); if (!stream->read(&faceLodSize, sizeof(khronos_uint32_t), stream->src)) { errorCode = KTX_UNEXPECTED_END_OF_FILE; goto cleanup; } if (header.endianness == KTX_ENDIAN_REF_REV) { _ktxSwapEndian32(&faceLodSize, 1); } faceLodSizeRounded = (faceLodSize + 3) & ~(khronos_uint32_t)3; if (!data) { /* allocate memory sufficient for the first level */ data = malloc(faceLodSizeRounded); if (!data) { errorCode = KTX_OUT_OF_MEMORY; goto cleanup; } dataSize = faceLodSizeRounded; } else if (dataSize < faceLodSizeRounded) { /* subsequent levels cannot be larger than the first level */ errorCode = KTX_INVALID_VALUE; goto cleanup; } for (face = 0; face < header.numberOfFaces; ++face) { if (!stream->read(data, faceLodSizeRounded, stream->src)) { errorCode = KTX_UNEXPECTED_END_OF_FILE; goto cleanup; } /* Perform endianness conversion on texture data */ if (header.endianness == KTX_ENDIAN_REF_REV && header.glTypeSize == 2) { _ktxSwapEndian16((khronos_uint16_t*)data, faceLodSize / 2); } else if (header.endianness == KTX_ENDIAN_REF_REV && header.glTypeSize == 4) { _ktxSwapEndian32((khronos_uint32_t*)data, faceLodSize / 4); } if (texinfo.textureDimensions == 1) { if (texinfo.compressed) { glCompressedTexImage1D(texinfo.glTarget + face, level, glInternalFormat, pixelWidth, 0, faceLodSize, data); } else { glTexImage1D(texinfo.glTarget + face, level, glInternalFormat, pixelWidth, 0, glFormat, header.glType, data); } } else if (texinfo.textureDimensions == 2) { if (header.numberOfArrayElements) { pixelHeight = header.numberOfArrayElements; } if (texinfo.compressed) { // It is simpler to just attempt to load the format, rather than divine which // formats are supported by the implementation. In the event of an error, // software unpacking can be attempted. glCompressedTexImage2D(texinfo.glTarget + face, level, glInternalFormat, pixelWidth, pixelHeight, 0, faceLodSize, data); } else { glTexImage2D(texinfo.glTarget + face, level, glInternalFormat, pixelWidth, pixelHeight, 0, glFormat, header.glType, data); } } else if (texinfo.textureDimensions == 3) { if (header.numberOfArrayElements) { pixelDepth = header.numberOfArrayElements; } if (texinfo.compressed) { glCompressedTexImage3D(texinfo.glTarget + face, level, glInternalFormat, pixelWidth, pixelHeight, pixelDepth, 0, faceLodSize, data); } else { glTexImage3D(texinfo.glTarget + face, level, glInternalFormat, pixelWidth, pixelHeight, pixelDepth, 0, glFormat, header.glType, data); } } errorTmp = glGetError(); #if SUPPORT_SOFTWARE_ETC_UNPACK // Renderion is returning INVALID_VALUE. Oops!! if ((errorTmp == GL_INVALID_ENUM || errorTmp == GL_INVALID_VALUE) && texinfo.compressed && texinfo.textureDimensions == 2 && (glInternalFormat == GL_ETC1_RGB8_OES || (glInternalFormat >= GL_COMPRESSED_R11_EAC && glInternalFormat <= GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC))) { GLubyte* unpacked; GLenum format, internalFormat, type; errorCode = _ktxUnpackETC((GLubyte*)data, glInternalFormat, pixelWidth, pixelHeight, &unpacked, &format, &internalFormat, &type, R16Formats, supportsSRGB); if (errorCode != KTX_SUCCESS) { goto cleanup; } if (!sizedFormats & _NON_LEGACY_FORMATS) { if (internalFormat == GL_RGB8) internalFormat = GL_RGB; else if (internalFormat == GL_RGBA8) internalFormat = GL_RGBA; } glTexImage2D(texinfo.glTarget + face, level, internalFormat, pixelWidth, pixelHeight, 0, format, type, unpacked); free(unpacked); errorTmp = glGetError(); } #endif if (errorTmp != GL_NO_ERROR) { if (pGlerror) *pGlerror = errorTmp; errorCode = KTX_GL_ERROR; goto cleanup; } } } cleanup: free(data); /* restore previous GL state */ if (previousUnpackAlignment != KTX_GL_UNPACK_ALIGNMENT) { glPixelStorei(GL_UNPACK_ALIGNMENT, previousUnpackAlignment); } if (errorCode == KTX_SUCCESS) { if (texinfo.generateMipmaps && glGenerateMipmap) { glGenerateMipmap(texinfo.glTarget); } *pTarget = texinfo.glTarget; if (pTexture) { *pTexture = texname; } if (pDimensions) { pDimensions->width = header.pixelWidth; pDimensions->height = header.pixelHeight; pDimensions->depth = header.pixelDepth; } if (pIsMipmapped) { if (texinfo.generateMipmaps || header.numberOfMipmapLevels > 1) *pIsMipmapped = GL_TRUE; else *pIsMipmapped = GL_FALSE; } } else { if (ppKvd && *ppKvd) { free(*ppKvd); *ppKvd = NULL; } if (!texnameUser) { glDeleteTextures(1, &texname); } } return errorCode; }
void GL1TextureProvider::create(int new_width, int new_height, int new_depth, int array_size, TextureFormat texture_format, int levels) { throw_if_disposed(); GLint gl_internal_format; GLenum gl_pixel_format; to_opengl_textureformat(texture_format, gl_internal_format, gl_pixel_format); if ( (new_width > 32768) || (new_width < 1) ) { throw Exception("Invalid texture width in the GL1 target"); } if ( (texture_type == GL_TEXTURE_2D) || (texture_type == GL_TEXTURE_3D) ) { if ( (new_height > 32768) || (new_height < 1) ) { throw Exception("Invalid texture height in the GL1 target"); } } if ( texture_type == GL_TEXTURE_3D ) { if ( (new_depth > 32768) || (new_depth < 1) ) { throw Exception("Invalid texture depth in the GL1 target"); } } width = new_width; height = new_height; depth = new_depth; GL1TextureStateTracker state_tracker(texture_type, handle); #ifndef __ANDROID__ if (texture_type == GL_TEXTURE_1D) { pot_width = get_next_power_of_two(new_width); if (pot_width == new_width) { power_of_two_texture=true; } else { power_of_two_texture=false; } pot_ratio_width = (float) width / pot_width; glTexImage1D( GL_TEXTURE_1D, // target 0, // level gl_internal_format, // internalformat pot_width, // width 0, // border gl_pixel_format, // format GL_UNSIGNED_BYTE, // type (it really doesn't matter since nothing is uploaded) nullptr); // texels (0 to avoid uploading) } #endif if (texture_type == GL_TEXTURE_2D) { pot_width = get_next_power_of_two(new_width); pot_height = get_next_power_of_two(new_height); if ( (pot_width == new_width) && (pot_height == new_height)) { power_of_two_texture=true; } else { power_of_two_texture=false; } pot_ratio_width = (float) width / pot_width; pot_ratio_height = (float) height / pot_height; glTexImage2D( GL_TEXTURE_2D, // target 0, // level gl_internal_format, // internalformat pot_width, // width pot_height, // height 0, // border gl_pixel_format, // format GL_UNSIGNED_BYTE, // type (it really doesn't matter since nothing is uploaded) nullptr); // texels (0 to avoid uploading) // Clear the whole texture if it is npot if (!power_of_two_texture) { PixelBuffer image = PixelBuffer(pot_width, pot_height, tf_rgba8); void *data = image.get_data(); memset(data, 0, pot_width * pot_height * 4); GLenum format; GLenum type; to_opengl_pixelformat(image, format, type); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); const int bytesPerPixel = image.get_bytes_per_pixel(); #ifndef __ANDROID__ glPixelStorei(GL_UNPACK_ROW_LENGTH, image.get_pitch() / bytesPerPixel); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); #endif glTexImage2D( GL_TEXTURE_2D, // target 0, // level gl_internal_format, // internalformat pot_width, // width pot_height, // height 0, // border format, // format type, // type data); // texels } } else { pot_width = get_next_power_of_two(new_width); pot_height = get_next_power_of_two(new_height); pot_depth = get_next_power_of_two(new_depth); pot_ratio_width = (float) width / pot_width; pot_ratio_height = (float) height / pot_height; pot_ratio_depth = (float) depth / pot_depth; if ( (pot_width == new_width) && (pot_height == new_height) && (pot_depth == new_depth)) { power_of_two_texture=true; } else { power_of_two_texture=false; } glTexImage3D( GL_TEXTURE_3D, // target 0, // level gl_internal_format, // internalformat pot_width, // width pot_height, // height pot_depth, // depth 0, // border gl_pixel_format, // format GL_UNSIGNED_BYTE, // type (it really doesn't matter since nothing is uploaded) nullptr); // texels (0 to avoid uploading) } }
/** * Create a texture image with reference values. Draw a textured quad. * Save reference image with glReadPixels(). * Loop: * replace a sub-region of the texture image with same values * draw test textured quad * read test image with glReadPixels * compare reference image to test image * \param target GL_TEXTURE_1D/2D/3D * \param intFormat the internal texture format */ static GLboolean test_format(GLenum target, GLenum intFormat) { const GLenum srcFormat = GL_RGBA; GLuint w = 128, h = 64, d = 8; GLuint tex, i, j, k, n, t; GLubyte *img, *ref, *testImg; GLboolean pass = GL_TRUE; GLuint bw, bh, wMask, hMask, dMask; get_format_block_size(intFormat, &bw, &bh); wMask = ~(bw-1); hMask = ~(bh-1); dMask = ~0; if (target != GL_TEXTURE_3D) d = 1; if (target == GL_TEXTURE_1D) h = 1; img = (GLubyte *) malloc(w * h * d * 4); ref = (GLubyte *) malloc(w * h * d * 4); testImg = (GLubyte *) malloc(w * h * d * 4); /* fill source tex image */ n = 0; for (i = 0; i < d; i++) { for (j = 0; j < h; j++) { for (k = 0; k < w; k++) { img[n++] = j * 4; img[n++] = k * 2; img[n++] = i * 16; img[n++] = 255; } } } glPixelStorei(GL_UNPACK_ROW_LENGTH, w); glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, h); glGenTextures(1, &tex); glBindTexture(target, tex); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); if (target == GL_TEXTURE_1D) { glTexImage1D(target, 0, intFormat, w, 0, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_2D) { glTexImage2D(target, 0, intFormat, w, h, 0, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_3D) { glTexImage3D(target, 0, intFormat, w, h, d, 0, srcFormat, GL_UNSIGNED_BYTE, img); } glEnable(target); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); /* draw reference image */ glClear(GL_COLOR_BUFFER_BIT); piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ref); for (t = 0; t < 10; t++) { /* Choose random region of texture to update. * Use sizes and positions that are multiples of * the compressed block size. */ GLint tw = (rand() % w) & wMask; GLint th = (rand() % h) & hMask; GLint td = (rand() % d) & dMask; GLint tx = (rand() % (w - tw)) & wMask; GLint ty = (rand() % (h - th)) & hMask; GLint tz = (rand() % (d - td)) & dMask; assert(tx + tw <= w); assert(ty + th <= h); assert(tz + td <= d); /* replace texture region (with same data) */ glPixelStorei(GL_UNPACK_SKIP_PIXELS, tx); glPixelStorei(GL_UNPACK_SKIP_ROWS, ty); glPixelStorei(GL_UNPACK_SKIP_IMAGES, tz); if (target == GL_TEXTURE_1D) { glTexSubImage1D(target, 0, tx, tw, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_2D) { glTexSubImage2D(target, 0, tx, ty, tw, th, srcFormat, GL_UNSIGNED_BYTE, img); } else if (target == GL_TEXTURE_2D) { glTexSubImage3D(target, 0, tx, ty, tz, tw, th, td, srcFormat, GL_UNSIGNED_BYTE, img); } /* draw test image */ glClear(GL_COLOR_BUFFER_BIT); piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0); glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, testImg); glutSwapBuffers(); if (!equal_images(ref, testImg, w, h)) { printf("texsubimage failed\n"); printf(" target: 0x%x\n", target); printf(" internal format: 0x%x\n", intFormat); printf(" region: %d, %d %d x %d\n", tx, ty, tw, th); pass = GL_FALSE; break; } } glDisable(target); free(img); free(ref); free(testImg); glDeleteTextures(1, &tex); return pass; }
void VisibilityExtractionDemo::init() { window = generateWindow(); // load a file std::vector<std::string> paths; //paths.push_back("/home/nlichtenberg/1crn.pdb"); paths.push_back("/home/nlichtenberg/1vis.pdb"); //paths.push_back("/home/nlichtenberg/Develop/Mol_Sandbox/resources/TrajectoryFiles/1aon.pdb"); MdTrajWrapper mdwrap; std::auto_ptr<Protein> prot = mdwrap.load(paths); impSph = new ImpostorSpheres(!useAtomicCounters, false); impSph->setProteinData(prot.get()); impSph->init(); num_balls = impSph->num_balls; if(perspectiveProj) projection = perspective(45.0f, getRatio(window), 0.1f, 100.0f); else projection = ortho(-30.0f, 30.0f, -30.0f, 30.0f, 0.0f, 100.0f); if (useAtomicCounters) { spRenderImpostor = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_InstancedUA.vert", "/VisibleAtomsDetection/Detection/solidColorInstanceCount.frag"); spRenderDiscs = ShaderProgram("/VisibleAtomsDetection//Impostor/impostorSpheres_InstancedUA.vert", "/VisibleAtomsDetection//Impostor/impostorSpheres_discardFragments_Instanced.frag"); if(perspectiveProj) spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Base/modelViewProjectionInstancedUA.vert", "/VisibleAtomsDetection/Impostor/Impostor3DSphere.frag"); else spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Base/modelViewProjectionInstancedUA.vert", "/VisibleAtomsDetection/Impostor/Impostor3DSphere_Ortho.frag"); } else { spRenderImpostor = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert", "/VisibleAtomsDetection/Detection/solidColorInstanceCount.frag"); spRenderDiscs = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert", "/VisibleAtomsDetection/Impostor/impostorSpheres_discardFragments_Instanced.frag"); spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert", "/VisibleAtomsDetection/Impostor/Impostor3DSphere.frag"); } /// Renderpass to render impostors/fake geometry renderBalls = new RenderPass( impSph, &spRenderBalls, getWidth(window), getHeight(window)); renderBalls->update("projection", projection); // define projection matrix for other shader programs renderBalls->setShaderProgram(&spRenderDiscs); renderBalls->update("projection", projection); renderBalls->setShaderProgram(&spRenderImpostor); renderBalls->update("projection", projection); /// Renderpass to detect the visible instances collectSurfaceIDs = new RenderPass( new Quad(), new ShaderProgram("/VisibleAtomsDetection/Base/fullscreen.vert", "/VisibleAtomsDetection/Detection/DetectVisibleInstanceIDs.frag"), getWidth(window), getHeight(window)); // prepare 1D buffer for entries tex_collectedIDsBuffer = new Texture(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_INT); tex_collectedIDsBuffer->genUimageBuffer(num_balls); collectSurfaceIDs->texture("collectedIDsBuffer", tex_collectedIDsBuffer); collectSurfaceIDs->texture("tex", renderBalls->get("InstanceID")); /// renderpass to display result frame result = new RenderPass( new Quad(), new ShaderProgram("/VisibleAtomsDetection/Base/fullscreen.vert", "/VisibleAtomsDetection/Detection/toneMapperLinearInstanceCount.frag")); result->texture("tex", renderBalls->get("fragColor")); /// compute shader to process a list of visible IDs (with the actual instanceID of the first general draw) computeSortedIDs = new ComputeProgram(new ShaderProgram("/VisibleAtomsDetection/Detection/CreateVisibleIDList.comp")); // 1D buffer for visible IDs tex_sortedVisibleIDsBuffer = new Texture(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT); tex_sortedVisibleIDsBuffer->genUimageBuffer(num_balls); computeSortedIDs->texture("collectedIDsBuffer", tex_collectedIDsBuffer); computeSortedIDs->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); // atomic counter buffer for consecutive index access in compute shader glGenBuffers(1, &atomBuff); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 3, atomBuff); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); positions_size = sizeof(glm::vec4) * impSph->instance_positions_s.instance_positions.size(); colors_size = sizeof(glm::vec4) * impSph->instance_colors_s.instance_colors.size(); // SSBO setup glGenBuffers(2, SSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); glBufferData(GL_SHADER_STORAGE_BUFFER, positions_size, &impSph->instance_positions_s.instance_positions[0], GL_DYNAMIC_COPY); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, SSBO[0], 0, positions_size); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); glBufferData(GL_SHADER_STORAGE_BUFFER, colors_size, &impSph->instance_colors_s.instance_colors[0], GL_DYNAMIC_COPY); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, SSBO[1], 0, colors_size); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // SSBO copy data glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); GLvoid* p_ = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); memcpy(p_, &impSph->instance_positions_s.instance_positions[0], positions_size); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); p_ = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); memcpy(p_, &impSph->instance_colors_s.instance_colors[0], colors_size); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // SSBO bind to shaders glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); GLuint block_index = 0; block_index = glGetProgramResourceIndex(spRenderBalls.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); block_index = glGetProgramResourceIndex(spRenderBalls.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); block_index = glGetProgramResourceIndex(spRenderDiscs.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); block_index = glGetProgramResourceIndex(spRenderDiscs.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); block_index = glGetProgramResourceIndex(spRenderImpostor.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); block_index = glGetProgramResourceIndex(spRenderImpostor.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1); // prepare data to reset the buffer that holds the visible instance IDs int byteCount = sizeof(unsigned int)* num_balls; zeros = new unsigned char[byteCount]; unsigned int f = 0; unsigned char const * p = reinterpret_cast<unsigned char const *>(&f); for (int i = 0; i < byteCount; i+=4) { zeros[i] = p[0]; zeros[i+1] = p[1]; zeros[i+2] = p[2]; zeros[i+3] = p[3]; } // prepare buffer with index = value // used to draw all istances identityInstancesMap.clear(); for (GLuint i = 0; i < num_balls; i++) identityInstancesMap.push_back(i); glBindTexture(GL_TEXTURE_1D, tex_sortedVisibleIDsBuffer->getHandle()); glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]); // map to set all instances visible mapAllVisible.resize(num_balls); std::fill(mapAllVisible.begin(), mapAllVisible.end(), 1); // time query GLuint timeQuery; glGenQueries(1, &timeQuery); glEnable(GL_DEPTH_TEST); }
/////////////////////////////////////////////////////////////////////////////// // OpenGL related startup code is safe to put here. Load textures, etc. void SetupRC(void) { GLfloat texCoordOffsets[4][5*5*2]; GLfloat exposureLUT[20] = { 11.0, 6.0, 3.2, 2.8, 2.2, 1.90, 1.80, 1.80, 1.70, 1.70, 1.60, 1.60, 1.50, 1.50, 1.40, 1.40, 1.30, 1.20, 1.10, 1.00 }; // Make sure OpenGL entry points are set GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); } // Will not use depth buffer glDisable(GL_DEPTH_TEST); curHDRTex = 0; // Init codel-view and leave it modelViewMatrix.LoadIdentity(); // Black glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Setup LUT texture for use with the adaptive exposure filter glGenTextures(1, lutTxtures); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_1D, lutTxtures[1]); glTexImage1D(GL_TEXTURE_1D, 0, GL_R16F, 20, 0, GL_RED, GL_FLOAT, exposureLUT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Setup HDR texture(s) glActiveTexture(GL_TEXTURE0); glGenTextures(1, hdrTextures); glBindTexture(GL_TEXTURE_2D, hdrTextures[curHDRTex]); // Load HDR image from EXR file LoadOpenEXRImage("Tree.exr", hdrTextures[curHDRTex], hdrTexturesWidth[curHDRTex], hdrTexturesHeight[curHDRTex]); // Create ortho matrix and screen-sized quad matching images aspect ratio GenerateOrtho2DMat(screenWidth, screenHeight, hdrTexturesWidth[curHDRTex], hdrTexturesHeight[curHDRTex]); //GenerateFBOOrtho2DMat(hdrTexturesWidth[curHDRTex], hdrTexturesHeight[curHDRTex]); gltGenerateOrtho2DMat(hdrTexturesWidth[curHDRTex], hdrTexturesHeight[curHDRTex], fboOrthoMatrix, fboQuad); // Setup tex coords to be used for fetching HDR kernel data for (int k = 0; k < 4; k++) { float xInc = 1.0f / (GLfloat)(hdrTexturesWidth[curHDRTex] >> k); float yInc = 1.0f / (GLfloat)(hdrTexturesHeight[curHDRTex] >> k); for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { texCoordOffsets[k][(((i*5)+j)*2)+0] = (-1.0f * xInc) + ((GLfloat)i * xInc); texCoordOffsets[k][(((i*5)+j)*2)+1] = (-1.0f * yInc) + ((GLfloat)j * yInc); } } } // Load shaders mapTexProg = gltLoadShaderPairWithAttributes("hdr.vs", "hdr_simple.fs", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0"); glBindFragDataLocation(mapTexProg, 0, "oColor"); glLinkProgram(mapTexProg); varExposureProg = gltLoadShaderPairWithAttributes("hdr.vs", "hdr_exposure_image.fs", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0"); glBindFragDataLocation(varExposureProg, 0, "oColor"); glLinkProgram(varExposureProg); glUseProgram(varExposureProg); glUniform1i(glGetUniformLocation(varExposureProg, "textureUnit0"), 0); adaptiveProg = gltLoadShaderPairWithAttributes("hdr.vs", "hdr_adaptive.fs", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0"); glBindFragDataLocation(adaptiveProg, 0, "oColor"); glLinkProgram(adaptiveProg); glUseProgram(adaptiveProg); glUniform1i(glGetUniformLocation(adaptiveProg, "textureUnit0"), 0); glUniform1i(glGetUniformLocation(adaptiveProg, "textureUnit1"), 1); glUniform2fv(glGetUniformLocation(adaptiveProg, "tc_offset"), 25, texCoordOffsets[0]); glUseProgram(0); // Create and bind an FBO glGenFramebuffers(1,&fboName); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboName); // Create the FBO texture glGenTextures(1, fboTextures); glBindTexture(GL_TEXTURE_2D, fboTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, hdrTexturesWidth[curHDRTex], hdrTexturesHeight[curHDRTex], 0, GL_RGBA, GL_FLOAT, NULL); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTextures[0], 0); // Make sure all went well gltCheckErrors(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Set first running mode curProg = adaptiveProg; }
// Creation / loading methods void GL3PlusTexture::createInternalResourcesImpl(void) { // set HardwareBuffer::Usage for TU_RENDERTARGET if nothing else specified if((mUsage & TU_RENDERTARGET) && (mUsage & ~TU_RENDERTARGET) == 0) mUsage |= HardwareBuffer::HBU_DYNAMIC; // Adjust format if required. mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); // Check requested number of mipmaps. uint32 maxMips = getMaxMipmaps(); if (PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0)) mNumRequestedMipmaps = 0; mNumMipmaps = mNumRequestedMipmaps; if (mNumMipmaps > maxMips) mNumMipmaps = maxMips; // Create a texture object and identify its GL type. OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID)); GLenum texTarget = getGL3PlusTextureTarget(); // Calculate size for all mip levels of the texture. uint32 width, height, depth; if ((mWidth * PixelUtil::getNumElemBytes(mFormat)) & 3) { // Standard alignment of 4 is not right for some formats. OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); } // Bind texture object to its type, making it the active texture object // for that type. mRenderSystem->_getStateCacheManager()->bindGLTexture( texTarget, mTextureID ); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, mNumMipmaps); // Set some misc default parameters, these can of course be changed later. mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Set up texture swizzling. mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); if (PixelUtil::isLuminance(mFormat) && (mRenderSystem->hasMinGLVersion(3, 3) || mRenderSystem->checkExtension("GL_ARB_texture_swizzle"))) { if (PixelUtil::getComponentCount(mFormat) == 2) { mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN); } else { mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED); mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ONE); } } GLenum format = GL3PlusPixelUtil::getGLInternalFormat(mFormat, mHwGamma); GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat); width = mWidth; height = mHeight; depth = mDepth; // Allocate texture storage so that glTexSubImageXD can be // used to upload the texture. if (PixelUtil::isCompressed(mFormat)) { // Compressed formats GLsizei size; for (uint32 mip = 0; mip <= mNumMipmaps; mip++) { size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat)); // std::stringstream str; // str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID) // << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat)) // << " Mip: " + StringConverter::toString(mip) // << " Width: " << StringConverter::toString(width) // << " Height: " << StringConverter::toString(height) // << " Format " << PixelUtil::getFormatName(mFormat) // << " Internal Format: 0x" << std::hex << format // << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat) // << " Data type: 0x" << std::hex << datatype; // LogManager::getSingleton().logMessage(LML_NORMAL, str.str()); switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, size, NULL)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, size, NULL)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, size, NULL)); break; case TEX_TYPE_2D_ARRAY: case TEX_TYPE_3D: OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format, width, height, depth, 0, size, NULL)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, size, NULL)); } break; default: break; }; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) { depth = depth / 2; } } } else { if (mRenderSystem->hasMinGLVersion(4, 2) || mRenderSystem->checkExtension("GL_ARB_texture_storage")) { switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glTexStorage1D(GL_TEXTURE_1D, GLsizei(mNumMipmaps+1), format, GLsizei(width))); break; case TEX_TYPE_2D: case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height))); break; case TEX_TYPE_CUBE_MAP: OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_CUBE_MAP, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height))); break; case TEX_TYPE_2D_ARRAY: OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_2D_ARRAY, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth))); break; case TEX_TYPE_3D: OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_3D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth))); break; } } else { GLenum originFormat = GL3PlusPixelUtil::getGLOriginFormat(mFormat); // Run through this process to pregenerate mipmap pyramid for(uint32 mip = 0; mip <= mNumMipmaps; mip++) { // std::stringstream str; // str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID) // << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(width, height, depth, mFormat)) // << " Mip: " + StringConverter::toString(mip) // << " Width: " << StringConverter::toString(width) // << " Height: " << StringConverter::toString(height) // << " Format " << PixelUtil::getFormatName(mFormat) // << " Internal Format: 0x" << std::hex << format // << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat) // << " Data type: 0x" << std::hex << datatype; // LogManager::getSingleton().logMessage(LML_NORMAL, str.str()); // Normal formats switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_3D: case TEX_TYPE_2D_ARRAY: OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format, width, height, depth, 0, originFormat, datatype, NULL)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, originFormat, datatype, NULL)); } break; default: break; }; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY) { depth = depth / 2; } } } } // Reset unpack alignment to defaults OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); _createSurfaceList(); // Generate mipmaps after all texture levels have been loaded // This is required for compressed formats such as DXT if (PixelUtil::isCompressed(mFormat) && mUsage & TU_AUTOMIPMAP) { OGRE_CHECK_GL_ERROR(glGenerateMipmap(getGL3PlusTextureTarget())); } // Get final internal format. mFormat = getBuffer(0,0)->getFormat(); }
void VisibilityExtractionDemo::run() { const GLuint zero = 0; render(window, [&] (float deltaTime) { numberOfFrames++; frameInterval += deltaTime; if (frameInterval > 1.0f) { fps = numberOfFrames / frameInterval; std::cout << "FPS: " << fps << std::endl; numberOfFrames = 0; frameInterval = 0.0f; } if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) (rotY - deltaTime < 0)? rotY -= deltaTime + 6.283 : rotY -= deltaTime; if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) (rotY + deltaTime > 6.283)? rotY += deltaTime - 6.283 : rotY += deltaTime; if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) (rotX - deltaTime < 0)? rotX -= deltaTime + 6.283 : rotX -= deltaTime; if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) (rotX + deltaTime > 6.283)? rotX += deltaTime - 6.283 : rotX += deltaTime; if (glfwGetKey(window, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS) distance += deltaTime * 50; if (glfwGetKey(window, GLFW_KEY_PAGE_UP) == GLFW_PRESS) distance = max(distance - deltaTime * 50, 0.0f); if (glfwGetKey(window, GLFW_KEY_PERIOD) == GLFW_PRESS) scale += deltaTime*4; if (glfwGetKey(window, GLFW_KEY_COMMA) == GLFW_PRESS) scale = glm::max(scale - deltaTime*4, 0.01f); if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {updateVisibilityMapLock = true; updateVisibilityMap = true;} if (glfwGetKey(window, GLFW_KEY_U) == GLFW_PRESS) updateVisibilityMapLock = false; if (glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) pingPongOff = false; if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) pingPongOff = true; if (glfwGetKey(window, GLFW_KEY_F11) == GLFW_PRESS) { vsync = !vsync; vsync ? glfwSwapInterval(1) : glfwSwapInterval(0); vsync ? std::cout << "VSync enabled\n" : std::cout << "VSync disabled\n"; } // Render impostor geometry if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderImpostor); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", 1.0f); result->texture("tex", renderBalls->get("fragColor")); } // Render impostor geometry as disc if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderDiscs); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", 1.0f); result->texture("tex", renderBalls->get("fragColor")); } // Render faked geometry if (glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderBalls); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", 1.0f); result->texture("tex", renderBalls->get("fragColor")); } // Render instance IDs geometry if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderBalls); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", float(impSph->num_balls)); result->texture("tex", renderBalls->get("InstanceID")); } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { if(animate) { animate = false; lastTime = glfwGetTime(); } else { animate = true; glfwSetTime(lastTime); } } if (animate) { elapsedTime = glfwGetTime(); if (elapsedTime > 628) { elapsedTime = 0; glfwSetTime(0); } } mat4 view = translate(mat4(1), vec3(0,0,-distance)) * eulerAngleXY(-rotX, -rotY); // reset the detected instance IDs glBindTexture(GL_TEXTURE_1D, tex_collectedIDsBuffer->getHandle()); glTexImage1D(GL_TEXTURE_1D, 0, GL_R8UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, zeros); //glBindTexture(GL_TEXTURE_1D, visibleIDsBuff->getHandle()); //glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff); glClearBufferSubData(GL_ATOMIC_COUNTER_BUFFER, GL_R32UI, 0, sizeof(GLuint), GL_RED_INTEGER, GL_UNSIGNED_INT, zero); renderBalls->clear(-1,-1,-1,-1); // the clear color may not interfere with the detected instance IDs renderBalls->clearDepth(); renderBalls->update("scale", vec2(scale)); renderBalls->update("view", view); renderBalls->update("probeRadius", probeRadius); renderBalls->run(); // Depending on user input: sort out instances for the next frame or not, // or lock the current set of visible instances if(useAtomicCounters) if (updateVisibilityMap && !pingPongOff) { // the following shaders in detectVisible look at what has been written to the screen (framebuffer0) // better render the instance stuff to a texture and read from there collectSurfaceIDs->run(); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT|GL_BUFFER_UPDATE_BARRIER_BIT); glBeginQuery(GL_TIME_ELAPSED, timeQuery); computeSortedIDs->run(16,1,1); // 16 work groups * 1024 work items = 16384 atoms and IDs glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT|GL_BUFFER_UPDATE_BARRIER_BIT); glEndQuery(GL_TIME_ELAPSED); glGetQueryObjectuiv(timeQuery, GL_QUERY_RESULT, &queryTime); std::cout << "compute shader time: " << queryTime << std::endl; // Check buffer data // GLuint visibilityMapFromBuff[ImpostorSpheres::num_balls]; // GLuint visibleIDsFromBuff[ImpostorSpheres::num_balls]; // glBindTexture(GL_TEXTURE_1D, bufferTex->getHandle()); // glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, visibilityMapFromBuff); // glBindTexture(GL_TEXTURE_1D, visibleIDsBuff->getHandle()); // glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, visibleIDsFromBuff); //get the value of the atomic counter glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff); GLuint* counterVal = (GLuint*) glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT ); glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); impSph->instancesToRender = *counterVal; std::cout << "Number of visible instances by atomic Counter: " << *counterVal << std::endl; updateVisibilityMap = false; }else { if(!updateVisibilityMapLock) { // ToDo // instead of uploading the data, swap the buffer glBindTexture(GL_TEXTURE_1D, tex_sortedVisibleIDsBuffer->getHandle()); glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]); impSph->instancesToRender = impSph->num_balls; updateVisibilityMap = true; // sort out every other frame } } else if (updateVisibilityMap && !pingPongOff) { collectSurfaceIDs->run(); // detect visible instances glBeginQuery(GL_TIME_ELAPSED, timeQuery); GLuint visibilityMapFromBuff[impSph->num_balls]; glBindTexture(GL_TEXTURE_1D, tex_collectedIDsBuffer->getHandle()); glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, visibilityMapFromBuff); // copy visible instance information to a vector with size = num_balls int num_vis = 0; std::vector<GLint> newMap; newMap.resize(num_balls); for (int i = 0; i < num_balls; i++) { newMap[i] = (int)visibilityMapFromBuff[i]; if(visibilityMapFromBuff[i] != 0) num_vis++; } glEndQuery(GL_TIME_ELAPSED); glGetQueryObjectuiv(timeQuery, GL_QUERY_RESULT, &queryTime); std::cout << "cpu time: " << queryTime << std::endl; // print number of visible instances std::cout << "Number of visible instances: " << num_vis << std::endl; impSph->updateVisibilityMap(newMap); updateVisibilityMap = false; }else { if(!updateVisibilityMapLock) { impSph->updateVisibilityMap(mapAllVisible); updateVisibilityMap = true; // sort out every other frame } } result->clear(num_balls,num_balls,num_balls,num_balls); result->run(); }); }
void Surface::init(unsigned w, unsigned h, unsigned d, GLenum ext_fmt, GLenum ext_type, GLvoid **ext_data) { if (gl_id > 0) { throw std::runtime_error("Already initialized"); } switch (desc.surface_type) { case SURF_NONE: throw std::invalid_argument("SURF_NONE"); case SURF_COLOUR: if (!desc.is_texture) return throw std::invalid_argument("Colour buffers must be textures"); break; case SURF_DEPTH: case SURF_STENCIL: case SURF_DEPTH_STENCIL: if (desc.is_texture) return throw std::invalid_argument("Stencil and depth buffers must not be textures"); break; } if (desc.is_texture) { if (desc.gl_tgt != GL_TEXTURE_RECTANGLE_ARB) { P2(w); P2(h); P2(d); } glGenTextures(1, &gl_id); glBindTexture(desc.gl_tgt, gl_id); glGetError(); if (ext_fmt == 0) ext_fmt = externalFormatForInternal(desc.gl_fmt); switch (desc.gl_tgt) { case GL_TEXTURE_1D: glTexImage1D(desc.gl_tgt, 0, desc.gl_fmt, w, 0, ext_fmt, ext_type, ext_data ? ext_data[0] : NULL); break; case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE_ARB: glTexImage2D(desc.gl_tgt, 0, desc.gl_fmt, w, h, 0, ext_fmt, ext_type, ext_data ? ext_data[0] : NULL); break; case GL_TEXTURE_CUBE_MAP: for (int i = 0; i < 6; ++i) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, desc.gl_fmt, w, h, 0, ext_fmt, ext_type, ext_data ? ext_data[i] : NULL); } break; case GL_TEXTURE_3D: glTexImage3D(desc.gl_tgt, 0, desc.gl_fmt, w, h, d, 0, ext_fmt, ext_type, ext_data ? ext_data[0] : NULL); break; } GLuint err = glGetError(); if (err) { glDeleteTextures(1, &gl_id); gl_id = 0; throw std::runtime_error("failed to initialize texture"); } if (desc.is_mipmapped) glGenerateMipmapEXT(desc.gl_tgt); desc.param.apply(desc.gl_tgt); glBindTexture(desc.gl_tgt, 0); } else { glGenRenderbuffersEXT(1, &gl_id); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, gl_id); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, desc.gl_fmt, w, h); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } width = w; height = h; depth = d; }
int gl_start(int width, int height, int req_depth, int FullScreen) { Uint32 flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL; GLubyte scanbuffer[256]; int i; flags |= (cvidmode == 16 ? SDL_RESIZABLE : 0); flags |= (FullScreen ? SDL_FULLSCREEN : 0); SurfaceX = width; SurfaceY = height; surface = SDL_SetVideoMode(SurfaceX, SurfaceY, req_depth, flags); if (surface == NULL) { fprintf(stderr, "Could not set %dx%d-GL video mode.\n", SurfaceX, SurfaceY); return FALSE; } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); glvidbuffer = (unsigned short *) malloc(512 * 512 * sizeof(short)); gl_clearwin(); SDL_WarpMouse(SurfaceX / 4, SurfaceY / 4); // Grab mouse in fullscreen mode FullScreen ? SDL_WM_GrabInput(SDL_GRAB_ON) : SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_WM_SetCaption("ZSNES", "ZSNES"); SDL_ShowCursor(0); /* Setup some GL stuff */ glEnable(GL_TEXTURE_1D); glEnable(GL_TEXTURE_2D); glViewport(0, 0, SurfaceX, SurfaceY); /* * gltextures[0]: 2D texture, 256x224 * gltextures[1]: 2D texture, Left half of 512x224 * gltextures[2]: 2D texture, Right half of 512x224 * gltextures[3]: 1D texture, 256 lines of alternating alpha */ glGenTextures(4, gltextures); /* Initialize the scanline texture (alternating opaque/transparent) */ for (i = 0; i < 256; i += 2) { scanbuffer[i] = 0xff; scanbuffer[i + 1] = 0; } glBindTexture(GL_TEXTURE_1D, gltextures[3]); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 256); glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE_ALPHA, 256, 0, GL_ALPHA, GL_UNSIGNED_BYTE, scanbuffer); return TRUE; }
// Creation / loading methods void GL3PlusTexture::createInternalResourcesImpl(void) { // Adjust format if required mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); // Check requested number of mipmaps size_t maxMips = GL3PlusPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); if(PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0)) mNumRequestedMipmaps = 0; mNumMipmaps = mNumRequestedMipmaps; if (mNumMipmaps > maxMips) mNumMipmaps = maxMips; // Generate texture name OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID)); GLenum texTarget = getGL3PlusTextureTarget(); // Set texture type OGRE_CHECK_GL_ERROR(glBindTexture(texTarget, mTextureID)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, (mMipmapsHardwareGenerated && (mUsage & TU_AUTOMIPMAP)) ? maxMips : mNumMipmaps )); // Set some misc default parameters, these can of course be changed later OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); // Set up texture swizzling if(mGLSupport.checkExtension("GL_ARB_texture_swizzle") || gl3wIsSupported(3, 3)) { OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA)); if(mFormat == PF_BYTE_LA) { OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN)); } else if(mFormat == PF_L8 || mFormat == PF_L16) { OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED)); OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_RED)); } } // If we can do automip generation and the user desires this, do so mMipmapsHardwareGenerated = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP); // Allocate internal buffer so that glTexSubImageXD can be used // Internal format GLenum format = GL3PlusPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat); size_t width = mWidth; size_t height = mHeight; size_t depth = mDepth; if (PixelUtil::isCompressed(mFormat)) { // Compressed formats size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat); // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not // accept a 0 pointer like normal glTexImageXD // Run through this process for every mipmap to pregenerate mipmap pyramid uint8* tmpdata = new uint8[size]; memset(tmpdata, 0, size); for (size_t mip = 0; mip <= mNumMipmaps; mip++) { size = PixelUtil::getMemorySize(width, height, depth, mFormat); switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, size, tmpdata)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, size, tmpdata)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, size, tmpdata)); break; case TEX_TYPE_2D_ARRAY: case TEX_TYPE_3D: OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format, width, height, depth, 0, size, tmpdata)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, size, tmpdata)); } break; default: break; }; // LogManager::getSingleton().logMessage("GL3PlusTexture::create - " + StringConverter::toString(mTextureID) + // " Mip: " + StringConverter::toString(mip) + // " Width: " + StringConverter::toString(width) + // " Height: " + StringConverter::toString(height) + // " Internal Format: " + StringConverter::toString(format) // ); if(width > 1) { width = width / 2; } if(height > 1) { height = height / 2; } if(depth > 1) { depth = depth / 2; } } delete [] tmpdata; } else { if((mGLSupport.checkExtension("GL_ARB_texture_storage") || gl3wIsSupported(4, 2)) && mTextureType == TEX_TYPE_2D) { OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLint(mNumMipmaps+1), format, GLsizei(width), GLsizei(height))); } else { // Run through this process to pregenerate mipmap pyramid for(size_t mip = 0; mip <= mNumMipmaps; mip++) { // Normal formats switch(mTextureType) { case TEX_TYPE_1D: OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, GL_RGBA, datatype, 0)); break; case TEX_TYPE_2D: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0)); break; case TEX_TYPE_2D_RECT: OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE, mip, format, width, height, 0, GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0)); break; case TEX_TYPE_3D: case TEX_TYPE_2D_ARRAY: OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format, width, height, depth, 0, GL_RGBA, datatype, 0)); break; case TEX_TYPE_CUBE_MAP: for(int face = 0; face < 6; face++) { OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0)); } break; default: break; }; if (width > 1) { width = width / 2; } if (height > 1) { height = height / 2; } if (depth > 1) { depth = depth / 2; } } } } _createSurfaceList(); // Get final internal format mFormat = getBuffer(0,0)->getFormat(); }
/** Test target params to glTexImage functions */ static GLboolean test_targets(void) { /* all of these should generate GL_INVALID_ENUM */ glTexImage1D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 0, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexImage2D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexImage2D", GL_INVALID_ENUM)) return GL_FALSE; glTexImage3D(GL_TEXTURE_1D, 0, GL_RGBA, 16, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexImage3D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage1D(GL_TEXTURE_2D, 0, 6, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage1D(GL_PROXY_TEXTURE_1D, 0, 6, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage2D(GL_PROXY_TEXTURE_2D, 0, 6, 6, 10, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glTexSubImage3D(GL_PROXY_TEXTURE_2D, 0, 6, 6, 6, 10, 10, 10, GL_RGBA, GL_FLOAT, NULL); if (!verify_error("glTexSubImage3D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexImage1D(GL_PROXY_TEXTURE_1D, 0, GL_RGBA, 4, 4, 16, 0); if (!verify_error("glCopyTexImage1D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, 4, 4, 16, 16, 0); if (!verify_error("glCopyTexImage2D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexImage2D(GL_TEXTURE_1D, 0, GL_RGBA, 4, 4, 16, 16, 0); if (!verify_error("glCopyTexImage2D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexSubImage1D(GL_PROXY_TEXTURE_1D, 0, 4, 4, 6, 10); if (!verify_error("glCopyTexSubImage1D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexSubImage2D(GL_PROXY_TEXTURE_2D, 0, 4, 4, 6, 6, 10, 10); if (!verify_error("glCopyTexSubImage2D", GL_INVALID_ENUM)) return GL_FALSE; glCopyTexSubImage3D(GL_PROXY_TEXTURE_3D, 0, 4, 4, 4, 6, 6, 10, 10); if (!verify_error("glCopyTexSubImage2D", GL_INVALID_ENUM)) return GL_FALSE; return GL_TRUE; }
CLLineStippleTexture::CLLineStippleTexture(const std::vector<unsigned int>& dasharray): mPatternLength(0), mTextureLength(0), mTextureName(0) { if (!dasharray.empty()) { std::vector<unsigned int>::const_iterator it = dasharray.begin(), endit = dasharray.end(); while (it != endit) { this->mPatternLength += *it; ++it; } // we only need to create a texture if the pattern length is not 0 if (this->mPatternLength != 0) { // the texture size should be a multiple of 2 unsigned int exponent = (unsigned int)ceil(log((double)this->mPatternLength) / log(2.0)); if (exponent <= 31) { this->mTextureLength = 1 << exponent; // make sure the texture name is really free this->mTextureName = 0; GLint w = -1; glTexImage1D(GL_PROXY_TEXTURE_1D, 0, GL_ALPHA, this->mTextureLength, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_WIDTH, &w); if (w != 0) { GLubyte* pTextureData = new GLubyte[this->mTextureLength]; // now we create the pattern it = dasharray.begin(); unsigned int i; bool gap = false; unsigned int index = 0; while (it != endit) { for (i = 0; i < *it; ++i) { // if it is a gap, we write 0, otherwise we write 255 pTextureData[index] = gap ? 0 : 255; ++index; } gap = !gap; ++it; } // fill the rest of the texture with 255 while (index < this->mTextureLength) { pTextureData[index++] = 70; } // now we load the texture data into OpenGL glGenTextures(1, &this->mTextureName); // make sure a new texture name has been created assert(this->mTextureName != 0); glBindTexture(GL_TEXTURE_1D, this->mTextureName); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage1D(GL_TEXTURE_1D, 0, GL_ALPHA, this->mTextureLength, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pTextureData); // delete the memory delete[] pTextureData; } else { std::cerr << "Line stipple texture of this size is not supported by the current OpenGL implementation." << std::endl; } } else { std::cerr << "texture to large." << std::endl; } } } }
static GLboolean ValidateTexSize (GLenum target, GLenum internalformat, bool useProxy) { int maxSide, k; GLfloat *pixels = NULL; GLenum err = GL_NO_ERROR; GLboolean first_oom; /* Query the largest supported texture size */ glGetIntegerv(getMaxTarget(target), &maxSide); if (!useProxy) { printf("%s, Internal Format = %s, Largest Texture Size =" " %d\n", piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(internalformat), maxSide); /* Allocate and initialize texture data array */ pixels = initTexData(target, maxSide); if ( pixels == NULL) { printf("Error allocating texture data array\n"); piglit_report_result(PIGLIT_SKIP); } } else { /* Compute largest supported texture size using proxy textures */ while(isValidTexSize(target, internalformat, maxSide)) maxSide *= 2; /* First unsupported size */ while(!isValidTexSize(target, internalformat, maxSide)) maxSide /= 2; while(isValidTexSize(target, internalformat, maxSide)) maxSide += 1; /* Last supported texture size */ maxSide -= 1; printf("%s, Internal Format = %s, Largest Texture Size =" " %d\n", piglit_get_gl_enum_name(getProxyTarget(target)), piglit_get_gl_enum_name(internalformat), maxSide); } switch (target) { case GL_TEXTURE_1D: if (!useProxy) { glTexImage1D(target, 0, internalformat, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); first_oom = err == GL_OUT_OF_MEMORY; /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { free(pixels); printf("Unexpected GL error: 0x%x\n", err); return false; } glTexSubImage1D(target, 0, 0, maxSide/2, GL_RGBA, GL_FLOAT, pixels); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY and * INVALID_VALUE */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY && (!first_oom || err != GL_INVALID_VALUE)) { free(pixels); printf("Unexpected GL error: 0x%x\n", err); return false; } } else { glTexImage1D(GL_PROXY_TEXTURE_1D, 0, internalformat, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); return false; } } break; case GL_TEXTURE_2D: if(!useProxy) { glTexImage2D(target, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); first_oom = err == GL_OUT_OF_MEMORY; /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { free(pixels); printf("Unexpected GL error: 0x%x\n", err); return false; } glTexSubImage2D(target, 0, 0, 0, maxSide/2, maxSide/2, GL_RGBA, GL_FLOAT, pixels); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY and * INVALID_VALUE */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY && (!first_oom || err != GL_INVALID_VALUE)) { free(pixels); printf("Unexpected GL error: 0x%x\n", err); return false; } } else { glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); return false; } } break; case GL_TEXTURE_RECTANGLE: glTexImage2D(target, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); return false; } break; case GL_TEXTURE_3D: //printf("Width = %d, Height = %d, Depth = %d\n", maxSide, // maxSide, maxSide); if(!useProxy) { glTexImage3D(target, 0, internalformat, maxSide, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); first_oom = err == GL_OUT_OF_MEMORY; /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); free(pixels); return false; } glTexSubImage3D(target, 0, 0, 0, 0, maxSide/2, maxSide/2, maxSide/2, GL_RGBA, GL_FLOAT, pixels); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY and * INVALID_VALUE */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY && (!first_oom || err != GL_INVALID_VALUE)) { free(pixels); printf("Unexpected GL error: 0x%x\n", err); return false; } } else { glTexImage3D(GL_PROXY_TEXTURE_3D, 0, internalformat, maxSide, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); if (err == GL_OUT_OF_MEMORY) return true; /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR) { printf("Unexpected GL error: 0x%x\n", err); return false; } } break; case GL_TEXTURE_CUBE_MAP_ARB: if (!useProxy) { first_oom = GL_FALSE; for (k = 0; k < 6; k++) { glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + k, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); first_oom = first_oom || err == GL_OUT_OF_MEMORY; /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); free(pixels); return false; } } for (k = 0; k < 6; k++) { glTexSubImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + k, 0, 0, 0, maxSide/2, maxSide/2, GL_RGBA, GL_FLOAT, pixels); err = glGetError(); if (err == GL_OUT_OF_MEMORY) { free(pixels); return true; } /* Report a GL error other than GL_OUT_OF_MEMORY and * INVALID_VALUE */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY && (!first_oom || err != GL_INVALID_VALUE)) { printf("Unexpected GL error: 0x%x\n", err); free(pixels); return false; } } } else { glTexImage2D(GL_PROXY_TEXTURE_CUBE_MAP, 0, internalformat, maxSide, maxSide, 0, GL_RGBA, GL_FLOAT, NULL); err = glGetError(); /* Report a GL error other than GL_OUT_OF_MEMORY */ if (err != GL_NO_ERROR && err != GL_OUT_OF_MEMORY) { printf("Unexpected GL error: 0x%x\n", err); return false; } } break; } if (pixels) free(pixels); /* If execution reaches this point, return true */ return true; }
void GL::Texture::setup(const void* data, GLenum type, int samples) { assert(_dimensions >= 1 && _dimensions <= 3); GLenum targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D}; GLenum wrap_enums[] = {GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_R}; _target = targets[_dimensions-1]; if (samples > 0) { // Multisample textures don't support mipmapping. assert(_min_filter != GL_NEAREST_MIPMAP_NEAREST); assert(_min_filter != GL_LINEAR_MIPMAP_NEAREST); assert(_min_filter != GL_NEAREST_MIPMAP_LINEAR); assert(_min_filter != GL_LINEAR_MIPMAP_LINEAR); assert(_dimensions == 2); if (_dimensions == 2) { _target = GL_TEXTURE_2D_MULTISAMPLE; } } bind(); if (samples == 0) { if (FLEXT_EXT_texture_filter_anisotropic) { glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_config.max_anisotropy()); } glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, _mag_filter); glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, _min_filter); for (int i = 0; i < _dimensions; ++i) { glTexParameteri(_target, wrap_enums[i], _wrap_method); } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); switch (_dimensions) { case 1: glTexImage1D(GL_TEXTURE_1D, // target 0, // level _internal_format, // internalFormat _width, // size 0, // border _format, // format type, // type data); // pixels break; case 2: if (samples < 1) { glTexImage2D(GL_TEXTURE_2D, // target 0, // level _internal_format, // internalFormat _width,_height, // size 0, // border _format, // format type, // type data); // pixels } else { glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, // target samples, // samples _internal_format, // internalFormat _width,_height, // size GL_FALSE); // fixedsamplelocations } break; case 3: glTexImage3D(GL_TEXTURE_3D, // target 0, // level _internal_format, // internalFormat _width,_height,_depth, // size 0, // border _format, // format type, // type data); // pixels break; default: assert(0); // To keep the compiler quiet.. } generate_mipmaps(); unbind(); }
static void Init( void ) { GLubyte *image; int imgWidth, imgHeight, minDim, w; GLenum imgFormat; if (!glutExtensionSupported("GL_ARB_texture_non_power_of_two")) { printf("Sorry, this program requires GL_ARB_texture_non_power_of_two\n"); exit(1); } #if 1 image = LoadRGBImage( IMAGE_FILE, &imgWidth, &imgHeight, &imgFormat ); if (!image) { printf("Couldn't read %s\n", IMAGE_FILE); exit(0); } #else int i, j; imgFormat = GL_RGB; imgWidth = 3; imgHeight = 3; image = malloc(imgWidth * imgHeight * 3); for (i = 0; i < imgHeight; i++) { for (j = 0; j < imgWidth; j++) { int k = (i * imgWidth + j) * 3; if ((i + j) & 1) { image[k+0] = 255; image[k+1] = 0; image[k+2] = 0; } else { image[k+0] = 0; image[k+1] = 255; image[k+2] = 0; } } } #endif printf("Read %d x %d\n", imgWidth, imgHeight); minDim = imgWidth < imgHeight ? imgWidth : imgHeight; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, imgWidth, 0, imgFormat, GL_UNSIGNED_BYTE, image); assert(glGetError() == GL_NO_ERROR); glTexImage1D(GL_PROXY_TEXTURE_1D, 0, GL_RGB, imgWidth, 0, imgFormat, GL_UNSIGNED_BYTE, image); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_WIDTH, &w); assert(w == imgWidth); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imgWidth, imgHeight, 0, imgFormat, GL_UNSIGNED_BYTE, image); assert(glGetError() == GL_NO_ERROR); glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGB, imgWidth, imgHeight, 0, imgFormat, GL_UNSIGNED_BYTE, image); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); assert(w == imgWidth); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, imgWidth, imgHeight, 1, 0, imgFormat, GL_UNSIGNED_BYTE, image); assert(glGetError() == GL_NO_ERROR); glTexImage3D(GL_PROXY_TEXTURE_3D, 0, GL_RGB, imgWidth, imgHeight, 1, 0, imgFormat, GL_UNSIGNED_BYTE, image); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &w); assert(w == imgWidth); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, minDim, minDim, 0, imgFormat, GL_UNSIGNED_BYTE, image); assert(glGetError() == GL_NO_ERROR); glTexImage2D(GL_PROXY_TEXTURE_CUBE_MAP, 0, GL_RGB, minDim, minDim, 0, imgFormat, GL_UNSIGNED_BYTE, image); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_CUBE_MAP, 0, GL_TEXTURE_WIDTH, &w); assert(w == minDim); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glEnable(GL_TEXTURE_2D); }
void CTexture1D::setTex(){ glBindTexture(GL_TEXTURE_1D, m_id); glTexImage1D(GL_TEXTURE_1D, 0, m_internalFormat, m_width, 0, m_format, m_type, m_data); glBindTexture(GL_TEXTURE_1D, 0); }
/* * WARNING: This function isn't finished and has never been tested!!!! */ GLint GLAPIENTRY gluBuild1DMipmaps(GLenum target, GLint components, GLsizei width, GLenum format, GLenum type, const void *data) { GLubyte *texture; GLint levels, max_levels; GLint new_width, max_width; GLint i, j, k, l; if (width < 1) return GLU_INVALID_VALUE; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_width); max_levels = ilog2(max_width) + 1; /* Compute how many mipmap images to make */ levels = ilog2(width) + 1; if (levels > max_levels) { levels = max_levels; } new_width = 1 << (levels - 1); texture = (GLubyte *) malloc(new_width * components); if (!texture) { return GLU_OUT_OF_MEMORY; } if (width != new_width) { /* initial rescaling */ switch (type) { case GL_UNSIGNED_BYTE: { GLubyte *ub_data = (GLubyte *) data; for (i = 0; i < new_width; i++) { j = i * width / new_width; for (k = 0; k < components; k++) { texture[i * components + k] = ub_data[j * components + k]; } } } break; default: /* Not implemented */ return GLU_ERROR; } } /* generate and load mipmap images */ for (l = 0; l < levels; l++) { glTexImage1D(GL_TEXTURE_1D, l, components, new_width, 0, format, GL_UNSIGNED_BYTE, texture); /* Scale image down to 1/2 size */ new_width = new_width / 2; for (i = 0; i < new_width; i++) { for (k = 0; k < components; k++) { GLint sample1, sample2; sample1 = (GLint) texture[i * 2 * components + k]; sample2 = (GLint) texture[(i * 2 + 1) * components + k]; texture[i * components + k] = (GLubyte) ((sample1 + sample2) / 2); } } } free(texture); return 0; }
static void create_1d_fbo(GLuint *out_tex, GLuint *out_ds) { GLuint tex, ds, fb; GLenum status; /* Create the color buffer. */ glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_1D, tex); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, BUF_WIDTH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); assert(glGetError() == 0); /* Create the depth-stencil buffer. */ glGenTextures(1, &ds); glBindTexture(GL_TEXTURE_1D, ds); glTexImage1D(GL_TEXTURE_1D, 0, f.iformat, BUF_WIDTH, 0, f.format, f.type, NULL); assert(glGetError() == 0); /* Create the FBO. */ glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_1D, tex, 0); glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_1D, ds, 0); if (f.format == GL_DEPTH_STENCIL) { glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_1D, ds, 0); } assert(glGetError() == 0); status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { piglit_report_result(PIGLIT_SKIP); } glViewport(0, 0, BUF_WIDTH, 1); glClearDepth(1); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_ALWAYS); glDepthRange(0, 0); glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); piglit_ortho_projection(BUF_WIDTH, 1, GL_FALSE); /* green */ glColor4f(0.0, 1.0, 0.0, 0.0); piglit_draw_rect(0, 0, BUF_WIDTH, 1); glBindFramebufferEXT(GL_FRAMEBUFFER, piglit_winsys_fbo); glDeleteFramebuffersEXT(1, &fb); *out_tex = tex; *out_ds = ds; }
//* Creation / loading methods ******************************************** void GLTexture::createInternalResourcesImpl(void) { if (!GLEW_VERSION_1_2 && mTextureType == TEX_TYPE_3D) OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "3D Textures not supported before OpenGL 1.2", "GLTexture::createInternalResourcesImpl"); if (!GLEW_VERSION_2_0 && mTextureType == TEX_TYPE_2D_ARRAY) OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "2D texture arrays not supported before OpenGL 2.0", "GLTexture::createInternalResourcesImpl"); // Convert to nearest power-of-two size if required mWidth = GLPixelUtil::optionalPO2(mWidth); mHeight = GLPixelUtil::optionalPO2(mHeight); mDepth = GLPixelUtil::optionalPO2(mDepth); // Adjust format if required mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage); // Check requested number of mipmaps size_t maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat); mNumMipmaps = mNumRequestedMipmaps; if(mNumMipmaps>maxMips) mNumMipmaps = maxMips; // Check if we can do HW mipmap generation mMipmapsHardwareGenerated = Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP); // Generate texture name glGenTextures( 1, &mTextureID ); // Set texture type mGLSupport.getStateCacheManager()->bindGLTexture( getGLTextureTarget(), mTextureID ); // This needs to be set otherwise the texture doesn't get rendered if (GLEW_VERSION_1_2) mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAX_LEVEL, mNumMipmaps); // Set some misc default parameters so NVidia won't complain, these can of course be changed later mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST); mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (GLEW_VERSION_1_2) { mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); mGLSupport.getStateCacheManager()->setTexParameteri(getGLTextureTarget(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } if((mUsage & TU_AUTOMIPMAP) && mNumRequestedMipmaps && mMipmapsHardwareGenerated) { mGLSupport.getStateCacheManager()->setTexParameteri( getGLTextureTarget(), GL_GENERATE_MIPMAP, GL_TRUE ); } // Allocate internal buffer so that glTexSubImageXD can be used // Internal format GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma); uint32 width = mWidth; uint32 height = mHeight; uint32 depth = mDepth; if(PixelUtil::isCompressed(mFormat)) { // Compressed formats GLsizei size = static_cast<GLsizei>(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat)); // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not // accept a 0 pointer like normal glTexImageXD // Run through this process for every mipmap to pregenerate mipmap piramid uint8 *tmpdata = new uint8[size]; memset(tmpdata, 0, size); for(uint8 mip=0; mip<=mNumMipmaps; mip++) { size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat)); switch(mTextureType) { case TEX_TYPE_1D: glCompressedTexImage1DARB(GL_TEXTURE_1D, mip, format, width, 0, size, tmpdata); break; case TEX_TYPE_2D: glCompressedTexImage2DARB(GL_TEXTURE_2D, mip, format, width, height, 0, size, tmpdata); break; case TEX_TYPE_2D_ARRAY: case TEX_TYPE_3D: glCompressedTexImage3DARB(getGLTextureTarget(), mip, format, width, height, depth, 0, size, tmpdata); break; case TEX_TYPE_CUBE_MAP: for(int face=0; face<6; face++) { glCompressedTexImage2DARB(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, size, tmpdata); } break; case TEX_TYPE_2D_RECT: break; }; if(width>1) width = width/2; if(height>1) height = height/2; if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY) depth = depth/2; } delete [] tmpdata; } else { // Run through this process to pregenerate mipmap pyramid for(uint8 mip=0; mip<=mNumMipmaps; mip++) { // Normal formats switch(mTextureType) { case TEX_TYPE_1D: glTexImage1D(GL_TEXTURE_1D, mip, format, width, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case TEX_TYPE_2D: glTexImage2D(GL_TEXTURE_2D, mip, format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case TEX_TYPE_2D_ARRAY: case TEX_TYPE_3D: glTexImage3D(getGLTextureTarget(), mip, format, width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); break; case TEX_TYPE_CUBE_MAP: for(int face=0; face<6; face++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); } break; case TEX_TYPE_2D_RECT: break; }; if(width>1) width = width/2; if(height>1) height = height/2; if(depth>1 && mTextureType != TEX_TYPE_2D_ARRAY) depth = depth/2; } } _createSurfaceList(); // Get final internal format mFormat = getBuffer(0,0)->getFormat(); }
ENTRYPOINT void init_tentacles (ModeInfo *mi) { tentacles_configuration *tc; int wire = MI_IS_WIREFRAME(mi); int i; if (!tcs) { tcs = (tentacles_configuration *) calloc (MI_NUM_SCREENS(mi), sizeof (tentacles_configuration)); if (!tcs) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } } tc = &tcs[MI_SCREEN(mi)]; tc->glx_context = init_GL(mi); reshape_tentacles (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); if (!wire) { GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); glLightfv(GL_LIGHT0, GL_AMBIENT, amb); glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); glLightfv(GL_LIGHT0, GL_SPECULAR, spc); } if (!wire && !cel_p) { glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); } tc->trackball = gltrackball_init (False); tc->left_p = !(random() % 5); if (arg_segments < 2) arg_segments = 2; if (arg_slices < 3) arg_slices = 3; if (arg_thickness < 0.1) arg_thickness = 0.1; if (arg_wiggliness < 0) arg_wiggliness = 0; if (arg_wiggliness > 1) arg_wiggliness = 1; if (arg_flexibility < 0) arg_flexibility = 0; if (arg_flexibility > 1) arg_flexibility = 1; parse_color (mi, "tentacleColor", arg_color, tc->tentacle_color); parse_color (mi, "stripeColor", arg_stripe, tc->stripe_color); parse_color (mi, "suckerColor", arg_sucker, tc->sucker_color); /* Black outlines for light colors, white outlines for dark colors. */ if (tc->tentacle_color[0] + tc->tentacle_color[1] + tc->tentacle_color[2] < 0.4) tc->outline_color[0] = 1; tc->outline_color[1] = tc->outline_color[0]; tc->outline_color[2] = tc->outline_color[0]; tc->outline_color[3] = 1; for (i = 0; i < MI_COUNT(mi); i++) move_tentacle (make_tentacle (mi, i, MI_COUNT(mi))); if (wire) texture_p = cel_p = False; if (cel_p) texture_p = False; if (texture_p || cel_p) { glGenTextures(1, &tc->texid); # ifdef HAVE_GLBINDTEXTURE glBindTexture ((cel_p ? GL_TEXTURE_1D : GL_TEXTURE_2D), tc->texid); # endif tc->texture = xpm_to_ximage (MI_DISPLAY(mi), MI_VISUAL(mi), MI_COLORMAP(mi), (cel_p ? grey_texture : scales)); if (!tc->texture) texture_p = cel_p = False; } if (texture_p) { glPixelStorei (GL_UNPACK_ALIGNMENT, 1); clear_gl_error(); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, tc->texture->width, tc->texture->height, 0, GL_RGBA, /* GL_UNSIGNED_BYTE, */ GL_UNSIGNED_INT_8_8_8_8_REV, tc->texture->data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); } else if (cel_p) { clear_gl_error(); glTexImage1D (GL_TEXTURE_1D, 0, GL_RGBA, tc->texture->width, 0, GL_RGBA, /* GL_UNSIGNED_BYTE, */ GL_UNSIGNED_INT_8_8_8_8_REV, tc->texture->data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_1D); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable (GL_LINE_SMOOTH); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_BLEND); /* Dark gray instead of black, so the outlines show up */ glClearColor (0.13, 0.13, 0.13, 1.0); } compute_unit_torus (mi, 0.5, MAX(5, arg_slices/6), MAX(9, arg_slices/3)); }
void KinectDataRenderer::init(Camera *camera) { this->camera = camera; ///--- Create vertex array object if(!vao.isCreated()){ bool success = vao.create(); assert(success); vao.bind(); } ///--- Load/compile shaders if (!program.isLinked()) { const char* vshader = ":/KinectDataRenderer/KinectDataRenderer_vshader.glsl"; const char* fshader = ":/KinectDataRenderer/KinectDataRenderer_fshader.glsl"; bool vok = program.addShaderFromSourceFile(QGLShader::Vertex, vshader); bool fok = program.addShaderFromSourceFile(QGLShader::Fragment, fshader); bool lok = program.link (); assert(lok && vok && fok); bool success = program.bind(); assert(success); } ///--- Used to create connectivity Grid grid(camera->width(),camera->height()); ///--- Create vertex buffer/attributes "position" { bool success = vertexbuffer.create(); assert(success); vertexbuffer.setUsagePattern( QGLBuffer::StaticDraw ); success = vertexbuffer.bind(); assert(success); vertexbuffer.allocate( grid.vertices.data(), grid.vertices.size() * sizeof(GLfloat) ); program.setAttributeBuffer("vpoint", GL_FLOAT, 0, 2 ); program.enableAttributeArray("vpoint"); } ///--- Create vertex buffer/attributes "uv" { bool success = uvbuffer.create(); assert(success); uvbuffer.setUsagePattern( QGLBuffer::StaticDraw ); success = uvbuffer.bind(); assert(success); uvbuffer.allocate( grid.texcoords.data(), grid.texcoords.size() * sizeof(GLfloat) ); program.setAttributeBuffer("uv", GL_FLOAT, 0, 2 ); program.enableAttributeArray("uv"); } ///--- Create the index "triangle" buffer { bool success = indexbuffer.create(); assert(success); indexbuffer.setUsagePattern( QGLBuffer::StaticDraw ); success = indexbuffer.bind(); assert(success); indexbuffer.allocate( grid.indices.data(), grid.indices.size() * sizeof(unsigned int) ); } ///--- Create texture to colormap the point cloud { // const int sz=2; GLfloat tex[3*sz] = {/*green*/ 0.000, 1.000, 0, /*red*/ 1.000, 0.000, 0,}; // const int sz=2; GLfloat tex[3*sz] = {/*gray*/ .1, .1, .1, /*black*/ 0.8, 0.8, 0.8}; const int sz=3; GLfloat tex[3*sz] = {/*red*/ 1.000, 0.000, 0, /*yellow*/ 1.0, 1.0, 0.0, /*green*/ 0.000, 1.000, 0}; glActiveTexture(GL_TEXTURE2); glGenTextures(1, &texture_id_cmap); glBindTexture(GL_TEXTURE_1D, texture_id_cmap); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, sz, 0, GL_RGB, GL_FLOAT, tex); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); program.setUniformValue("colormap", 2 /*GL_TEXTURE2*/); } ///--- @todo upload data to do inverse projection set_uniform("inv_proj_matrix",camera->inv_projection_matrix()); ///--- upload near/far planes set_zNear(camera->zNear()); set_zFar(camera->zFar()); // set_alpha(1.0); ///< default no alpha blending set_alpha(.7); ///< default no alpha blending set_discard_cosalpha_th(.3); ///< default sideface clipping ///--- save for glDrawElements num_indexes = grid.indices.size(); num_vertices = grid.vertices.size(); ///--- Avoid pollution program.release(); vao.release(); }
// submit manually // supports the modes valid in GLES 1.0 virtual void submit(void * pixels=NULL, uint32_t align=4) { validate(); glBindTexture(mTarget, id()); // set glPixelStore according to the array layout: //glPixelStorei(GL_UNPACK_ALIGNMENT, align); switch (mTarget) { case GL_TEXTURE_1D: glTexImage1D(mTarget, 0, // GLint level mInternalFormat, width(), 0, //GLint border, mInternalFormat, GL_UNSIGNED_BYTE, pixels); break; case GL_TEXTURE_2D: glTexImage2D(mTarget, 0, // GLint level mInternalFormat, width(), height(), 0, //GLint border, mInternalFormat, GL_UNSIGNED_BYTE, pixels); break; case GL_TEXTURE_3D: glTexImage3D(mTarget, 0, // GLint level mInternalFormat, width(), height(), depth(), 0, //GLint border, mInternalFormat, GL_UNSIGNED_BYTE, pixels); break; default: printf("texture target not supported yet\n"); break; } // set alignment back to default //glPixelStorei(GL_UNPACK_ALIGNMENT, 4); Graphics::error("submitting texture"); // // OpenGL may have changed the internal format to one it supports: // GLint format; // glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); // if (format != mInternalFormat) { // printf("converted from %X to %X format\n", mInternalFormat, format); // mInternalFormat = format; // } //printf("submitted texture data %p\n", pixels); glBindTexture(mTarget, 0); }
void startup() { glGenVertexArrays(1, &vao); glBindVertexArray(vao); printf("create program\n"); program = glCreateProgram(); GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fs, 1, fs_source, NULL); glCompileShader(fs); check_shader(fs); printf("create shader\n"); GLuint vs = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vs, 1, vs_source, NULL); glCompileShader(vs); check_shader(vs); printf("attach shaders\n"); glAttachShader(program, vs); glAttachShader(program, fs); glLinkProgram(program); printf("locate uniforms\n"); uniforms.zoom = glGetUniformLocation(program, "zoom"); uniforms.offset = glGetUniformLocation(program, "offset"); uniforms.C = glGetUniformLocation(program, "C"); uniforms.screen = glGetUniformLocation(program, "screen"); uniforms.iter = glGetUniformLocation(program, "max_iterations"); uniforms.mode = glGetUniformLocation(program, "mode"); uniforms.damp = glGetUniformLocation(program, "damp"); uniforms.log_a_min = glGetUniformLocation(program, "log_a_min"); uniforms.log_a_max = glGetUniformLocation(program, "log_a_max"); printf("delete shaders\n"); glDeleteShader(vs); glDeleteShader(fs); printf("gen texture\n"); glGenTextures(1, &palette_texture); glBindTexture(GL_TEXTURE_1D, palette_texture); glTexImage1D( GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, NULL); glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGB, GL_UNSIGNED_BYTE, palette); glGenerateMipmap(GL_TEXTURE_1D); }
void OGLTexture1D::CreateHWResource(ElementInitData const * init_data) { uint32_t texel_size = NumFormatBytes(format_); GLint glinternalFormat; GLenum glformat; GLenum gltype; OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_); if (sample_count_ <= 1) { glBindTexture(target_type_, texture_); glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1); OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); for (uint32_t array_index = 0; array_index < array_size_; ++ array_index) { for (uint32_t level = 0; level < num_mip_maps_; ++ level) { uint32_t const w = this->Width(level); re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]); if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * block_size; glBufferData(GL_PIXEL_UNPACK_BUFFER, image_size, nullptr, GL_STREAM_DRAW); re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if (array_size_ > 1) { if (0 == array_index) { glCompressedTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, image_size * array_size_, nullptr); } if (init_data != nullptr) { glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1, glformat, image_size, init_data[array_index * num_mip_maps_ + level].data); } } else { glCompressedTexImage1D(target_type_, level, glinternalFormat, w, 0, image_size, (nullptr == init_data) ? nullptr : init_data[array_index * num_mip_maps_ + level].data); } } else { GLsizei const image_size = w * texel_size; glBufferData(GL_PIXEL_UNPACK_BUFFER, image_size, nullptr, GL_STREAM_DRAW); re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if (array_size_ > 1) { if (0 == array_index) { glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr); } if (init_data != nullptr) { glTexSubImage2D(target_type_, level, 0, array_index, w, 1, glformat, gltype, init_data[array_index * num_mip_maps_ + level].data); } } else { glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype, (nullptr == init_data) ? nullptr : init_data[array_index * num_mip_maps_ + level].data); } } } } } else { glBindRenderbuffer(GL_RENDERBUFFER, texture_); glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1); } hw_res_ready_ = true; }
void nuiGLDrawContext::DrawShade (const nuiRect& rSourceRect, const nuiRect& rShadeRect) { // return; bool blending = mCurrentState.mBlending; GLenum blendfunc1,blendfunc2; blendfunc1 = mCurrentState.mBlendSourceFactor; blendfunc2 = mCurrentState.mBlendDestinationFactor; EnableBlending(true); SetBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); nuiSize ShadeSize = rSourceRect.mLeft - rShadeRect.mLeft; // Left shadow uint8 pLUT[256*4]; uint i; for (i = 0; i<256; i++) { pLUT[0+(i*4)] = 0; pLUT[1+(i*4)] = 0; pLUT[2+(i*4)] = 0; pLUT[3+(i*4)] = i; } EnableTexture2D(false); EnableTexture1D(true); glBindTexture(GL_TEXTURE_1D,0); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pLUT); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glBegin(GL_QUADS); glColor4f(0,0,0,0); glTexCoord1f(0); glVertex2f(rSourceRect.mLeft-ShadeSize,rSourceRect.mTop); glTexCoord1f(1); glVertex2f(rSourceRect.mLeft,rSourceRect.mTop); glColor4f(0,0,0,SHADE_ALPHA); glTexCoord1f(1); glVertex2f(rSourceRect.mLeft,rSourceRect.mTop+ShadeSize); glTexCoord1f(0); glVertex2f(rSourceRect.mLeft-ShadeSize,rSourceRect.mTop+ShadeSize); glEnd(); EnableTexture1D(false); glBegin(GL_QUADS); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mLeft-ShadeSize,rSourceRect.mTop+ShadeSize); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mLeft,rSourceRect.mTop+ShadeSize); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mLeft,rSourceRect.mBottom); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mLeft-ShadeSize,rSourceRect.mBottom); glEnd(); // bottom shadow glBegin(GL_QUADS); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mLeft,rSourceRect.mBottom+ShadeSize); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mLeft,rSourceRect.mBottom); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mRight,rSourceRect.mBottom); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mRight,rSourceRect.mBottom+ShadeSize); glEnd(); // Right shadow EnableTexture1D(true); glBegin(GL_QUADS); glColor4f(0,0,0,0); glTexCoord1f(1); glVertex2f(rSourceRect.mRight,rSourceRect.mTop); glTexCoord1f(0); glVertex2f(rSourceRect.mRight+ShadeSize,rSourceRect.mTop); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mRight+ShadeSize,rSourceRect.mTop+ShadeSize); glTexCoord1f(1); glVertex2f(rSourceRect.mRight,rSourceRect.mTop+ShadeSize); glEnd(); EnableTexture1D(false); glBegin(GL_QUADS); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mRight+ShadeSize,rSourceRect.mTop+ShadeSize); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mRight,rSourceRect.mTop+ShadeSize); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mRight,rSourceRect.mBottom); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mRight+ShadeSize,rSourceRect.mBottom); glEnd(); EnableTexture1D(true); glBegin(GL_QUADS); // Right Corner glColor4f(0,0,0,SHADE_ALPHA); glTexCoord1f(1); glVertex2f(rSourceRect.mRight,rSourceRect.mBottom); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mRight+ShadeSize,rSourceRect.mBottom); glColor4f(0,0,0,0); glTexCoord1f(0); glVertex2f(rSourceRect.mRight+ShadeSize,rSourceRect.mBottom+ShadeSize); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mRight,rSourceRect.mBottom+ShadeSize); // Left Corner: glColor4f(0,0,0,0); glTexCoord1f(1); glVertex2f(rSourceRect.mLeft-ShadeSize,rSourceRect.mBottom); glColor4f(0,0,0,SHADE_ALPHA); glVertex2f(rSourceRect.mLeft,rSourceRect.mBottom); glColor4f(0,0,0,SHADE_ALPHA); glTexCoord1f(0); glVertex2f(rSourceRect.mLeft,rSourceRect.mBottom+ShadeSize); glColor4f(0,0,0,0); glVertex2f(rSourceRect.mLeft-ShadeSize,rSourceRect.mBottom+ShadeSize); glEnd(); EnableTexture1D(false); EnableBlending(blending); SetBlendFunc(blendfunc1, blendfunc2); }
void Mandlebrot::init(void) { glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); // Create and compile our GLSL program from the shaders #if VERSION == 330 programID = LoadShaders("passthrough.vert", "mand_single.frag"); #else programID = LoadShaders("passthrough.vert", "mand.frag"); #endif if (!programID) exit(-1); // get a handle for the MVP input. MatrixID = glGetUniformLocation(programID, "MVP"); iterID = glGetUniformLocation(programID, "iter"); Projection = glm::ortho(1.0f, 1.0f, 1.0f, -1.0f); // Make a square. const GLfloat g_vertex_buffer_data[][4] = { {-1, -1, 0, 1}, {-1, 1, 0, 1}, {1, -1, 0, 1}, {1, 1, 0, 1}}; glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); // These are the u,v coordinates of each vertex. const GLfloat g_textcoords[][2] = { {-1.0, -1.0}, {-1.0, 1.0}, {1.0, -1.0}, {1.0, 1.0}}; glGenBuffers(1, &uvbuffer); glBindBuffer(GL_ARRAY_BUFFER, uvbuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(g_textcoords), g_textcoords, GL_STATIC_DRAW); // Create a 1-d texture to use as a color palette. const GLubyte g_colors[][4] = {{0xff, 0x33, 0, 0xff}, {0x33, 0x33, 0xff, 0xff}, {0xff, 0x33, 0x33, 0xff}, {0x44, 0x88, 0xff, 0xff}, {0x44, 0x44, 0xff, 0xff}, {0xff, 0x44, 0x44, 0xff}, {0x33, 0x88, 0xdd, 0xff}, {0x33, 0x55, 0xdd, 0xff}, {0xdd, 0x55, 0x33, 0xff}, {0x33, 0x88, 0xdd, 0xff}, {0x33, 0x33, 0xff, 0xff}, {0xdd, 0x44, 0x44, 0xff}, {0x33, 0x88, 0xff, 0xff}}; glGenTextures(1, &TextureID); glBindTexture(GL_TEXTURE_1D, TextureID); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 12, 0, GL_RGBA, GL_UNSIGNED_BYTE, g_colors); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); TextureLoc = glGetUniformLocation(programID, "colors"); u_iter = glGetUniformLocationARB(programID, "iter"); u_asp = glGetUniformLocationARB(programID, "aspect"); u_scale = glGetUniformLocation(programID, "scale"); u_center = glGetUniformLocationARB(programID, "center"); glBindBuffer(GL_ARRAY_BUFFER, 0); }