将iPhone游戏移植到Android-纹理和缓冲区 我用C++编程了我的游戏。我已经设法用ndk编译了所有的东西,但是我注意到了一些障碍

将iPhone游戏移植到Android-纹理和缓冲区 我用C++编程了我的游戏。我已经设法用ndk编译了所有的东西,但是我注意到了一些障碍,c++,android,opengl-es,android-ndk,C++,Android,Opengl Es,Android Ndk,如何将纹理加载到NDK OpenGL中(因为代码已经存在)?我确实使用了位图工厂来加载图像,然后将像素复制到一个ByteBuffer中,我分配了一个宽*高*4的大小。然后,我将ByteBuffer的数组发送到本机代码,并使用Get/ReleasePrimiativeArrayCritical拉出一个指针。我认为它不起作用,因为它在渲染时会崩溃。另外,我也情不自禁地注意到垃圾编译器抱怨说,当映像只有16KB时,占用了大约5.37MB的空间 另一个是缓冲区,比如帧缓冲区和渲染缓冲区。我注意到它没有使

如何将纹理加载到NDK OpenGL中(因为代码已经存在)?我确实使用了位图工厂来加载图像,然后将像素复制到一个ByteBuffer中,我分配了一个宽*高*4的大小。然后,我将ByteBuffer的数组发送到本机代码,并使用Get/ReleasePrimiativeArrayCritical拉出一个指针。我认为它不起作用,因为它在渲染时会崩溃。另外,我也情不自禁地注意到垃圾编译器抱怨说,当映像只有16KB时,占用了大约5.37MB的空间


另一个是缓冲区,比如帧缓冲区和渲染缓冲区。我注意到它没有使用帧缓冲区和渲染缓冲区。GLSurfaceView是否自动执行此操作?使用我自己的缓冲区可以吗?

我已经弄明白了。结果是BitmapFactory将我的图像缩放为非2倍大小,因此无法工作。GLSurfaceView支持OpenGL ES 1.0的操作方式,您只需在屏幕上绘制即可。我可以使用帧缓冲区,但我必须将它们链接到纹理,然后将纹理绘制到屏幕上。我使用它并将其移植到本机,不包括深度缓冲区

代码如下:

爪哇:

C++:

