am a99be30d: Merge "opengles Translator: get Compressed texture handling out from GLEScontext"
* commit 'a99be30d60ab0902b856502334a9c363b432b3bd': opengles Translator: get Compressed texture handling out from GLEScontext
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -705,6 +705,20 @@ GL_API void GL_APIENTRY glGetBooleanv( GLenum pname, GLboolean *params) {
|
||||
ctx->dispatcher().glGetBooleanv(GL_TEXTURE_GEN_R,&state_r);
|
||||
*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);
|
||||
}
|
||||
@@ -794,7 +824,21 @@ GL_API void GL_APIENTRY glGetFloatv( GLenum pname, GLfloat *params) {
|
||||
case GL_TEXTURE_GEN_STR_OES:
|
||||
glGetIntegerv(pname,&i);
|
||||
*params = (GLfloat)i;
|
||||
break;
|
||||
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