Andriod OpenGL 教程 07 - 光照和输入控制

关键字: android OpenGL 移动开发 教程

 

在这一课,我们将添加光照和输入控制,它可以是我们的应用看起来更美观,在这一课我们将演示三种不同的纹理滤波方式。演示如何通过键盘和触屏操作来移动场景中的对象,同时将演示在OpenGL场景中应用简单的光照。

为了演示用户输入,捕获用户输入事件,我们需要从GLSurfaceView导出一个子类来重载事件处理方法(比如重载onKeyUp(), onTouchEvent())。该子类的命名为MyGLSurfaceView,我们重载了onKeyUponTouchEvent方法,分别用来处理键盘和触屏事件。

在第六课的基础上,TextureCube处理更换了纹理,其他都没做改变。在MyGLRenderer中加了几个控制变量:

   floatangleX = 0.0f;

    floatangleY = 0.0f;

    floatspeedX = 0.0f;

    floatspeedY = 0.0f;

   floatz = -6.0f;

用于控制立方体的在Z方向的位置,在xy方向旋转的角度和速度。对其中onDrawFrame方法中的内容做了相应调整,方便我们演示用户输入的效果。

public void onDrawFrame(GL10 gl)
	{
		// 清除屏幕和深度缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		// 启动和关闭光源
	    if (lightingEnabled) {
	       gl.glEnable(GL10.GL_LIGHTING);
	    } else {
	         gl.glDisable(GL10.GL_LIGHTING);
	    }
		
		// -------- 渲染彩色立方体 ------
		// 重置当前的模型观察矩阵
		gl.glLoadIdentity();
		// 纵深向里移动z
		gl.glTranslatef(0.0f, 0.0f, z);
		// 绕X轴旋转立方体 
		gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f);
		// 绕Y轴旋转立方体
		gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f);
		// 画立方体
		cube.draw(gl, currentTextureFilter);
		
		// 每次刷新之后更新旋转角度
		angleX += speedX;
		angleY += speedY;
	}


 

MyGLSurfaceView实现了用户输入控制。

 

相应的,GLLesson07Activity.javaonCreate方法的代码调整为:

publicvoid onCreate(Bundle savedInstanceState) {   

        super.onCreate(savedInstanceState);

        glView =new MyGLSurfaceView(this);//创建一个定制的GLSurfaceView

        setContentView(glView);                   

}

编译运行,我们就可以通过输入一些控制来看立方体空间位置的变化。

 

现在我们演示不同的纹理映射滤波方式,首先对TextureCube中的代码进行调整textureIDs现在数组的的长度为3

int[]textureIDs =newint[3];//纹理-ID数组

draw方法添加了一个新的输入变量inttextureFilter用于选择滤波方式。

public class TextureCube {

     …………

             //通过纹理坐标ID选择纹理的滤波方式

   gl.glBindTexture(GL10.GL_TEXTURE_2D,textureIDs[textureFilter]);

   …………

    gl.glGenTextures(3, textureIDs, 0);//3个纹理生成纹理ID数组

    //生成 Nearest方式滤波的纹理并绑定到纹理0

    gl.glBindTexture(GL10.GL_TEXTURE_2D,textureIDs[0]);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

    //生成Linear方式滤波的纹理并绑定到纹理1

    gl.glBindTexture(GL10.GL_TEXTURE_2D,textureIDs[1]);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

         

    //生成mipmapped方式滤波的纹理并绑定到纹理2

    gl.glBindTexture(GL10.GL_TEXTURE_2D,textureIDs[2]);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);

    if(glinstanceof GL11) {

       gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);

    }

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

   bmp.recycle();

}

MyGLRenderer中的代码修还为:

…………

intcurrentTextureFilter = 0;  //当前纹理滤波方式

…………

cube.draw(gl,currentTextureFilter);

…………

 

MyGLSurfaceViewonKeyUp方法,添加

case KeyEvent.KEYCODE_DPAD_CENTER//选择纹理滤波方式

         renderer.currentTextureFilter = (renderer.currentTextureFilter + 1) % 3;

     break;

然后编译运行。选择DPAD_CENTER按钮点击,观察纹理的效果,就会发现NEAEST效果差一些,其他两种方式的效果要好些。

最后一步,我们演示光照效果。在MyGLRenderer中加入灯光控制的代码

声明几个控制光照的变量

    booleanlightingEnabled =false;  //是否打开光照

    privatefloat[]lightAmbient = {0.5f, 0.5f, 0.5f, 1.0f};

    privatefloat[]lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};

privatefloat[]lightPosition = {0.0f, 0.0f, 2.0f, 1.0f};

