float val; // input 0.0 ~ 1.0 unsigned char R, G, B; // output 0 ~ 255 R = (unsigned char)(( val > 0.5f ? 0.0f : ( val < 0.25f ? 1.0f : (2.0f - 4.0f*val)) ) * 255.0f ); G = (unsigned char)(( val < 0.25f ? 4.0f*val : ( val > 0.75f ? (4.0f - 4.0f*val) : 1.0f ) ) * 255.0f ); B = (unsigned char)(( val < 0.5f ? 0.0f : ( val > 0.75f ? 1.0f : (4.0f*val - 2.0f) )) * 255.0f );
Showing posts with label code. Show all posts
Showing posts with label code. Show all posts
February 6, 2018
0.0 ~ 1.0 to RGB (Red - Yellow - Green - Cyan - Blue)
June 23, 2015
FBO on Android
private void initFBO(int width, int height) {
hFBOTex = new int[1];
GLES20.glGenTextures(1,hFBOTex,0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, hFBOTex[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,width,height,0,GLES20.GL_RGBA,GLES20.GL_UNSIGNED_BYTE,null);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
hFBO = new int[1];
GLES20.glGenFramebuffers(1,hFBO,0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,hFBO[0]);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,GLES20.GL_COLOR_ATTACHMENT0,GLES20.GL_TEXTURE_2D,hFBOTex[0],0);
int[] depth;
depth = new int[1];
GLES20.glGenRenderbuffers(1,depth,0);
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER,depth[0]);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER,GLES20.GL_DEPTH_COMPONENT16,width,height);
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,GLES20.GL_DEPTH_ATTACHMENT,GLES20.GL_RENDERBUFFER,depth[0]);
if ( GLES20.glGetError() != GLES20.GL_NO_ERROR) Log.i("mr","initFBO - rbo");
if(GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER) != GLES20.GL_FRAMEBUFFER_COMPLETE)
Log.e("mr","initFBO");
}
public void onDrawFrame ( GL10 unused ) {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,hFBO[0]);
// draw somethings to FBO
GLES20.glFlush();
// read a block of pixels from back buffer in double-buffered configurations
ByteBuffer buf = ByteBuffer.allocateDirect(width*height*4);
GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,0);
// draw somethings to frame(back) buffer
// you can use hFBOTex[0] as a texture
}
March 23, 2015
Render camera preview using OpenGL ES 2.0 on Android API 21 or higher
I referred to the Android Samples for android.hardware.camera2 (samples\android-21\media\Camera2Basic).
In the code, I fixed the resolution of camera preview to the device resolution, and tested on the NEXUS 9.
// AndroidManifest.xml
...
< uses-feature android:glEsVersion="0x00020000" android:required="true"/>
< uses-feature android:name="android.hardware.camera2"/>
< uses-permission android:name="android.permission.CAMERA"/>
...
< activity android:name=".MainActivity" android:screenOrientation="landscape">
...
// MainActivity.java
package ...
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
private MainView mView;
@Override
public void onCreate ( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
int ui = getWindow().getDecorView().getSystemUiVisibility();
ui = ui | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(ui);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mView = new MainView(this);
setContentView ( mView );
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
}
@Override
protected void onPause() {
mView.onPause();
super.onPause();
}
}
// MainView.java
package ...
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.SurfaceHolder;
public 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 ) {
super.surfaceDestroyed ( holder );
}
public void surfaceChanged ( SurfaceHolder holder, int format, int w, int h ) {
super.surfaceChanged ( holder, format, w, h );
}
@Override
public void onResume() {
super.onResume();
mRenderer.onResume();
}
@Override
public void onPause() {
mRenderer.onPause();
super.onPause();
}
}
// MainRenderer.java
package ...
import android.content.Context;
import android.graphics.Point;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Arrays;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
private final String vss_default = "" +
"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_default = "" +
"#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 SurfaceTexture mSTexture;
private boolean mGLInit = false;
private boolean mUpdateST = false;
private MainView mView;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCaptureSession;
private CaptureRequest.Builder mPreviewRequestBuilder;
private String mCameraID;
private Size mPreviewSize = new Size ( 1920, 1080 );
private HandlerThread mBackgroundThread;
private Handler mBackgroundHandler;
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
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 onResume() {
startBackgroundThread();
}
public void onPause() {
mGLInit = false;
mUpdateST = false;
closeCamera();
stopBackgroundThread();
}
public void onSurfaceCreated ( GL10 unused, EGLConfig config ) {
initTex();
mSTexture = new SurfaceTexture ( hTex[0] );
mSTexture.setOnFrameAvailableListener(this);
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
hProgram = loadShader ( vss_default, fss_default );
Point ss = new Point();
mView.getDisplay().getRealSize(ss);
cacPreviewSize(ss.x, ss.y);
openCamera();
mGLInit = true;
}
public void onDrawFrame ( GL10 unused ) {
if ( !mGLInit ) return;
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" );
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.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex[0]);
GLES20.glUniform1i(GLES20.glGetUniformLocation ( hProgram, "sTexture" ), 0);
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);
}
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);
}
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;
}
void cacPreviewSize( final int width, final int height ) {
CameraManager manager = (CameraManager)mView.getContext().getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraID : manager.getCameraIdList()) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID);
if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT)
continue;
mCameraID = cameraID;
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
for ( Size psize : map.getOutputSizes(SurfaceTexture.class)) {
if ( width == psize.getWidth() && height == psize.getHeight() ) {
mPreviewSize = psize;
break;
}
}
break;
}
} catch ( CameraAccessException e ) {
Log.e("mr", "cacPreviewSize - Camera Access Exception");
} catch ( IllegalArgumentException e ) {
Log.e("mr", "cacPreviewSize - Illegal Argument Exception");
} catch ( SecurityException e ) {
Log.e("mr", "cacPreviewSize - Security Exception");
}
}
void openCamera() {
CameraManager manager = (CameraManager)mView.getContext().getSystemService(Context.CAMERA_SERVICE);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraID);
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
manager.openCamera(mCameraID,mStateCallback,mBackgroundHandler);
} catch ( CameraAccessException e ) {
Log.e("mr", "OpenCamera - Camera Access Exception");
} catch ( IllegalArgumentException e ) {
Log.e("mr", "OpenCamera - Illegal Argument Exception");
} catch ( SecurityException e ) {
Log.e("mr", "OpenCamera - Security Exception");
} catch ( InterruptedException e ) {
Log.e("mr", "OpenCamera - Interrupted Exception");
}
}
private void closeCamera() {
try {
mCameraOpenCloseLock.acquire();
if (null != mCaptureSession) {
mCaptureSession.close();
mCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
} finally {
mCameraOpenCloseLock.release();
}
}
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
mCameraDevice = cameraDevice;
createCameraPreviewSession();
}
@Override
public void onDisconnected(CameraDevice cameraDevice) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(CameraDevice cameraDevice, int error) {
mCameraOpenCloseLock.release();
cameraDevice.close();
mCameraDevice = null;
}
};
private void createCameraPreviewSession() {
try {
mSTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface surface = new Surface(mSTexture);
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
mPreviewRequestBuilder.addTarget(surface);
mCameraDevice.createCaptureSession(Arrays.asList(surface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
if (null == mCameraDevice)
return;
mCaptureSession = cameraCaptureSession;
try {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), null, mBackgroundHandler);
} catch (CameraAccessException e) {
Log.e("mr", "createCaptureSession");
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
}
}, null
);
} catch (CameraAccessException e) {
Log.e("mr", "createCameraPreviewSession");
}
}
private void startBackgroundThread() {
mBackgroundThread = new HandlerThread("CameraBackground");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
private void stopBackgroundThread() {
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
Log.e("mr", "stopBackgroundThread");
}
}
}
December 26, 2014
Render the captured image from real camera matrix using OpenGL
// intrinsic parameter: fx, fy, cx, cy, skew
// image size: width, hegiht
// view frustum: nearp, farp
// extrinsic parameter: r00, r01, r02, r10, r11, r12, r20, r21, r22, tx, ty, tz
// projection matrix
float pm[16] = { 0.0f };
pm[0] = 2.0f*fx/width;
pm[4] = -2.0f*skew/width;
pm[8] = 1.0f - 2.0f*cx/width;
pm[12] = 0.0f;
pm[1] = 0.0f;
pm[5] = -2.0f*fy/height;
pm[9] = 1.0f - 2.0f*cy/height;
pm[13] = 0.0f;
pm[2] = 0.0f;
pm[6] = 0.0f;
pm[10] = -(farp+nearp)/(farp-nearp);
pm[14] = -2.0f*farp*nearp/(farp-nearp);
pm[3] = 0.0f;
pm[7] = 0.0f;
pm[11] = -1.0f;
pm[15] = 0.0f;
glViewport ( 0, 0, width, height);
glMatrixMode ( GL_PROJECTION );
glLoadMatrixf ( pm );
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity();
// -z direction
float rm[16] = { 0.0f };
rm[0] = 1.0f;
rm[5] = 1.0f;
rm[10] = -1.0f;
rm[15] = 1.0f;
glMultMatrixf ( rm );
rm[0] = r00;
rm[4] = r01;
rm[8] = r02;
rm[1] = r10;
rm[5] = r11;
rm[9] = r12;
rm[2] = r20;
rm[6] = r21;
rm[10] = r22;
rm[15] = 1.0f;
// inverse rotation and translation
glMultTransposeMatrixf ( rm );
glTranslatef ( -tx, -ty, -tz );
September 24, 2012
Render camera preview using OpenGL ES 2.0 on Android
Please refer -> updated version for Lollipop
// 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();
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;
}
}
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)