opengles Translator: get Compressed texture handling out from GLEScontext
This commit does few things: 1. Gets doCompressedTexImage2D out of the context and TextureUtils 2. Gets palette textures out of TextureUtils and into PaletteTexture 3. Makes TextureUtils generic for all compressed textures 4. Moves the glGet's dealing with compressed textures from GLEScontext to the impl. Change-Id: Ibbde6968810a66a4f3488f3887ee3f015fc32c11
This commit is contained in:
committed by
David 'Digit' Turner
parent
7fdf635d3a
commit
1d9dc99abb
@@ -428,7 +428,7 @@ GL_API void GL_APIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLe
|
||||
GET_CTX_CM()
|
||||
SET_ERROR_IF(!GLEScmValidate::textureTargetEx(target),GL_INVALID_ENUM);
|
||||
|
||||
ctx->doCompressedTexImage2D(target, level, internalformat,
|
||||
doCompressedTexImage2D(ctx, target, level, internalformat,
|
||||
width, height, border,
|
||||
imageSize, data);
|
||||
}
|
||||
@@ -706,6 +706,20 @@ GL_API void GL_APIENTRY glGetBooleanv( GLenum pname, GLboolean *params) {
|
||||
*params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
|
||||
}
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = (GLboolean)getCompressedFormats(NULL);
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
{
|
||||
int nparams = getCompressedFormats(NULL);
|
||||
if (nparams>0) {
|
||||
int * iparams = new int[nparams];
|
||||
getCompressedFormats(iparams);
|
||||
for (int i=0; i<nparams; i++) params[i] = (GLboolean)iparams[i];
|
||||
delete [] iparams;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ctx->dispatcher().glGetBooleanv(pname,params);
|
||||
}
|
||||
@@ -766,6 +780,22 @@ GL_API void GL_APIENTRY glGetFixedv( GLenum pname, GLfixed *params) {
|
||||
case GL_TEXTURE_GEN_STR_OES:
|
||||
glGetFloatv(pname,&fParams[0]);
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = I2X(getCompressedFormats(NULL));
|
||||
return;
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
{
|
||||
int nparams = getCompressedFormats(NULL);
|
||||
if (nparams>0) {
|
||||
int * iparams = new int[nparams];
|
||||
getCompressedFormats(iparams);
|
||||
for (int i=0; i<nparams; i++) params[i] = I2X(iparams[i]);
|
||||
delete [] iparams;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ctx->dispatcher().glGetFloatv(pname,fParams);
|
||||
}
|
||||
@@ -795,6 +825,20 @@ GL_API void GL_APIENTRY glGetFloatv( GLenum pname, GLfloat *params) {
|
||||
glGetIntegerv(pname,&i);
|
||||
*params = (GLfloat)i;
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = (GLfloat)getCompressedFormats(NULL);
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
{
|
||||
int nparams = getCompressedFormats(NULL);
|
||||
if (nparams>0) {
|
||||
int * iparams = new int[nparams];
|
||||
getCompressedFormats(iparams);
|
||||
for (int i=0; i<nparams; i++) params[i] = (GLfloat)iparams[i];
|
||||
delete [] iparams;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ctx->dispatcher().glGetFloatv(pname,params);
|
||||
}
|
||||
@@ -827,6 +871,12 @@ GL_API void GL_APIENTRY glGetIntegerv( GLenum pname, GLint *params) {
|
||||
*params = thrd->shareGroup->getLocalName(RENDERBUFFER,i);
|
||||
}
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = getCompressedFormats(NULL);
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
getCompressedFormats(params);
|
||||
break;
|
||||
default:
|
||||
ctx->dispatcher().glGetIntegerv(pname,params);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "GLESv2Context.h"
|
||||
#include "GLESv2Validate.h"
|
||||
#include "ShaderParser.h"
|
||||
#include <GLcommon/TextureUtils.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -286,7 +287,7 @@ GL_APICALL void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level,
|
||||
GET_CTX();
|
||||
SET_ERROR_IF(!GLESv2Validate::textureTargetEx(target),GL_INVALID_ENUM);
|
||||
|
||||
ctx->doCompressedTexImage2D(target, level, internalformat,
|
||||
doCompressedTexImage2D(ctx, target, level, internalformat,
|
||||
width, height, border,
|
||||
imageSize, data);
|
||||
}
|
||||
@@ -682,6 +683,20 @@ GL_APICALL void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params){
|
||||
glGetIntegerv(pname,&i);
|
||||
*params = (GLfloat)i;
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = (GLfloat)getCompressedFormats(NULL);
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
{
|
||||
int nparams = getCompressedFormats(NULL);
|
||||
if (nparams>0) {
|
||||
int * iparams = new int[nparams];
|
||||
getCompressedFormats(iparams);
|
||||
for (int i=0; i<nparams; i++) params[i] = (GLfloat)iparams[i];
|
||||
delete [] iparams;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ctx->dispatcher().glGetFloatv(pname,params);
|
||||
@@ -717,6 +732,12 @@ GL_APICALL void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params){
|
||||
*params = thrd->shareGroup->getLocalName(RENDERBUFFER,i);
|
||||
}
|
||||
break;
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = getCompressedFormats(NULL);
|
||||
break;
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
getCompressedFormats(params);
|
||||
break;
|
||||
default:
|
||||
ctx->dispatcher().glGetIntegerv(pname,params);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ LOCAL_SRC_FILES := \
|
||||
DummyGLfuncs.cpp \
|
||||
RangeManip.cpp \
|
||||
TextureUtils.cpp \
|
||||
PaletteTexture.cpp \
|
||||
etc1.cpp \
|
||||
objectNameManager.cpp
|
||||
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
#include <GLcommon/GLESmacros.h>
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
#include <GLcommon/etc1.h>
|
||||
#include <GLcommon/GLESvalidate.h>
|
||||
#include <GLcommon/TextureUtils.h>
|
||||
#include <cmath>
|
||||
|
||||
//decleration
|
||||
static int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices);
|
||||
@@ -541,15 +539,6 @@ bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params)
|
||||
bool result = false;
|
||||
GLint numParams = 1;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numParams);
|
||||
break;
|
||||
default:
|
||||
numParams=1;
|
||||
}
|
||||
|
||||
GLint* iParams = new GLint[numParams];
|
||||
if (numParams>0 && glGetIntegerv(pname,iParams)) {
|
||||
while(numParams >= 0)
|
||||
@@ -569,15 +558,6 @@ bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params)
|
||||
bool result = false;
|
||||
GLint numParams = 1;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numParams);
|
||||
break;
|
||||
default:
|
||||
numParams=1;
|
||||
}
|
||||
|
||||
GLint* iParams = new GLint[numParams];
|
||||
if (numParams>0 && glGetIntegerv(pname,iParams)) {
|
||||
while(numParams >= 0)
|
||||
@@ -613,14 +593,6 @@ bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
|
||||
*params = m_activeTexture+GL_TEXTURE0;
|
||||
break;
|
||||
|
||||
case GL_COMPRESSED_TEXTURE_FORMATS:
|
||||
getCompressedFormats(params);
|
||||
break;
|
||||
|
||||
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
|
||||
*params = getCompressedFormats(NULL);
|
||||
break;
|
||||
|
||||
case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
|
||||
*params = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
@@ -628,7 +600,6 @@ bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
|
||||
case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
|
||||
*params = GL_RGBA;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -636,67 +607,3 @@ bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
|
||||
return true;
|
||||
}
|
||||
|
||||
void GLEScontext::doCompressedTexImage2D(GLenum target, GLint level,
|
||||
GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLint border,
|
||||
GLsizei imageSize, const GLvoid* data)
|
||||
{
|
||||
GLEScontext *ctx = this; // needed for macros used below
|
||||
|
||||
switch (internalformat) {
|
||||
case GL_ETC1_RGB8_OES:
|
||||
{
|
||||
GLint format = GL_RGB;
|
||||
GLint type = GL_UNSIGNED_BYTE;
|
||||
|
||||
GLsizei compressedSize = etc1_get_encoded_data_size(width, height);
|
||||
SET_ERROR_IF((compressedSize > imageSize), GL_INVALID_VALUE);
|
||||
|
||||
const int32_t align = getUnpackAlignment()-1;
|
||||
const int32_t bpr = ((width * 3) + align) & ~align;
|
||||
const size_t size = bpr * height;
|
||||
|
||||
etc1_byte* pOut = new etc1_byte[size];
|
||||
int res = etc1_decode_image((const etc1_byte*)data, pOut, width, height, 3, bpr);
|
||||
SET_ERROR_IF(res!=0, GL_INVALID_VALUE);
|
||||
dispatcher().glTexImage2D(target,level,format,width,height,border,format,type,pOut);
|
||||
delete [] pOut;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
{
|
||||
SET_ERROR_IF(level > log2(getMaxTexSize()) ||
|
||||
border !=0 || level > 0 ||
|
||||
!GLESvalidate::texImgDim(width,height,getMaxTexSize()+2),GL_INVALID_VALUE)
|
||||
|
||||
int nMipmaps = -level + 1;
|
||||
GLsizei tmpWidth = width;
|
||||
GLsizei tmpHeight = height;
|
||||
|
||||
for(int i = 0; i < nMipmaps ; i++)
|
||||
{
|
||||
GLenum uncompressedFrmt;
|
||||
unsigned char* uncompressed = uncompressTexture(internalformat,uncompressedFrmt,width,height,imageSize,data,i);
|
||||
dispatcher().glTexImage2D(target,i,uncompressedFrmt,tmpWidth,tmpHeight,border,uncompressedFrmt,GL_UNSIGNED_BYTE,uncompressed);
|
||||
tmpWidth/=2;
|
||||
tmpHeight/=2;
|
||||
delete uncompressed;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SET_ERROR_IF(1, GL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "GLcommon/PaletteTexture.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
struct Color
|
||||
{
|
||||
Color(unsigned char r, unsigned char g,unsigned char b, unsigned char a):red(r),green(g),blue(b),alpha(a){};
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char alpha;
|
||||
};
|
||||
|
||||
void getPaletteInfo(GLenum internalFormat,unsigned int& indexSizeBits,unsigned int& colorSizeBytes,GLenum& colorFrmt) {
|
||||
|
||||
colorFrmt = GL_RGB;
|
||||
switch(internalFormat)
|
||||
{
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
indexSizeBits = 4;
|
||||
colorSizeBytes = 3;
|
||||
break;
|
||||
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
indexSizeBits = 4;
|
||||
colorSizeBytes = 4;
|
||||
colorFrmt = GL_RGBA;
|
||||
break;
|
||||
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
colorFrmt = GL_RGBA;
|
||||
/* fall-through */
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
indexSizeBits = 4;
|
||||
colorSizeBytes = 2;
|
||||
break;
|
||||
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
indexSizeBits = 8;
|
||||
colorSizeBytes = 3;
|
||||
break;
|
||||
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
indexSizeBits = 8;
|
||||
colorSizeBytes = 4;
|
||||
colorFrmt = GL_RGBA;
|
||||
break;
|
||||
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
colorFrmt = GL_RGBA;
|
||||
/* fall-through */
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
indexSizeBits = 8;
|
||||
colorSizeBytes = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Color paletteColor(const unsigned char* pallete,unsigned int index,GLenum format)
|
||||
{
|
||||
short s;
|
||||
switch(format) {
|
||||
//RGB
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
return Color(pallete[index],pallete[index+1],pallete[index+2],0);
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
s = *((short *)(pallete+index));
|
||||
return Color((s >> 11)*255/31,((s >> 5) & 0x3f)*255/63 ,(s & 0x1f)*255/31,0);
|
||||
|
||||
//RGBA
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
return Color(pallete[index],pallete[index+1],pallete[index+2],pallete[index+3]);
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
s = *((short *)(pallete+index));
|
||||
return Color(((s >> 12) & 0xf)*255/15,((s >> 8) & 0xf)*255/15,((s >> 4) & 0xf)*255/15 ,(s & 0xf)*255/15);
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
s = *((short *)(pallete+index));
|
||||
return Color(((s >> 11) & 0x1f)*255/31,((s >> 6) & 0x1f)*255/31,((s >> 1) & 0x1f)*255/31 ,(s & 0x1) * 255);
|
||||
default:
|
||||
return Color(255,255,255,255);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level) {
|
||||
|
||||
unsigned int indexSizeBits; //the size of the color index in the pallete
|
||||
unsigned int colorSizeBytes; //the size of each color cell in the pallete
|
||||
|
||||
getPaletteInfo(internalformat,indexSizeBits,colorSizeBytes,formatOut);
|
||||
if(!data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char* palette = static_cast<const unsigned char *>(data);
|
||||
|
||||
//the pallete positioned in the begininng of the data
|
||||
// so we jump over it to get to the colos indices in the palette
|
||||
|
||||
int nColors = 2 << (indexSizeBits -1); //2^indexSizeBits
|
||||
int paletteSizeBytes = nColors*colorSizeBytes;
|
||||
const unsigned char* imageIndices = palette + paletteSizeBytes;
|
||||
|
||||
//jumping to the the correct mipmap level
|
||||
for(int i=0;i<level;i++) {
|
||||
imageIndices+= (width*height*indexSizeBits)/8;
|
||||
width = width >> 1;
|
||||
height = height >> 1;
|
||||
}
|
||||
|
||||
int colorSizeOut = (formatOut == GL_RGB? 3:4);
|
||||
int nPixels = width*height;
|
||||
unsigned char* pixelsOut = new unsigned char[nPixels*colorSizeOut];
|
||||
if(!pixelsOut) return NULL;
|
||||
|
||||
int leftBytes = ((palette + imageSize) /* the end of data pointer*/
|
||||
- imageIndices);
|
||||
int leftPixels = (leftBytes * 8 )/indexSizeBits;
|
||||
|
||||
int maxIndices = (leftPixels < nPixels) ? leftPixels:nPixels;
|
||||
|
||||
//filling the pixels array
|
||||
for(int i =0 ; i < maxIndices ; i++) {
|
||||
int paletteIndex = 0;
|
||||
int indexOut = i*colorSizeOut;
|
||||
if(indexSizeBits == 4) {
|
||||
paletteIndex = (i%2) == 0 ?
|
||||
imageIndices[i/2] >> 4: //upper bits
|
||||
imageIndices[i/2] & 0xf; //lower bits
|
||||
} else {
|
||||
paletteIndex = imageIndices[i];
|
||||
}
|
||||
|
||||
paletteIndex*=colorSizeBytes;
|
||||
Color c = paletteColor(palette,paletteIndex,internalformat);
|
||||
|
||||
pixelsOut[indexOut] = c.red;
|
||||
pixelsOut[indexOut+1] = c.green;
|
||||
pixelsOut[indexOut+2] = c.blue;
|
||||
if(formatOut == GL_RGBA) {
|
||||
pixelsOut[indexOut+3] = c.alpha;
|
||||
}
|
||||
}
|
||||
return pixelsOut;
|
||||
}
|
||||
|
||||
@@ -13,164 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "GLcommon/TextureUtils.h"
|
||||
#include <GLcommon/TextureUtils.h>
|
||||
#include <GLcommon/GLESmacros.h>
|
||||
#include <GLcommon/GLESvalidate.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_SUPPORTED_PALLETE 10
|
||||
|
||||
|
||||
struct Color
|
||||
{
|
||||
Color(unsigned char r, unsigned char g,unsigned char b, unsigned char a):red(r),green(g),blue(b),alpha(a){};
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
unsigned char alpha;
|
||||
};
|
||||
|
||||
void getPaletteInfo(GLenum internalFormat,unsigned int& indexSizeBits,unsigned int& colorSizeBytes,GLenum& colorFrmt) {
|
||||
|
||||
colorFrmt = GL_RGB;
|
||||
switch(internalFormat)
|
||||
{
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
indexSizeBits = 4;
|
||||
colorSizeBytes = 3;
|
||||
break;
|
||||
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
indexSizeBits = 4;
|
||||
colorSizeBytes = 4;
|
||||
colorFrmt = GL_RGBA;
|
||||
break;
|
||||
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
colorFrmt = GL_RGBA;
|
||||
/* fall-through */
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
indexSizeBits = 4;
|
||||
colorSizeBytes = 2;
|
||||
break;
|
||||
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
indexSizeBits = 8;
|
||||
colorSizeBytes = 3;
|
||||
break;
|
||||
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
indexSizeBits = 8;
|
||||
colorSizeBytes = 4;
|
||||
colorFrmt = GL_RGBA;
|
||||
break;
|
||||
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
colorFrmt = GL_RGBA;
|
||||
/* fall-through */
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
indexSizeBits = 8;
|
||||
colorSizeBytes = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Color paletteColor(const unsigned char* pallete,unsigned int index,GLenum format)
|
||||
{
|
||||
short s;
|
||||
switch(format) {
|
||||
//RGB
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
return Color(pallete[index],pallete[index+1],pallete[index+2],0);
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
s = *((short *)(pallete+index));
|
||||
return Color((s >> 11)*255/31,((s >> 5) & 0x3f)*255/63 ,(s & 0x1f)*255/31,0);
|
||||
|
||||
//RGBA
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
return Color(pallete[index],pallete[index+1],pallete[index+2],pallete[index+3]);
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
s = *((short *)(pallete+index));
|
||||
return Color(((s >> 12) & 0xf)*255/15,((s >> 8) & 0xf)*255/15,((s >> 4) & 0xf)*255/15 ,(s & 0xf)*255/15);
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
s = *((short *)(pallete+index));
|
||||
return Color(((s >> 11) & 0x1f)*255/31,((s >> 6) & 0x1f)*255/31,((s >> 1) & 0x1f)*255/31 ,(s & 0x1) * 255);
|
||||
default:
|
||||
return Color(255,255,255,255);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level) {
|
||||
|
||||
unsigned int indexSizeBits; //the size of the color index in the pallete
|
||||
unsigned int colorSizeBytes; //the size of each color cell in the pallete
|
||||
|
||||
getPaletteInfo(internalformat,indexSizeBits,colorSizeBytes,formatOut);
|
||||
if(!data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unsigned char* palette = static_cast<const unsigned char *>(data);
|
||||
|
||||
//the pallete positioned in the begininng of the data
|
||||
// so we jump over it to get to the colos indices in the palette
|
||||
|
||||
int nColors = 2 << (indexSizeBits -1); //2^indexSizeBits
|
||||
int paletteSizeBytes = nColors*colorSizeBytes;
|
||||
const unsigned char* imageIndices = palette + paletteSizeBytes;
|
||||
|
||||
//jumping to the the correct mipmap level
|
||||
for(int i=0;i<level;i++) {
|
||||
imageIndices+= (width*height*indexSizeBits)/8;
|
||||
width = width >> 1;
|
||||
height = height >> 1;
|
||||
}
|
||||
|
||||
int colorSizeOut = (formatOut == GL_RGB? 3:4);
|
||||
int nPixels = width*height;
|
||||
unsigned char* pixelsOut = new unsigned char[nPixels*colorSizeOut];
|
||||
if(!pixelsOut) return NULL;
|
||||
|
||||
int leftBytes = ((palette + imageSize) /* the end of data pointer*/
|
||||
- imageIndices);
|
||||
int leftPixels = (leftBytes * 8 )/indexSizeBits;
|
||||
|
||||
int maxIndices = (leftPixels < nPixels) ? leftPixels:nPixels;
|
||||
|
||||
//filling the pixels array
|
||||
for(int i =0 ; i < maxIndices ; i++) {
|
||||
int paletteIndex = 0;
|
||||
int indexOut = i*colorSizeOut;
|
||||
if(indexSizeBits == 4) {
|
||||
paletteIndex = (i%2) == 0 ?
|
||||
imageIndices[i/2] >> 4: //upper bits
|
||||
imageIndices[i/2] & 0xf; //lower bits
|
||||
} else {
|
||||
paletteIndex = imageIndices[i];
|
||||
}
|
||||
|
||||
paletteIndex*=colorSizeBytes;
|
||||
Color c = paletteColor(palette,paletteIndex,internalformat);
|
||||
|
||||
pixelsOut[indexOut] = c.red;
|
||||
pixelsOut[indexOut+1] = c.green;
|
||||
pixelsOut[indexOut+2] = c.blue;
|
||||
if(formatOut == GL_RGBA) {
|
||||
pixelsOut[indexOut+3] = c.alpha;
|
||||
}
|
||||
}
|
||||
return pixelsOut;
|
||||
}
|
||||
#include <cmath>
|
||||
|
||||
int getCompressedFormats(int* formats){
|
||||
if(formats){
|
||||
//Palette
|
||||
formats[0] = GL_PALETTE4_RGBA8_OES;
|
||||
formats[1] = GL_PALETTE4_RGBA4_OES;
|
||||
formats[2] = GL_PALETTE8_RGBA8_OES;
|
||||
@@ -181,6 +32,72 @@ int getCompressedFormats(int* formats){
|
||||
formats[7] = GL_PALETTE8_RGB5_A1_OES;
|
||||
formats[8] = GL_PALETTE4_R5_G6_B5_OES;
|
||||
formats[9] = GL_PALETTE8_R5_G6_B5_OES;
|
||||
//ETC
|
||||
formats[MAX_SUPPORTED_PALETTE] = GL_ETC1_RGB8_OES;
|
||||
}
|
||||
return MAX_SUPPORTED_PALETTE + MAX_ETC_SUPPORTED;
|
||||
}
|
||||
|
||||
void doCompressedTexImage2D(GLEScontext * ctx, GLenum target, GLint level,
|
||||
GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLint border,
|
||||
GLsizei imageSize, const GLvoid* data)
|
||||
{
|
||||
|
||||
switch (internalformat) {
|
||||
case GL_ETC1_RGB8_OES:
|
||||
{
|
||||
GLint format = GL_RGB;
|
||||
GLint type = GL_UNSIGNED_BYTE;
|
||||
|
||||
GLsizei compressedSize = etc1_get_encoded_data_size(width, height);
|
||||
SET_ERROR_IF((compressedSize > imageSize), GL_INVALID_VALUE);
|
||||
|
||||
const int32_t align = ctx->getUnpackAlignment()-1;
|
||||
const int32_t bpr = ((width * 3) + align) & ~align;
|
||||
const size_t size = bpr * height;
|
||||
|
||||
etc1_byte* pOut = new etc1_byte[size];
|
||||
int res = etc1_decode_image((const etc1_byte*)data, pOut, width, height, 3, bpr);
|
||||
SET_ERROR_IF(res!=0, GL_INVALID_VALUE);
|
||||
ctx->dispatcher().glTexImage2D(target,level,format,width,height,border,format,type,pOut);
|
||||
delete [] pOut;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
{
|
||||
SET_ERROR_IF(level > log2(ctx->getMaxTexSize()) ||
|
||||
border !=0 || level > 0 ||
|
||||
!GLESvalidate::texImgDim(width,height,ctx->getMaxTexSize()+2),GL_INVALID_VALUE)
|
||||
|
||||
int nMipmaps = -level + 1;
|
||||
GLsizei tmpWidth = width;
|
||||
GLsizei tmpHeight = height;
|
||||
|
||||
for(int i = 0; i < nMipmaps ; i++)
|
||||
{
|
||||
GLenum uncompressedFrmt;
|
||||
unsigned char* uncompressed = uncompressTexture(internalformat,uncompressedFrmt,width,height,imageSize,data,i);
|
||||
ctx->dispatcher().glTexImage2D(target,i,uncompressedFrmt,tmpWidth,tmpHeight,border,uncompressedFrmt,GL_UNSIGNED_BYTE,uncompressed);
|
||||
tmpWidth/=2;
|
||||
tmpHeight/=2;
|
||||
delete uncompressed;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SET_ERROR_IF(1, GL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
return MAX_SUPPORTED_PALLETE;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ public:
|
||||
bool isInitialized() { return m_initialized; };
|
||||
void setUnpackAlignment(GLint param){ m_unpackAlignment = param; };
|
||||
GLint getUnpackAlignment(){ return m_unpackAlignment; };
|
||||
void doCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
|
||||
|
||||
bool isArrEnabled(GLenum);
|
||||
void enableArr(GLenum arr,bool enable);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __PALETTE_TEXTURE_H__
|
||||
#define __PALETTE_TEXTURE_H__
|
||||
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#define MAX_SUPPORTED_PALETTE 10
|
||||
|
||||
unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level);
|
||||
|
||||
#endif
|
||||
@@ -17,9 +17,15 @@
|
||||
#define _TEXTURE_UTILS_H
|
||||
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
#include "GLEScontext.h"
|
||||
#include "PaletteTexture.h"
|
||||
#include "etc1.h"
|
||||
|
||||
|
||||
unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level);
|
||||
int getCompressedFormats(int* formats);
|
||||
void doCompressedTexImage2D(GLEScontext * ctx, GLenum target, GLint level,
|
||||
GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLint border,
|
||||
GLsizei imageSize, const GLvoid* data);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef __etc1_h__
|
||||
#define __etc1_h__
|
||||
|
||||
#define MAX_ETC_SUPPORTED 1
|
||||
|
||||
#define ETC1_ENCODED_BLOCK_SIZE 8
|
||||
#define ETC1_DECODED_BLOCK_SIZE 48
|
||||
|
||||
|
||||
Reference in New Issue
Block a user