// in Manifest < 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 ); } } // Renderer 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(); Listpsize = 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; } }
September 24, 2012
Render camera preview using OpenGL ES 2.0 on Android
Please refer -> updated version for Lollipop
January 17, 2012
Creating OpenGL shaders
include : glut.h, glew.h
library : glut32.lib, glew32.lib
bin : glut32.dll, glew32.dll
// initialize glew in the begging of application glewInit(); // compile and link shader program from string GLhandleARB InstallShaders ( const char *_vsSource, const char *_fsSource ) { GLuint program; GLuint vs, fs; GLint vertCompiled; GLint fragCompiled; GLint linked; vs = glCreateShader ( GL_VERTEX_SHADER ); if ( vs ) { glShaderSource ( vs, 1, &_vsSource, NULL ); glCompileShader ( vs ); glGetShaderiv ( vs, GL_COMPILE_STATUS, &vertCompiled ); if ( !vertCompiled ) { GLint infologLength = 0; glGetShaderiv ( vs, GL_INFO_LOG_LENGTH, &infologLength ); if ( infologLength > 0 ) { char *infoLog = (char*)malloc ( infologLength ); glGetShaderInfoLog ( vs, infologLength, NULL, infoLog ); int dsize = MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, -1, NULL, NULL ); WCHAR *des = new WCHAR[dsize]; MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, dsize, des, dsize ); MessageBox ( g_hMain, des, L"Vertex Shader Compile Error", MB_ICONERROR ); delete[] des; free ( infoLog ); } glDeleteShader ( vs ); vs = 0; return 0; } } fs = glCreateShader ( GL_FRAGMENT_SHADER ); if ( fs ) { glShaderSource ( fs, 1, &_fsSource, NULL ); glCompileShader ( fs ); glGetShaderiv ( fs, GL_COMPILE_STATUS, &fragCompiled ); if ( !fragCompiled ) { int infologLength = 0; glGetShaderiv ( fs, GL_INFO_LOG_LENGTH, &infologLength ); if ( infologLength > 0 ) { char *infoLog = (char*)malloc ( infologLength ); glGetShaderInfoLog ( fs, infologLength, NULL, infoLog ); int dsize = MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, -1, NULL, NULL ); WCHAR *des = new WCHAR[dsize]; MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, dsize, des, dsize ); MessageBox ( g_hMain, des, L"Fragment Shader Compile Error", MB_ICONERROR ); delete[] des; free ( infoLog ); } glDeleteShader ( fs ); fs = 0; return 0; } } if ( vs > 0 && fs > 0 ) { program = glCreateProgram(); if ( program ) { glAttachShader ( program, vs ); glAttachShader ( program, fs ); glDeleteShader ( vs ); glDeleteShader ( fs ); glLinkProgram ( program ); glGetProgramiv ( program, GL_LINK_STATUS, &linked ); if ( !linked ) { int infologLength = 0; glGetProgramiv ( program, GL_INFO_LOG_LENGTH, &infologLength); if ( infologLength > 0 ) { char *infoLog = (char*)malloc ( infologLength ); glGetProgramInfoLog ( program, infologLength, NULL, infoLog ); int dsize = MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, -1, NULL, NULL ); WCHAR *des = new WCHAR[dsize]; MultiByteToWideChar ( CP_ACP, 0, (char*)infoLog, dsize, des, dsize ); MessageBox ( g_hMain, des, L"Shader Link Error", MB_ICONERROR ); delete[] des; free ( infoLog ); } glDeleteProgram ( program ); program = 0; return 0; } return program; } return 0; } return 0; } // clean up shader GLint CleanUpShaders ( GLuint *_program ) { glDeleteProgram ( *_program ); _program = 0; return 1; }
Trace in visual studio
include : windows.h, stdio.h, stdarg.h
void Trace ( char *_format, ... ) { va_list args; va_start ( args, _format ); int len = _vscprintf ( _format, args ) + 1; char *str = new char[len]; vsprintf_s ( str, len, _format, args ); va_end ( args ); int dsize = MultiByteToWideChar ( CP_ACP, 0, str, -1, NULL, NULL ); WCHAR *des = new WCHAR[dsize]; MultiByteToWideChar ( CP_ACP, 0, str, dsize, des, dsize ); OutputDebugString ( des ); delete[] des; delete[] str; }
January 12, 2012
Save BMP file using win32 API
include : windows.h
int SaveBMP ( const unsigned char *_buf, const char *_name, const int _width, const int _height ) { int i, j; BITMAPFILEHEADER bmfh; memset ( &bmfh, 0, sizeof ( BITMAPFILEHEADER ) ); bmfh.bfType = 0x4d42; bmfh.bfSize = sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPINFOHEADER ) + _width * _height * 3 + ( _width % 4 ) * _height + 2; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof ( BITMAPFILEHEADER ) + sizeof ( BITMAPINFOHEADER ); BITMAPINFOHEADER bmih; memset ( &bmih, 0, sizeof ( BITMAPINFOHEADER ) ); bmih.biSize = sizeof ( BITMAPINFOHEADER ); bmih.biWidth = _width; bmih.biHeight = _height; bmih.biPlanes = 1; bmih.biBitCount = 24; bmih.biCompression = BI_RGB; bmih.biSizeImage = 0; bmih.biXPelsPerMeter = 0; bmih.biYPelsPerMeter = 0; bmih.biClrUsed = 0; bmih.biClrImportant = 0; FILE *bmf = NULL; if ( fopen_s ( &bmf, _name, "wcb" ) != 0 ) return -1; fwrite ( &bmfh, sizeof ( BITMAPFILEHEADER ), 1, bmf ); fwrite ( &bmih, sizeof ( BITMAPINFOHEADER ), 1, bmf ); unsigned char c = 0; int index; for ( i = _height-1; i >= 0; i-- ) { for ( j = 0; j < _width; j++ ) { index = i*_width+j; c = _buf[index*4+2]; fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); c = _buf[index*4+1]; fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); c = _buf[index*4+0]; fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); } c = 0; switch ( _width % 4 ) { case 3: fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); case 2: fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); case 1: fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); case 0: break; } } c = 0; fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); fwrite ( &c, sizeof ( unsigned char ), 1, bmf ); fflush ( bmf ); fclose ( bmf ); bmf = NULL; return 1; }
Read image from file in win32 using gdiplus
include : gdiplus.h
library : gdiplus.lib
// initialize in the begging of application Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR hgdiplusToken; Gdiplus::GdiplusStartup ( &hgdiplusToken, &gdiplusStartupInput, NULL ); // read image from file Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap ( L"filename.png" ); int width = bitmap->GetWidth(); int height = bitmap->GetHeight(); Gdiplus::Rect rt ( 0, 0, width, height ); unsigned char *image = new unsigned char[width*height*4]; Gdiplus::BitmapData data; bitmap->LockBits ( &rt, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &data ); memcpy ( image, data.Scan0, sizeof ( unsigned char ) * width * height * 4 ); bitmap->UnlockBits ( &data ); delete bitmap; bitmap = NULL; // release in the end of application delete[] image; Gdiplus::GdiplusShutdown ( hgdiplusToken );
Subscribe to:
Posts (Atom)