努力学习OpenGL中🍺|

xvsay

园龄:8年粉丝:1关注:1

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, &params);
printf(" ID: %d\n", params);
eglGetConfigAttrib(esContext->eglDisplay, config, EGL_RENDERABLE_TYPE, &params);
printf(" RENDERABLE TYPE: %d\n", params);
eglGetConfigAttrib(esContext->eglDisplay, config, EGL_SURFACE_TYPE, &params);
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 中国大陆许可协议进行许可。

posted @   xvsay  阅读(136)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起