Déterminer la limite de taille de texture Max / Min dans Android OpenGLES

J'ai été affecté à créer un port Java open source de ce framework Objective C GPUImage afin qu'il puisse être utilisé dans une application Android. Je dois le recréer aussi étroitement que possible, avec tous les noms de variables, noms de fonctions, etc. tout de même. Je suis dans les étapes de début et j'essaie de transporter GPUImageOpenGLESContext.h et GPUImageOpenGLESContext.m (Désolé, fournira des liens, mais en tant que nouveaux utilisateurs, je ne peux pas ajouter d'autres liens).

J'ai de la difficulté avec ces méthodes

  • Base de données SQLite pour une application Android avec de multiples utilisateurs potentiels
  • Comment lire le tampon de trame actuel dans Android?
  • Modification de l'image de ressource de Progress Bar
  • Afficher une image "Loading ..." pendant le chargement en arrière-plan de l'image avec Picasso
  • Filtrage des ressources du monolithe Play Services pour rendre votre APK plus petit
  • Régler la hauteur de la vue dans Scrollview dans Android
  • + (GLint)maximumTextureSizeForThisDevice; { GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); return maxTextureSize; } + (GLint)maximumTextureUnitsForThisDevice; { GLint maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); return maxTextureUnits; } 

    Il semble que dans Objective C, vous pouvez simplement appeler ces méthodes, mais Java vous ne pouvez pas. J'ai fait des recherches et trouvé que la plupart des gens ont dit utiliser un GLSurfaceView, mais cela nécessiterait une activité, n'est-ce pas? J'étais très excité quand j'ai trouvé cette limite de taille de texture Maximum Maximum OpenGL ES 2.0 sur Android , mais la réponse affirme que le code ne fonctionnerait pas.

    Donc, ma question est de savoir comment obtenir la texture minimale et maximale dans une classe qui n'est pas une activité? À l'aide de GLSurfaceView?

    J'apprécierais également toute suggestion sur la façon de mettre fin à cela. Je n'ai jamais porté quelque chose de Objective C à Java, donc tout conseil serait apprécié!

    Si cela serait utile, voici mon code actuel:

     public class GPUImageOpenGLESContext { private static GPUImageOpenGLESContext instance = null; EGLContext context; protected GPUImageOpenGLESContext() { // This is a protected empty method // that exists only to prevent // this singleton object from // multiple instantiation return; } public enum GPUImageRotationMode { kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizontal, kGPUImageRotateRightFlipVertical, kGPUImageRotate180 } public GPUImageRotationMode GPUImageRotationSwapsWidthAndHeight(GPUImageRotationMode rotation) { // TODO: Implement GPUImageRotationSwapsWidthAndHeight macro as method //rotation = ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical) return rotation; } public static GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext() { if (instance == null) { instance = new GPUImageOpenGLESContext(); } return instance; } public static void useImageProcessingContext() { EGLContext imageProcessingContext = GPUImageOpenGLESContext.sharedImageProcessingOpenGLESContext().context; if (EGLContext.getEGL() != imageProcessingContext) { // In Objective C, this call would be here: // [EAGLContext setCurrentContext:imageProcessingContext] // Cannot figure out how to handle this. For now, throws an exception. throw new RuntimeException("useImageProcessingContext not equal to EGLContext"); } return; } public static int maximumTextureSizeForThisDevice() { int[] maxTextureSize = new int[1]; // TODO: See if you can use gl. without an activity //GL10 gl = new GL10(); //EGL gl = EGLContext.getEGL(); //gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0); return maxTextureSize[0]; } public static int maximumTextureUnitsForThisDevice() { // TODO: Implement maximumTextureUnitsForThisDevice(); return -1; } public static CGSize sizeThatFitsWithinATextureForSize(CGSize inputSize) { int maxTextureSize = maximumTextureSizeForThisDevice(); if ((inputSize.width < maxTextureSize) && (inputSize.height < maxTextureSize)) { return inputSize; } CGSize adjustedSize = new CGSize(); if (inputSize.width > inputSize.height) { adjustedSize.width = (float)maxTextureSize; adjustedSize.height = ((float)maxTextureSize / inputSize.width) * inputSize.height; } else { adjustedSize.height = (float)maxTextureSize; adjustedSize.width = ((float)maxTextureSize / inputSize.height) * inputSize.width; } return adjustedSize; } public EGLContext getContext() { if (context == null) { // TODO: Implement getContext() } } public interface GPUImageInput { public void newFrameReadyAtTime(Time frameTime); public void setInputTextureAtIndex(int newInputTexture, int textureIndex); public int nextAvailableTextureIndex(); public void setInputSizeAtIndex(CGSize newSize, int textureIndex); public void setInputRotationAtIndex(GPUImageRotationMode newInputRotation, int textureIndex); public CGSize maximumOutputSize(); public void endProcessing(); public boolean shouldIgnoreUpdatesToThisTarget(); } } 

  • Logcat ne s'affichera pas
  • Seuls certains utilisateurs signalent une erreur "Resource Not Found". Est-ce que ça a du sens?
  • L-Release-like Touch Ripple animation sur pré-L
  • Comment puis-je désérialiser un objet JSON mais garder un champ spécifique en tant que Chaîne au lieu d'un objet imbriqué?
  • Valeur AudioSource pour microphone USB sur Android
  • Correction de debug.keystore pour fonctionner avec ADT 22 et Google Maps v1 API Key
  • One Solution collect form web for “Déterminer la limite de taille de texture Max / Min dans Android OpenGLES”

    Je me rends compte que c'est une ancienne publication, mais votre problème est que vous n'avez pas correctement initialisé l'EGLContext.

    Habituellement, vous souhaitez utiliser un GLSurfaceView ou un TextureView pour inclure réellement votre contenu GL dans la hiérarchie View. GLSurfaceView traitera beaucoup de choses pour vous, comme créer correctement EGLContext et gérer un thread de rendu. TextureView nécessite un peu plus de travail manuel.

    Une fois que vous avez un contexte par l'un ou l'autre de ces moyens, vous pouvez utiliser:

     GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, size, 0); 

    En supposant que vous avez lié l'OpenGL ES 2.0 API. D'abord, assurez-vous que vous avez créé correctement votre EGLContext et que vous pouvez exécuter des appels EGL et GLES alors vous devriez pouvoir interroger la taille maximale de la texture.

    Vous pouvez voir la publication de Romain Guy sur l'utilisation d'une TextureView comme vous le verrez GLSurfaceView pour voir les détails généraux sur la gestion de votre propre EGLContext ici ( https://groups.google.com/d/msg/android-developers/U5RXFGpAHPE/IqHeIeGXhr0J ) :

    GLSurfaceView gère la configuration GL pour vous, que TextureView ne fera pas. Une TextureView peut être utilisée comme fenêtre native lorsque vous créez une surface EGL. Voici un exemple (la partie intéressante est l'appel à eglCreateWindowSurface ()):

     @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mRenderThread = new RenderThread(getResources(), surface); mRenderThread.start(); } private static class RenderThread extends Thread { private static final String LOG_TAG = "GLTextureView"; static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; static final int EGL_OPENGL_ES2_BIT = 4; private volatile boolean mFinished; private final Resources mResources; private final SurfaceTexture mSurface; private EGL10 mEgl; private EGLDisplay mEglDisplay; private EGLConfig mEglConfig; private EGLContext mEglContext; private EGLSurface mEglSurface; private GL mGL; RenderThread(Resources resources, SurfaceTexture surface) { mResources = resources; mSurface = surface; } private static final String sSimpleVS = "attribute vec4 position;\n" + "attribute vec2 texCoords;\n" + "varying vec2 outTexCoords;\n" + "\nvoid main(void) {\n" + " outTexCoords = texCoords;\n" + " gl_Position = position;\n" + "}\n\n"; private static final String sSimpleFS = "precision mediump float;\n\n" + "varying vec2 outTexCoords;\n" + "uniform sampler2D texture;\n" + "\nvoid main(void) {\n" + " gl_FragColor = texture2D(texture, outTexCoords);\n" + "}\n\n"; private static final int FLOAT_SIZE_BYTES = 4; private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; private final float[] mTriangleVerticesData = { // X, Y, Z, U, V -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; @Override public void run() { initGL(); FloatBuffer triangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); triangleVertices.put(mTriangleVerticesData).position(0); int texture = loadTexture(R.drawable.large_photo); int program = buildProgram(sSimpleVS, sSimpleFS); int attribPosition = glGetAttribLocation(program, "position"); checkGlError(); int attribTexCoords = glGetAttribLocation(program, "texCoords"); checkGlError(); int uniformTexture = glGetUniformLocation(program, "texture"); checkGlError(); glBindTexture(GL_TEXTURE_2D, texture); checkGlError(); glUseProgram(program); checkGlError(); glEnableVertexAttribArray(attribPosition); checkGlError(); glEnableVertexAttribArray(attribTexCoords); checkGlError(); glUniform1i(uniformTexture, texture); checkGlError(); while (!mFinished) { checkCurrent(); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); checkGlError(); glClear(GL_COLOR_BUFFER_BIT); checkGlError(); // drawQuad triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { throw new RuntimeException("Cannot swap buffers"); } checkEglError(); try { Thread.sleep(2000); } catch (InterruptedException e) { // Ignore } } finishGL(); } private int loadTexture(int resource) { int[] textures = new int[1]; glActiveTexture(GL_TEXTURE0); glGenTextures(1, textures, 0); checkGlError(); int texture = textures[0]; glBindTexture(GL_TEXTURE_2D, texture); checkGlError(); 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); Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource); GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0); checkGlError(); bitmap.recycle(); return texture; } private int buildProgram(String vertex, String fragment) { int vertexShader = buildShader(vertex, GL_VERTEX_SHADER); if (vertexShader == 0) return 0; int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); if (fragmentShader == 0) return 0; int program = glCreateProgram(); glAttachShader(program, vertexShader); checkGlError(); glAttachShader(program, fragmentShader); checkGlError(); glLinkProgram(program); checkGlError(); int[] status = new int[1]; glGetProgramiv(program, GL_LINK_STATUS, status, 0); if (status[0] != GL_TRUE) { String error = glGetProgramInfoLog(program); Log.d(LOG_TAG, "Error while linking program:\n" + error); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glDeleteProgram(program); return 0; } return program; } private int buildShader(String source, int type) { int shader = glCreateShader(type); glShaderSource(shader, source); checkGlError(); glCompileShader(shader); checkGlError(); int[] status = new int[1]; glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0); if (status[0] != GL_TRUE) { String error = glGetShaderInfoLog(shader); Log.d(LOG_TAG, "Error while compiling shader:\n" + error); glDeleteShader(shader); return 0; } return shader; } private void checkEglError() { int error = mEgl.eglGetError(); if (error != EGL10.EGL_SUCCESS) { Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error)); } } private void checkGlError() { int error = glGetError(); if (error != GL_NO_ERROR) { Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error)); } } private void finishGL() { mEgl.eglDestroyContext(mEglDisplay, mEglContext); mEgl.eglDestroySurface(mEglDisplay, mEglSurface); } private void checkCurrent() { if (!mEglContext.equals(mEgl.eglGetCurrentContext()) || !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) { if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { throw new RuntimeException("eglMakeCurrent failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); } } } private void initGL() { mEgl = (EGL10) EGLContext.getEGL(); mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { throw new RuntimeException("eglGetDisplay failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); } int[] version = new int[2]; if (!mEgl.eglInitialize(mEglDisplay, version)) { throw new RuntimeException("eglInitialize failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); } mEglConfig = chooseEglConfig(); if (mEglConfig == null) { throw new RuntimeException("eglConfig not initialized"); } mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null); if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { int error = mEgl.eglGetError(); if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); return; } throw new RuntimeException("createWindowSurface failed " + GLUtils.getEGLErrorString(error)); } if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { throw new RuntimeException("eglMakeCurrent failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); } mGL = mEglContext.getGL(); } EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); } private EGLConfig chooseEglConfig() { int[] configsCount = new int[1]; EGLConfig[] configs = new EGLConfig[1]; int[] configSpec = getConfig(); if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { throw new IllegalArgumentException("eglChooseConfig failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); } else if (configsCount[0] > 0) { return configs[0]; } return null; } private int[] getConfig() { return new int[] { EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_BLUE_SIZE, 8, EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_STENCIL_SIZE, 0, EGL10.EGL_NONE }; } void finish() { mFinished = true; } } 

    Vous auriez pu aussi suivre la route NDK et ce serait probablement une transition plus directe de l'objectif C.

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.