1. 程式人生 > >Cocos2dx-- 圖片置灰實現

Cocos2dx-- 圖片置灰實現

前言:遊戲中有很多按鈕控制元件,它們一般會有選中和未選中2種狀態。我們如果要區分這兩種狀態的表現,很多時候是直接叫美術給兩種狀態下的資源,或直接setColor設定顏色。這樣無疑增加了資源的大小或不美觀(看需求)。本節將介紹怎麼通過opengl es程式來實現圖片置灰操作。

注:這個置灰操作是基於Cocos-Lua的,具體原理分析這裡不打算介紹,主要講如何實現。

實現步驟

  • Lua端操作:

1,置灰Lua程式碼(ShaderEffect.lua)

local ShaderEffect = {

        vertDefaultSource = "\n"..
        "attribute vec4 a_position; \n"
.. "attribute vec2 a_texCoord; \n" .. "attribute vec4 a_color; \n".. "#ifdef GL_ES \n".. "varying lowp vec4 v_fragmentColor;\n".. "varying mediump vec2 v_texCoord;\n".. "#else \n"
.. "varying vec4 v_fragmentColor; \n" .. "varying vec2 v_texCoord; \n".. "#endif \n".. "void main() \n".. "{\n" .. "gl_Position = CC_PMatrix * a_position; \n".. "v_fragmentColor = a_color;\n".. "v_texCoord = a_texCoord;\n".. "}"
, pszFragSource2 = "#ifdef GL_ES \n" .. "precision mediump float; \n" .. "#endif \n" .. "uniform sampler2D u_texture; \n" .. "varying vec2 v_texCoord; \n" .. "varying vec4 v_fragmentColor;\n".. "uniform vec2 pix_size;\n".. "void main(void) \n" .. "{ \n" .. "vec4 sum = vec4(0, 0, 0, 0); \n" .. "sum += texture2D(u_texture, v_texCoord - 4.0 * pix_size) * 0.05;\n".. "sum += texture2D(u_texture, v_texCoord - 3.0 * pix_size) * 0.09;\n".. "sum += texture2D(u_texture, v_texCoord - 2.0 * pix_size) * 0.12;\n".. "sum += texture2D(u_texture, v_texCoord - 1.0 * pix_size) * 0.15;\n".. "sum += texture2D(u_texture, v_texCoord ) * 0.16;\n".. "sum += texture2D(u_texture, v_texCoord + 1.0 * pix_size) * 0.15;\n".. "sum += texture2D(u_texture, v_texCoord + 2.0 * pix_size) * 0.12;\n".. "sum += texture2D(u_texture, v_texCoord + 3.0 * pix_size) * 0.09;\n".. "sum += texture2D(u_texture, v_texCoord + 4.0 * pix_size) * 0.05;\n".. "gl_FragColor = sum;\n".. "}", --變灰 psGrayShader = "#ifdef GL_ES \n" .. "precision mediump float; \n" .. "#endif \n" .. "varying vec4 v_fragmentColor; \n" .. "varying vec2 v_texCoord; \n" .. "void main(void) \n" .. "{ \n" .. "vec4 c = texture2D(CC_Texture0, v_texCoord); \n" .. "gl_FragColor.xyz = vec3(0.3*c.r + 0.15*c.g +0.11*c.b); \n".. "gl_FragColor.w = c.w; \n".. "}" , --移除變灰 psRemoveGrayShader = "#ifdef GL_ES \n" .. "precision mediump float; \n" .. "#endif \n" .. "varying vec4 v_fragmentColor; \n" .. "varying vec2 v_texCoord; \n" .. "void main(void) \n" .. "{ \n" .. "gl_FragColor = texture2D(CC_Texture0, v_texCoord); \n" .. "}" , pszFragSource1 = "#ifdef GL_ES \n" .. "precision mediump float; \n" .. "#endif \n" .. "varying vec4 v_fragmentColor; \n" .. "varying vec2 v_texCoord; \n" .. "void main(void) \n" .. "{ \n" .. "vec4 c = texture2D(CC_Texture0, v_texCoord); \n" .. "gl_FragColor.xyz = vec3(0.3*c.r + 0.15*c.g +0.11*c.b); \n".. "gl_FragColor.w = c.w; \n".. "}" , } function ShaderEffect:init() local pGrayProgram = cc.GLProgram:createWithByteArrays(self.vertDefaultSource,self.psGrayShader) pGrayProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION,cc.VERTEX_ATTRIB_POSITION) pGrayProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR,cc.VERTEX_ATTRIB_COLOR) pGrayProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD,cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) pGrayProgram:link() pGrayProgram:use() pGrayProgram:updateUniforms() cc.GLProgramCache:getInstance():addGLProgram(pGrayProgram,"pGrayProgram") local pRemoveGrayProgram = cc.GLProgram:createWithByteArrays(self.vertDefaultSource,self.psRemoveGrayShader) pRemoveGrayProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION,cc.VERTEX_ATTRIB_POSITION) pRemoveGrayProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR,cc.VERTEX_ATTRIB_COLOR) pRemoveGrayProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD,cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) pRemoveGrayProgram:link() pRemoveGrayProgram:use() pRemoveGrayProgram:updateUniforms() cc.GLProgramCache:getInstance():addGLProgram(pRemoveGrayProgram,"pRemoveGrayProgram") end function ShaderEffect:addGrayNode(node) --變灰的 local pProgram = cc.GLProgram:createWithByteArrays(self.vertDefaultSource,self.psGrayShader) pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION,cc.VERTEX_ATTRIB_POSITION) pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR,cc.VERTEX_ATTRIB_COLOR) pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD,cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) pProgram:link() pProgram:use() pProgram:updateUniforms() node:setGLProgram(pProgram) end function ShaderEffect:removeGrayNode(node) local pProgram = cc.GLProgram:createWithByteArrays(self.vertDefaultSource,self.psRemoveGrayShader) pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION,cc.VERTEX_ATTRIB_POSITION) pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR,cc.VERTEX_ATTRIB_COLOR) pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD,cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) pProgram:link() pProgram:use() pProgram:updateUniforms() node:setGLProgram(pProgram) end function ShaderEffect:AddBlur(node) local fileUtiles = cc.FileUtils:getInstance() local vertSource = self.vertDefaultSource local fragSource = fileUtiles:getStringFromFile("shaders/example_Blur.fsh") local pProgram = cc.GLProgram:createWithByteArrays(vertSource, fragSource) node:setGLProgram(pProgram) --local glprogramstate = cc.GLProgramState:getOrCreateWithGLProgram(pProgram) local size = node:getTexture():getContentSizeInPixels() node:getGLProgramState():setUniformVec2("pix_size", size) node:getGLProgramState():setUniformFloat("blurRadius", 20.0); node:getGLProgramState():setUniformFloat("sampleNum", 0.1); -- -- pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_POSITION,cc.VERTEX_ATTRIB_POSITION) -- pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_COLOR,cc.VERTEX_ATTRIB_COLOR) -- pProgram:bindAttribLocation(cc.ATTRIBUTE_NAME_TEX_COORD,cc.VERTEX_ATTRIB_FLAG_TEX_COORDS) pProgram:link() pProgram:use() pProgram:updateUniforms() end -- 按鈕置灰 function ShaderEffect:addGrayButton(button) if button == nil then cclog("param can't be nil") return end -- 遍歷按鈕的子節點 --[[local children = button:getChildren() if children and #children>0 then for _, aSprite in ipairs(children) do if aSprite.getVirtualRenderer then self:addGrayNode(aSprite:getVirtualRenderer():getSprite()) elseif aSprite.setGLProgram then self:addGrayNode(aSprite) end end end ]] -- 按鈕本身 local sprite9 = button:getVirtualRenderer() local sprite = sprite9:getSprite() self:addGrayNode(sprite) end -- 按鈕返回正常 function ShaderEffect:removeGrayButton(button) if button == nil then cclog("param can't be nil") return end -- 按鈕本身 local sprite9 = button:getVirtualRenderer() local sprite = sprite9:getSprite() self:removeGrayNode(sprite) end --遍歷變灰 function ShaderEffect:setGrayAndChild(node,isNotRecursive) if node == nil then return end local array = node:getSpriteChildren() for key, var in pairs(array) do var:setGLProgram(cc.GLProgramCache:getInstance():getGLProgram("pGrayProgram")) end if isNotRecursive ~= true then --children local array = node:getChildren() for key, var in pairs(array) do self:setGrayAndChild(var) end end end --遍歷取消變灰 function ShaderEffect:setRemoveGrayAndChild(node,isNotRecursive) if node == nil then return end local array = node:getSpriteChildren() for key, var in pairs(array) do var:setGLProgram(cc.GLProgramCache:getInstance():getGLProgram("pRemoveGrayProgram")) end if isNotRecursive ~= true then --children local array = node:getChildren() for key, var in pairs(array) do self:setRemoveGrayAndChild(var) end end end ShaderEffect:init() return ShaderEffect

2,使用

local ShaderEffect = require("ShaderEffect")  --載入

ShaderEffect:setGrayAndChild(Button)  --置灰
ShaderEffect:setRemoveGrayAndChild(Button)  --取消置灰
  • cocos C++端操作:

Lua端程式碼需要呼叫C++端擴充套件的getSpriteChildren()介面(得到控制元件的精靈物件),下面就來看看C++端怎麼來擴充套件這個介面(這裡以Button置灰為例,其它控制元件思路一樣):

1,首先在基類CCNode.h中新增這個介面,保證其它控制元件(沒有實現的)至少不會執行出錯。

virtual Vector<Node*> getSpriteChildren() { Vector<Node*> vec; return vec; } //@cxx

2,既然以按鈕控制元件為例,就先找到UIButton.h中表示按鈕精靈資訊的成員,發現是這4個變量表示:

Scale9Sprite* _buttonNormalRenderer; //初始狀態圖片
Scale9Sprite* _buttonClickedRenderer; //點選狀態圖片
Scale9Sprite* _buttonDisableRenderer;//擡起後圖片
Label* _titleRenderer; //按鈕裡文字

從這裡可以看出,要得到按鈕的所有精靈,還得去Scal9Sprite類和Label類中修改,先上UIButton類中getSpriteChildren()的實現:

Vector<Node*> Button::getSpriteChildren()
{
    Vector<Node*> vec;
    if (_buttonNormalRenderer) {
        vec.pushBack(_buttonNormalRenderer->getSpriteChildren());
    }
    if (_buttonClickedRenderer) {
        vec.pushBack(_buttonClickedRenderer->getSpriteChildren());
    }
    if (_buttonDisableRenderer) {
        vec.pushBack(_buttonDisableRenderer->getSpriteChildren());
    }
    if (_titleRenderer) {
        vec.pushBack(_titleRenderer->getSpriteChildren());
    }
    return vec;
}

3,上面按鈕圖片資源資料既然是返回的Scale9Sprite物件的指標,那我們就得去這個類中得到精靈資訊,具體getSpriteChildren()的實現如下:

Vector<Node*> Scale9Sprite::getSpriteChildren()
    {
        Vector<Node*> vec;
        if (_scale9Image) {
            vec.pushBack(_scale9Image);
        }
        if (_topLeftSprite) {
            vec.pushBack(_topLeftSprite);
        }
        if (_topSprite) {
            vec.pushBack(_topSprite);
        }
        if (_topRightSprite) {
            vec.pushBack(_topRightSprite);
        }
        if (_leftSprite) {
            vec.pushBack(_leftSprite);
        }
        if (_centerSprite) {
            vec.pushBack(_centerSprite);
        }
        if (_rightSprite) {
            vec.pushBack(_rightSprite);
        }
        if (_bottomLeftSprite) {
            vec.pushBack(_bottomLeftSprite);
        }
        if (_bottomSprite) {
            vec.pushBack(_bottomSprite);
        }
        if (_bottomRightSprite) {
            vec.pushBack(_bottomRightSprite);
        }
        return vec;
    }

4,按鈕的文字資料返回的是Label物件指標,同樣,我們得去Label類中實現getSpriteChildren()得到文字的精靈,程式碼如下:

Vector<Node*> Label::getSpriteChildren()
{
    Vector<Node*> vec;
    if (_textSprite) {
        vec.pushBack(_textSprite);
    }
    return vec;
}

5,好,這樣按鈕的4個相關精靈資料都能得到了,接下來就是tolua繫結到Lua端呼叫,如何繫結,前面章節有介紹。(Lua Shader那邊反正是要最終得到 Sprite* 精靈物件來進行處理,遇到間接的紋理物件就一層一層的剝吧…)

效果圖

這裡寫圖片描述

相關推薦

Cocos2dx-- 圖片實現

前言:遊戲中有很多按鈕控制元件,它們一般會有選中和未選中2種狀態。我們如果要區分這兩種狀態的表現,很多時候是直接叫美術給兩種狀態下的資源,或直接setColor設定顏色。這樣無疑增加了資源的大小或不美觀(看需求)。本節將介紹怎麼通過opengl es程式來實現圖

cocos2dx 圖片及正常顯示實現(lua可以呼叫)

圖片變灰, 採用shader就可以實現,   有2中方法, 1,  像CCSprite一樣create 2.  把CCSprite傳進來, 並把圖片要不要變灰的flag傳進來, 具體實現看程式碼和後面的使用方法 ---------------------------

cocos2dx tableview基礎:實現圖片的滑動顯示

通過tableview實現滑動顯示26個字母圖片,點選圖片執行相應的動作。 tableview 需要繼承TableViewDataSource(資料來源),TableViewDelegate(觸屏事件處理),同時實現其虛擬函式。 程式碼如下: 標頭檔案TableViewTe

cocos2dx shader版本讓圖片(lua版本)

function UI.setSpriteGray( sp ) local vertShaderByteArray = "\n".. "attribute vec4 a_pos

Unity圖片的方式

灰度 約定 bar str data mod main 又一 lai http://www.tuicool.com/articles/Vruuqme NGUI中的Button差點兒是最經常使用到的控件之中的一個,而且能夠組合各種組件(比方UIButtonColor,UI

動畫效果 詳情請看 jQuery api 動畫收放 slideUp slideDown 通過id class 來設 jQuery實現效果

color ada htm border order style borde query list <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8">

Eclipse4.7使用基礎 在創建類的時候,進行設自動實現抽象父類的所有抽象方法

sleep 所有 png 2-2 finish highlight lips ner eclipse os :windows7 x64 jdk:jdk-8u131-windows-x64 ide:Eclipse Oxygen Release (4.7.0

java生成圖片驗證碼實現

isp tex version edi ade 頁面 類型 logs exp 兩種圖片樣式分別是用Graphics類和Graphics2D 類實現(Graphics2D擴展了Graphics類),可以參考資料,畫出自己想要的圖片 Graphics2D 參考api地址:ht

自定義按鈕自定義

常見 -a js代碼 tdi poi microsoft font not clas js代碼如下: 大於0時為可點擊狀態;小於0時為不可點擊狀態。 if(totalCount>0){ $("#btnExport").removeClass("btnExpo

【Thinkphp 5】auth權限設以及實現

new bsp ssi 登陸 public check ces 最終 ont 1.將auth類下載好 放置目錄: extend\auth\auth.php 2.將類中的SQL語句執行,可以在數據庫中創建3張表 auth_group(用戶組表) auth_

Java圖片度處理方法

gpo sta 個數 像素 blue public ++ 最小 顏色 通過看網上各種大牛的總結,和自己親身測試總結一下Java圖片的灰度處理方法 (1)我們熟知的圖片中的像素點有RGB值。 (2)圖片灰度化的方式大概分為四種,第一種是最大值法(取顏色RGB中的最大值作為灰度

php編程之kindeditor上傳圖片加水印實現

php 圖片加水印 對於如何在圖片上添加水印是許多技術人員遇到的一個難題,那大家都見過微信公眾號及一些其他技術平臺是可以實現這個功能的,但是對於源碼是如何實現的,卻沒有頭緒,那麽今天就為大家介紹一下關於kindeditor上傳圖片加水印的方法,看完之後相信各位技術人員就知道了。第一步:修改upload

用類的內方法實現類型檢查

log tle bug for sel war new formatter 實現類 1.利用重寫__setattr__來實現。 import logging logger = logging.getLogger(‘logger‘) streamhandler = log

lenovo 無線關閉 打開無線

lenovo 無線關閉 打開無線置電腦信息:主機型號:Lenovo G40-70m當前操作系統 Windows 7 64位問題描述:win+x打開無線 置灰其它服務也都開啟通過在網上找了各種方法都是正常的。解決方法:下載“聯想電源管理”http://support.lenovo.com.cn/lenovo/

web 圖片上傳實現本地預覽

UNC view 使用 區別 lec F5 sed 邊界 urn 在說上傳之前先說說如何替換or美化瀏覽器自帶的簡陋上傳按鈕(自定義自己的上傳按鈕 如:img): 1.將自定義上傳按鈕上方添加 input file 框,實現input實現透明處理。 2.對自定義

CKEditor圖片上傳實現詳細步驟(使用Struts 2)

struts2 none bject parameter found contains 使用 工具 call 本人使用的CKEditor版本是4.7.0 CKEditor的編輯器工具欄中有一項“圖片域”,該工具可以貼上圖片地址來在文本編輯器中加入圖片,但是沒有圖片上傳。

python 圖片識別

rom nump mage bmp def dst div nsf port # -*- coding: cp936 -*- from skimage import io,transform,color import numpy as np def convert_g

pdf及word右上角新增圖片(Java實現

以下程式碼,如有問題,請大家不吝指出,如有更優實現方案,歡迎一起討論。 最近在做一個需求:在pdf和word右上角新增一個二維碼 其中,pdf可以靈活實現二維碼的位置,但是word由於我是在頁首處新增的圖片,因此我的方法只能在頁首處新增圖片。 首先定義一個介面(先丟擲Exception,

深度學習圖片過大--------------實現將一張圖片裁剪成二圖片併合並

import os import cv2 import numpy as np import tqdm #cv2讀取一律寫成預設模式 #path = 'D:\\program\\fast-neural-style-tensorflow-master\\C\\pic\\' path = 'D:\\pr

Qt點滴 QLabel Disabled時 圖片

void QLabel::paintEvent(QPaintEvent *) {     ....... #endif     if (d->pixmap && !d->pixmap->isNull()