深圳做微商网站设计,wordpress gpl协议,wordpress 用户中心,手机下载工具app目录 立方体绘制基本原理立方体的顶点坐标和绘制顺序立方体颜色和着色器实现效果和参考代码 立方体绘制基本原理
一个立方体是由8个顶点组成#xff0c;共6个面#xff0c;所以绘制立方体本质上就是绘制这6个面共12个三角形
顶点的坐标体系如下图所示#xff0c;三维坐标… 目录 立方体绘制基本原理立方体的顶点坐标和绘制顺序立方体颜色和着色器实现效果和参考代码 立方体绘制基本原理
一个立方体是由8个顶点组成共6个面所以绘制立方体本质上就是绘制这6个面共12个三角形
顶点的坐标体系如下图所示三维坐标的中心原点位于立方体的中心但是要特别注意的是前后方向表示的是Z轴上下方向表示的是Y轴
立方体的顶点坐标和绘制顺序
立方体坐标定义如下
static GLfloat vertices[] {// 位置 // 颜色-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // 左下后 红色0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下后 绿色0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // 右上后 蓝色-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, // 左上后 黄色-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // 左下前 青色0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 1.0f, // 右下前 品红0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, // 右上前 灰色-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f // 左上前 白色
};// 立方体索引数据
static GLuint indices[] {// 后面0, 1, 2,2, 3, 0,// 前面4, 5, 6,6, 7, 4,// 左面0, 4, 7,7, 3, 0,// 右面1, 5, 6,6, 2, 1,// 底面0, 1, 5,5, 4, 0,// 顶面3, 2, 6,6, 7, 3
};在这里vertices定义不同的顶点indices数组中表示不同顶点的绘制顺序每三个顶点构成一个三角形最后由 glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_INT,0);每三个顶点为一组绘制共12个三角形不同的面和顶点的绑定关系如下
立方体颜色和着色器
这里为立方体的每个顶点定义不同的颜色同时在VertexShader中将颜色传递给FragmentShader,这样 FragmentShader会得到经过插值后的每个片元的颜色并将这个颜色设置为最终的显示实现的是一个渐变色的效果shader 程序如下
static const char* vertexShaderSource #version 300 es \nprecision mediump float;\nuniform mat4 u_mvpMatrix; \nlayout(location 0) in vec3 a_position; \nlayout(location 1) in vec3 a_color; \nout vec3 v_color; \nvoid main() {\n gl_Position u_mvpMatrix*vec4(a_position,1.0);\n v_color a_color; \n}\n;// Fragment Shader source code
static const char* fragmentShaderSource #version 300 es \nprecision mediump float;\nlayout(location 0) out vec4 outColor; \nin vec3 v_color; \nvoid main() {\n outColor vec4(v_color, 1.0);\n}\n;实现效果和参考代码
最终实现效果
参考代码如下 Note: 这里还使用了ModeViewProject Matrix实现了旋转的效果同时使用VAO,VBO,EBO实现了对顶点内容和顶点Index的缓冲 typedef struct {GLuint programObject;GLuint vboIds[2];GLuint vaoId;uint64_t timeInMiliSeconds;GLint mvpLoc;GLfloat angle;GLint deltaTime;ESMatrix mvpMatrix;
} UserData;static GLfloat vertices[] {// 位置 // 颜色-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, // 左下后 红色0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下后 绿色0.5f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // 右上后 蓝色-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, // 左上后 黄色-0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // 左下前 青色0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 1.0f, // 右下前 品红0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, // 右上前 灰色-0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f // 左上前 白色
};// 立方体索引数据
static GLuint indices[] {// 后面0, 1, 2,2, 3, 0,// 前面4, 5, 6,6, 7, 4,// 左面0, 4, 7,7, 3, 0,// 右面1, 5, 6,6, 2, 1,// 底面0, 1, 5,5, 4, 0,// 顶面3, 2, 6,6, 7, 3
};static const char* vertexShaderSource #version 300 es \nprecision mediump float;\nuniform mat4 u_mvpMatrix; \nlayout(location 0) in vec3 a_position; \nlayout(location 1) in vec3 a_color; \nout vec3 v_color; \nvoid main() {\n gl_Position u_mvpMatrix*vec4(a_position,1.0);\n v_color a_color; \n}\n;// Fragment Shader source code
static const char* fragmentShaderSource #version 300 es \nprecision mediump float;\nlayout(location 0) out vec4 outColor; \nin vec3 v_color; \nvoid main() {\n outColor vec4(v_color, 1.0);\n}\n;static int initInternal(ESContext* esContext) {UserData *userData esContext-userData;// Vertex Shader source codeGLuint programObject esLoadProgram(vertexShaderSource, fragmentShaderSource);if (programObject 0) {return GL_FALSE;}// turn on depth testglEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);glClearColor(0.0, 0.0, 0.0, 1.0);// Store the program objectuserData-programObject programObject;userData-vboIds[0] userData-vboIds[1] 0;userData-mvpLoc glGetUniformLocation(userData-programObject, u_mvpMatrix);userData-angle 0.0f;return GL_TRUE;
}static void uMVPMatrixUpdateRotate(ESContext *esContext, GLuint deltaTime)
{UserData *userData esContext-userData;ESMatrix perspective;ESMatrix modelview;float aspect;userData-angle 1.0f;if (userData-angle 360.0f) {userData-angle - 360.0f;}aspect (GLfloat) esContext-width / (GLfloat) esContext-height;esMatrixLoadIdentity(perspective);esMatrixLoadIdentity(modelview);esPerspective(perspective, 45.0f, aspect, 1.0f, 10.0f);esTranslate(modelview, 0.0, 0.0, -4.0);esRotate(modelview, userData-angle, 0.0, 1.0, 0.0);esMatrixMultiply(userData-mvpMatrix, modelview, perspective);
}static void DrawPrimitiveWithVBOs(ESContext *esContext)
{UserData *userData esContext-userData;GLuint offset 0;// vboIds[0] - used to store vertex attribute data// vboIds[l] - used to store element indicesif (userData-vboIds[0] 0 userData-vboIds[1] 0) {// Only allocate on the first drawglGenBuffers(2, userData-vboIds);glGenVertexArrays(1, userData-vaoId);printf(gen vbo id:%d %d vao id:%d.\n,userData-vboIds[0],userData-vboIds[1],userData-vaoId);glBindVertexArray(userData-vaoId);glBindBuffer(GL_ARRAY_BUFFER, userData-vboIds[0]);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3,GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat) , NULL);glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat) ,(void*)(3*sizeof(GLfloat)));glEnableVertexAttribArray(1);// notice using GL_ARRAY_BUFFERglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData-vboIds[1]);glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices), indices, GL_STATIC_DRAW);glBindVertexArray(0);}glBindVertexArray(userData-vaoId);glUniformMatrix4fv(userData-mvpLoc, 1, GL_FALSE, (GLfloat *)userData-mvpMatrix.m[0][0]);glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_INT,0);glBindVertexArray(0);
}static int drawLoopInternal(ESContext* esContext) {UserData *userData esContext-userData;struct timespec currentts;clock_gettime(CLOCK_REALTIME, currentts);uint64_t milliseconds currentts.tv_sec * 1000LL currentts.tv_nsec / 1000000;int periodInMs milliseconds - userData-timeInMiliSeconds;userData-timeInMiliSeconds milliseconds;userData-deltaTime;//printf(current time in milliseconds %lld period:%d\n,milliseconds, (periodInMs 0 ? periodInMs: -1));// Set the viewportglViewport(0, 0, 640, 480);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glUseProgram(userData-programObject);uMVPMatrixUpdateRotate(esContext,userData-deltaTime);DrawPrimitiveWithVBOs(esContext);// Swap bufferseglSwapBuffers(esContext-eglDisplay, esContext-eglSurface);
}static int cleanupInternal(ESContext* esContext) {printf(%s enter!.\n,__FUNCTION__);UserData *userData esContext-userData;glDeleteProgram(userData-programObject);eglDestroySurface(esContext-eglDisplay, esContext-eglSurface);eglDestroyContext(esContext-eglDisplay, esContext-eglContext);eglTerminate(esContext-eglDisplay);XDestroyWindow(esContext-x_display, esContext-win);XCloseDisplay(esContext-x_display);return GL_TRUE;
}int testbasicDrawCube(ESContext* esContext) {printf(%s enter!.\n, __FUNCTION__);esContext-userData (UserData*)malloc(sizeof(UserData));esCreateWindow(esContext, esContext-testcaseName,640, 480, ES_WINDOW_DEPTH);initInternal(esContext);while (1) {XEvent xev;while (XPending(esContext-x_display)) {XNextEvent(esContext-x_display, xev);if (xev.type KeyPress) {cleanupInternal(esContext);}}drawLoopInternal(esContext);}
}