3D Views: Source Code

Page 1

Java Activity Code

IntroductionApp DescriptionJava Activity CodeSummary

Main Screen - App Description

The 3D Views app allows you to view scenes in three dimensions with OpenGL ES.Swipe left and right to view in 3600.Tap the scene to see the next scene.

The right navigation bar includes an X icon, world icon and Tap - View text. Tap the X to exit the application.Tap the world icon for more 3D content at my 3D sub domain.Tap the Tap - View text to see a new scene.

Introduction

The 3D Views Android app incorporates two dimensionaland three dimensional code with Java, OpenGL ES, XML resources, photographs, Photoshop 2D images and 3ds Max renderings.This short series of code demonstrates how to prepare a simple 3D model viewer for Android.

The CubeViewActivity Java class loads the application's mainActivity, creates an OpenGL ES SurfaceView, changes views when you tap the scene, closes the app when you tap the upper right corner X,opens the Web browser to my 3D subdomain when you tap the Web (World) icon,saves and restores the view.

Updated

This app has been updated (8/23/23) with an action bar.An X allows users to quickly exit and a world iconnavigates to more 3D scenes online.

Java Activity

CubeViewActivity Subclass of Activity

package com.seventhundersoftware.cubeview;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.View.OnSystemUiVisibilityChangeListener;
import android.widget.FrameLayout;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;


import com.seventhundersoftware.cubeview.common.TextureHelper;
import static com.seventhundersoftware.cubeview.CubeViewConstants.*;

/***
 * Copyright (c) 2021 Amy Washburn Butler
 * GNU General Public License v3.0

 * The CubeViewActivity class loads the application's main
 * Activity, creates an OpenGL ES SurfaceView,
 * changes views, when the user taps a translucent, overlay button,
 * saves and restores the view.
 *
 * The app's lifecycle pairs:
 * onCreate() onDestroy()
 * onPause(), onResume(),
 * onSaveInstanceState(), onRestoreInstanceState(),
 * onStart(),onStop()
 */
public class CubeViewActivity extends Activity
{
	public static final String PREFERENCE_FILE_NAME = "CubeView.xml";

	/** Hold a reference to our GLSurfaceView */
	private CubeViewGLSurfaceView mGLSurfaceView = null;
	private CubeViewRenderer mRenderer = null;
	private Context mContext = null;

	private static final String SETTING_VIEWS = "setting_views";
	private static final String TAG = "CubeViewActivity";

	private  ActivityManager  activityManager = null;
	private ConfigurationInfo configurationInfo = null;
	private boolean supportsEs2 = false;
	private int currentApiVersion;

	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		FrameLayout fl = (FrameLayout) findViewById(R.id.cube_view);
		setContentView(R.layout.cube_view);
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		ImageButton btnClose = (ImageButton) findViewById(R.id.btn_close);
		btnClose.setOnClickListener(this::onButtonStop) ;
		ImageButton btnEmail = (ImageButton) findViewById(R.id.btn_web);
		btnEmail.setOnClickListener(this::onButtonWeb) ;
		TextView btnTap = (TextView) findViewById(R.id.btn_info);
		btnTap.setOnClickListener(this::onButtonTap) ;

		currentApiVersion = android.os.Build.VERSION.SDK_INT;

		final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
				View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
				View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
				View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;

