Cocos2d-x/Android searchlight effects (spotlight)

Source: Internet
Author: User
Tags addchild

Idea: use OpenGL to draw a circle, the vertex is the center + the point on the circumference, the vertex color value (0, 0, 0, 0), the color value of the circumference point (0, 0, 0, 0, 0xff), enable Alpha mixing, and use glblendfunc (gl_zero, gl_src_alpha). In this way, OpenGL will automatically gradient in the middle area.

Effect:

Code:

Cococs2d-x implementation

Spotlight. h

#ifndef __SPOT_LIGHT_H__#define __SPOT_LIGHT_H__class CCSpotLight: public CCSprite{public:CCSpotLight();~CCSpotLight();static CCSpotLight* spotLightWithRenderTexture(CCRenderTexture* texture, float radius, ccColor4B color);CC_SYNTHESIZE_RETAIN(CCRenderTexture*, m_renderTexture, RenderTexture)CC_SYNTHESIZE(float, m_spotLightRadius, SpotLightRadius)CC_SYNTHESIZE_PASS_BY_REF(ccColor4B, m_renderColor, RenderColor)private:bool initWithRenderTexture(CCRenderTexture* texture, float radius, ccColor4B color);void draw();};#endif// __SPOT_LIGHT_H__

Spotlight. cpp

# Include <cocos2d. h> using namespace cocos2d; # include "spotlight. H "const int spot_light_vertices_count = 45; // The number of vertices on the center and circumference must be greater than 5. Const cccolor4b spot_light_center_color = ccc4 (0, 0, 0, 0 ); const cccolor4b labels = ccc4 (0, 0, 0, 0xff); ccspotlight: ccspotlight () {m_rendertexture = NULL; m_spotlightradius = 0; m_rendercolor.r = 0; m_rendercolor.g = 0; m_rendercolor. B = 0; m_rendercolor.a = 0;} CC Spotlight ::~ Ccspotlight () {cc_safe_release (m_rendertexture);} ccspotlight * ccspotlight: spotlightwithrendertexture (ccrendertexture * texture, float radius, cccolor4b color) {ccspotlight * spotlight = NULL; spotlight = new ccspotlight (); If (spotlight & spotlight-> initwithrendertexture (texture, radius, color) {spotlight-> autorelease (); Return spotlight ;} cc_safe_delete (spotlight); Return spotlight;} bool ccspotlight: ini Twithrendertexture (ccrendertexture * texture, float radius, cccolor4b color) {bool Bret = false; do {Bret = ccsprite: Init (); cc_break_if (! Bret); setrendertexture (texture); setspotlightradius (RADIUS); setrendercolor (color); Bret = true;} while (0); Return Bret;} void ccspotlight: Draw () {ccsprite: Draw (); int segs = spot_light_vertices_count; glfloat * vertices = new glfloat [2 * segs]; // malloc (sizeof (glfloat) * 2 * (segs); glfloat * coordinates = new glfloat [2 * segs]; // malloc (sizeof (glfloat) * 2 * (segs )); cccolor4b * Colors = new cccolor4b [segs]; // malloc (sizeof (cccolor4b) * (segs); memset (vertices, 0, sizeof (glfloat) * 2 * (segs); memset (coordinates, 0, sizeof (glfloat) * 2 * (segs); ccsize winsize = ccdirector: shareddire () -> getwinsize (); m_rendertexture-> clear (m_rendercolor.r, m_rendercolor.g, m_rendercolor. B, m_rendercolor.a); // m_rendertexture-> clear (0, 0, 0, 0xff ); colors [0] = spot_light_center_color; For (INT I = 1; I <segs; I ++) {colors [I] = spot_light_edge_color;} const float coef = 2.0f * (float) m_pi/(segs-2); ccpoint Pos = getposition (); ccsize size = This-> getcontentsize (); vertices [0] = 0; // POS. x; vertices [1] = 0; // POS. y; coordinates [0] = vertices [0]/winsize. width; coordinates [1] = (size. height-vertices [1])/winsize. height; For (INT I = 1; I <segs; I ++) {float rads = I * coef; float J = m_spotlightradius * cosf (rads); // + POS. x; float K = m_spotlightradius * sinf (rads); // + POS. y; vertices [I * 2] = J; vertices [I * 2 + 1] = K; coordinates [I * 2] = (j)/winsize. width; coordinates [I * 2 + 1] = (size. height-k)/winsize. height;} // update the render texture // [self. rendertexture begin]; m_rendertexture-> begin (); glbindtexture ); glvertexpointer (2, gl_float, 0, vertices); gltexcoordpointer (2, gl_float, 0, coordinates); glcolorpointer (4, vertex, 0, colors); gldrawarrays (cost, 0, segs); glcolormask (gl_true, gl_true); glblendfunc (cc_blend_src, cc_blend_dst); // [self. rendertexture end]; m_rendertexture-> end (); cc_safe_delete (vertices); cc_safe_delete (coordinates); cc_safe_delete (colors );}

