gpt4 book ai didi

android - 使用 OpenGL 2.0 API 在 GLSurfaceView 上将 Android Camera Preview 旋转 90 度

转载 作者:行者123 更新时间:2023-12-04 23:54:38 26 4
gpt4 key购买 nike

注意 我是 Android 和 OpenGL 的新手。

我使用代码在屏幕上显示 Android Camera Preview。我想在下面的“MainRenderer”类中使用 OpenGL 2.0 将相机角度旋转 90 度(以匹配我的相机的纵向分辨率,因为我的应用程序处于纵向模式)。我调查了Android camera rotate但它没有执行轮换。

在布局 xml 中设置“android:rotation='90'”会旋转表面 View 但会产生黑色表面 - 无相机预览。

因为我使用的是 GLSurfaceView,所以我现在希望在 OpenGL 2.0 中实际旋转相机预览,而不是通过执行矩阵旋转和纵横比调整。很少有像这样的帖子 How to rotate a camera view in OpenGL 2.0 EShttp://www.programcreek.com/java-api-examples/index.php?class=android.opengl.Matrix&method=rotateM但由于我不熟悉 OpenGL(我希望尽快熟悉它),所以无法将 API 与下面的代码相关联。

我知道 rotateM 和 translateM(猜测使用 ModelViewProjection 矩阵)可能会完成我打算完成的事情。

我想知道下面的 vtmp 和 ttmp 可能需要更改吗?

感谢任何帮助。

原码来自http://maninara.blogspot.com/2012/09/render-camera-preview-using-opengl-es.html

//在 list 中

< uses-feature android:glEsVersion="0x00020000" android:required="true"/>
< uses-feature android:name="android.hardware.camera"/>
< uses-permission android:name="android.permission.CAMERA"/>
< uses-permission android:name="android.permission.WAKE_LOCK"/>
... android:screenOrientation="landscape" ... // activity property

//Activity

public class MainActivity extends Activity {
private MainView mView;
private WakeLock mWL;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// full screen & full brightness
requestWindowFeature ( Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mWL = ((PowerManager)getSystemService ( Context.POWER_SERVICE )).newWakeLock(PowerManager.FULL_WAKE_LOCK, "WakeLock");
mWL.acquire();
mView = new MainView(this);
setContentView ( mView );
}

@Override
protected void onPause() {
if ( mWL.isHeld() )
mWL.release();
mView.onPause();
super.onPause();
}

@Override
protected void onResume() {
super.onResume();
mView.onResume();
if(!mWL.isHeld()) mWL.acquire();
}
}

// View

class MainView extends GLSurfaceView {
MainRenderer mRenderer;

MainView ( Context context ) {
super ( context );
mRenderer = new MainRenderer(this);
setEGLContextClientVersion ( 2 );
setRenderer ( mRenderer );
setRenderMode ( GLSurfaceView.RENDERMODE_WHEN_DIRTY );
}

public void surfaceCreated ( SurfaceHolder holder ) {
super.surfaceCreated ( holder );
}

public void surfaceDestroyed ( SurfaceHolder holder ) {
mRenderer.close();
super.surfaceDestroyed ( holder );
}

public void surfaceChanged ( SurfaceHolder holder, int format, int w, int h ) {
super.surfaceChanged ( holder, format, w, h );
}
}

//渲染器

public class MainRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
private final String vss =
"attribute vec2 vPosition;\n" +
"attribute vec2 vTexCoord;\n" +
"varying vec2 texCoord;\n" +
"void main() {\n" +
" texCoord = vTexCoord;\n" +
" gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );\n" +
"}";

private final String fss =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" +
"uniform samplerExternalOES sTexture;\n" +
"varying vec2 texCoord;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture,texCoord);\n" +
"}";

private int[] hTex;
private FloatBuffer pVertex;
private FloatBuffer pTexCoord;
private int hProgram;

private Camera mCamera;
private SurfaceTexture mSTexture;

private boolean mUpdateST = false;

private MainView mView;

