C/C++教程

[C/C++] OpenGL ES 3.0教程:01 三角形

本文主要是介绍[C/C++] OpenGL ES 3.0教程:01 三角形,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

头文件

在弄好框架后,创建一个.hpp(或.h),内容如下:

esUtil.hpp

#ifndef ESUTIL_HPP_
#define ESUTIL_HPP_

#include <android_native_app_glue.h>
#include <GLES3/gl3.h>
#include <EGL/egl.h>

#include <fstream>
#include <string>

#include "esEvent.hpp"
#include "esShader.c"
#include "esShapes.c"
#include "esTransform.c"
#include "esUtil_Android.c"
#include "esUtil_win.h"
#include "esUtil.c"
#include "esUtil.h"

#endif

esEvent.hpp(p.s.要不要无所谓,反正本章用不到)

#ifndef ESEVENT_HPP_
#define ESEVENT_HPP_
#include <android/input.h>

class ESEvent
{
	public:
	AInputEvent * event;
	public:
	int getX(int);
	int getY(int);
	int getType();
};

int ESEvent::getX(int n)
{
	return AMotionEvent_getX(event,n);
}
int ESEvent::getY(int n)
{
	return AMotionEvent_getY(event,n);
}
int ESEvent::getType()
{
	return AInputEvent_getType(event);
}

#endif

程序框架

弄好上述事以后,就该编写程序的框架

#include <android_native_app_glue.h> //c4droid必须要
#include "esUtil.hpp"

struct UserData
{
    GLuint id;//着色程序id
};
bool init(ESContext*);
void draw(ESContext*);
void shutdown(ESContext*);

int esMain(ESContext * esContext)
{
    esContext->userData = new UserData;
    esCreateWindow ( esContext, "", 1080, 2160, ES_WINDOW_RGB );//我的手机屏幕分辨率是1080*2160的,这个根据情况而定
    esRegisterShutdownFunc ( esContext, shutdown );
    esRegisterDrawFunc ( esContext, draw );
    if ( !init ( esContext ) )
    {
        return 0;//表示退出
    }
    return 1;
}

当然不使用ES框架也可以,不过有些麻烦,推荐自己做一个窗口创建函数

着色器

OpenGL ES 1.0使用的渲染管线是不需要自己做的,但是从OpenGL ES 2.0开始,要开始自己制作着色器了。
如果你学习过OpenGL ES 2.0,那么可以跳过

着色器首先要声明版本

#version 300 es

GLSL(OpenGL Shading Language)的语法类似C

然后是输入数据,使用in关键字

layout(location=0)in vec3 pos;

layout(location=0)之后会讲解
vec3是一个包含3个float分量的向量,可以理解为一个包含3个元素的float数组
紧接着是main()函数

void main()
{
    gl_Position = vec4(pos.x,pos.y,pos.z,1.0);
}

gl_Position是一个内置变量,类型是vec4,我们可以用vec4构造函数赋值过去
然后程序转到下一个步骤:片段着色
同顶点着色器一样的步骤

#version 300 es
out vec4 color;

void main()
{
    color = vec4(1.0,1.0,1.0,1.0);
}

它要输出一个vec4作为顶点的颜色,,我们在main()中对它赋值为白色

bool init(ESContext * esContext)
{
    UserData * ud = (UserData*)esContext->userData;
    char vStr[] =
    "#version 300 es\n"
    "layout(location=0)in vec3 pos;\n"
    "void main()\n"
    "{\n"
    "    gl_Position = vec4(pos.x,pos.y,pos.z,1.0);\n"
    "}\n";
    char fStr[] =
    "#version 300 es\n"
    "out vec4 color;\n"
    "void main()\n"
    "{\n"
    "    color = vec4(1.0,1.0,1.0,1.0);\n"
    "}\n";
    ud->id = esLoadProgram(vStr,fStr);
    if(ud->id == 0)
        return false;
    return true;
}

esLoadProgram()接受两个char*作为参数,分别是顶点着色器和片段着色器,然后返回加载好后的着色程序,如果失败就是返回0
(p.s.如果你用的不是ES框架,请暂时跳到下一章,那里会讲解)

绘制

接下来是绘制
首先是顶点数组

GLfloat ver[] =
{
    0.0,0.5,0.0,
    -0.5,-0.5,0.0,
    0.5,-0.5,0.,
};

OpenGL ES的坐标和SDL什么的不一样,是以屏幕中点为原点的,和数学里的很像(就是)
好丑
最后画出来的就长这样,一个三角形(这里的图片是640 * 480的,如果是500 * 500的应该是一个等边三角形吧)

glClearColor(0.0,0.0,0.0,0.0); //背景颜色,这里是黑色
glClear(GL_COLOR_BUFFER_BIT); //清理颜色缓冲区(???)

绘制前记得清空

glViewport ( 0, 0, esContext->width, esContext->height );

设置视口,以屏幕中心为原点,长宽分别是屏幕的长宽
没使用ES框架的可以

glQuerySurface(display,surface,EGL_WIDTH,&width);
glQuerySurface(display,surface,EGL_HEIGHT,&height);

这些完成之后

    glUseProgram ( ud->id ); //使用着色程序
    glEnableVertexAttribArray ( 0 );
    glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, ver ); //绑定顶点
    glDrawArrays ( GL_TRIANGLES, 0, 3 ); //绘制
    glDisableVertexAttribArray ( 0 );

其中重点讲解一下glVertexAttribPointer()函数
它的原型如下

GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);

第一个参数就是顶点着色器里的

layout(location=0)in vec3 pos;

location的值
第二个是顶点分量的数量,顶点着色器里用的是vec3,那就是3
第三个是顶点类型,我们用的是

GLfloat ver[] = {...};

也就是float类型,这里写入GL_FLOAT
第四个是是否标准化,填GL_FALSE
第五个是步长,这里写入0
第六个是顶点数组,也就是ver

shutdown()

退出时销毁一些玩意

UserData * ud = (UserData*)esContext->userData;
glDeleteProgram ( ud->id );

最后

最后运行程序就可以了,效果如下
运行效果
如果出了点问题,可以查看代码

这篇关于[C/C++] OpenGL ES 3.0教程:01 三角形的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!