加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

OpenGL ES2学习笔记(4)-- 画点

发布时间:2020-12-14 16:52:00 所属栏目:大数据 来源:网络整理
导读:代码和效果 打开OpenGL Console,把下面的代码复制到编辑器里: import java.nio.ByteBufferimport java.nio.ByteOrderimport javax.media.opengl.GLdef vertexShaderCode = """ attribute vec4 a_Position; void main() { gl_Position = a_Position; gl_Poi

代码和效果

打开OpenGL Console,把下面的代码复制到编辑器里:

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

def vertexShaderCode = """
  attribute vec4 a_Position;

  void main() {                              
    gl_Position = a_Position;
    gl_PointSize = 10.0;
  }
"""

def fragmentShaderCode = """
  precision mediump float; 

  void main() {
    gl_FragColor = vec4(0.7,0.0,0.3,1.0);
  }
"""

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


def BYTES_PER_FLOAT = 4
def POSITION_ELEMENT_COUNT = 2
def POINT_COUNT = 3

def vertices = [
  0.0f,0.0f,0.5f,-0.2f,-0.2f
] 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,vertexData)
gl.glEnableVertexAttribArray(aPositionLocation)


gl.glClear(gl.GL_COLOR_BUFFER_BIT)
gl.glDrawArrays(gl.GL_POINTS,POINT_COUNT)
点击Run Script按钮,应该会看到三个点出现在画布上:

Vertex Shader代码

attribute vec4 a_Position;

  void main() {                              
    gl_Position = a_Position;
    gl_PointSize = 10.0;
  }
Vertex Shader的工作是对顶点进行各种变换,所以必须通过某种方式把顶点属性(比如位置)传递给Vertex Shader。 attribute关键字告诉OpenGL,通过a_Position把顶点属性传递给Vertex Shader。vec4是GLSL语言内置的 数据类型,是包含四个float的 向量,可以代表顶点的 xyz坐标和w。

像C语言一样,Shader程序的入口也是main()方法。gl_Position是GLSL语言的一个特殊变量,表示处理后的顶点位置。这里我们只是简单的把a_Position赋值给gl_Position,不做任何变换。

gl_PointSize也是一个GLSL特殊变量,通过它我们告诉OpenGL把点画成10x10个像素大。

Fragment Shader代码

#ifdef GL_ES
  precision mediump float; 
  #endif 

  void main() {
    gl_FragColor = vec4(0.7,1.0);
  }
第一行定义默认的浮点数精度,可选精度包括 lowp、mediump和highp。gl_FragColor是个特殊变量,表示 光栅化后 Fragment的颜色。

编译和链接Shader

def shaderProgram = glob.compileAndLink(vertexShaderCode,fragmentShaderCode)
def aPositionLocation = shaderProgram.getAttribLocation("a_Position")
shaderProgram.use();
第一行代码编译和链接Shader代码。

第二行代码获取Vertex Shader代码里的a_Position位置,后面会用到:

public class ShaderProgram extends GLObject {
    
    public int getAttribLocation(String aName) {
        return getGL().glGetAttribLocation(objectId,aName);
    }
    
    ...
}
第三行把链接好的Shader Program设置为激活状态:

public class ShaderProgram extends GLObject {
    
    public void use() {
        getGL().glUseProgram(objectId);
    }
    ...
}

顶点数据

def vertices = [
  // x    y 
 ?0.0f,-0.2f
] as float[];

顶点数据包含三个顶点,每个顶点只定义了x和y坐标,OpenGL会自动把z的值设置成0,把w的值设置成1。

NDC

OpenGL工作在一个叫做NDC(Normalized Device Coordinates)的坐标系统下,在这个坐标系统中,x、y和z的值全部都坐落在[-1,+1]范围内,超出这个范围的点会被OpenGL忽略。因为我们直接使用OpenGL的NDC坐标系统,所以顶点坐标的值在-1到+1之间。

把顶点数据和Shader关联

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,vertexData)
gl.glEnableVertexAttribArray(aPositionLocation)
通过调用 glVertexAttribPointer()方法,我们把顶点数据和Vertex Shader里的a_Position联系起来,这样OpenGL就会把vertexData里的顶点依次取出交给Shader处理。

POSITION_ELEMENT_COUNT参数告诉OpenGL,vertexData里的顶点只包含x和y坐标。GL_FLOAT参数告诉OpenGL,把vertexData当做float数组来看待。

glEnableVertexAttribArray()方法激活顶点数据。

画点

gl.glClear(gl.GL_COLOR_BUFFER_BIT)
gl.glDrawArrays(gl.GL_POINTS,POINT_COUNT)
glClear()清除屏幕, glDrawArrays()最终把三个点画在了屏幕上。OpenGL实际上只能绘制 点、线或三角形, GL_POINTS参数告诉OpenGL我们想要画的是点。POINT_COUNT参数告诉OpenGL画三个点。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读