onSurfaceCreated中添加设置光源的代码:

// 设置光源 GL_LIGHT1的环境光(ambient)漫射光(diffuse)

        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT,lightAmbient, 0);

        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE,lightDiffuse, 0);

        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION,lightPosition, 0);

        gl.glEnable(GL10.GL_LIGHT1);  //使能光源1

    gl.glEnable(GL10.GL_LIGHT0);  //使能缺省光源0

onDramFrame中加入启动和关闭光源的代码

// 启动和关闭光源

        if (lightingEnabled) {

           gl.glEnable(GL10.GL_LIGHTING);

        } else {

             gl.glDisable(GL10.GL_LIGHTING);

    }

最后在MyGLSurfece.java中的onKey方法中加入用户控制代码,用于打开个关闭光源。

case KeyEvent.KEYCODE_L//光源开关

             renderer.lightingEnabled = !renderer.lightingEnabled;

         break;

代码:

GLLesson07Activity.java

package wintop.gllesson07;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class GLLesson07Activity extends Activity {
	private GLSurfaceView glView;	// 使用GLSurfaceView 导出类

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) { 	
        super.onCreate(savedInstanceState);
               
        glView = new MyGLSurfaceView(this);			// 创建一个定制的GLSurfaceView
        setContentView(glView);						
    }
    
    // Call back when the activity is going into the background
    @Override
    protected void onPause(){
    	super.onPause();
    	glView.onPause();
    }
    
    // Call back after onPause()
    @Override
    protected void onResume()
    {
    	super.onResume();
    	glView.onResume();
    }
}


MyGLRenderer.java

package wintop.gllesson07;

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;

public class MyGLRenderer implements  GLSurfaceView.Renderer {
	private Context context;	// 应用的上下文句柄
	private TextureCube  cube;
	
	// 下面的变量控制立方体的在Z方向的位置,在x和y方向旋转的角度和速度
	float angleX = 0.0f;
	float angleY = 0.0f;
	float speedX = 0.0f;
	float speedY = 0.0f;
	float z = -6.0f;
	
	int currentTextureFilter = 0;	// 当前纹理滤波方式

	// 光照
	boolean lightingEnabled = false;   // 是否打开光照
	private float[] lightAmbient = {0.5f, 0.5f, 0.5f, 1.0f};
	private float[] lightDiffuse = {1.0f, 1.0f, 1.0f, 1.0f};
	private float[] lightPosition = {0.0f, 0.0f, 2.0f, 1.0f};
	
	// Constructor with global application context
	public MyGLRenderer(Context context) {
		this.context = context;
		
		// 设置所用图形的数据数组缓冲区
		cube = new TextureCube();
	}
	
	// Call back when the surface is first created or re-created
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config)
	{
		// 启用阴影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		
		// 设置背景颜色
		gl.glClearColor(0.2f, 0.4f, 0.52f, 1.0f);
		
		// 设置深度缓存
		gl.glClearDepthf(1.0f);
		
		// 启用深度测试
		gl.glEnable(GL10.GL_DEPTH_TEST);
		
		// 所作深度测试的类型
		gl.glDepthFunc(GL10.GL_LEQUAL);
		
		// 告诉系统对透视进行修正
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
		
		// 禁止抖动以取得更好的性能
		gl.glDisable(GL10.GL_DITHER);
		
		// 设置纹理
		cube.loadTexture(gl, context);		// 加载纹理
		gl.glEnable(GL10.GL_TEXTURE_2D);	// 纹理使能
		
		// 设置光源 GL_LIGHT1 的环境光(ambient)和 漫射光(diffuse)
	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient, 0);
	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse, 0);
	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition, 0);
	    gl.glEnable(GL10.GL_LIGHT1);   // 使能光源1
	    gl.glEnable(GL10.GL_LIGHT0);   // 使能缺省光源0
	}
	
	// Call back after onSurfaceCreated() or whenever the window's size changes
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height)
	{
		if(height == 0)	// 防止被零除
		{
			height = 1;	
		}
		
		// 重置当前的视图区域
		gl.glViewport(0, 0, width, height);
		
		// 选择投影矩阵
		gl.glMatrixMode(GL10.GL_PROJECTION);
		
		// 重置投影矩阵
		gl.glLoadIdentity();
		
		// 设置视图区域的大小
		GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,0.1f,100.0f);
		
		// 选择模型观察矩阵
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		
		// 重置模型观察矩阵
		gl.glLoadIdentity();
	}
	
	// Call back to draw the current frame.
	@Override
	public void onDrawFrame(GL10 gl)
	{
		// 清除屏幕和深度缓存
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		// 启动和关闭光源
	    if (lightingEnabled) {
	       gl.glEnable(GL10.GL_LIGHTING);
	    } else {
	         gl.glDisable(GL10.GL_LIGHTING);
	    }
		
		// -------- 渲染彩色立方体 ------
		// 重置当前的模型观察矩阵
		gl.glLoadIdentity();
		// 纵深向里移动z
		gl.glTranslatef(0.0f, 0.0f, z);
		// 绕X轴旋转立方体 
		gl.glRotatef(angleX, 1.0f, 0.0f, 0.0f);
		// 绕Y轴旋转立方体
		gl.glRotatef(angleY, 0.0f, 1.0f, 0.0f);
		// 画立方体
		cube.draw(gl, currentTextureFilter);
		
		// 每次刷新之后更新旋转角度
		angleX += speedX;
		angleY += speedY;
	}
}


