TriangleSample.h
//
// Created by ByteFlow on 2019/7/9.
//
#ifndef NDK_OPENGLES_3_0_TRIANGLESAMPLE_H
#define NDK_OPENGLES_3_0_TRIANGLESAMPLE_H
#include "GLSampleBase.h"
class TriangleSample : public GLSampleBase
{
public:
TriangleSample();
virtual ~TriangleSample();
virtual void LoadImage(NativeImage *pImage);
virtual void Init();
virtual void Draw(int screenW, int screenH);
virtual void Destroy();
private:
GLuint m_TextureId;
GLint m_SamplerLoc;
NativeImage m_RenderImage;
};
#endif //NDK_OPENGLES_3_0_TRIANGLESAMPLE_H
显示一个红色三角形
TriangleSample.cpp
//
// Created by ByteFlow on 2019/7/9.
//
#include "TriangleSample.h"
#include "../util/GLUtils.h"
#include "../util/LogUtil.h"
TriangleSample::TriangleSample()
{
}
TriangleSample::~TriangleSample()
{
}
void TriangleSample::LoadImage(NativeImage *pImage)
{
//null implement
}
void TriangleSample::Init()
{
if(m_ProgramObj != 0)
return;
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n"
"} \n";
m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader); //创建着色器程序
}
void TriangleSample::Draw(int screenW, int screenH)
{
LOGCATE("TriangleSample::Draw");
GLfloat vVertices[] = {
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
if(m_ProgramObj == 0)
return;
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除模板缓冲 颜色缓冲 深度缓冲
glClearColor(1.0, 1.0, 1.0, 1.0); //用于设置背景色
// Use the program object
glUseProgram (m_ProgramObj); //激活着色器
// Load the vertex data
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices ); //更新顶点格式
glEnableVertexAttribArray (0); //启用指定属性 可在顶点着色器中访问逐顶点的属性数据(即允许着色器读取GPU数据)
glDrawArrays (GL_TRIANGLES, 0, 3); //画三角形
glUseProgram (GL_NONE);
}
void TriangleSample::Destroy()
{
if (m_ProgramObj)
{
glDeleteProgram(m_ProgramObj);
m_ProgramObj = GL_NONE;
}
}
结果:
显示一个绿色三角形
TriangleSample.cpp
//
// Created by ByteFlow on 2019/7/9.
//
#include "TriangleSample.h"
#include "../util/GLUtils.h"
#include "../util/LogUtil.h"
TriangleSample::TriangleSample()
{
}
TriangleSample::~TriangleSample()
{
}
void TriangleSample::LoadImage(NativeImage *pImage)
{
//null implement
}
void TriangleSample::Init()
{
if(m_ProgramObj != 0)
return;
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 vPosition; \n"
"out vec4 vertexColor; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
" vertexColor = vec4( 0.0, 1.0, 0.0, 1.0); \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec4 vertexColor; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = vertexColor; \n"
"} \n";
m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader); //创建着色器程序
}
void TriangleSample::Draw(int screenW, int screenH)
{
LOGCATE("TriangleSample::Draw");
GLfloat vVertices[] = {
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
if(m_ProgramObj == 0)
return;
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除模板缓冲 颜色缓冲 深度缓冲
glClearColor(1.0, 1.0, 1.0, 1.0); //用于设置背景色
// Use the program object
glUseProgram (m_ProgramObj); //激活着色器
// Load the vertex data
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices ); //更新顶点格式
glEnableVertexAttribArray (0); //启用指定属性 可在顶点着色器中访问逐顶点的属性数据(即允许着色器读取GPU数据)
glDrawArrays (GL_TRIANGLES, 0, 3); //画三角形
glUseProgram (GL_NONE);
}
void TriangleSample::Destroy()
{
if (m_ProgramObj)
{
glDeleteProgram(m_ProgramObj);
m_ProgramObj = GL_NONE;
}
}
结果:
使用uniform显示一个绿色三角形
TriangleSample.cpp
//
// Created by ByteFlow on 2019/7/9.
//
#include "TriangleSample.h"
#include "../util/GLUtils.h"
#include "../util/LogUtil.h"
TriangleSample::TriangleSample()
{
}
TriangleSample::~TriangleSample()
{
}
void TriangleSample::LoadImage(NativeImage *pImage)
{
//null implement
}
void TriangleSample::Init()
{
if(m_ProgramObj != 0)
return;
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 vPosition; \n"
"out vec4 vertexColor; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
" vertexColor = vec4( 1.0, 0.0, 0.0, 1.0); \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec4 vertexColor; \n"
"uniform vec4 ourColor; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = ourColor; \n"
"} \n";
m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader); //创建着色器程序
if (m_ProgramObj)
{
vertexColorLocation = glGetUniformLocation(m_ProgramObj, "ourColor"); //获取一致变量在着色器程序中的位置序号 通过该序号设置一致变量的值
}
}
void TriangleSample::Draw(int screenW, int screenH)
{
LOGCATE("TriangleSample::Draw");
GLfloat vVertices[] = {
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
if(m_ProgramObj == 0)
return;
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除模板缓冲 颜色缓冲 深度缓冲
glClearColor(1.0, 1.0, 1.0, 1.0); //用于设置背景色
// Use the program object
glUseProgram (m_ProgramObj); //激活着色器
// Load the vertex data
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices ); //更新顶点格式
glEnableVertexAttribArray (0); //启用指定属性 可在顶点着色器中访问逐顶点的属性数据(即允许着色器读取GPU数据)
glDrawArrays (GL_TRIANGLES, 0, 3); //画三角形
float greenValue = 1.0;
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
glUseProgram (GL_NONE);
}
void TriangleSample::Destroy()
{
if (m_ProgramObj)
{
glDeleteProgram(m_ProgramObj);
m_ProgramObj = GL_NONE;
}
}
显示一个彩色三角形
TriangleSample.cpp
//
// Created by ByteFlow on 2019/7/9.
//
#include "TriangleSample.h"
#include "../util/GLUtils.h"
#include "../util/LogUtil.h"
TriangleSample::TriangleSample()
{
}
TriangleSample::~TriangleSample()
{
}
void TriangleSample::LoadImage(NativeImage *pImage)
{
//null implement
}
void TriangleSample::Init()
{
if(m_ProgramObj != 0)
return;
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec3 vPosition; \n"
"layout(location = 1) in vec3 aColor; \n"
"out vec4 vertexColor; \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(vPosition,1.0); \n"
" vertexColor = vec4( aColor, 1.0); \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec4 vertexColor; \n"
"uniform vec4 ourColor; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = vertexColor; \n"
"} \n";
m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader); //创建着色器程序
if (m_ProgramObj)
{
vertexColorLocation = glGetUniformLocation(m_ProgramObj, "ourColor"); //获取一致变量在着色器程序中的位置序号 通过该序号设置一致变量的值
}
}
void TriangleSample::Draw(int screenW, int screenH)
{
LOGCATE("TriangleSample::Draw");
GLfloat vVertices[] = {
// 位置 // 颜色
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部
};
if(m_ProgramObj == 0)
return;
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除模板缓冲 颜色缓冲 深度缓冲
glClearColor(1.0, 1.0, 1.0, 1.0); //用于设置背景色
// Use the program object
glUseProgram (m_ProgramObj); //激活着色器
// Load the vertex data
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, vVertices ); //更新顶点格式
glEnableVertexAttribArray (0); //启用指定属性 可在顶点着色器中访问逐顶点的属性数据(即允许着色器读取GPU数据)
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices), vVertices, GL_STATIC_DRAW);
// 位置属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 颜色属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
glEnableVertexAttribArray(1);
glDrawArrays (GL_TRIANGLES, 0, 3); //画三角形
float greenValue = 1.0;
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
glUseProgram (GL_NONE);
}
void TriangleSample::Destroy()
{
if (m_ProgramObj)
{
glDeleteProgram(m_ProgramObj);
m_ProgramObj = GL_NONE;
}
}
结果:
显示一个有纹理的三角形
TriangleSample.cpp
//
// Created by ByteFlow on 2019/7/9.
//
#include "TriangleSample.h"
#include "../util/GLUtils.h"
#include "../util/LogUtil.h"
TriangleSample::TriangleSample()
{
}
TriangleSample::~TriangleSample()
{
}
void TriangleSample::LoadImage(NativeImage *pImage)
{
LOGCATE("TextureMapSample::LoadImage pImage = %p", pImage->ppPlane[0]);
if (pImage)
{
m_RenderImage.width = pImage->width;
m_RenderImage.height = pImage->height;
m_RenderImage.format = pImage->format;
NativeImageUtil::CopyNativeImage(pImage, &m_RenderImage);
}
}
void TriangleSample::Init()
{
//create RGBA texture
glGenTextures(1, &m_TextureId); //生成纹理 通过使用ID来创建 (需要输入生成纹理的数量 储存在第二个参数)
glBindTexture(GL_TEXTURE_2D, m_TextureId); //绑定
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //纹理过滤函数 为当前绑定的纹理对象设置环绕,过滤方式
glTexParameterf(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);
glBindTexture(GL_TEXTURE_2D, GL_NONE);
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 a_position; \n"
"layout(location = 1) in vec2 a_texCoord; \n"
"out vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec2 v_texCoord; \n"
"layout(location = 0) out vec4 outColor; \n"
"uniform sampler2D s_TextureMap; \n"
"void main() \n"
"{ \n"
" outColor = texture(s_TextureMap, v_texCoord); \n"
" //outColor = texelFetch(s_TextureMap, ivec2(int(v_texCoord.x * 404.0), int(v_texCoord.y * 336.0)), 0);\n"
"} \n";
m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader); //创建着色器程序
if (m_ProgramObj)
{
m_SamplerLoc = glGetUniformLocation(m_ProgramObj, "s_TextureMap");
//获取一致变量在着色器程序中的位置序号
}
else
{
LOGCATE("TextureMapSample::Init create program fail");
}
}
void TriangleSample::Draw(int screenW, int screenH)
{
LOGCATE("TriangleSample::Draw");
GLfloat verticesCoords[] = {
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
GLfloat textureCoords[] = {
0.0f, 0.0f, // 左下角
1.0f, 0.0f, // 右下角
0.5f, 1.0f // 上中
};
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
//upload RGBA image data
glActiveTexture(GL_TEXTURE0); //在绑定纹理之前先激活纹理单元 GL_TEXTURE0默认总是被激活
glBindTexture(GL_TEXTURE_2D, m_TextureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_RenderImage.width, m_RenderImage.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_RenderImage.ppPlane[0]);
//根据指定的参数 生成2D纹理(GL_TEXTURE_2D:目标纹理,level:执行细节级别,0:最基本的图像级别 width:纹理图像的宽度 height:纹理图像的高度 0:指定边框的宽度 GL_RGBA:像素数据的颜色格式
// GL_UNSIGNED_BYTE:指定像素数据的数据类型 m_RenderImage.ppPlane[0]:指定内存中指向图像数据的指针 )
glBindTexture(GL_TEXTURE_2D, GL_NONE);
// Use the program object
glUseProgram (m_ProgramObj);
// Load the vertex position
glVertexAttribPointer (0, 3, GL_FLOAT,
GL_FALSE, 3 * sizeof (GLfloat), verticesCoords);
//选择一个纹理中指定属性 0:顶点位置 3:一个顶点所有数据个数 GL_FLOAT:描述顶点数据的类型 GL_FALSE:是否需要显卡帮忙把数据归到-1到1区间 3 * sizeof (GLfloat):一个顶点占有的总的字节数
//verticesCoords
// Load the texture coordinate
glVertexAttribPointer (1, 2, GL_FLOAT,
GL_FALSE, 2 * sizeof (GLfloat), textureCoords);
glEnableVertexAttribArray (0); //启用顶点的指定属性
glEnableVertexAttribArray (1);
// Bind the RGBA map
glActiveTexture(GL_TEXTURE0); //在绑定纹理之前先激活纹理单元
glBindTexture(GL_TEXTURE_2D, m_TextureId);
// Set the RGBA map sampler to texture unit to 0
glUniform1i(m_SamplerLoc, 0); //保证每个uniform采样器对应着正确的纹理单元
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
void TriangleSample::Destroy()
{
if (m_ProgramObj)
{
glDeleteProgram(m_ProgramObj);
glDeleteTextures(1, &m_TextureId);
m_ProgramObj = GL_NONE;
}
}
结果: