我正在尝试在Android(java)中为Unity3D创建一个插件,以使用OpenGL纹理进行渲染,获取原生指针并在Unity中编写Quad . 到目前为止我的Unity代码很简单:
// Use this for initialization
void Start () {
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
context = jc.GetStatic<AndroidJavaObject>("currentActivity");
surface2Unity = new AndroidJavaObject("com.everywoah.surface2unity.Surface2Unity");
int i = surface2Unity.Call<int> ("getTextureID");
t =Texture2D.CreateExternalTexture (1280, 720, TextureFormat.ARGB32, false,false, new IntPtr(i));
t.filterMode = FilterMode.Bilinear;
t.wrapMode = TextureWrapMode.Repeat;
debug.text = "" + i;
GetComponent<MeshRenderer> ().material.mainTexture = t;
}
// Update is called once per frame
void Update () {
//transform.Rotate(1f,1f,1f);
surface2Unity.Call ("draw");
}
在Java中我有:
public MyRenderer(){
initGL();
initFBO();
}
private void initGL(){
GLstatics.checkGlError("initGL_S");
String vertexShader = "attribute vec4 aPosition;\n" +
"attribute vec4 aTex;\n" +
"varying vec2 tex;\n" +
"void main() {\n" +
" gl_Position = aPosition;\n" +
"tex=aTex.xy;\n" +
"}";
String fragmentShader = "precision mediump float;\n" +
"\n" +
"void main(){\n" +
" gl_FragColor = vec4(1.0,1.0,0.0,1.0);\n" +
"\n" +
"}";
mProgram = GLstatics.createProgram(vertexShader, fragmentShader);
maPositionHandle = GLES30.glGetAttribLocation(mProgram, "aPosition");
maTexHandle = GLES30.glGetAttribLocation(mProgram, "aTex");
GLstatics.checkGlError("initGL_E");
}
private void initFBO(){
GLstatics.checkGlError("initFBO_S");
GLES30.glGenFramebuffers(1, mFboId, 0);
GLES30.glGenRenderbuffers(1, mRboId, 0);
GLES30.glGenTextures(1, mTexId, 0);
GLES30.glGenBuffers(1,buffer, 0);
GLES30.glBindRenderbuffer(GLES30.GL_RENDERBUFFER, mRboId[0]);
GLES30.glRenderbufferStorage(GLES30.GL_RENDERBUFFER, GLES30.GL_DEPTH_COMPONENT16, 1280,
720);
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFboId[0]);
GLES30.glFramebufferRenderbuffer(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_ATTACHMENT,
GLES30.GL_RENDERBUFFER, mRboId[0]);
GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mTexId[0]);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA, 1280, 720, 0,
GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, null);
GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0,
GLES30.GL_TEXTURE_2D, mTexId[0], 0);
GLstatics.checkGlError("initFBO_E ");
}
public void draw() {
GLstatics.checkGlError("draw_S");
GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFboId[0]);
GLES30.glClearColor(0.0f,0.0f,1.0f,1.0f);
GLES30.glViewport(0, 0, 1280, 720);
GLES30.glClear(GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT);
GLES30.glUseProgram(mProgram);
mVtxBuf.position(0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, buffer[0]);
GLES30.glVertexAttribPointer(maPositionHandle,
3, GLES30.GL_FLOAT, false, 4*(3+2), mVtxBuf);
GLES30.glEnableVertexAttribArray(maPositionHandle);
mVtxBuf.position(3);
GLES30.glVertexAttribPointer(maTexHandle, 2, GLES30.GL_FLOAT, false, 4 * (3 + 2), mVtxBuf);
GLES30.glEnableVertexAttribArray(maTexHandle);
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
GLstatics.checkGlError("draw_E ");
}
它应该是一个非常简单的代码,只是在蓝色背景中绘制一个黄色矩形,我可以使它在一个Activity中工作 . 这里的问题是我的应用程序看起来像这样:
从我认为我已经搞乱了已经绑定的openGL缓冲区,导致我的矩形的顶点被绘制但内部有一个奇怪的东西 . 我已经尝试保存它们并在绘制函数后绑定它们但我得到了相同的结果 . 我有什么想法我做错了吗?如果可能,我真的想用Java解决这个问题,我有使用NDK的经验 .
2 回答
java side:public int loadImageReturnTexturePtr(String imagePath,int width,int heigh){Log.d(“unity”,“loading image1:”imagePath);
unity c#side://用于初始化void Start(){AndroidJavaObject mImageLoader = new AndroidJavaObject(“com.dvision.load.LoadTexture”); Texture2D texture2D = new Texture2D(2048,2048,TextureFormat.ARGB32,false);
你可以使用这个函数:Texture2D.CreateExternalTexture它很简单 .
好吧,问题是我必须自己控制EGLContex,我不能在与Unity相同的上下文中进行渲染,所以我需要这个类:
和方法:
这样我可以调用saveRenderState(),makeCurrent(),draw()和restoreRenderState(),现在一切正常 .