		if (currentApiVersion >= Build.VERSION_CODES.KITKAT) {
			getWindow().getDecorView().setSystemUiVisibility(flags);
			final View decorView = getWindow().getDecorView();

			decorView.setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() {
				@Override
				public void onSystemUiVisibilityChange(int visibility) {

					if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
						decorView.setSystemUiVisibility(flags);
					}
				}
			});
		}

		mGLSurfaceView = findViewById(R.id.gl_surface_view);
		mContext = this;

		// Check if the system supports OpenGL ES 2.0.
		activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
		configurationInfo = activityManager.getDeviceConfigurationInfo();
		supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;
		// Request an OpenGL ES 2.0 compatible context.
		mGLSurfaceView.setEGLContextClientVersion(2);
	}

	public void onButtonStop(View v){
		int clicked_btn_stop = Log.d(TAG, "clicked stop button");
		this.onCloseApp();
	}
	public void onButtonTap(View v){
		int clicked_btn_stop = Log.d(TAG, "clicked tap button");
		mGLSurfaceView.assignView();
	}
	public void onButtonWeb(View v){
		int clicked_btn_web = Log.d(TAG, "clicked email button");
		try {
			Uri webpage = Uri.parse("https://3d.7Thunders.biz");
			Intent myIntent = new Intent(
					Intent.ACTION_VIEW,
					webpage);
			startActivity(myIntent);
		} catch (ActivityNotFoundException e) {
			Toast.makeText(this, "No application can handle this request."
					+ " Please install a webbrowser",  Toast.LENGTH_LONG).show();

		}
		Log.d(TAG, "Starting Web browser.");
		this.onCloseApp();
	}


	/***
	 * Close the application from
	 * the X button and browser world icon.
	 * Used profiler to verify all memory's cleaned up.
	 * finish() calls onDestroy().
	 */
	protected void onCloseApp(){
		this.finish();
	}

	/***
	 * OnDestroy() and onCreate() often pair.
	 * Meaning if onDestroy() is called, then
	 * onCreate() will be called at start up.
	 */
	@Override
	protected void onDestroy(){
		super.onDestroy();
		TextureHelper.FreeTexture();
		if(mRenderer != null){
			mRenderer.onDestroy();
		}

		Log.d(TAG,"onDestroy()");
		// Profiler won't display lingering memory:
		System.exit(0);
	}

	/***
	 * onResume() and onPause() often pair.
	 * Meaning if onPause() is called, then
	 * onResume() will be called at start up.
	 */
	@Override
	protected void onResume() 
	{
		super.onResume();
		Log.d(TAG,"onResume()");
		if (supportsEs2)
		{
			// Request an OpenGL ES 2.0 compatible context.
			mGLSurfaceView.setEGLContextClientVersion(2);

			final DisplayMetrics displayMetrics = new DisplayMetrics();
			getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

			// Activity creates SurfaceView.
			// Activity creates Renderer.
			// SurfaceView assigns Renderer.
			// The last parameter is the image number.
			if(mRenderer == null){
				mRenderer = new CubeViewRenderer(this);
				mGLSurfaceView.setRenderer(mRenderer, displayMetrics.density);
			}

			Log.d(TAG,"onCreate()");

		}
	}

	/***
	 * Android pauses or moves away from app.
	 */
	@Override
	protected void onPause()
	{
		super.onPause();
		int iSaveView = I_ISLANDS;
		SharedPreferences sharedPrefs = getApplicationContext().getSharedPreferences(PREFERENCE_FILE_NAME, Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = sharedPrefs.edit();
		if(mGLSurfaceView != null){
			iSaveView = mGLSurfaceView.getView();
		}
		editor.putInt(SETTING_VIEWS, iSaveView);
		editor.apply();
		Log.d(TAG,"onPause()");
	}

	/***
	 * onStart() and onStart() often pair.
	 * Left here for output to show the
	 * Android life cycle.
	 */
	@Override
	protected void onStart() {
		super.onStart();
		Log.d(TAG,"onStart()");
	}

	@Override
	protected void onStop() {
		super.onStop();
		Log.d(TAG,"onStop()");
	}

	/***
	 * onSaveInstanceState() and onRestoreInstanceState()
	 * often pair. However when view orientation is
	 * restricted to either landscape or portrait,
	 * then onRestoreInstanceState() is not called.
	 * This app only displays in landscape mode.
	 * Therefore these two methods are just left
	 * for reference.
	 * @param savedInstanceState: Bundle to save state.
	 */
	@Override
	protected void onSaveInstanceState (Bundle savedInstanceState){
		super.onSaveInstanceState(savedInstanceState);
	}

	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
	}
}

Graphics

The island scene and art gallery graphics were prepared with 3ds Max and Photoshop.The lighthouse scene was modified from iPhone photos taken in panoramic mode.The grid view was prepared with Photoshop.

Summary

The CubeViewActivity Java class loads the application's mainActivity, creates an OpenGL ES SurfaceView, changes views when you tap the scene, closes the app when you tap the upper right corner X,opens the Web browser to my 3D subdomain when you tap the Web (World) icon,saves and restores the view.

Java & OpenGL ES

This set of pages include Android Java, combined with OpenGL ES, to display a set of simple three dimensional views. The views apply a unique, simple concept to render 3D backgrounds, without Skyboxes or time consuming shader switching. Each view's contained in one graphic, with room for other sprites and meshes.

Java and OpenGL ES source code was ported from WebGL with only minor changes. The book, 3D Scenes: Learn WebGL Book 3, explains implementation and graphics preparation for the WebGL app, in detail.

Tags

Free source code, free Java, free OpenGL ES, 3D programming, learn to code,

Ads >
Create 3D Games: Learn WebGL Book 2 Simple Shaders: Learn WebGL Book 4
3D Programming for Beginners: Learn WebGL Book 1
Web Graphics & Illustration Architectural Rendering 3D Architectural Web Animation
Web Development Python & MySQL Send Email Complete Sitemap About Search 3D