#include <stdlib.h>
#include "esUtil.h"
#include <math.h>
#define PI 3.1415926
typedef struct
{
// Handle to a program object
GLuint programObject;
// VertexBufferObject Ids
GLuint vboIds[3];
} UserData;
#define VERTEX_POS_SIZE 3 // x, y and z
#define VERTEX_COLOR_SIZE 4 // r, g, b, and a
#define VERTEX_POS_INDX 0
#define VERTEX_COLOR_INDX 1
float r = 1;
float theat = PI/4;
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);
}
}
///
// Initialize the shader and program object
//
int Init ( ESContext *esContext )
{
UserData *userData = esContext->userData;
//顶点着色器
const char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 a_position; \n"
"layout(location = 1) in vec4 a_color; \n"
"out vec4 v_color; \n"
"void main() \n"
"{ \n"
" v_color = a_color; \n"
" gl_Position = a_position; \n"
"}";
//片段着色器
const char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"in vec4 v_color; \n"
"out vec4 o_fragColor; \n"
"void main() \n"
"{ \n"
" o_fragColor = v_color; \n"
"}" ;
GLuint vertexShader;
GLuint fragmentShader;
GLuint programObject;
GLint linked;
/* Create the program object function as the same as beneath*/
// vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr ); //
// fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr ); //
// programObject = glCreateProgram ( );
// glAttachShader ( programObject, vertexShader );
// glAttachShader ( programObject, fragmentShader );
// glLinkProgram ( programObject );
/* Create the program object function as the same as top*/
programObject = esLoadProgram ( vShaderStr, fShaderStr );
// Store the program object
userData->programObject = programObject;
userData->vboIds[0] = 0;
userData->vboIds[1] = 0;
userData->vboIds[2] = 0;
glClearColor ( 100.0f, 100.0f, 100.0f, 1.0f );
return TRUE;
}
void DrawPrimitiveWithVBOs ( ESContext *esContext,
GLint numVertices, GLfloat **vtxBuf,
GLint *vtxStrides, GLint numIndices,
GLushort *indices )
{
UserData *userData = esContext->userData;
if ( userData->vboIds[0] == 0 && userData->vboIds[1] == 0 &&
userData->vboIds[2] == 0 )
{
// Only allocate on the first draw
// 申请开辟新的VBO
glGenBuffers ( 3, userData->vboIds );
//绑定buffer 传入顶点数据
glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] );
glBufferData ( GL_ARRAY_BUFFER, vtxStrides[0] * numVertices,
vtxBuf[0], GL_DYNAMIC_DRAW );
// 绑定buffer 传入颜色数据
glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[1] );
glBufferData ( GL_ARRAY_BUFFER, vtxStrides[1] * numVertices,
vtxBuf[1], GL_DYNAMIC_DRAW );
// GL_ELEMENT_ARRAY_BUFFER(用于为索引数组传值)
glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[2] );
// 将数据传递给当前绑定的VBO。
glBufferData ( GL_ARRAY_BUFFER, sizeof ( GLushort ) * numIndices,
indices, GL_DYNAMIC_DRAW );
}
glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] );
glEnableVertexAttribArray ( VERTEX_POS_INDX );
glVertexAttribPointer ( VERTEX_POS_INDX, VERTEX_POS_SIZE,
GL_FLOAT, GL_FALSE, vtxStrides[0], 0 );
glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[1] );
glEnableVertexAttribArray ( VERTEX_COLOR_INDX );
glVertexAttribPointer ( VERTEX_COLOR_INDX,VERTEX_COLOR_SIZE,
GL_FLOAT, GL_FALSE, vtxStrides[1], 0 );
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[2] );
glDrawArrays ( GL_TRIANGLE_FAN, 0, 12 ); // 绘制图元
glDisableVertexAttribArray ( VERTEX_POS_INDX );
glDisableVertexAttribArray ( VERTEX_COLOR_INDX );
glBindBuffer ( GL_ARRAY_BUFFER, 0 );
glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 );
}
GLfloat vertexPos[12 * VERTEX_POS_SIZE] =
{
0.0f, -0.0f, 0.0f, // v0
-1.0f, -1.0f, 0.0f, // v1
-0.5f, 0.5f, 0.0f, // v2
-1.0f, 1.0f, 0.0f, // v3
0.5f, 0.5f, 0.0f, // v4
1.0f, 1.0f, 0.0f, // v5
0.5f, -0.5f, 0.0f, // v6
1.0f, -1.0f, 0.0f, // v7
-0.5f, -0.5f, 0.0f, // v8
};
GLfloat color[12 * VERTEX_COLOR_SIZE] =
{
1.0f, 0.0f, 0.0f, 1.0f, // c0
0.0f, 1.0f, 0.0f, 1.0f, // c1
0.0f, 0.0f, 1.0f, 1.0f, // c2
0.0f, 1.0f, 1.0f, 1.0f, // c3
0.0f, 1.0f, 1.0f, 1.0f, // c3
0.0f, 0.0f, 0.0f, 1.0f, // c3
0.5f, 0.0f, 0.0f, 1.0f, // c0
0.0f, 0.5f, 0.0f, 1.0f, // c1
0.0f, 0.0f, 0.5f, 1.0f, // c2
0.0f, 0.1f, 1.0f, 1.0f, // c3
0.0f, 0.2f, 1.0f, 1.0f, // c3
0.3f, 0.0f, 0.0f, 1.0f // c3
}; // Index buffer data
// GLushort indices[12] = { 0, 1 ,2,3,4,5,6,7,8,9,10,11};
GLushort indices[12] = { 0,1,2,0,3,4,0,5,6,0,7,8};
GLfloat *vtxBuf[2] = { vertexPos, color };
GLint vtxStrides[2] =
{
VERTEX_POS_SIZE * sizeof ( GLfloat ),
VERTEX_COLOR_SIZE * sizeof ( GLfloat )
};
//
// Draw a triangle using the shader pair created in Init()
//
void Draw ( ESContext *esContext )
{
UserData *userData = esContext->userData;
glViewport ( 150, 150, 0.5*esContext->width, 0.5*esContext->height );// Set the viewport
glClear ( GL_COLOR_BUFFER_BIT );// Clear the color buffer
glUseProgram ( userData->programObject );// Use the program object
/*
* *esContext, numVertices, **vtxBuf, *vtxStrides, numIndices, *indices
*/
DrawPrimitiveWithVBOs ( esContext, 12, vtxBuf, vtxStrides, 12, indices );
DrawCircle(0.0,0.0,r,userData->programObject,48.0f);
DrawCircle(0.0,0.0,r+0.2,userData->programObject,48.0f);
DrawCircle(0.0,0.0,r+0.4,userData->programObject,48.0f);
}
void Update (ESContext *esContext,float deltaTime)
{
UserData *userData = ( UserData * ) esContext->userData;
if(r>0 && r<=1)
{
r -=0.01;
}
else r=1;
if (theat >=0 && theat < 2*PI-0.1)
{
vertexPos[3] = 1*cos(theat+PI*1);
vertexPos[4] = 1*sin(theat+PI*1);
vertexPos[6] = 0.5*cos(theat+PI*0.5);
vertexPos[7] = 0.5*sin(theat+PI*0.5);
vertexPos[9] = 1*cos(theat+PI*0.5);
vertexPos[10] = 1*sin(theat+PI*0.5);
vertexPos[12] = 0.5*cos(theat);
vertexPos[13] = 0.5*sin(theat);
vertexPos[15] = 1*cos(theat);
vertexPos[16] = 1*sin(theat);
vertexPos[18] = 0.5*cos(theat+PI*1.5);
vertexPos[19] = 0.5*sin(theat+PI*1.5);
vertexPos[21] = 1*cos(theat+PI*1.5);
vertexPos[22] = 1*sin(theat+PI*1.5);
vertexPos[24] = 0.5*cos(theat+PI*1);
vertexPos[25] = 0.5*sin(theat+PI*1);
theat +=0.01;
}else
{
theat = 0;
}
glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] );
glBufferData ( GL_ARRAY_BUFFER, vtxStrides[0] * 12,
vtxBuf[0], GL_DYNAMIC_DRAW );
// }
}
void Shutdown ( ESContext *esContext )
{
UserData *userData = esContext->userData;
glDeleteProgram ( userData->programObject );
}
int esMain ( ESContext *esContext )
{
esContext->userData = malloc ( sizeof ( UserData ) );
esCreateWindow ( esContext, "Hello Square", 500, 500, ES_WINDOW_RGB | ES_WINDOW_DEPTH);
if ( !Init ( esContext ) )
{
return GL_FALSE;
}
esRegisterShutdownFunc ( esContext, Shutdown );//recall Shutdown function
esRegisterUpdateFunc ( esContext, Update );
esRegisterDrawFunc ( esContext, Draw ); //recall Draw function
return GL_TRUE;
}