MyGLSurfaceView.java

package wintop.gllesson07;

import android.opengl.GLSurfaceView;
import android.content.Context;
import android.view.KeyEvent;
import android.view.MotionEvent;

// 为了捕获用户输入事件,我们需要从GLSurfaceView导出一个子类来重载事件处理
// 方法(比如重载onKeyUp(), onTouchEvent())
public class MyGLSurfaceView extends GLSurfaceView {
	MyGLRenderer renderer;    // 定制的 GL 渲染器
	
	//  用于触屏事件
	private final float TOUCH_SCALE_FACTOR = 180.0f / 320.0f;
	private float previousX;
	private float previousY;
	
	// 构造函数 - 创建和设置渲染器
	public MyGLSurfaceView(Context context) {
		super(context);
		renderer = new MyGLRenderer(context);
		this.setRenderer(renderer);
		// 设置焦点,否则键盘/按钮可能无响应
		this.requestFocus();
		this.setFocusableInTouchMode(true);
	}
	
	// 处理键盘事件
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent evt) {
	    switch(keyCode) {
	         case KeyEvent.KEYCODE_DPAD_LEFT:   // 减少Y向旋转速度
	            renderer.speedY -= 0.1f;
	            break;
	         case KeyEvent.KEYCODE_DPAD_RIGHT:  // 增加Y向旋转速度
	            renderer.speedY += 0.1f;
	            break;
	         case KeyEvent.KEYCODE_DPAD_UP:     // 减少X向旋转速度
	            renderer.speedX -= 0.1f;
	            break;
	         case KeyEvent.KEYCODE_DPAD_DOWN:   // 增加X向旋转速度 
	            renderer.speedX += 0.1f;
	            break;
	         case KeyEvent.KEYCODE_A:           // 缩小 (减少 z)
	            renderer.z -= 0.2f;
	            break;
	         case KeyEvent.KEYCODE_Z:           // 放大 (增加 z)
	            renderer.z += 0.2f;
	            break;
	         case KeyEvent.KEYCODE_DPAD_CENTER:  // 选择纹理滤波方式
	             renderer.currentTextureFilter = (renderer.currentTextureFilter + 1) % 3;
	             break;
	         case KeyEvent.KEYCODE_L:  // 光源开关 
	             renderer.lightingEnabled = !renderer.lightingEnabled;
	             break;
	         default:
	        	 return super.onKeyUp(keyCode, evt);
	      }
	      return true;  // 事件处理后返回
	   }
	
	// 处理触屏事件
	@Override
	public boolean onTouchEvent(final MotionEvent evt) {
		float currentX = evt.getX();
	    float currentY = evt.getY();
	    float deltaX, deltaY;
	    switch (evt.getAction()) {
	       case MotionEvent.ACTION_MOVE:
	          // 根据物体的移动调整合理的旋转角度
	          deltaX = currentX - previousX;
	          deltaY = currentY - previousY;
	          renderer.angleX += deltaY * TOUCH_SCALE_FACTOR;
	          renderer.angleY += deltaX * TOUCH_SCALE_FACTOR;
	    }
	    // Save current x, y
	    previousX = currentX;
	    previousY = currentY;
	    return true;  // 事件处理后返回
	}
}


TextureCube.java

package wintop.gllesson07;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

// 生成一个带纹理的立方体
// 这里指定义一个面的顶点,立方体的其他面通过平移和旋转这个面来渲染
public class TextureCube {
	private FloatBuffer vertexBuffer;	// 顶点数组缓冲区
	private FloatBuffer texBuffer;		// 纹理坐标数据缓冲区
	
