Merge "Support for cubemaps."
This commit is contained in:
committed by
Android (Google) Code Review
commit
a332678135
@@ -34,6 +34,18 @@ public class Allocation extends BaseObj {
|
||||
Type mType;
|
||||
Bitmap mBitmap;
|
||||
|
||||
public enum CubemapLayout {
|
||||
VERTICAL_FACE_LIST (0),
|
||||
HORIZONTAL_FACE_LIST (1),
|
||||
VERTICAL_CROSS (2),
|
||||
HORIZONTAL_CROSS (3);
|
||||
|
||||
int mID;
|
||||
CubemapLayout(int id) {
|
||||
mID = id;
|
||||
}
|
||||
}
|
||||
|
||||
Allocation(int id, RenderScript rs, Type t) {
|
||||
super(id, rs);
|
||||
mType = t;
|
||||
@@ -355,18 +367,21 @@ public class Allocation extends BaseObj {
|
||||
throw new RSInvalidStateException("Bad bitmap type: " + bc);
|
||||
}
|
||||
|
||||
static private Type typeFromBitmap(RenderScript rs, Bitmap b) {
|
||||
static private Type typeFromBitmap(RenderScript rs, Bitmap b, boolean mip) {
|
||||
Element e = elementFromBitmap(rs, b);
|
||||
Type.Builder tb = new Type.Builder(rs, e);
|
||||
tb.add(Dimension.X, b.getWidth());
|
||||
tb.add(Dimension.Y, b.getHeight());
|
||||
if (mip) {
|
||||
tb.add(Dimension.LOD, 1);
|
||||
}
|
||||
return tb.create();
|
||||
}
|
||||
|
||||
static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips) {
|
||||
|
||||
static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
|
||||
Element dstFmt, boolean genMips) {
|
||||
rs.validate();
|
||||
Type t = typeFromBitmap(rs, b);
|
||||
Type t = typeFromBitmap(rs, b, genMips);
|
||||
|
||||
int id = rs.nAllocationCreateFromBitmap(dstFmt.getID(), genMips, b);
|
||||
if(id == 0) {
|
||||
@@ -375,10 +390,49 @@ public class Allocation extends BaseObj {
|
||||
return new Allocation(id, rs, t);
|
||||
}
|
||||
|
||||
static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
|
||||
Element dstFmt,
|
||||
boolean genMips,
|
||||
CubemapLayout layout) {
|
||||
rs.validate();
|
||||
int height = b.getHeight();
|
||||
int width = b.getWidth();
|
||||
|
||||
if (layout != CubemapLayout.VERTICAL_FACE_LIST) {
|
||||
throw new RSIllegalArgumentException("Only vertical face list supported");
|
||||
}
|
||||
if (height % 6 != 0) {
|
||||
throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
|
||||
}
|
||||
if (height / 6 != width) {
|
||||
throw new RSIllegalArgumentException("Only square cobe map faces supported");
|
||||
}
|
||||
boolean isPow2 = (width & (width - 1)) == 0;
|
||||
if (!isPow2) {
|
||||
throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
|
||||
}
|
||||
|
||||
Element e = elementFromBitmap(rs, b);
|
||||
Type.Builder tb = new Type.Builder(rs, e);
|
||||
tb.add(Dimension.X, width);
|
||||
tb.add(Dimension.Y, width);
|
||||
tb.add(Dimension.FACE, 1);
|
||||
if (genMips) {
|
||||
tb.add(Dimension.LOD, 1);
|
||||
}
|
||||
Type t = tb.create();
|
||||
|
||||
int id = rs.nAllocationCubeCreateFromBitmap(dstFmt.getID(), genMips, b);
|
||||
if(id == 0) {
|
||||
throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
|
||||
}
|
||||
return new Allocation(id, rs, t);
|
||||
}
|
||||
|
||||
static public Allocation createBitmapRef(RenderScript rs, Bitmap b) {
|
||||
|
||||
rs.validate();
|
||||
Type t = typeFromBitmap(rs, b);
|
||||
Type t = typeFromBitmap(rs, b, false);
|
||||
|
||||
int id = rs.nAllocationCreateBitmapRef(t.getID(), b);
|
||||
if(id == 0) {
|
||||
@@ -404,7 +458,9 @@ public class Allocation extends BaseObj {
|
||||
if (aId == 0) {
|
||||
throw new RSRuntimeException("Load failed.");
|
||||
}
|
||||
return new Allocation(aId, rs, null);
|
||||
Allocation alloc = new Allocation(aId, rs, null);
|
||||
alloc.updateFromNative();
|
||||
return alloc;
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
|
||||
@@ -36,9 +36,32 @@ public class Program extends BaseObj {
|
||||
public static final int MAX_CONSTANT = 8;
|
||||
public static final int MAX_TEXTURE = 8;
|
||||
|
||||
public enum TextureType {
|
||||
TEXTURE_2D (0),
|
||||
TEXTURE_CUBE (1);
|
||||
|
||||
int mID;
|
||||
TextureType(int id) {
|
||||
mID = id;
|
||||
}
|
||||
}
|
||||
|
||||
enum ProgramParam {
|
||||
INPUT (0),
|
||||
OUTPUT (1),
|
||||
CONSTANT (2),
|
||||
TEXTURE_TYPE (3);
|
||||
|
||||
int mID;
|
||||
ProgramParam(int id) {
|
||||
mID = id;
|
||||
}
|
||||
};
|
||||
|
||||
Element mInputs[];
|
||||
Element mOutputs[];
|
||||
Type mConstants[];
|
||||
TextureType mTextures[];
|
||||
int mTextureCount;
|
||||
String mShader;
|
||||
|
||||
@@ -54,27 +77,34 @@ public class Program extends BaseObj {
|
||||
a.getType().getID() != mConstants[slot].getID()) {
|
||||
throw new IllegalArgumentException("Allocation type does not match slot type.");
|
||||
}
|
||||
mRS.nProgramBindConstants(getID(), slot, a.getID());
|
||||
int id = a != null ? a.getID() : 0;
|
||||
mRS.nProgramBindConstants(getID(), slot, id);
|
||||
}
|
||||
|
||||
public void bindTexture(Allocation va, int slot)
|
||||
throws IllegalArgumentException {
|
||||
mRS.validate();
|
||||
if((slot < 0) || (slot >= mTextureCount)) {
|
||||
if ((slot < 0) || (slot >= mTextureCount)) {
|
||||
throw new IllegalArgumentException("Slot ID out of range.");
|
||||
}
|
||||
if (va != null && va.getType().getFaces() &&
|
||||
mTextures[slot] != TextureType.TEXTURE_CUBE) {
|
||||
throw new IllegalArgumentException("Cannot bind cubemap to 2d texture slot");
|
||||
}
|
||||
|
||||
mRS.nProgramBindTexture(getID(), slot, va.getID());
|
||||
int id = va != null ? va.getID() : 0;
|
||||
mRS.nProgramBindTexture(getID(), slot, id);
|
||||
}
|
||||
|
||||
public void bindSampler(Sampler vs, int slot)
|
||||
throws IllegalArgumentException {
|
||||
mRS.validate();
|
||||
if((slot < 0) || (slot >= mTextureCount)) {
|
||||
if ((slot < 0) || (slot >= mTextureCount)) {
|
||||
throw new IllegalArgumentException("Slot ID out of range.");
|
||||
}
|
||||
|
||||
mRS.nProgramBindSampler(getID(), slot, vs.getID());
|
||||
int id = vs != null ? vs.getID() : 0;
|
||||
mRS.nProgramBindSampler(getID(), slot, id);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +114,7 @@ public class Program extends BaseObj {
|
||||
Element mOutputs[];
|
||||
Type mConstants[];
|
||||
Type mTextures[];
|
||||
TextureType mTextureTypes[];
|
||||
int mInputCount;
|
||||
int mOutputCount;
|
||||
int mConstantCount;
|
||||
@@ -100,6 +131,7 @@ public class Program extends BaseObj {
|
||||
mOutputCount = 0;
|
||||
mConstantCount = 0;
|
||||
mTextureCount = 0;
|
||||
mTextureTypes = new TextureType[MAX_TEXTURE];
|
||||
}
|
||||
|
||||
public BaseProgramBuilder setShader(String s) {
|
||||
@@ -192,6 +224,17 @@ public class Program extends BaseObj {
|
||||
throw new IllegalArgumentException("Max texture count exceeded.");
|
||||
}
|
||||
mTextureCount = count;
|
||||
for (int i = 0; i < mTextureCount; i ++) {
|
||||
mTextureTypes[i] = TextureType.TEXTURE_2D;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public BaseProgramBuilder addTexture(TextureType texType) throws IllegalArgumentException {
|
||||
if(mTextureCount >= MAX_TEXTURE) {
|
||||
throw new IllegalArgumentException("Max texture count exceeded.");
|
||||
}
|
||||
mTextureTypes[mTextureCount ++] = texType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -203,6 +246,8 @@ public class Program extends BaseObj {
|
||||
p.mConstants = new Type[mConstantCount];
|
||||
System.arraycopy(mConstants, 0, p.mConstants, 0, mConstantCount);
|
||||
p.mTextureCount = mTextureCount;
|
||||
p.mTextures = new TextureType[mTextureCount];
|
||||
System.arraycopy(mTextureTypes, 0, p.mTextures, 0, mTextureCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,23 +37,25 @@ public class ProgramFragment extends Program {
|
||||
|
||||
public ProgramFragment create() {
|
||||
mRS.validate();
|
||||
int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + 1) * 2];
|
||||
int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
|
||||
int idx = 0;
|
||||
|
||||
for (int i=0; i < mInputCount; i++) {
|
||||
tmp[idx++] = 0;
|
||||
tmp[idx++] = ProgramParam.INPUT.mID;
|
||||
tmp[idx++] = mInputs[i].getID();
|
||||
}
|
||||
for (int i=0; i < mOutputCount; i++) {
|
||||
tmp[idx++] = 1;
|
||||
tmp[idx++] = ProgramParam.OUTPUT.mID;
|
||||
tmp[idx++] = mOutputs[i].getID();
|
||||
}
|
||||
for (int i=0; i < mConstantCount; i++) {
|
||||
tmp[idx++] = 2;
|
||||
tmp[idx++] = ProgramParam.CONSTANT.mID;
|
||||
tmp[idx++] = mConstants[i].getID();
|
||||
}
|
||||
tmp[idx++] = 3;
|
||||
tmp[idx++] = mTextureCount;
|
||||
for (int i=0; i < mTextureCount; i++) {
|
||||
tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
|
||||
tmp[idx++] = mTextureTypes[i].mID;
|
||||
}
|
||||
|
||||
int id = mRS.nProgramFragmentCreate(mShader, tmp);
|
||||
ProgramFragment pf = new ProgramFragment(id, mRS);
|
||||
|
||||
@@ -46,23 +46,25 @@ public class ProgramVertex extends Program {
|
||||
|
||||
public ProgramVertex create() {
|
||||
mRS.validate();
|
||||
int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount +1) * 2];
|
||||
int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
|
||||
int idx = 0;
|
||||
|
||||
for (int i=0; i < mInputCount; i++) {
|
||||
tmp[idx++] = 0;
|
||||
tmp[idx++] = ProgramParam.INPUT.mID;
|
||||
tmp[idx++] = mInputs[i].getID();
|
||||
}
|
||||
for (int i=0; i < mOutputCount; i++) {
|
||||
tmp[idx++] = 1;
|
||||
tmp[idx++] = ProgramParam.OUTPUT.mID;
|
||||
tmp[idx++] = mOutputs[i].getID();
|
||||
}
|
||||
for (int i=0; i < mConstantCount; i++) {
|
||||
tmp[idx++] = 2;
|
||||
tmp[idx++] = ProgramParam.CONSTANT.mID;
|
||||
tmp[idx++] = mConstants[i].getID();
|
||||
}
|
||||
tmp[idx++] = 3;
|
||||
tmp[idx++] = mTextureCount;
|
||||
for (int i=0; i < mTextureCount; i++) {
|
||||
tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
|
||||
tmp[idx++] = mTextureTypes[i].mID;
|
||||
}
|
||||
|
||||
int id = mRS.nProgramVertexCreate(mShader, tmp);
|
||||
ProgramVertex pv = new ProgramVertex(id, mRS);
|
||||
|
||||
@@ -204,6 +204,10 @@ public class RenderScript {
|
||||
synchronized int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp) {
|
||||
return rsnAllocationCreateFromBitmap(mContext, dstFmt, genMips, bmp);
|
||||
}
|
||||
native int rsnAllocationCubeCreateFromBitmap(int con, int dstFmt, boolean genMips, Bitmap bmp);
|
||||
synchronized int nAllocationCubeCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp) {
|
||||
return rsnAllocationCubeCreateFromBitmap(mContext, dstFmt, genMips, bmp);
|
||||
}
|
||||
native int rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
|
||||
synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
|
||||
return rsnAllocationCreateBitmapRef(mContext, type, bmp);
|
||||
|
||||
@@ -455,6 +455,27 @@ nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint dst
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nAllocationCubeCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint dstFmt, jboolean genMips, jobject jbitmap)
|
||||
{
|
||||
SkBitmap const * nativeBitmap =
|
||||
(SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
|
||||
const SkBitmap& bitmap(*nativeBitmap);
|
||||
SkBitmap::Config config = bitmap.getConfig();
|
||||
|
||||
RsElement e = SkBitmapToPredefined(config);
|
||||
if (e) {
|
||||
bitmap.lockPixels();
|
||||
const int w = bitmap.width();
|
||||
const int h = bitmap.height();
|
||||
const void* ptr = bitmap.getPixels();
|
||||
jint id = (jint)rsaAllocationCubeCreateFromBitmap(con, w, h, (RsElement)dstFmt, e, genMips, ptr);
|
||||
bitmap.unlockPixels();
|
||||
return id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nAllocationUpdateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
|
||||
{
|
||||
@@ -1301,6 +1322,7 @@ static JNINativeMethod methods[] = {
|
||||
{"rsnAllocationCreateTyped", "(II)I", (void*)nAllocationCreateTyped },
|
||||
{"rsnAllocationUpdateFromBitmap", "(IILandroid/graphics/Bitmap;)V", (void*)nAllocationUpdateFromBitmap },
|
||||
{"rsnAllocationCreateFromBitmap", "(IIZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap },
|
||||
{"rsnAllocationCubeCreateFromBitmap","(IIZLandroid/graphics/Bitmap;)I", (void*)nAllocationCubeCreateFromBitmap },
|
||||
{"rsnAllocationCreateBitmapRef", "(IILandroid/graphics/Bitmap;)I", (void*)nAllocationCreateBitmapRef },
|
||||
{"rsnAllocationCreateFromAssetStream","(IIZI)I", (void*)nAllocationCreateFromAssetStream },
|
||||
{"rsnAllocationUploadToTexture", "(IIZI)V", (void*)nAllocationUploadToTexture },
|
||||
|
||||
@@ -160,6 +160,11 @@ enum RsSamplerValue {
|
||||
RS_SAMPLER_CLAMP
|
||||
};
|
||||
|
||||
enum RsTextureTarget {
|
||||
RS_TEXTURE_2D,
|
||||
RS_TEXTURE_CUBE
|
||||
};
|
||||
|
||||
enum RsDimension {
|
||||
RS_DIMENSION_X,
|
||||
RS_DIMENSION_Y,
|
||||
@@ -218,7 +223,7 @@ enum RsProgramParam {
|
||||
RS_PROGRAM_PARAM_INPUT,
|
||||
RS_PROGRAM_PARAM_OUTPUT,
|
||||
RS_PROGRAM_PARAM_CONSTANT,
|
||||
RS_PROGRAM_PARAM_TEXTURE_COUNT,
|
||||
RS_PROGRAM_PARAM_TEXTURE_TYPE,
|
||||
};
|
||||
|
||||
enum RsPrimitive {
|
||||
@@ -322,6 +327,7 @@ RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimCount,
|
||||
const RsDimension *dims, const uint32_t *vals);
|
||||
RsAllocation rsaAllocationCreateTyped(RsContext rsc, RsType vtype);
|
||||
RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data);
|
||||
RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data);
|
||||
|
||||
#ifndef NO_RS_FUNCS
|
||||
#include "rsgApiFuncDecl.h"
|
||||
|
||||
BIN
libs/rs/java/Samples/res/drawable/cubemap_test.png
Normal file
BIN
libs/rs/java/Samples/res/drawable/cubemap_test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
8
libs/rs/java/Samples/res/raw/shadercubef.glsl
Normal file
8
libs/rs/java/Samples/res/raw/shadercubef.glsl
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
varying vec3 worldNormal;
|
||||
|
||||
void main() {
|
||||
lowp vec4 col = textureCube(UNI_Tex0, worldNormal);
|
||||
gl_FragColor = col;
|
||||
}
|
||||
|
||||
10
libs/rs/java/Samples/res/raw/shadercubev.glsl
Normal file
10
libs/rs/java/Samples/res/raw/shadercubev.glsl
Normal file
@@ -0,0 +1,10 @@
|
||||
varying vec3 worldNormal;
|
||||
|
||||
// This is where actual shader code begins
|
||||
void main() {
|
||||
vec4 worldPos = UNI_model * ATTRIB_position;
|
||||
gl_Position = UNI_proj * worldPos;
|
||||
|
||||
mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
|
||||
worldNormal = model3 * ATTRIB_normal;
|
||||
}
|
||||
@@ -22,6 +22,8 @@ import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.renderscript.*;
|
||||
import android.renderscript.Allocation.CubemapLayout;
|
||||
import android.renderscript.Program.TextureType;
|
||||
import android.renderscript.ProgramStore.DepthFunc;
|
||||
import android.renderscript.Sampler.Value;
|
||||
import android.util.Log;
|
||||
@@ -80,6 +82,9 @@ public class RsRenderStatesRS {
|
||||
private ProgramVertex mProgVertexCustom2;
|
||||
private ProgramFragment mProgFragmentCustom2;
|
||||
|
||||
private ProgramVertex mProgVertexCube;
|
||||
private ProgramFragment mProgFragmentCube;
|
||||
|
||||
private ProgramRaster mCullBack;
|
||||
private ProgramRaster mCullFront;
|
||||
private ProgramRaster mCullNone;
|
||||
@@ -88,6 +93,7 @@ public class RsRenderStatesRS {
|
||||
private Allocation mTexOpaque;
|
||||
private Allocation mTexTransparent;
|
||||
private Allocation mTexChecker;
|
||||
private Allocation mTexCube;
|
||||
|
||||
private Mesh mMbyNMesh;
|
||||
private Mesh mTorus;
|
||||
@@ -240,6 +246,19 @@ public class RsRenderStatesRS {
|
||||
mProgFragmentCustom2 = pfbCustom.create();
|
||||
mProgFragmentCustom2.bindConstants(mFSConst2.getAllocation(), 0);
|
||||
|
||||
// Cubemap test shaders
|
||||
pvbCustom = new ProgramVertex.ShaderBuilder(mRS);
|
||||
pvbCustom.setShader(mRes, R.raw.shadercubev);
|
||||
pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
|
||||
pvbCustom.addConstant(mVSConst.getAllocation().getType());
|
||||
mProgVertexCube = pvbCustom.create();
|
||||
mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
|
||||
|
||||
pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
|
||||
pfbCustom.setShader(mRes, R.raw.shadercubef);
|
||||
pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
|
||||
mProgFragmentCube = pfbCustom.create();
|
||||
|
||||
pfbCustom = new ProgramFragment.ShaderBuilder(mRS);
|
||||
pfbCustom.setShader(mRes, R.raw.multitexf);
|
||||
pfbCustom.setTextureCount(3);
|
||||
@@ -247,10 +266,11 @@ public class RsRenderStatesRS {
|
||||
|
||||
mScript.set_gProgVertexCustom(mProgVertexCustom);
|
||||
mScript.set_gProgFragmentCustom(mProgFragmentCustom);
|
||||
mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
|
||||
|
||||
mScript.set_gProgVertexCustom2(mProgVertexCustom2);
|
||||
mScript.set_gProgFragmentCustom2(mProgFragmentCustom2);
|
||||
mScript.set_gProgVertexCube(mProgVertexCube);
|
||||
mScript.set_gProgFragmentCube(mProgFragmentCube);
|
||||
mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
|
||||
}
|
||||
|
||||
private Allocation loadTextureRGB(int id) {
|
||||
@@ -272,11 +292,16 @@ public class RsRenderStatesRS {
|
||||
mTexOpaque = loadTextureRGB(R.drawable.data);
|
||||
mTexTransparent = loadTextureARGB(R.drawable.leaf);
|
||||
mTexChecker = loadTextureRGB(R.drawable.checker);
|
||||
Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
|
||||
mTexCube = Allocation.createCubemapFromBitmap(mRS, b, Element.RGB_565(mRS), false,
|
||||
Allocation.CubemapLayout.VERTICAL_FACE_LIST);
|
||||
mTexCube.uploadToTexture(0);
|
||||
|
||||
mScript.set_gTexTorus(mTexTorus);
|
||||
mScript.set_gTexOpaque(mTexOpaque);
|
||||
mScript.set_gTexTransparent(mTexTransparent);
|
||||
mScript.set_gTexChecker(mTexChecker);
|
||||
mScript.set_gTexCube(mTexCube);
|
||||
}
|
||||
|
||||
private void initFonts() {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "rs_graphics.rsh"
|
||||
#include "shader_def.rsh"
|
||||
|
||||
const int gMaxModes = 10;
|
||||
const int gMaxModes = 11;
|
||||
|
||||
rs_program_vertex gProgVertex;
|
||||
rs_program_fragment gProgFragmentColor;
|
||||
@@ -34,6 +34,7 @@ rs_allocation gTexOpaque;
|
||||
rs_allocation gTexTorus;
|
||||
rs_allocation gTexTransparent;
|
||||
rs_allocation gTexChecker;
|
||||
rs_allocation gTexCube;
|
||||
|
||||
rs_mesh gMbyNMesh;
|
||||
rs_mesh gTorusMesh;
|
||||
@@ -71,6 +72,8 @@ rs_program_vertex gProgVertexCustom;
|
||||
rs_program_fragment gProgFragmentCustom;
|
||||
rs_program_vertex gProgVertexCustom2;
|
||||
rs_program_fragment gProgFragmentCustom2;
|
||||
rs_program_vertex gProgVertexCube;
|
||||
rs_program_fragment gProgFragmentCube;
|
||||
rs_program_fragment gProgFragmentMultitex;
|
||||
|
||||
float gDt = 0;
|
||||
@@ -506,6 +509,42 @@ void displayCustomShaderSamples2() {
|
||||
rsgDrawText("Custom shader sample with array uniforms", 10, rsgGetHeight() - 10);
|
||||
}
|
||||
|
||||
void displayCubemapShaderSample() {
|
||||
// Update vertex shader constants
|
||||
// Load model matrix
|
||||
// Aplly a rotation to our mesh
|
||||
gTorusRotation += 50.0f * gDt;
|
||||
if (gTorusRotation > 360.0f) {
|
||||
gTorusRotation -= 360.0f;
|
||||
}
|
||||
|
||||
// Position our model on the screen
|
||||
// Position our model on the screen
|
||||
rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f);
|
||||
rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f);
|
||||
rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f);
|
||||
// Setup the projectioni matrix
|
||||
float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
|
||||
rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
|
||||
rsAllocationMarkDirty(rsGetAllocation(gFSConstants));
|
||||
|
||||
rsgBindProgramVertex(gProgVertexCube);
|
||||
|
||||
// Fragment shader with texture
|
||||
rsgBindProgramStore(gProgStoreBlendNoneDepth);
|
||||
rsgBindProgramFragment(gProgFragmentCube);
|
||||
rsgBindSampler(gProgFragmentCube, 0, gLinearClamp);
|
||||
rsgBindTexture(gProgFragmentCube, 0, gTexCube);
|
||||
|
||||
// Use back face culling
|
||||
rsgBindProgramRaster(gCullBack);
|
||||
rsgDrawMesh(gTorusMesh);
|
||||
|
||||
rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
rsgBindFont(gFontMono);
|
||||
rsgDrawText("Cubemap shader sample", 10, rsgGetHeight() - 10);
|
||||
}
|
||||
|
||||
void displayMultitextureSample() {
|
||||
bindProgramVertexOrtho();
|
||||
rs_matrix4x4 matrix;
|
||||
@@ -632,6 +671,9 @@ int root(int launchID) {
|
||||
case 9:
|
||||
displayCustomShaderSamples2();
|
||||
break;
|
||||
case 10:
|
||||
displayCubemapShaderSample();
|
||||
break;
|
||||
}
|
||||
|
||||
return 10;
|
||||
|
||||
@@ -143,8 +143,19 @@ void * Adapter2D::getElement(uint32_t x, uint32_t y) const {
|
||||
rsAssert(mAllocation.get());
|
||||
rsAssert(mAllocation->getPtr());
|
||||
rsAssert(mAllocation->getType());
|
||||
if (mFace != 0 && !mAllocation->getType()->getDimFaces()) {
|
||||
LOGE("Adapter wants cubemap face, but allocation has none");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t * ptr = static_cast<uint8_t *>(mAllocation->getPtr());
|
||||
ptr += mAllocation->getType()->getLODOffset(mLOD, x, y);
|
||||
|
||||
if (mFace != 0) {
|
||||
uint32_t totalSizeBytes = mAllocation->getType()->getSizeBytes();
|
||||
uint32_t faceOffset = totalSizeBytes / 6;
|
||||
ptr += faceOffset * mFace;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,8 +123,22 @@ void Allocation::deferedUploadToTexture(const Context *rsc, bool genMipmap, uint
|
||||
mTextureGenMipmap = !mType->getDimLOD() && genMipmap;
|
||||
}
|
||||
|
||||
uint32_t Allocation::getGLTarget() const {
|
||||
if (mIsTexture) {
|
||||
if (mType->getDimFaces()) {
|
||||
return GL_TEXTURE_CUBE_MAP;
|
||||
} else {
|
||||
return GL_TEXTURE_2D;
|
||||
}
|
||||
}
|
||||
if (mIsVertexBuffer) {
|
||||
return GL_ARRAY_BUFFER;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Allocation::uploadToTexture(const Context *rsc) {
|
||||
//rsAssert(!mTextureId);
|
||||
|
||||
mIsTexture = true;
|
||||
if (!rsc->checkDriver()) {
|
||||
@@ -155,9 +169,30 @@ void Allocation::uploadToTexture(const Context *rsc) {
|
||||
}
|
||||
isFirstUpload = true;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, mTextureID);
|
||||
|
||||
GLenum target = (GLenum)getGLTarget();
|
||||
glBindTexture(target, mTextureID);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (target == GL_TEXTURE_2D) {
|
||||
upload2DTexture(isFirstUpload);
|
||||
} else if (target == GL_TEXTURE_CUBE_MAP) {
|
||||
uploadCubeTexture(isFirstUpload);
|
||||
}
|
||||
|
||||
if (mTextureGenMipmap) {
|
||||
#ifndef ANDROID_RS_BUILD_FOR_HOST
|
||||
glGenerateMipmap(target);
|
||||
#endif //ANDROID_RS_BUILD_FOR_HOST
|
||||
}
|
||||
|
||||
rsc->checkError("Allocation::uploadToTexture");
|
||||
}
|
||||
|
||||
void Allocation::upload2DTexture(bool isFirstUpload) {
|
||||
GLenum type = mType->getElement()->getComponent().getGLType();
|
||||
GLenum format = mType->getElement()->getComponent().getGLFormat();
|
||||
|
||||
Adapter2D adapt(getContext(), this);
|
||||
for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
|
||||
adapt.setLOD(lod+mTextureLOD);
|
||||
@@ -169,17 +204,45 @@ void Allocation::uploadToTexture(const Context *rsc) {
|
||||
0, format, type, ptr);
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
|
||||
adapt.getDimX(), adapt.getDimY(),
|
||||
format, type, ptr);
|
||||
adapt.getDimX(), adapt.getDimY(),
|
||||
format, type, ptr);
|
||||
}
|
||||
}
|
||||
if (mTextureGenMipmap) {
|
||||
#ifndef ANDROID_RS_BUILD_FOR_HOST
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
#endif //ANDROID_RS_BUILD_FOR_HOST
|
||||
}
|
||||
}
|
||||
|
||||
rsc->checkError("Allocation::uploadToTexture");
|
||||
void Allocation::uploadCubeTexture(bool isFirstUpload) {
|
||||
GLenum type = mType->getElement()->getComponent().getGLType();
|
||||
GLenum format = mType->getElement()->getComponent().getGLFormat();
|
||||
|
||||
GLenum faceOrder[] = {
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
||||
};
|
||||
|
||||
Adapter2D adapt(getContext(), this);
|
||||
for (uint32_t face = 0; face < 6; face ++) {
|
||||
adapt.setFace(face);
|
||||
|
||||
for (uint32_t lod = 0; (lod + mTextureLOD) < mType->getLODCount(); lod++) {
|
||||
adapt.setLOD(lod+mTextureLOD);
|
||||
|
||||
uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
|
||||
|
||||
if (isFirstUpload) {
|
||||
glTexImage2D(faceOrder[face], lod, format,
|
||||
adapt.getDimX(), adapt.getDimY(),
|
||||
0, format, type, ptr);
|
||||
} else {
|
||||
glTexSubImage2D(faceOrder[face], lod, 0, 0,
|
||||
adapt.getDimX(), adapt.getDimY(),
|
||||
format, type, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Allocation::deferedUploadToBufferObject(const Context *rsc) {
|
||||
@@ -205,10 +268,10 @@ void Allocation::uploadToBufferObject(const Context *rsc) {
|
||||
mUploadDefered = true;
|
||||
return;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
GLenum target = (GLenum)getGLTarget();
|
||||
glBindBuffer(target, mBufferID);
|
||||
glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(target, 0);
|
||||
rsc->checkError("Allocation::uploadToBufferObject");
|
||||
}
|
||||
|
||||
@@ -816,3 +879,55 @@ RsAllocation rsaAllocationCreateFromBitmap(RsContext con, uint32_t w, uint32_t h
|
||||
|
||||
return texAlloc;
|
||||
}
|
||||
|
||||
RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data) {
|
||||
Context *rsc = static_cast<Context *>(con);
|
||||
const Element *src = static_cast<const Element *>(_src);
|
||||
const Element *dst = static_cast<const Element *>(_dst);
|
||||
|
||||
// Cubemap allocation's faces should be Width by Width each.
|
||||
// Source data should have 6 * Width by Width pixels
|
||||
// Error checking is done in the java layer
|
||||
RsDimension dims[] = {RS_DIMENSION_X, RS_DIMENSION_Y, RS_DIMENSION_LOD, RS_DIMENSION_FACE};
|
||||
uint32_t dimValues[] = {w, w, genMips, true};
|
||||
RsType type = rsaTypeCreate(rsc, _dst, 4, dims, dimValues);
|
||||
|
||||
RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, type);
|
||||
Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
|
||||
if (texAlloc == NULL) {
|
||||
LOGE("Memory allocation failure");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *sourcePtr = (uint8_t*)data;
|
||||
ElementConverter_t cvt = pickConverter(dst, src);
|
||||
if (cvt) {
|
||||
for (uint32_t face = 0; face < 6; face ++) {
|
||||
Adapter2D faceAdapter(rsc, texAlloc);
|
||||
faceAdapter.setFace(face);
|
||||
|
||||
cvt(faceAdapter.getElement(0, 0), sourcePtr, w * w);
|
||||
|
||||
// Move the data pointer to the next cube face
|
||||
sourcePtr += w * w * src->getSizeBytes();
|
||||
|
||||
if (genMips) {
|
||||
Adapter2D adapt(rsc, texAlloc);
|
||||
Adapter2D adapt2(rsc, texAlloc);
|
||||
adapt.setFace(face);
|
||||
adapt2.setFace(face);
|
||||
for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
|
||||
adapt.setLOD(lod);
|
||||
adapt2.setLOD(lod + 1);
|
||||
mip(adapt2, adapt);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
|
||||
delete texAlloc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return texAlloc;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ public:
|
||||
void uploadToTexture(const Context *rsc);
|
||||
uint32_t getTextureID() const {return mTextureID;}
|
||||
|
||||
uint32_t getGLTarget() const;
|
||||
|
||||
void deferedUploadToBufferObject(const Context *rsc);
|
||||
void uploadToBufferObject(const Context *rsc);
|
||||
uint32_t getBufferObjectID() const {return mBufferID;}
|
||||
@@ -134,7 +136,8 @@ protected:
|
||||
|
||||
private:
|
||||
void init(Context *rsc, const Type *);
|
||||
|
||||
void upload2DTexture(bool isFirstUpload);
|
||||
void uploadCubeTexture(bool isFirstUpload);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -498,8 +498,8 @@ void FontState::initRenderState() {
|
||||
uint32_t tmp[4];
|
||||
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
|
||||
tmp[1] = (uint32_t)inputType;
|
||||
tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
|
||||
tmp[3] = 1;
|
||||
tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE;
|
||||
tmp[3] = RS_TEXTURE_2D;
|
||||
|
||||
mFontShaderFConstant.set(new Allocation(mRSC, inputType));
|
||||
ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(),
|
||||
|
||||
@@ -48,13 +48,14 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
|
||||
if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
|
||||
mConstantCount++;
|
||||
}
|
||||
if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_COUNT) {
|
||||
mTextureCount = params[ct+1];
|
||||
if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
|
||||
mTextureCount++;
|
||||
}
|
||||
}
|
||||
|
||||
mTextures = new ObjectBaseRef<Allocation>[mTextureCount];
|
||||
mSamplers = new ObjectBaseRef<Sampler>[mTextureCount];
|
||||
mTextureTargets = new RsTextureTarget[mTextureCount];
|
||||
mInputElements = new ObjectBaseRef<Element>[mInputCount];
|
||||
mOutputElements = new ObjectBaseRef<Element>[mOutputCount];
|
||||
mConstantTypes = new ObjectBaseRef<Type>[mConstantCount];
|
||||
@@ -63,6 +64,7 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
|
||||
uint32_t input = 0;
|
||||
uint32_t output = 0;
|
||||
uint32_t constant = 0;
|
||||
uint32_t texture = 0;
|
||||
for (uint32_t ct=0; ct < paramLength; ct+=2) {
|
||||
if (params[ct] == RS_PROGRAM_PARAM_INPUT) {
|
||||
mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1]));
|
||||
@@ -73,6 +75,9 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
|
||||
if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) {
|
||||
mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1]));
|
||||
}
|
||||
if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) {
|
||||
mTextureTargets[texture++] = (RsTextureTarget)params[ct+1];
|
||||
}
|
||||
}
|
||||
mIsInternal = false;
|
||||
uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL);
|
||||
@@ -106,6 +111,7 @@ Program::~Program() {
|
||||
}
|
||||
delete[] mTextures;
|
||||
delete[] mSamplers;
|
||||
delete[] mTextureTargets;
|
||||
delete[] mInputElements;
|
||||
delete[] mOutputElements;
|
||||
delete[] mConstantTypes;
|
||||
@@ -127,6 +133,7 @@ void Program::initMemberVars() {
|
||||
|
||||
mTextures = NULL;
|
||||
mSamplers = NULL;
|
||||
mTextureTargets = NULL;
|
||||
mInputElements = NULL;
|
||||
mOutputElements = NULL;
|
||||
mConstantTypes = NULL;
|
||||
@@ -176,6 +183,12 @@ void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) {
|
||||
LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot);
|
||||
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot");
|
||||
return;
|
||||
}
|
||||
|
||||
//LOGE("bindtex %i %p", slot, a);
|
||||
mTextures[slot].set(a);
|
||||
mDirty = true;
|
||||
|
||||
@@ -105,7 +105,7 @@ protected:
|
||||
// Constants are strictly accessed by programetic loads.
|
||||
ObjectBaseRef<Allocation> *mTextures;
|
||||
ObjectBaseRef<Sampler> *mSamplers;
|
||||
|
||||
RsTextureTarget *mTextureTargets;
|
||||
bool loadShader(Context *, uint32_t type);
|
||||
};
|
||||
|
||||
|
||||
@@ -99,15 +99,20 @@ void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, Shader
|
||||
}
|
||||
|
||||
mTextures[ct]->uploadCheck(rsc);
|
||||
glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
|
||||
GLenum target = (GLenum)mTextures[ct]->getGLTarget();
|
||||
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
|
||||
LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
|
||||
rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
|
||||
}
|
||||
glBindTexture(target, mTextures[ct]->getTextureID());
|
||||
rsc->checkError("ProgramFragment::setupGL2 tex bind");
|
||||
if (mSamplers[ct].get()) {
|
||||
mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
rsc->checkError("ProgramFragment::setupGL2 tex env");
|
||||
}
|
||||
|
||||
@@ -130,7 +135,11 @@ void ProgramFragment::createShader() {
|
||||
appendUserConstants();
|
||||
char buf[256];
|
||||
for (uint32_t ct=0; ct < mTextureCount; ct++) {
|
||||
sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct);
|
||||
if (mTextureTargets[ct] == RS_TEXTURE_2D) {
|
||||
sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct);
|
||||
} else {
|
||||
sprintf(buf, "uniform samplerCube UNI_Tex%i;\n", ct);
|
||||
}
|
||||
mShader.append(buf);
|
||||
}
|
||||
mShader.append(mUserShader);
|
||||
@@ -191,15 +200,13 @@ void ProgramFragmentState::init(Context *rsc) {
|
||||
|
||||
Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
|
||||
|
||||
uint32_t tmp[4];
|
||||
uint32_t tmp[2];
|
||||
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
|
||||
tmp[1] = (uint32_t)inputType;
|
||||
tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
|
||||
tmp[3] = 0;
|
||||
|
||||
Allocation *constAlloc = new Allocation(rsc, inputType);
|
||||
ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
|
||||
shaderString.length(), tmp, 4);
|
||||
shaderString.length(), tmp, 2);
|
||||
pf->bindAllocation(rsc, constAlloc, 0);
|
||||
pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
|
||||
@@ -253,16 +253,14 @@ void ProgramVertexState::init(Context *rsc) {
|
||||
shaderString.append(" varTex0 = ATTRIB_texture0;\n");
|
||||
shaderString.append("}\n");
|
||||
|
||||
uint32_t tmp[6];
|
||||
uint32_t tmp[4];
|
||||
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
|
||||
tmp[1] = (uint32_t)inputType;
|
||||
tmp[2] = RS_PROGRAM_PARAM_INPUT;
|
||||
tmp[3] = (uint32_t)attrElem;
|
||||
tmp[4] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
|
||||
tmp[5] = 0;
|
||||
|
||||
ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
|
||||
shaderString.length(), tmp, 6);
|
||||
shaderString.length(), tmp, 4);
|
||||
Allocation *alloc = new Allocation(rsc, inputType);
|
||||
pv->bindAllocation(rsc, alloc, 0);
|
||||
|
||||
|
||||
@@ -71,29 +71,32 @@ void Sampler::setupGL(const Context *rsc, const Allocation *tex) {
|
||||
GL_CLAMP_TO_EDGE, //RS_SAMPLER_CLAMP
|
||||
};
|
||||
|
||||
// This tells us the correct texture type
|
||||
GLenum target = (GLenum)tex->getGLTarget();
|
||||
|
||||
if (!rsc->ext_OES_texture_npot() && tex->getType()->getIsNp2()) {
|
||||
if (tex->getHasGraphicsMipmaps() && rsc->ext_GL_NV_texture_npot_2D_mipmap()) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, transNP[mMagFilter]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, transNP[mWrapS]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, transNP[mWrapT]);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, transNP[mMagFilter]);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, transNP[mWrapS]);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, transNP[mWrapT]);
|
||||
} else {
|
||||
if (tex->getHasGraphicsMipmaps()) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, trans[mMinFilter]);
|
||||
} else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
|
||||
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, transNP[mMinFilter]);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, trans[mWrapS]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, trans[mWrapT]);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, trans[mMagFilter]);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, trans[mWrapS]);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, trans[mWrapT]);
|
||||
}
|
||||
|
||||
float anisoValue = rsMin(rsc->ext_texture_max_aniso(), mAniso);
|
||||
if (rsc->ext_texture_max_aniso() > 1.0f) {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
|
||||
glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisoValue);
|
||||
}
|
||||
|
||||
rsc->checkError("Sampler::setupGL2 tex env");
|
||||
|
||||
Reference in New Issue
Block a user