OpenGl ES 绘制一个动态时钟
试着自己用OpenGl ES 画了一个时钟,指针是可以运动的,如下图所示。(画的比较简陋,但是具备基本功能)欢迎补充和讨论~~
这是静态效果图,实际指针是可以动起来的
下面是完整代码.
#include "esUtil.h"
#include <math.h>
#define PI 3.1415926
typedef struct
{
// Handle to a program object
GLuint programObject;
GLuint programObject2;
// GLuint programObject3;
} UserData;
///
// Create a shader object, load the shader source, and
// compile the shader.
//
GLuint LoadShader ( GLenum type, const char *shaderSrc )
{
GLuint shader; // GLuint is typedefed as unsigned int
GLint compiled; // GLint is typedefed as int
// Create the shader object
shader = glCreateShader ( type )
glShaderSource ( shader, 1, &shaderSrc, NULL );// Load the shader source
glCompileShader ( shader );// Compile the shader
glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); // Check the compile status
return shader;
}
///
// Initialize the shader and program object
//
int Init ( ESContext *esContext )
{
UserData *userData = esContext->userData;
char vShaderStr[] = //顶点着色器
"#version 300 es \n" //声明着色器版本
"layout(location = 0) in vec4 vPosition; \n" //输入一个属性数组
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n" //将属性数组拷贝到gl_Position的特殊输出变量中
" gl_PointSize = 5.0f; \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, 1.0 ); \n" //给这个输出变量赋值
"} \n";
char fShaderStr2[] = //片段着色器
"#version 300 es \n" //
"precision mediump float; \n" //声明着色器中浮点变量的默认精度
"out vec4 fragColor; \n" //声明一个输出变量
"void main() \n"
"{ \n"
" fragColor = vec4 ( 0.0, 0.0, 0.0, 1.0 ); \n" //给这个输出变量赋值
"} \n";
GLuint vertexShader,vertexShader2,vertexShader3;
GLuint fragmentShader,fragmentShader2,fragmentShader3;
GLuint programObject,programObject2,programObject3;
GLint linked,linked2,linked3;
// Load the vertex/fragment shaders
vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr ); //
vertexShader2 = LoadShader ( GL_VERTEX_SHADER, vShaderStr ); //
fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr ); //
fragmentShader2 = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr2 );
// Create the program object
programObject = glCreateProgram ( );
programObject2 = glCreateProgram ( );
// programObject3 = glCreateProgram ( );
if ( programObject == 0 )
{
return 0;
}
glAttachShader ( programObject, vertexShader );
glAttachShader ( programObject2, vertexShader2 );
glAttachShader ( programObject, fragmentShader );
glAttachShader ( programObject2, fragmentShader2 );
// Link the program
glLinkProgram ( programObject );
glLinkProgram ( programObject2);
// Store the program object
userData->programObject = programObject;
userData->programObject2 = programObject2;
glClearColor ( 100.0f, 100.0f, 100.0f, 1.0f );
return TRUE;
}
void DrawCircle(GLfloat x, GLfloat y, GLfloat r, GLuint programObject, GLfloat num)
{
glUseProgram ( programObject );
GLfloat x1 = x,y1=y,x2=r+x,y2=y;
GLfloat Vertices[] = {
x1, y1, 0.0f,
x2, y2, 0.0f,
};
// GLfloat num = 48.0f;
for(int i = 0; i < num; i++)
{
x1 = x2;y1=y2;
x2 = r*cos((GLfloat)(2*PI)/num*i)+x;
y2 = r*sin((GLfloat)(2*PI)/num*i)+y;
GLfloat Vertices[] = {
x1, y1, 0.0f,
x2, y2,0.0f,
};
glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, Vertices );// 载入顶点数据
glEnableVertexAttribArray ( 0 ); // 启用顶点使用数组--使能
glDrawArrays ( GL_LINE_STRIP, 0, 2 ); // 绘制图元
glLineWidth(2);
}
}
GLfloat vVertices2[] = {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.8f, 0.0f,
};
///
// Draw a triangle using the shader pair created in Init()
//
void Draw ( ESContext *esContext )
{
UserData *userData = esContext->userData;
glViewport ( 0, 0, esContext->width, esContext->height ); // Set the viewport
glClear ( GL_COLOR_BUFFER_BIT ); // Clear the color buffer
DrawCircle(0.0,0.0,0.01,userData->programObject2,48.0f);
glUseProgram ( userData->programObject ); // Use the program object
GLfloat x1 = 0.0f,y1=0.0f,x2=1.0f,y2=0.0f;
GLfloat vVertices[] = {
x1, y1, 0.0f,
x2, y2, 0.0f,
};
GLfloat num = 12.0f;
for(int i = 0; i <= num; i++)
{
x1 = x2;y1=y2;
x2 = 1*cos((GLfloat)(2*PI)/num*i);
y2 = 1*sin((GLfloat)(2*PI)/num*i);
GLfloat vVertices[] = {
x1, y1, 0.0f,
x2, y2,0.0f,
};
glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );// 载入顶点数据
glEnableVertexAttribArray ( 0 ); // 启用顶点使用数组--使能
glDrawArrays ( GL_POINTS, 0, 2 ); // 绘制图元
// glLineWidth(5); // 线宽
}
glUseProgram ( userData->programObject2 ); // Use the program object
glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices2 );// 载入顶点数据
glEnableVertexAttribArray ( 0 ); // 启用顶点使用数组--使能
glDrawArrays ( GL_LINES, 1, 2 ); // 绘制图元
glDrawArrays ( GL_LINES, 3, 2 ); // 绘制图元
glLineWidth(5);
}
float theat = 0.0;
float theat2 = 1.57;
void Update (ESContext *esContext,float deltaTime)
{
if(theat>=0.0003 && theat <=2*3.14159)
{
vVertices2[6]=0.5*cos(theat);
vVertices2[7]=0.5*sin(theat);
theat -= 0.0003;
}else
{
theat =2*3.14158;
}
if(theat2>=0.006 && theat2 <=2*3.14159)
{
vVertices2[12]=0.8*cos(theat2);
vVertices2[13]=0.8*sin(theat2);
theat2 -= 0.006;
}else
{
theat2 =2*3.14158;
}
}
void Shutdown ( ESContext *esContext )
{
UserData *userData = esContext->userData;
glDeleteProgram ( userData->programObject );
glDeleteProgram ( userData->programObject2 );
}
int esMain ( ESContext *esContext )
{
esContext->userData = malloc ( sizeof ( UserData ) );
esCreateWindow ( esContext, "Hello Triangle", 500, 500, ES_WINDOW_RGB );
if ( !Init ( esContext ) )
{
return GL_FALSE;
}
esRegisterShutdownFunc ( esContext, Shutdown );//recall Shutdown function
esRegisterUpdateFunc ( esContext, Update );
esRegisterDrawFunc ( esContext, Draw ); //recall Draw function
return GL_TRUE;
}