首页 > 社交 > 科普中国

OpenGL

常驻编辑 科普中国 2022-09-30 连贯   角形   纹理   顶点   绑定   变量   直线   片段   图像   窗口   梦想


TrX拜客生活常识网

编译着色器TrX拜客生活常识网

//创建着色器
//type有  GL_VERTEX_SHADER - 顶点着色器   GL_FRAGMENT_SHADER - 片段着色器
shaderId = glCreateShader(type);
if (!glIsShader(shaderId)) {
    //检查是否创建成功
    return false;
}

//shaderSrc就是上面着色器代码的字符串
glShaderSource(shaderId, 1, &shaderSrc, NULL);

//开始编译
glCompileShader(shaderId);

//检查是否编译成功
GLint compiled = 0;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
    GLint infoLen = 0;
    glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &infoLen);
    if (infoLen > 1)
    {
        //获取编译失败的信息
        infoLog = new char[infoLen]();
        glGetShaderInfoLog(shaderId, infoLen, NULL, infoLog);
        printf("Error compiling shader:
%s
", infoLog);
        delete[] infoLog;
    }
    glDeleteShader(shaderId);
    return false;
}

//编译成功,得到shaderId

4.2 创建Program

m_programId = glCreateProgram();
if (m_programId == 0) {
    close();
    return false;
}

//连接上面编译好的两个着色器
glAttachShader(m_programId, m_vShaderId);
glAttachShader(m_programId, m_fShaderId);
glLinkProgram(m_programId);

//检查一下连接是否成功
GLint linked = 0, infoLen = 0;
glGetProgramiv(m_programId, GL_LINK_STATUS, &linked);
if (!linked) {

    glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &infoLen);
    if (infoLen > 1)
    {
        //连接失败原因
        char* infoLog = new char[sizeof(char) * infoLen]();
        glGetProgramInfoLog(m_programId, infoLen, NULL, infoLog);
        printf("Error linking program:
%s
", infoLog);
        delete[] infoLog;
    }

    return false;
}

//开始使用
glUseProgram(m_programId);

//一般会在绘制前先刷一下底色
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);



4.3 创建纹理

纹理是绘制片段着色器时使用的贴图,示例中绘制的是YUV数据,所以我们分布对Y U V创建三个纹理。TrX拜客生活常识网

	for (int i = 0; i < 3; i++) {
		glGenTextures(1, &m_textures[i]);
		glBindTexture(GL_TEXTURE_2D, m_textures[i]);
		// 为当前绑定的纹理对象设置环绕、过滤方式
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	}


TrX拜客生活常识网

4.4 绘制

4.4.1 切换上下文

//切换上下文
eglMakeCurrent(m_display, m_surface, m_surface, m_context);
glUseProgram(m_programId);
glViewport(x, y, cx, cy);

4.4.2 构建顶点数据

//index=0 对应顶点着色器代码中的vPosition变量
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), vVertices);
glEnableVertexAttribArray(0);

//index=1 对应顶点着色器代码中的aTexCoord变量
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), vVertices + 3); 
glEnableVertexAttribArray(1);

顶点数据TrX拜客生活常识网

static const GLfloat vertices[] =
{
	-1.0f, 1.0f, 0.0f,    0.0f, 1.0f, 0.0f, //左上  这里是 一个顶点坐标+一个纹理坐标
	1.0f, 1.0f, 0.0f,      1.0f, 1.0f, 0.0f,  //右上
	-1.0f, -1.0f, 0.0f,    0.0f, 0.0f, 0.0f,  //左下
	1.0f, -1.0f, 0.0f,	   1.0f,  0.0f, 0.0f   //右下
};

顶点数据包含了顶点坐标和纹理坐标,顶点坐标用来确定物体绘制形状的边界,纹理坐标用来给物体刷漆时框定的边界,但是他们具有不同的坐标系:TrX拜客生活常识网

顶点坐标的坐标系TrX拜客生活常识网

TrX拜客生活常识网

纹理坐标的坐标系TrX拜客生活常识网

TrX拜客生活常识网

当按照这个标准把YUV图形渲染上去的时候你会惊奇地发现图像是倒着的,具体原因我没去详细了解过,应该是跟图片的读取有关,最简单的解决办法就是在顶点数组里调整一下纹理坐标,纹理倒着刷,图像不就变正了么,千万别自己去把YUV数据倒过来,这样太耗性能了。TrX拜客生活常识网


TrX拜客生活常识网

glVertexAttribPointer

相关阅读:

  • 尤伯杯陈雨菲开门红,何冰娇三局险胜,中国队横扫印尼进四
  • 管理订单状态,该上状态机吗?
  • 当前正在热播的六部剧,《破事精英》排第三,你在追哪一部
  • 女孩醉心武侠,自导自演成一派,这表演看着过瘾
  • 第74集团军某旅组织侦察专业跨昼夜连贯考核——大雨未
  • A股,或将迎来一次大洗牌
  • 第74集团军某旅组织侦察专业跨昼夜连贯考核
  • 陪你笑,看你闹
  • 酒局小游戏,无道具(3.0)
  • 西媒:超仿真机器人能表达感情
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。