#包括“您的公司_NativeRenderer.h”
#包括
#包括
#包括
#包括
#包括“Functions.h”
静态胶合纹理[2];
静态GLuint帧缓冲区;
静态胶粘渲染缓冲;
静态胶粘织物缓冲;
静态int纹理宽度;
静态int结构权重;
静态整数开关;
静态积分;
静态浮点数;
void viewportFramebuffer()
{
glViewport(0,0,纹理宽度,纹理高度);
glMatrixMode(GL_投影);
glLoadIdentity();
静态浮动视口FrameBufferRight=160.0f+(320.0/(浮动)sWidth)*(纹理宽度-sWidth);
静态浮动视口FrameBufferTop=hhHeight+((2*hheight)/(float)sHeight)*(纹理高度-sHeight);
glOrthof(-160.0f,viewportFramebufferRight,-hhHeight,viewportFramebufferTop,-1.0f,1.0f);
glMatrixMode(GLU模型视图);
glLoadIdentity();
}
void视口曲面()
{
glViewport(0,0,sWidth,sheigh);
glMatrixMode(GL_投影);
glLoadIdentity();
格洛托夫(-160.0f,160.0f,-hhheight,hhheight,-1.0f,1.0f);
glMatrixMode(GLU模型视图);
glLoadIdentity();
}
JNIEXPORT void JNICALL Java\u您的公司\u NativeRenderer\u init
(JNIEnv*env,jclass obj)
{
__安卓日志打印(安卓日志信息,标签,“init()”;
glGenFramebuffersOES(1,&framebuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES,FRAMEBUFFER);
glEnable(GL_纹理_2D);
//glEnable(GL_混合物);
glGenTextures(2,纹理);
texturebuffer=纹理[0];
}
JNIEXPORT void JNICALL Java\u您的公司\u本地供应商\u setTexture
(JNIEnv*env、jclass obj、jbyteArray数组、jint宽度、jint高度)
{
__android_log_print(android_log_INFO,标签,“setTexture()”);
void*image=env->GetPrimitiveArrayCritical(数组,0);
unsigned int*imageData=static_cast(图像);
FlipImageVertical(imageData、宽度、高度);//垂直翻转字节
glBindTexture(GL_TEXTURE_2D,纹理[1]);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
GLTEXAGE2D(GL_纹理_2D,0,GL_RGBA,宽度,高度,0,GL_RGBA,GL_无符号_字节,图像);
env->ReleasePrimitiveArrayCritical(数组,图像,0);
}
JNIEXPORT void JNICALL Java\u您的公司\u本地用户\u调整大小
(JNINEV*env,jclass obj,jint宽度,jint高度)
{
__安卓日志打印(安卓日志信息,标签,“调整大小(宽度:%d,高度:%d)”,宽度,高度);
sWidth=宽度;
sHeight=高度;
hhheight=240.0f+附加刻度平面(宽度、高度);//用于调整spect比率
//iPhone是2:3,我的Galaxy S是5:3
__android_日志_打印(android_日志_信息,标签,“hhheight:%g”,hhheight);
textureWidth=功率(宽度);
纹理高度=功率(高度);
__安卓日志打印(安卓日志信息,标签,“纹理:{w:%d,h:%d}”,纹理宽度,纹理高度);
glBindTexture(GL_TEXTURE_2D,texturebuffer);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
glTexParameteri(GL_纹理_2D、GL_纹理_包裹、GL_夹紧_至_边缘);
glTexParameteri(GL_纹理\u 2D、GL_纹理\u包裹\u T、GL_夹紧\u至\u边缘);
glColor4ub(0,0,0,255);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,textureWidth,TextureHight,0,GL_RGBA,GL_无符号字节,NULL);
int area[]={0.0,0.0,sWidth,sHeight};//使用draw_纹理扩展
glTexParameteriv(GL_纹理2D、GL_纹理裁剪、面积);
glBindFramebufferOES(GL_FRAMEBUFFER_OES,FRAMEBUFFER);
glFramebufferTexture2DOES(GL_帧缓冲区_OES、GL_颜色_附件0_OES、GL_纹理_2D、texturebuffer,0);
int status=glCheckFramebufferStatusOES(GL\u FRAMEBUFFER\u OES);
如果(状态!=GL\U帧缓冲区\U完成\U OES)
__android_日志_打印(android_日志_错误,标记“帧缓冲区未完成:%x”,状态);
glBindFramebufferOES(GL_FRAMEBUFFER_OES,FRAMEBUFFER);
}
JNIEXPORT void JNICALL Java\u您的公司\u本地供应商\u呈现
(JNIEnv*env,jclass obj)
{
静态浮动texCoord[]={
0.0, 0.0,
0.0, 480.0/512.0,
320.0/512.0, 0.0,
320.0/512.0, 480.0/512.0,
};
静态浮点顶点[]={
-160.0, -240.0,
-160.0, 240.0,
160.0, -240.0,
160.0, 240.0,
};
//屏幕外
viewportFramebuffer();
glBindFramebufferOES(GL_FRAMEBUFFER_OES,FRAMEBUFFER);
glClearColor(1.0,0.0,0.0,1.0);
glClear(GLU颜色缓冲位);
glEnableClientState(GL_顶点_数组);
glEnableClientState(GL_纹理_坐标_阵列);
glBindTexture(GL_TEXTURE_2D,纹理[1]);
glVertexPointer(2,GLU浮动,
public class NativeRenderer implements Renderer {

    static {
        System.loadLibrary("Test");
    }

    private static native void init();
    private static native void setTexture(byte[] data, int width, int height);
    private static native void resize(int width, int height);
    private static native void render();

    private Context mContext;

    public NativeRenderer(Context context)
    {
        mContext = context;
    }

    public void onDrawFrame(GL10 gl) {
        render();
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        resize(width, height);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        init();

        ByteBuffer data;

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.ARGB_8888;  //ARGB_888 is the default
        opts.inDensity = 240; // this needed so my images are 512x512 (power of 2)
        opts.inScaled = false; // someone suggested to add this
        Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.image, opts);

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        data = ByteBuffer.allocate(width * height * 4);

        Log.i(TAG, "allocate:" + (width * height * 4));
        data.order(ByteOrder.nativeOrder());
        bitmap.copyPixelsToBuffer(data);
        data.position(0);
        bitmap.recycle();

        Log.i(TAG, "data.hasArray():" + data.hasArray());

        setTexture(data.array(), width, height);
    }
}
#include "your_company_NativeRenderer.h"
#include <android/log.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <string.h>
#include "Functions.h"

static GLuint texture[2];
static GLuint framebuffer;
static GLuint renderbuffer;
static GLuint texturebuffer;
static int textureWidth;
static int textureHeight;
static int sWidth;
static int sHeight;
static float hheight;

void viewportFramebuffer()
{
    glViewport(0, 0, textureWidth, textureHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    static float viewportFramebufferRight = 160.0f + (320.0 / (float)sWidth) * (textureWidth - sWidth);
    static float viewportFramebufferTop = hheight + ((2 * hheight) / (float)sHeight) * (textureHeight - sHeight);

    glOrthof(-160.0f, viewportFramebufferRight, -hheight, viewportFramebufferTop, -1.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void viewportSurface()
{
    glViewport(0, 0, sWidth, sHeight);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glOrthof(-160.0f, 160.0f, -hheight, hheight, -1.0f, 1.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

JNIEXPORT void JNICALL Java_your_company_NativeRenderer_init
  (JNIEnv *env, jclass obj)
{
    __android_log_print(ANDROID_LOG_INFO, TAG, "init()");

    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

    glEnable(GL_TEXTURE_2D);
    //glEnable(GL_BLEND);

    glGenTextures(2, texture);
    texturebuffer = texture[0];
}

JNIEXPORT void JNICALL Java_your_company_NativeRenderer_setTexture
  (JNIEnv *env, jclass obj, jbyteArray array, jint width, jint height)
{
    __android_log_print(ANDROID_LOG_INFO, TAG, "setTexture()");

    void *image = env->GetPrimitiveArrayCritical(array, 0);
    unsigned int *imageData = static_cast<unsigned int *>(image);

    flipImageVertically(imageData, width, height); // flips the bytes vertically

    glBindTexture(GL_TEXTURE_2D, texture[1]);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

    env->ReleasePrimitiveArrayCritical(array, image, 0);
}

JNIEXPORT void JNICALL Java_your_company_NativeRenderer_resize
  (JNIEnv *env, jclass obj, jint width, jint height)
{
    __android_log_print(ANDROID_LOG_INFO, TAG, "resize(width:%d, height:%d)", width, height);

    sWidth = width;
    sHeight = height;

    hheight = 240.0f + additionToScalePlane(width, height); // used to adjust the spect ratio
    // iPhone is 2 : 3, my Galaxy S is 5 : 3

    __android_log_print(ANDROID_LOG_INFO, TAG, "hheight:%g", hheight);

    textureWidth = powerOf2Bigger(width);
    textureHeight = powerOf2Bigger(height);

    __android_log_print(ANDROID_LOG_INFO, TAG, "texture:{w:%d, h:%d}", textureWidth, textureHeight);

    glBindTexture(GL_TEXTURE_2D, texturebuffer);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glColor4ub(0, 0, 0, 255);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    int area[] = {0.0, 0.0, sWidth, sHeight}; // using draw_texture extension

    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, area);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texturebuffer, 0);

    int status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if(status != GL_FRAMEBUFFER_COMPLETE_OES)
        __android_log_print(ANDROID_LOG_ERROR, TAG, "Framebuffer is not complete: %x", status);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);
}

JNIEXPORT void JNICALL Java_your_company_NativeRenderer_render
  (JNIEnv *env, jclass obj)
{
    static float texCoord[] = {
            0.0, 0.0,
            0.0, 480.0/512.0,
            320.0/512.0, 0.0,
            320.0/512.0, 480.0/512.0,
    };

    static float vertex[] = {
            -160.0, -240.0,
            -160.0, 240.0,
            160.0, -240.0,
            160.0, 240.0,
    };

    //off-screen
    viewportFramebuffer();

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

    glClearColor(1.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindTexture(GL_TEXTURE_2D, texture[1]);

    glVertexPointer(2, GL_FLOAT, 0, vertex);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

    //on-screen
    viewportSurface();

    glClearColor(0.0, 0.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    /*static float textureCoord[] = {
        0.0, 0.0,
        0.0, sHeight/(float)textureHeight,
        sWidth/(float)textureWidth, 0.0,
        sWidth/(float)textureWidth, sHeight/(float)textureHeight,
    };

    static float textureVertex[] = {
            -160.0, -hheight,
            -160.0, hheight,
            160.0, -hheight,
            160.0, hheight,
    };*/ //if there isn't draw_texture extension

    glBindTexture(GL_TEXTURE_2D, texturebuffer);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glActiveTexture(GL_TEXTURE0);

    glDrawTexiOES(0, 0, 0, sWidth, sHeight);

    //glVertexPointer(2, GL_FLOAT, 0, textureVertex);
    //glTexCoordPointer(2, GL_FLOAT, 0, textureCoord);
    //glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    //glDisableClientState(GL_VERTEX_ARRAY);
    //glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindTexture(GL_TEXTURE_2D, 0);
}