Call method:

CCRenderTexture* renderLayer = CCRenderTexture::renderTextureWithWidthAndHeight(size.width, size.height);renderLayer->setPosition(ccp(size.width/2, size.height/2));ccBlendFunc bf = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};renderLayer->getSprite()->setBlendFunc(bf);addChild(renderLayer);CCSpotLight* spotLight = CCSpotLight::spotLightWithRenderTexture(renderLayer, 60.0f, ccc4(0, 0, 0, 0xFF));CC_BREAK_IF(!spotLight);spotLight->setAnchorPoint(ccp(0, 0));spotLight->setPosition(ccp(size.width/2, size.height/2));//spotLight->setPosition(ccp(0, 0));addChild(spotLight);

Refer:

1. IOS version spotlight effect demo http://www.supersuraccoon-cocos2d.com/zh/2011/09/09/spot-light-demo/

========================================================== ========================================================== ===

Android

Main. xml

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <ImageView        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:src="@drawable/dota"         />        <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_gravity="center_vertical"        android:textColor="@android:color/primary_text_light"        android:text="@string/hello" />        <Button        android:id="@+id/btn_click_me"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/btn_click"         />    <com.kle.SpotLight.SpotLightGLSurfaceView        android:id="@+id/spotlight_gl_surfaceview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        /></FrameLayout>

Spotlightactivity. Java