	private float[] vertices = { // 定义一个面的顶点坐标
		-1.0f, -1.0f, 0.0f,  // 0. 左-底-前
		1.0f, -1.0f, 0.0f,   // 1. 右-底-前
		-1.0f,  1.0f, 0.0f,  // 2. 左-顶-前
		1.0f,  1.0f, 0.0f    // 3. 右-顶-前
	};
	
	float[] texCoords = { // 定义上面的面的纹理坐标
        0.0f, 1.0f,  // A. 左-下
        1.0f, 1.0f,  // B. 右-下 
        0.0f, 0.0f,  // C. 左-上 
        1.0f, 0.0f   // D. 右-上
    };

	int[] textureIDs = new int[3]; // 纹理-ID数组
	
	// 构造函数,设置缓冲区
	public TextureCube()
	{
		// 设置顶点数组,顶点数据为浮点数据类型。一个浮点类型的数据长度为四个字节
	    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
	    vbb.order(ByteOrder.nativeOrder()); // 使用原生字节顺序
	    vertexBuffer = vbb.asFloatBuffer(); // 将字节类型缓冲区转换成浮点类型
	    vertexBuffer.put(vertices);         // 将数据复制进缓冲区
	    vertexBuffer.position(0);           // 定位到初始位置
	 
	    // 设置纹理坐标数组缓冲区,起数据类型为浮点数据
	    ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
	    tbb.order(ByteOrder.nativeOrder());
	    texBuffer = tbb.asFloatBuffer();
	    texBuffer.put(texCoords);
	    texBuffer.position(0);
	}
	
	// 绘图
	public void draw(GL10 gl, int textureFilter){	// 选择滤波方式  
		gl.glFrontFace(GL10.GL_CCW);    // 正前面为逆时针方向
	    gl.glEnable(GL10.GL_CULL_FACE); // 使能剔除面
	    gl.glCullFace(GL10.GL_BACK);    // 剔除背面(不显示)
	    
	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
	    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  // 使能纹理坐标数组
	    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // 定义纹理坐标数组缓冲区
	    
	    // 通过纹理坐标ID选择纹理的滤波方式
	    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[textureFilter]);
	    
	    // 前
	    gl.glPushMatrix();
	    gl.glTranslatef(0.0f, 0.0f, 1.0f);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	    gl.glPopMatrix();
	    
	    // 左
	    gl.glPushMatrix();
	    gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
	    gl.glTranslatef(0.0f, 0.0f, 1.0f);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	    gl.glPopMatrix();
	    
	    // 后
	    gl.glPushMatrix();
	    gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
	    gl.glTranslatef(0.0f, 0.0f, 1.0f);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	    gl.glPopMatrix();

	    // 右
	    gl.glPushMatrix();
	    gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
	    gl.glTranslatef(0.0f, 0.0f, 1.0f);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	    gl.glPopMatrix();

	    // 顶
	    gl.glPushMatrix();
	    gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
	    gl.glTranslatef(0.0f, 0.0f, 1.0f);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	    gl.glPopMatrix();

	    // 底
	    gl.glPushMatrix();
	    gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
	    gl.glTranslatef(0.0f, 0.0f, 1.0f);
	    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
	    gl.glPopMatrix();
	    
	    // 恢复原来的状态
	    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
	    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	    gl.glDisable(GL10.GL_CULL_FACE);
	}
	
	// 加载一个图像到GL纹理
	public void loadTexture(GL10 gl, Context context) {
		gl.glGenTextures(1, textureIDs, 0);	// 生成纹理ID数组
		
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]);	// 绑定到纹理ID
		// 设置纹理过滤方式
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
	
		// 构造一个输入流来加载纹理文件"res/drawable/crate.bmp"
		InputStream ins = context.getResources().openRawResource(R.drawable.crate);
		Bitmap bmp;
		try {
			// 读取并将输入流解码成位图
			bmp = BitmapFactory.decodeStream(ins);
		} finally {
			try {
				ins.close();
			}catch(IOException e) {}
		}
		
		gl.glGenTextures(3, textureIDs, 0); // 为3个纹理生成纹理ID数组

		// 生成 Nearest方式滤波的纹理并绑定到纹理0
	    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]);
	    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
	    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
	    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

	    // 生成Linear方式滤波的纹理并绑定到纹理1
	    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[1]);
	    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
	    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);

	      
	    // 生成 mipmapped方式滤波的纹理并绑定到纹理2
	    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[2]);
	    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
	    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_NEAREST);
	    if(gl instanceof GL11) {
	       gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
	    }
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
		bmp.recycle();
	}
}


程序的运行结果如下图所示:

 

 代码下载地址:http://download.csdn.net/detail/seniorwizard/4470542

你可能感兴趣的:(filter,Class,buffer,import,float,Constructor)