unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name) { int rh,rw; int texformat=TexFormat[gl_texture_format]; bool deletebuffer=false; if (forcenocompression) { texformat = GL_RGBA8; } TranslatedTexture * glTex=GetTexID(translation); if (glTex->glTexID==0) glGenTextures(1,&glTex->glTexID); if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); glBindTexture(GL_TEXTURE_2D, glTex->glTexID); FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name); lastbound[texunit] = glTex->glTexID; if (!buffer) { w=texwidth; h=abs(texheight); rw = GetTexDimension (w); rh = GetTexDimension (h); // The texture must at least be initialized if no data is present. glTex->mipmapped = false; buffer=(unsigned char *)calloc(4,rw * (rh+1)); deletebuffer=true; //texheight=-h; } else { rw = GetTexDimension (w); rh = GetTexDimension (h); if (rw < w || rh < h) { // The texture is larger than what the hardware can handle so scale it down. unsigned char * scaledbuffer=(unsigned char *)calloc(4,rw * (rh+1)); if (scaledbuffer) { Resize(rw, rh, buffer, scaledbuffer); deletebuffer=true; buffer=scaledbuffer; } } } glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); if (deletebuffer) free(buffer); if (mipmap && TexFilter[gl_texture_filter].mipmapping) { glGenerateMipmap(GL_TEXTURE_2D); glTex->mipmapped = true; } if (texunit != 0) glActiveTexture(GL_TEXTURE0); return glTex->glTexID; }
int FHardwareTexture::GetDepthBuffer() { if (glDepthID == 0) { glGenRenderbuffers(1, &glDepthID); glBindRenderbuffer(GL_RENDERBUFFER, glDepthID); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, GetTexDimension(texwidth), GetTexDimension(texheight)); glBindRenderbuffer(GL_RENDERBUFFER, 0); } return glDepthID; }
//=========================================================================== // // Loads the texture image into the hardware // // NOTE: For some strange reason I was unable to find the source buffer // should be one line higher than the actual texture. I got extremely // strange crashes deep inside the GL driver when I didn't do it! // //=========================================================================== void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit) { int rh,rw; int texformat=TexFormat[gl_texture_format]; bool deletebuffer=false; bool use_mipmapping = TexFilter[gl_texture_filter].mipmapping; if (alphatexture) texformat=GL_ALPHA8; else if (forcenocompression) texformat = GL_RGBA8; if (glTexID==0) glGenTextures(1,&glTexID); glBindTexture(GL_TEXTURE_2D, glTexID); lastbound[texunit]=glTexID; if (!buffer) { w=texwidth; h=abs(texheight); rw = GetTexDimension (w); rh = GetTexDimension (h); // The texture must at least be initialized if no data is present. mipmap=false; glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, false); buffer=(unsigned char *)calloc(4,rw * (rh+1)); deletebuffer=true; //texheight=-h; } else { rw = GetTexDimension (w); rh = GetTexDimension (h); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (mipmap && use_mipmapping && !forcenofiltering)); if (rw < w || rh < h) { // The texture is larger than what the hardware can handle so scale it down. unsigned char * scaledbuffer=(unsigned char *)calloc(4,rw * (rh+1)); if (scaledbuffer) { Resize(rw, rh, buffer, scaledbuffer); deletebuffer=true; buffer=scaledbuffer; } } } glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); if (deletebuffer) free(buffer); // When using separate samplers the stuff below is not needed. // if (gl.flags & RFL_SAMPLER_OBJECTS) return; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapparam==GL_CLAMP? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapparam==GL_CLAMP? GL_CLAMP_TO_EDGE : GL_REPEAT); clampmode = wrapparam==GL_CLAMP? GLT_CLAMPX|GLT_CLAMPY : 0; if (forcenofiltering) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); } else { if (mipmap && use_mipmapping) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); if (gl_texture_filter_anisotropic) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); } }