[√]creator对color处理的细节逻辑

简介: [√]creator对color处理的细节逻辑

color的val

this._val = ((a << 24) >>> 0) + (b << 16) + (g << 8) + (r|0);

使用4字节整数表示rgba, 从低位到高位依次是rgba

var vfmtPosUvColor = new gfx.VertexFormat([
    { name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
    { name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
    { name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
]);

为啥看到了蓝色

image.png

const red = new cc.Color(255, 0, 0, 255);
red._val = 4278190335   // 白色 4294967295
vbuf[index]=red._val 

4278190335 使用float32Array存储,4字节刚好是01007F4F, 对应的颜色刚好是#01007F4F,这个颜色刚好是带有透明度的暗蓝色,这也解释了为啥我看到的是蓝色

所以颜色是不能这么设置的。

createData (index, verticesFloats, indicesCount) {
   let vertices = new Float32Array(verticesFloats);// 注意这里是Float32Array
   let indices = new Uint16Array(indicesCount);
   this.updateMesh(index, vertices, indices);
},
updateMesh (index, vertices:Float32Array, indices) {
    // 指向的都是同一个vertices
   this.vDatas[index] = vertices;
   this.uintVDatas[index] = new Uint32Array(vertices.buffer, 0, vertices.length); // 但是这个使用的是Uint32Array
   //这个类型非常重要,如果还是Float32Array,会导致存储的数据异常,因为整数和浮点数的存储方式是不同的
   // 所以看到这里转接了一层,这样方便再updateColor中设置4字节整数的时候正常
   this.iDatas[index] = indices;
   this.meshCount = this.vDatas.length;
},
// assembler-2d 
updateColor (comp, color) {
   let uintVerts:Uint32Array = this._renderData.uintVDatas[0];
   if (!uintVerts) return;
   color = color != null ? color : comp.node.color._val;
   let floatsPerVert = this.floatsPerVert;
   let colorOffset = this.colorOffset;
   for (let i = colorOffset, l = uintVerts.length; i < l; i += floatsPerVert) {
       uintVerts[i] = color;
   }
}

image.png

engine

每个meshbuffer都有对应的vertexformat,决定了这个buffer的数据如何解析填充到gpu

function _commitTextures(gl, cur, next) {
  for (let i = 0; i < next.maxTextureSlot + 1; ++i) {
    if (cur.textureUnits[i] !== next.textureUnits[i]) {
      let texture = next.textureUnits[i];// 取纹理
      if (texture && texture._glID !== -1) {
        gl.activeTexture(gl.TEXTURE0 + i);
        gl.bindTexture(texture._target, texture._glID);
      }
    }
  }
}

textureUnits是通过外部设置的

  setTexture(name, texture, slot) {
    if (slot >= this._caps.maxTextureUnits) {
      console.warn(`Can not set texture ${name} at stage ${slot}, max texture exceed: ${this._caps.maxTextureUnits}`);
      return;
    }
    this._next.textureUnits[slot] = texture;// 这里设置新的纹理
    this.setUniform(name, slot);
    if (this._next.maxTextureSlot < slot) {
      this._next.maxTextureSlot = slot;
    }
  }

往上溯源,发现

  _setProperty (prop) {
  // 省略了好多的代码
      device.setTexture(prop.name, param, this._allocTextureUnit());
  }

又见到了熟悉的_draw函数

  _draw (item) {
      // for each pass
    for (let i = 0; i < passes.length; ++i) {
          let program = programLib.getProgram(pass, defines, effect.name);
      device.setProgram(program);
      let uniforms = program._uniforms;// 对应effect里面对应的所有uniform变量
      let variants = pass._properties; // 对应effect里面的pass定义的properties
      for (let j = 0; j < uniforms.length; j++) {
        let prop = variants[uniforms[j].name];
        if (prop !== undefined){
          this._setProperty(prop);
        }
      }
    }
  }

builtin-2d-sprite.mtl

{
  "__type__": "cc.Material",
  "_name": "builtin-2d-sprite",
  "_objFlags": 0,
  "_native": "",
  "_effectAsset": {
    "__uuid__": "2874f8dd-416c-4440-81b7-555975426e93"
  },
  "_techniqueData": {
    "0": {
      "defines": {
        "USE_TEXTURE": true
      }
    }
  }
}

builtin-2d-sprite.effect

CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: { value: white }
        alphaThreshold: { value: 0.5 }
}%
CCProgram vs %{
  precision highp float;
  #include <cc-global>
  #include <cc-local>
  in vec3 a_position;
  in vec4 a_color;
  out vec4 v_color;
  #if USE_TEXTURE
  in vec2 a_uv0;
  out vec2 v_uv0;
  #endif
  void main () {
    vec4 pos = vec4(a_position, 1);
    #if CC_USE_MODEL
    pos = cc_matViewProj * cc_matWorld * pos;
    #else
    pos = cc_matViewProj * pos;
    #endif
    #if USE_TEXTURE
    v_uv0 = a_uv0;
    #endif
    v_color = a_color;
    gl_Position = pos;
  }
}%
CCProgram fs %{
  precision highp float;
  #include <alpha-test>
  #include <texture>
  in vec4 v_color;
  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif
  void main () {
    vec4 o = vec4(1, 1, 1, 1);
    #if USE_TEXTURE
      CCTexture(texture, v_uv0, o);
    #endif
    o *= v_color;
    ALPHA_TEST(o);
    #if USE_BGRA
      gl_FragColor = o.bgra;
    #else
      gl_FragColor = o.rgba;
    #endif
  }
}%
目录
相关文章
|
8月前
|
存储 前端开发 安全
SAP UI5 应用的标准 Theme 和自定义 Theme 的加载讨论
SAP UI5 应用的标准 Theme 和自定义 Theme 的加载讨论
61 1
|
Android开发
Android开发教程 - 使用Data Binding(七)使用BindingAdapter简化图片加载
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fragment中的使用 ...
1098 0
|
6月前
[√]creator 自定义顶点
[√]creator 自定义顶点
28 0
Revit API 修改视觉样式(Visual Style)
Revit API 修改视觉样式(Visual Style)
|
开发框架 小程序 Android开发
列表组件list-view的使用、flex布局教程,以APICloud AVM框架为例
avm.js是 APICloud 推出的多端开发框架。使用 avm.js 一个技术栈可同时开发 Android & iOS 原生 App、小程序和 iOS 轻 App,且多端渲染效果统一;全新的 App 引擎 3.0 不依赖 webView,提供百分百的原生渲染,保障 App 性能和体验与原生 App 一致。
461 0
|
Unix 编译器 Linux
把bthread_start_background封装成现代C++的风格!
在基于brpc开发服务的时候,bthread_start_background()一定是高频函数。bthread_start_background()是brpc框架提供给我们的API,让我们可以方便使用brpc的协程bthread。
243 0
|
开发框架 小程序 开发工具
APICloud AVM框架列表组件list-view的使用、flex布局教程
avm.js 是APICloud 推出的多端开发框架。使用 avm.js 一个技术栈可同时开发 Android & iOS 原生 App、小程序和 iOS 轻 App,且多端渲染效果统一;全新的 App 引擎 3.0 不依赖 webView,提供百分百的原生渲染,保障 App 性能和体验与原生 App 一致。
176 0
APICloud AVM框架列表组件list-view的使用、flex布局教程
|
虚拟化
QT应用编程: 使用Enigma Virtual Box 封装单执行文件
QT应用编程: 使用Enigma Virtual Box 封装单执行文件
228 0
QT应用编程: 使用Enigma Virtual Box 封装单执行文件
|
编译器
Qt Creator plugin动手实践(5)分享一个简化版的插件框架,qt-creator-minimal
Qt Creator plugin动手实践(5)分享一个简化版的插件框架,qt-creator-minimal
366 0
Qt Creator plugin动手实践(5)分享一个简化版的插件框架,qt-creator-minimal