OpenGL ES 2.0编程指导阅读笔记(四)一个简单例子
#include <stdlib.h> #include <stdio.h> #include <time.h> #include <GLES2/gl2.h> #include <EGL/egl.h> #include "esUtil.h" #include "esUtil_win.h" typedef struct { GLfloat *vertices; GLfloat *speed; } UserData; typedef struct { GLfloat x; GLfloat y; GLfloat z; } Coord; typedef struct { Coord lb; Coord lt; Coord rb; Coord rt; } Square; EGLBoolean egl_init(ESContext *esContext, unsigned int width, unsigned int height, UserData *userData) { esInitContext(esContext); esContext->width = width; esContext->height = height; esContext->userData = userData; // Get Display printf("建立到EGL Display Server的连接...\n"); esContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (esContext->eglDisplay == EGL_NO_DISPLAY) { return EGL_FALSE; } // Initialize EGL printf("初始化EGL...\n"); if (!eglInitialize(esContext->eglDisplay, NULL, NULL)) { return EGL_FALSE; } // Get configs EGLint numConfigs; printf("获取Display可用配置数量...\n"); if (!eglGetConfigs(esContext->eglDisplay, NULL, 0, &numConfigs)) { return EGL_FALSE; } else { printf("Display总计支持配置%d种\n", numConfigs); } /* EGL Configuration */ printf("选择RGB模式的2D配置...\n"); EGLint attribList[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, EGL_DONT_CARE, EGL_DEPTH_SIZE, EGL_DONT_CARE, EGL_STENCIL_SIZE, EGL_DONT_CARE, EGL_SAMPLE_BUFFERS, 0, EGL_NONE}; // Choose config EGLConfig config; if (!eglChooseConfig(esContext->eglDisplay, attribList, &config, 1, &numConfigs)) { return EGL_FALSE; } // Show config printf("最终选择的配置如下:\n"); EGLint params; eglGetConfigAttrib(esContext->eglDisplay, config, EGL_CONFIG_ID, ¶ms); printf(" ID: %d\n", params); eglGetConfigAttrib(esContext->eglDisplay, config, EGL_RENDERABLE_TYPE, ¶ms); printf(" RENDERABLE TYPE: %d\n", params); eglGetConfigAttrib(esContext->eglDisplay, config, EGL_SURFACE_TYPE, ¶ms); printf(" SURFACE TYPE: %d\n", params); /* Create a window */ printf("创建窗口...\n"); if (!WinCreate(esContext, "Hello Triangle")) { return GL_FALSE; } // Create a surface printf("创建Surface...\n"); esContext->eglSurface = eglCreateWindowSurface(esContext->eglDisplay, config, (EGLNativeWindowType)esContext->hWnd, NULL); if (esContext->eglSurface == EGL_NO_SURFACE) { return EGL_FALSE; } // Create a GL context printf("创建Context...\n"); EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE}; esContext->eglContext = eglCreateContext(esContext->eglDisplay, config, EGL_NO_CONTEXT, contextAttribs); if (esContext->eglContext == EGL_NO_CONTEXT) { return EGL_FALSE; } // Make the context current printf("激活Context...\n"); if (!eglMakeCurrent(esContext->eglDisplay, esContext->eglSurface, esContext->eglSurface, esContext->eglContext)) { return EGL_FALSE; } } int load_program() { GLbyte vShaderStr[] = "attribute vec4 vPosition; \n" "uniform vec4 offset; \n" "void main() \n" "{ \n" " gl_Position = vPosition + offset; \n" "} \n"; GLbyte fShaderStr[] = "precision mediump float; \n" "void main() \n" "{ \n" " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n" "} \n"; /* Load the vertex shader */ GLuint vertex_shader; // Create the shader object printf("创建vertex shader...\n"); vertex_shader = glCreateShader(GL_VERTEX_SHADER); if (vertex_shader == 0) { printf("%x\n", eglGetError()); return FALSE; } // Load the shader source printf("加载vertex shader源代码...\n"); char *vptr = vShaderStr; glShaderSource(vertex_shader, 1, &vptr, NULL); // Compile the shader printf("编译vertex shader...\n"); glCompileShader(vertex_shader); // Check the compile status printf("获取vertex shader状态...\n"); GLint compiled; glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { printf("编译失败,获取vertex shader编译信息...\n"); GLint infoLen = 0; glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char *infoLog = malloc(sizeof(char) * infoLen); glGetShaderInfoLog(vertex_shader, infoLen, NULL, infoLog); esLogMessage("Error compiling vertex shader:\n%s\n", infoLog); free(infoLog); } glDeleteShader(vertex_shader); return FALSE; } printf("编译成功...\n"); /* Load the fragment shader */ GLuint fragment_shader; // Create the shader object printf("创建fragment shader...\n"); fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); if (fragment_shader == 0) return FALSE; // Load the shader source printf("加载fragment shader源代码...\n"); char *fptr = fShaderStr; glShaderSource(fragment_shader, 1, &fptr, NULL); // Compile the shader printf("编译fragment shader...\n"); glCompileShader(fragment_shader); // Check the compile status printf("获取fragment shader状态...\n"); glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { printf("编译失败,获取fragment shader编译信息...\n"); GLint infoLen = 0; glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char *infoLog = malloc(sizeof(char) * infoLen); glGetShaderInfoLog(fragment_shader, infoLen, NULL, infoLog); esLogMessage("Error compiling fragment shader:\n%s\n", infoLog); free(infoLog); } glDeleteShader(fragment_shader); return FALSE; } printf("编译成功...\n"); glReleaseShaderCompiler(); GLuint programObject; GLint linked; // Create the program object printf("创建program...\n"); programObject = glCreateProgram(); if (programObject == 0) { return FALSE; } printf("附加shader...\n"); glAttachShader(programObject, vertex_shader); glAttachShader(programObject, fragment_shader); // Bind vPosition to attribute 1 printf("绑定attribute location...\n"); glBindAttribLocation(programObject, 1, "vPosition"); // Link the program printf("链接程序...\n"); glLinkProgram(programObject); // Check the link status printf("获取program状态...\n"); glGetProgramiv(programObject, GL_LINK_STATUS, &linked); if (!linked) { printf("链接失败,获取program链接信息...\n"); GLint infoLen = 0; glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen > 1) { char *infoLog = malloc(sizeof(char) * infoLen); glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); esLogMessage("Error linking program:\n%s\n", infoLog); free(infoLog); } printf("删除program...\n"); glDeleteProgram(programObject); return FALSE; } printf("链接成功...\n"); /* Show program information */ printf("Program信息:\n"); GLuint num; glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &num); printf(" Uniform数量: %d\n", num); GLsizei max_length; glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_length); char *name; name = malloc(max_length); GLint size; GLint type; for (int i = 0; i < num; i++) { GLint loc; glGetActiveUniform(programObject, i, max_length, NULL, &size, &type, name); loc = glGetUniformLocation(programObject, name); printf(" ID %d: <%d> %s[%d] (%x)\n", i, loc, name, size, type); } free(name); glGetProgramiv(programObject, GL_ACTIVE_ATTRIBUTES, &num); printf(" Attribute数量: %d\n", num); glGetProgramiv(programObject, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_length); name = malloc(max_length); for (int i = 0; i < num; i++) { GLint loc; glGetActiveAttrib(programObject, i, max_length, NULL, &size, &type, name); loc = glGetAttribLocation(programObject, name); printf(" ID %d: <%d> %s[%d] (%x)\n", i, loc, name, size, type); } free(name); printf("使用program...\n"); glUseProgram(programObject); return TRUE; } void updateFunc(ESContext *esContext, float deltaTime) { UserData *userData = esContext->userData; Square *square = userData->vertices; Coord *speed = userData->speed; GLfloat width = square->rb.x - square->lb.x; GLfloat height = square->lt.y - square->lb.y; square->lb.x += deltaTime * speed->x; if (square->lb.x <= -1.0) { square->lb.x = -2.0 - square->lb.x; speed->x = -speed->x; } else if (square->lb.x + width >= 1.0) { square->lb.x = 2.0 - 2 * width - square->lb.x; speed->x = -speed->x; } square->lt.x = square->lb.x; square->rb.x = square->lb.x + width; square->rt.x = square->rb.x; square->lb.y += deltaTime * speed->y; if (square->lb.y <= -1.0) { square->lb.y = -2.0 - square->lb.y; speed->y = -speed->y; } else if (square->lb.y + height >= 1.0) { square->lb.y = 2.0 - 2 * height - square->lb.y; speed->y = -speed->y; } square->rb.y = square->lb.y; square->lt.y = square->lb.y + height; square->rt.y = square->lt.y; } void Draw(ESContext *esContext) { UserData *userData = esContext->userData; GLfloat *vVertices = userData->vertices; // Set the viewport glViewport(0, 0, esContext->width, esContext->height); // Clear the color buffer glClear(GL_COLOR_BUFFER_BIT); // Load the vertex data glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, vVertices); glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // glDrawArrays(GL_TRIANGLES, 0, 6); eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface); } int main(int argc, char *argv[]) { /* Initialize esContext */ ESContext esContext; UserData userData; // UserData GLfloat vVertices[] = {0.0f, 0.0f, 0.0f, 0.0f, 0.05f, 0.0f, 0.05f, 0.0f, 0.0f, 0.05f, 0.05f, 0.0f}; userData.vertices = vVertices; GLfloat speed[] = {0.4f, 0.1f, 0.0f}; userData.speed = speed; if (!egl_init(&esContext, 800, 800, &userData)) { printf("初始化EGL失败...\n"); return -1; } /* load shader source & compile & link */ if (!load_program()) { printf("加载程序失败...\n"); return -2; } /* global graphical configuration */ printf("设置背景色...\n"); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set uniform glUniform4f(0, -0.025f, -0.025f, 0.0f, 0.0f); /* assign draw function */ printf("指定绘图程序...\n"); esContext.drawFunc = Draw; esContext.updateFunc = updateFunc; /* start drawing */ printf("开始绘图...\n"); MSG msg = {0}; int done = 0; DWORD lastTime = GetTickCount64(); while (!done) { int gotMsg = (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0); DWORD curTime = GetTickCount64(); float deltaTime = (float)(curTime - lastTime) / 1000.0f; if (deltaTime < 0.00833f) { Sleep(1); continue; } lastTime = curTime; if (gotMsg) { if (msg.message == WM_QUIT) { done = 1; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else SendMessage(esContext.hWnd, WM_PAINT, 0, 0); // Call update function if registered if (esContext.updateFunc != NULL) esContext.updateFunc(&esContext, deltaTime); } return 0; }
本文作者:xvsay
本文链接:https://www.cnblogs.com/belatedluck/p/17050067.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步