MainRenderer ( MainView view ) {
mView = view;
float[] vtmp = { 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f };
float[] ttmp = { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
pVertex = ByteBuffer.allocateDirect(8*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
pVertex.put ( vtmp );
pVertex.position(0);
pTexCoord = ByteBuffer.allocateDirect(8*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
pTexCoord.put ( ttmp );
pTexCoord.position(0);
}

public void close()
{
mUpdateST = false;
mSTexture.release();
mCamera.stopPreview();
mCamera.release();
mCamera = null;
deleteTex();
}

public void onSurfaceCreated ( GL10 unused, EGLConfig config ) {
//String extensions = GLES20.glGetString(GLES20.GL_EXTENSIONS);
//Log.i("mr", "Gl extensions: " + extensions);
//Assert.assertTrue(extensions.contains("OES_EGL_image_external"));

initTex();
mSTexture = new SurfaceTexture ( hTex[0] );
mSTexture.setOnFrameAvailableListener(this);

mCamera = Camera.open();
try {
mCamera.setPreviewTexture(mSTexture);
} catch ( IOException ioe ) {
}

GLES20.glClearColor ( 1.0f, 1.0f, 0.0f, 1.0f );

hProgram = loadShader ( vss, fss );
}

public void onDrawFrame ( GL10 unused ) {
GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );

synchronized(this) {
if ( mUpdateST ) {
mSTexture.updateTexImage();
mUpdateST = false;
}
}

GLES20.glUseProgram(hProgram);

int ph = GLES20.glGetAttribLocation(hProgram, "vPosition");
int tch = GLES20.glGetAttribLocation ( hProgram, "vTexCoord" );
int th = GLES20.glGetUniformLocation ( hProgram, "sTexture" );

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
GLES20.glUniform1i(th, 0);

GLES20.glVertexAttribPointer(ph, 2, GLES20.GL_FLOAT, false, 4*2, pVertex);
GLES20.glVertexAttribPointer(tch, 2, GLES20.GL_FLOAT, false, 4*2, pTexCoord );
GLES20.glEnableVertexAttribArray(ph);
GLES20.glEnableVertexAttribArray(tch);

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glFlush();
}

public void onSurfaceChanged ( GL10 unused, int width, int height ) {
GLES20.glViewport( 0, 0, width, height );
Camera.Parameters param = mCamera.getParameters();
List psize = param.getSupportedPreviewSizes();
if ( psize.size() > 0 ) {
int i;
for ( i = 0; i < psize.size(); i++ ) {
if ( psize.get(i).width < width || psize.get(i).height < height )
break;
}
if ( i > 0 )
i--;
param.setPreviewSize(psize.get(i).width, psize.get(i).height);
//Log.i("mr","ssize: "+psize.get(i).width+", "+psize.get(i).height);
}
param.set("orientation", "landscape");
mCamera.setParameters ( param );
mCamera.startPreview();
}

private void initTex() {
hTex = new int[1];
GLES20.glGenTextures ( 1, hTex, 0 );
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
}

private void deleteTex() {
GLES20.glDeleteTextures ( 1, hTex, 0 );
}

public synchronized void onFrameAvailable ( SurfaceTexture st ) {
mUpdateST = true;
mView.requestRender();
}

private static int loadShader ( String vss, String fss ) {
int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vshader, vss);
GLES20.glCompileShader(vshader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e("Shader", "Could not compile vshader");
Log.v("Shader", "Could not compile vshader:"+GLES20.glGetShaderInfoLog(vshader));
GLES20.glDeleteShader(vshader);
vshader = 0;
}

int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fshader, fss);
GLES20.glCompileShader(fshader);
GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e("Shader", "Could not compile fshader");
Log.v("Shader", "Could not compile fshader:"+GLES20.glGetShaderInfoLog(fshader));
GLES20.glDeleteShader(fshader);
fshader = 0;
}

int program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vshader);
GLES20.glAttachShader(program, fshader);
GLES20.glLinkProgram(program);

return program;
}
}

最佳答案

我认为有几种方法取决于哪种方法更适合您:

  1. 根据角度更改顶点数组值(可能是最简单的一个)
  2. Camera.setDisplayOrientation
  3. 您可以稍微更改一下您的顶点(它与您目前使用的有点不同,我使用 vec4 而不是 vec2,需要进行一些其他更改以在您的代码中说明这一点):
static final String vss =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 vPosition;\n" +
"attribute vec4 vTexCoord;\n" +
"varying vec2 texCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * vPosition;\n" +
" texCoord = (uSTMatrix * vTexCoord).xy;\n" +
"}\n";

然后

float[] mvpMatrix = new float[16];
int uMVPMatrixHandle;

uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
checkLocation(uMVPMatrixHandle, "uMVPMatrix");

绘图时指定您想要的任何角度:

Matrix.setIdentityM(mvpMatrix, 0);
Matrix.rotateM(mvpMatrix, 0, angle, 0f, 0f, 1f);
GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, mvpMatrix, 0);
EGL.checkGlError("glUniformMatrix4fv");

关于android - 使用 OpenGL 2.0 API 在 GLSurfaceView 上将 Android Camera Preview 旋转 90 度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36703984/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com