Package COM. gr. spotlight; import android. app. activity; import android. OS. bundle; public class spotlightactivity extends activity {/** called when the activity is first created. * // @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); m_glview = (spotlightglsurfaceview) findviewbyid (R. id. spotlight_gl_surfaceview); spotlightrender Renderer = new spotlightrender (480,800); m_glview.setrenderer (Renderer); spotlight slight = new spotlight (0,480,100, 5); // the coordinate system is the GL coordinate system, that is, the coordinate origin in the lower left corner of the screen, to the right is the positive direction of the X axis, to the positive direction of the Y axis m_glview.addspotlight (slight); slight = new spotlight (0,480,400, 10); // the coordinate system is the GL coordinate system, that is, the coordinate origin in the lower left corner of the screen, to the right is the positive direction of the X axis, and to the positive direction of the Y axis m_glview.addspotlight (slight); // slight. setposition (240,400); // you can set the coordinate button BTN = (button) findviewbyid (R. id. btn_clic K_me); BTN. setonclicklistener (New onclicklistener () {@ override public void onclick (view v) {// todo auto-generated method stub toast. maketext (getapplicationcontext (), "click me! ", Toast. length_short). Show () ;}}) ;}spotlightglsurfaceview m_glview = NULL ;}

Spotlightglsurfaceview. Java

Package COM. gr. spotlight; import android. content. context; import android. graphics. pixelformat; import android. openGL. glsurfaceview; import android. util. attributeset; import android. view. surfaceholder; public class spotlightglsurfaceview extends glsurfaceview {public spotlightglsurfaceview (context, attributeset attrs) {super (context, attrs ); // todo auto-generated constructor stub // The code must be in Setzorderontop (true) before Renderer; seteglconfigchooser (8, 8, 8, 8, 16, 0); surfaceholder holder = getholder (); holder. setformat (pixelformat. translucent);} public void setrenderer (Renderer) {super. setrenderer (Renderer); m_renderer = (spotlightrender) Renderer;} public int addspotlight (spotlight SL) {int nret = 0; If (m_renderer! = NULL) {m_renderer.addspotlight (SL);} return nret;} public void updatespotlights () {If (m_renderer! = NULL) {m_renderer.updatemove () ;}} private spotlightrender m_renderer = NULL ;}

Spotlightrender. Java

package com.gr.SpotLight;import java.util.ArrayList;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLSurfaceView.Renderer;public class SpotLightRender implements Renderer{    public SpotLightRender(int width, int height)    {        super();        m_width = width;        m_height = height;    }        @Override    public void onSurfaceCreated(GL10 gl, EGLConfig config)    {        // TODO Auto-generated method stub        gl.glDisable(GL10.GL_DITHER);                gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);                gl.glClearColor(0, 0, 0, 1);                gl.glShadeModel(GL10.GL_SMOOTH);        //gl.glEnable(GL10.GL_CULL_FACE);        gl.glOrthof(0, m_width, 0, m_height, 1, -1);    }    @Override    public void onSurfaceChanged(GL10 gl, int width, int height)    {        // TODO Auto-generated method stub        m_width = width;        m_height = height;        gl.glViewport(0, 0, width, height);        // make adjustments for screen ratio        float ratio = (float)width / height;        gl.glMatrixMode(GL10.GL_PROJECTION);// set matrix to projection mode        gl.glLoadIdentity();// reset the matrix to its default state        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);// apply the projection matrix    }    @Override    public void onDrawFrame(GL10 gl)    {        // TODO Auto-generated method stub        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);        gl.glMatrixMode(GL10.GL_PROJECTION);        gl.glLoadIdentity();        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);                for (int i = 0; i < m_spotLightArray.size(); i++)        {            ((SpotLight)m_spotLightArray.get(i)).moveByFrame();            ((SpotLight)m_spotLightArray.get(i)).draw(gl);        }    }        public int addSpotLight(SpotLight spotLight)    {        int nRet = 0;                if (m_spotLightArray == null)        {            m_spotLightArray = new ArrayList<SpotLight>();        }                if (m_spotLightArray != null && spotLight != null)        {            m_spotLightArray.add(spotLight);            nRet = m_spotLightArray.size();        }                return nRet;    }        public void clearSpotLightArray()    {        if (m_spotLightArray != null)        {            m_spotLightArray.clear();            m_spotLightArray = null;        }    }        public void updateMove()    {        for (int i = 0; i < m_spotLightArray.size(); i++)        {            ((SpotLight)m_spotLightArray.get(i)).moveByFrame();        }    }    private ArrayList<SpotLight> m_spotLightArray = new ArrayList<SpotLight>();    private int m_width = 480;    private int m_height = 800;}

Spotlight. Java

Package COM. gr. spotlight; import Java. NIO. bytebuffer; import Java. NIO. byteorder; import Java. NIO. floatbuffer; import Java. NIO. intbuffer; import javax. microedition. khronos. opengles. gl10; import android. graphics. color; import android. graphics. point; import android. graphics. pointf; public class spotlight {public spotlight () {Init (0, 0, 0, velocity_default, radius_default, vertex_count_default);} public spotl Ight (float lx, float RX, float y, float v) {Init (LX, RX, Y, V, radius_default, vertex_count_default);} public spotlight (float lx, float RX, float y, float V, float radius) {Init (LX, RX, Y, V, radius, vertex_count_default);} public spotlight (float lx, float RX, float y, float V, float radius, int vertexcount) {Init (LX, RX, Y, V, radius, vertexcount);} private void Init (float lx, float RX, Flo At Y, float V, float radius, int vertexcount) {If (LX> RX) {float TMP = RX; RX = Lx; Lx = TMP;} m_leftx = Lx; m_rightx = RX; m_mydirector = m_rand.nextboolean ()? Director_left: director_right; float x = round () * (m_rightx-m_leftx) + m_leftx; m_position.set (x, y); m_vbyframe = V; m_radius = radius; m_vertexcount = vertexcount; initvertices ();} private void initvertices () {int I = 0; m_vertices = new float [point_size * m_vertexcount]; m_colors = new int [color_size * m_vertexcount]; double coef= 2.0 * Math. PI/(m_vertexcount-2); // center m_vertices [0] = 0; // m_position.x; m_vertices [1] = 0; // m_position.y; m_colors [0] = 0; m_colors [1] = 0; m_colors [2] = 0; m_colors [3] = 0; for (I = 1; I <m_vertexcount; I ++) {double rads = I * coef; m_vertices [I * point_size] = (float) (m_vertices [0] + m_radius * Math. cos (rads); m_vertices [I * point_size + 1] = (float) (m_vertices [1] + m_radius * Math. sin (rads); m_colors [I * color_size] = 0; // 0 xFFFF; m_colors [I * color_size + 1] = 0; m_colors [I * color_size + 2] = 0; m_colors [I * color_size + 3] = 0 xFFFF; // 0;} convert2glpos (); bytebuffer CBB = bytebuffer. allocatedirect (m_colors.length * integer. size/byte. size); CBB. order (byteorder. nativeorder (); m_colorbuffer = CBB. asintbuffer (); m_colorbuffer.put (m_colors); m_colorbuffer.position (0);} private void convert2glpos () {float VT [] = new float [point_size * m_vertexcount]; int I = 0; for (I = 0; I <m_vertexcount; I ++) {vt [I * point_size] = m_vertices [I * point_size] + m_position.x; VT [I * point_size + 1] = m_vertices [I * point_size + 1] + m_position.y;} bytebuffer vBB = bytebuffer. allocatedirect (vt. length * float. size/byte. size); vBB. order (byteorder. nativeorder (); m_vertexbuffer = vBB. asfloatbuffer (); m_vertexbuffer.put (VT); m_vertexbuffer.position (0);} public void draw (gl10 GL) {GL. glfrontface (gl10.gl _ CW); GL. glvertexpointer (point_size, gl10.gl _ float, 0, m_vertexbuffer); GL. glcolorpointer (color_size, gl10.gl _ fixed, 0, m_colorbuffer); GL. trim (gl10.gl _ forward, 0, m_vertexcount);} public void movebyframe () {m_position.offset (m_mydirector * m_vbyframe, 0); If (m_position.x> m_rightx) {forward = m_rightx; m_mydirector = director_left;} else if (m_position.x <m_leftx) {direction = m_leftx; m_mydirector = director_right;} convert2glpos ();} public void setposition (float X, float y) {m_position.set (x, y); convert2glpos ();} public void offposition (float dx, float Dy) {m_position.offset (dx, Dy); convert2glpos ();} public void setradius (float R) {m_radius = r; double coef = 2.0 * Math. PI/(m_vertexcount-2); int I = 0; for (I = 1; I <m_vertexcount; I ++) {double rads = I * coef; m_vertices [I * point_size] = (float) (m_vertices [0] + m_radius * Math. cos (rads); m_vertices [I * point_size + 1] = (float) (m_vertices [1] + m_radius * Math. sin (rads);} convert2glpos ();} private pointf m_position = new pointf (); // relative coordinate, private float m_leftx = 0 in gl_surfaceview; private float m_rightx = 0; private float m_radius; private int m_vertexcount; private point m_parentwinsize = new point (); Private float m_vertices [] = NULL; private int m_colors [] = NULL; private floatbuffer m_vertexbuffer = NULL; private intbuffer m_colorbuffer = NULL; private random m_rand = new random (system. currenttimemillis (); Private Final Static int director_left =-1; private final static int director_right = 1; private int m_mydirector = director_left; private final static float velocity_default = 1; private float m_vbyframe = velocity_default; private final static float radius_default = 100; private final static int vertex_count_default = 45; //> 5 private final static int point_size = 2; private Final Static int color_size = 4; // R, G, B, A private final static int center_color = color. argb (0x00, 0x00, 0x00, 0x00); Private Final Static int edge_color = color. argb (0xff, 0x00, 0x00, 0x00 );}

Refer:

1. android3d collision of objects -- cube collision http://www.2cto.com/kf/201110/109245.html

2. Make glsurfaceview transparent background image http://blog.csdn.net/cc_lq/article/details/6629659

Http://blog.sina.com.cn/s/blog_7705f5140100rive.html

Http://topic.csdn.net/u/20110215/16/c2849359-b07e-424f-bf0d-db0506b69002.html

Summary:

1. Basically, OpenGL is not used, so it is easy to understand. It is very big and you need to learn OpenGL well.

2. At first I was modeled on the cocos2d-x code written Android code, shit doesn't get through it, is not displayed, but also a variety of collapse.

3. The glsurfaceview transparent reference is to make the glsurfaceview transparent and visible background image: three main sentences

mGLSurfaceView.setZOrderOnTop(true);mGLSurfaceView.setEGLConfigChooser(8,8,8,8,16,0);mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

Mglsurfaceview. seteglconfigchooser (8, 8, 8, 8, 16, 0); add it before setrender.

4. Color problems:

The glclearcolor parameter is float, that is, 0 ~ Number between 1, the order of R G B

Glcolorpointer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.