[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 );
最后
最后运行程序就可以了,效果如下
如果出了点问题,可以查看代码
标签:01,1.0,OpenGL,int,pos,C++,vec4,esContext,include 来源: https://blog.csdn.net/qq_53530146/article/details/118650781