既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
//将GL_ELEMENT_ARRAY_BUFFER缓冲区绑定到EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//将索引坐标绑定到GL_ELEMENT_ARRAY_BUFFER
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
纹理属性绑定
1表示顶点着色器里面location里面的1属性,2表示从顶点数组取两个数据
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float ), (void *)(3*sizeof(float)));//这个与顶点数组的数据内容相关
glEnableVertexAttribArray(1);//启动
创建加载纹理
//创建纹理对象
glGenTextures(1, &texture);
//将纹理绑定到GL_TEXTURE_2D 纹理目标
glBindTexture(GL_TEXTURE_2D, texture);
//为当前绑定的纹理对象设定纹理环绕方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);//重复纹理的填充方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//为当前绑定的纹理对象设定纹理过滤方式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);//缩小时线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//放到就是线性
绑定纹理数据
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturewidth, textureheight, 0, GL_RGB, GL_UNSIGNED_BYTE, texturedata);
LOGD("CreateProgram %s", texturedata);
glGenerateMipmap(GL_TEXTURE_2D);//为当前绑定的纹理自动生成所有需要的多级渐远纹理
LOGD("CreateProgram END");
4)绘画纹理
//指定使用的着色器程序
glUseProgram(program);
glBindTexture(GL_TEXTURE_2D, texture);
LOGD("glBindTexture");
//绑定顶点数组
glBindVertexArray(VAO);
//画纹理
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
第二部分项目工程部分
以三、画三角形的区别为例
Java端没有区别,都是一致的。
C++端存在区别,需引入纹理相关的
1)加载assets资源文件下面的图片资源并解析bmp的图片数据
在ReadFileUtil.h中添加
unsigned char *DecodeBMP(unsigned char *bmpFileData, int &width, int &height) {
if (0x4D42 == *((short *) bmpFileData)) { // 数据头是否为0x4D42 判断是否是 24 位的位图,
// 读格式头
int pixelDataOffset = *((int *) (bmpFileData + 10));// 取出像素数据在内存块的偏移地址
width = *((int *) (bmpFileData + 18));
height = *((int *) (bmpFileData + 22));
LOGD("pixelDataOffset %d", pixelDataOffset);
unsigned char *pixelData = bmpFileData + pixelDataOffset;
// 位图像素数据是 BGR 排布的,所以更换 r b 的位置
for (int i = 0; i < width * height * 3; i += 3) {
char temp = pixelData[i];
pixelData[i] = pixelData[i + 2];
pixelData[i + 2] = temp;
}
return pixelData;
}
LOGD("DecodeBMP END");
return nullptr;
}
unsigned char *ReadBMP(char *bmpPath, int &width, int &height) {
unsigned char *bmpFileContent = const_cast<unsigned char *>(LoadFileContent(bmpPath));
if (bmpFileContent == NULL) {
return 0;
}
unsigned char *pixelData = DecodeBMP(bmpFileContent, width, height);
LOGD("pixelData %d, width = %d, height = %d",pixelData, width, height);
if (pixelData == NULL) {
delete[] bmpFileContent;
return 0;
}
LOGD("ReadBMP END");
return bmpFileContent;
}
2)在Nativity.cpp中调用解析bmp数据并赋值到纹理类中
JNIEXPORT void JNICALL NativeImpl_init(JNIEnv *env, jobject instance)
{
TextureDemo::GetInstance();
int width = 0, height = 0;
unsigned char *img = ReadBMP("awesomeface.bmp", width, height);//解析获取图片数据
TextureDemo::GetInstance()->getTexturedata(img, width, height);
TextureDemo::GetInstance()->CreateProgram(
reinterpret_cast<const char *>(LoadFileContent("vertex.vs")),
reinterpret_cast<const char *>(LoadFileContent("fragment.fs")));
}
3)纹理实现类
TextureDemo.h
//
// Created by CreatWall_zhouwen on 2023/4/13.
//
#ifndef TWODRAWTEXTURE_TEXTUREDEMO_H
#define TWODRAWTEXTURE_TEXTUREDEMO_H
#include <GLES3/gl3.h>
class TextureDemo {
public:
TextureDemo(){
program = 0;
vertexShaderHandle = 0;
fragShaderHandle = 0;
};
~TextureDemo(){};
void CreateProgram(const char *ver, const char *frag);
void Draw();
void getTexturedata(unsigned char *data, int width, int height);
static TextureDemo* GetInstance();
static void DestroyInstance();
private:
GLuint program;
GLuint vertexShaderHandle;
GLuint fragShaderHandle;
GLuint VBO, VAO, EBO;
unsigned int texture;
unsigned char *texturedata;
int texturewidth, textureheight;
};
#endif //TWODRAWTEXTURE_TEXTUREDEMO_H
TextureDemo.cpp
//
// Created by CreatWall_zhouwen on 2023/4/13.
//
#include "TextureDemo.h"
#include "Util.h"
TextureDemo* m_pContext = nullptr;
#define TAG "DRAWTEXTURE"
float vertices[] = {
//---- 位置 ---- - 纹理坐标 -
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // 右上
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // 左下
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // 左上
};
//索引数组
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
void TextureDemo::CreateProgram(const char *ver, const char *frag)
{
LOGD("CreateProgram Enter");
//程序中加载编译顶点着色器
vertexShaderHandle = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
glShaderSource(vertexShaderHandle, 1, &ver, NULL);
glCompileShader(vertexShaderHandle);
GLint compiled = 0;
glGetShaderiv(vertexShaderHandle, GL_COMPILE_STATUS, &compiled);//
if (!compiled){
LOGD("glCompileShader vertexShaderHandle error");
return;
}
//程序中加载编译片段着色器
fragShaderHandle = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShaderHandle, 1, &frag, NULL);
glCompileShader(fragShaderHandle);
glGetShaderiv(fragShaderHandle, GL_COMPILE_STATUS, &compiled);
if(!compiled){
LOGD("glCompileShader fragShaderHandle error");
return;
}
//创建程序
program = glCreateProgram();
if (program)
{
//添加顶点着色器
GLint AttachStatus = GL_FALSE;
glAttachShader(program, vertexShaderHandle);
glGetShaderiv(vertexShaderHandle, GL_ATTACHED_SHADERS, &AttachStatus);
if(AttachStatus == 1){
LOGD("glAttachShader vertexShaderHandle error");
return;
}
//添加片段着色器
glAttachShader(program, fragShaderHandle);
glGetShaderiv(fragShaderHandle, GL_ATTACHED_SHADERS, &AttachStatus);
if(AttachStatus == 2){
LOGD("glAttachShader fragShaderHandle error");
return;
}
//链接
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE){
LOGD("glLinkProgram error");
return;
}
//成功连接到程序之后就可以解绑删除
glDetachShader(program, vertexShaderHandle);
glDeleteShader(vertexShaderHandle);
glDetachShader(program, fragShaderHandle);
glDeleteShader(fragShaderHandle);
vertexShaderHandle = 0;
fragShaderHandle = 0;
}
LOGD("program success");
/* -----顶点相关------ */
//创建顶点数组
glGenVertexArrays(1, &VAO);
//创建顶点缓冲区
glGenBuffers(1, &VBO);
//绑定顶点数组
glBindVertexArray(VAO);
//将顶点缓冲区绑定为GL_ARRAY_BUFFER
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//将定义的顶点数组绑定到GL_ARRAY_BUFFER这个缓存中,这个缓存对应顶点缓冲区数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/* -----绑定纹理相关------ */
//将GL_ELEMENT_ARRAY_BUFFER缓冲区绑定到EBO
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
//将索引坐标绑定到GL_ELEMENT_ARRAY_BUFFER
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//指定配置的顶点属性,第一个index参数对应顶点着色器的location值
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float ), (void *)0);
//启用顶点属性
glEnableVertexAttribArray(0);
//纹理属性绑定
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float ), (void *)(3*sizeof(float)));
glEnableVertexAttribArray(1);
//将顶点数组和顶点缓冲区置空则不让其他修改
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
![img](https://img-blog.csdnimg.cn/img_convert/387552d6fc5bfe6192547343ed154ebb.png)
![img](https://img-blog.csdnimg.cn/img_convert/55bc057cbe707b0d9c3f576736c4bf9a.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**
glBindVertexArray(0);
[外链图片转存中...(img-f5J1aKjc-1715826197158)]
[外链图片转存中...(img-q96SHykd-1715826197159)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**