OpenGL ES2学习笔记(8)-- Varying变量

上一篇文章里绘制的三角形,颜色都是写死在Fragment Shader里的,这篇文章介绍如何把颜色写到顶点数据里并且在Shader里使用Varying变量实现颜色插值。

代码和效果

下面的脚本复制到OpenGL Console里:

import java.nio.ByteBuffer
import java.nio.ByteOrder
import javax.media.opengl.GL

def vertexShaderCode = """
  attribute vec4 a_Position;
  attribute vec4 a_Color;
  varying   vec4 v_Color;
  
  void main() {
    gl_Position = a_Position;
    v_Color = a_Color;
  }
"""

def fragmentShaderCode = """
  precision mediump float;
  varying vec4 v_Color;
  
  void main() {
    gl_FragColor = v_Color;
  }
"""

def shaderProgram = glob.compileAndLink(vertexShaderCode, fragmentShaderCode)
def aPositionLocation = shaderProgram.getAttribLocation("a_Position")
def aColorLocation = shaderProgram.getAttribLocation("a_Color")
shaderProgram.use()


def BYTES_PER_FLOAT = 4
def POSITION_ELEMENT_COUNT = 2
def COLOR_ELEMENT_COUNT = 3
def STRIDE = (POSITION_ELEMENT_COUNT + COLOR_ELEMENT_COUNT) * BYTES_PER_FLOAT
def POINT_COUNT = 3

def vertices = [
//x     y     r     g     b
 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
 0.8f, 0.0f, 0.0f, 1.0f, 0.0f,
 0.0f, 0.8f, 0.0f, 0.0f, 1.0f,
] as float[]

def vertexData = ByteBuffer
        .allocateDirect(vertices.length * BYTES_PER_FLOAT)
        .order(ByteOrder.nativeOrder())
        .asFloatBuffer()
vertexData.put(vertices)

vertexData.position(0)
gl.glVertexAttribPointer(aPositionLocation,
        POSITION_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData)
gl.glEnableVertexAttribArray(aPositionLocation)

vertexData.position(POSITION_ELEMENT_COUNT)
gl.glVertexAttribPointer(aColorLocation,
        COLOR_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData)
gl.glEnableVertexAttribArray(aColorLocation)


gl.glClear(gl.GL_COLOR_BUFFER_BIT)
gl.glDrawArrays(gl.GL_TRIANGLES, 0, POINT_COUNT)
效果:

顶点颜色属性

先来看看Vertex Shader代码:

  attribute vec4 a_Position;
  attribute vec4 a_Color;
  varying   vec4 v_Color;
  
  void main() {
    gl_Position = a_Position;
    v_Color = a_Color;
  }
现在有两个vec4类型的 attribute变量,一个代表顶点的位置( xyzw),一个代表颜色( rgba)。我画了个示意图:


def BYTES_PER_FLOAT = 4
def POSITION_ELEMENT_COUNT = 2
def COLOR_ELEMENT_COUNT = 3
def STRIDE = (POSITION_ELEMENT_COUNT + COLOR_ELEMENT_COUNT) * BYTES_PER_FLOAT
def POINT_COUNT = 3

def vertices = [
//x     y     r     g     b
 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
 0.8f, 0.0f, 0.0f, 1.0f, 0.0f,
 0.0f, 0.8f, 0.0f, 0.0f, 1.0f,
] as float[]
除了位置(x和y坐标)外,我们把颜色(rgb)也放到了数组里,如下图所示:


def shaderProgram = glob.compileAndLink(vertexShaderCode, fragmentShaderCode)
def aPositionLocation = shaderProgram.getAttribLocation("a_Position")
def aColorLocation = shaderProgram.getAttribLocation("a_Color")
shaderProgram.use()
...
vertexData.position(0)
gl.glVertexAttribPointer(aPositionLocation,
        POSITION_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData)
gl.glEnableVertexAttribArray(aPositionLocation)

vertexData.position(POSITION_ELEMENT_COUNT)
gl.glVertexAttribPointer(aColorLocation,
        COLOR_ELEMENT_COUNT, gl.GL_FLOAT, false, STRIDE, vertexData)
gl.glEnableVertexAttribArray(aColorLocation)
上面这段代码把Vertex Shader和顶点数据联系在了一起:


Varying变量

Vertex Shader和Fragment Shader都定义了一个vec4类型的Varying变量,这个变量将Vertex和Fragment Shader连接了起来。Vertex Shader把顶点的颜色属性传递给varying变量(v_Color = a_Color;),然后OpenGL会对其进行插值,这样我们就可以在Fragment Shader里使用插值后的变量了(gl_FragColor = v_Color;)。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值