前言
openGLES3.0报错,信息如下:
FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GLES32Api when calling glCreateShader
FATAL - Exception thrown in GLES32Api::glGetProgramInfoLog -> FATAL: No EGL context available for type GLES32Api when calling glGetProgramInfoLog
failed:Error message:Invoke ?"
FATAL - Exception thrown in GLES32Api::glGetProgramInfoLog -> FATAL: No EGL context available for type GLES32Api when calling glGetProgramInfoLog
failed:Error message:Invoke Init()
GL renderer: [Intel(R) UHD Graphics]
GL vendor:[Intel]
GL version: [3.3.0 - Build 27.20.100.8280]
GL shading language version: [3.30 - Build 27.20.100.8280]
D:\openGLESExercise\openGLES3.0Example_6_VertexBufferObjects\x64\Debug\openGLES3.0Example_6_VertexBufferObjects.exe (进 程 14528)已退出,代码为 0。
按任意键关闭此窗口. . .
定位错误
1. 程序源码
#include "esUtil.h"
//#include "esUtil_win.h"
//#include <string.h> //c编译器
typedef struct
{
// Handle to a program object
GLuint programObject;
// VertexBufferObject Ids
GLuint vboIds[2];
// x-offset uniform location
GLuint offsetLoc;
} 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
//打印日志信息
void PrintLogMessage(ESContext* esContext, char* msg)
{
UserData* userData = esContext->userData;
//GLint infoLen = GL_INFO_LOG_LENGTH;
GLint infoLen = 512;
char* infoLog = malloc(sizeof(char) * 512);
glGetProgramInfoLog(userData->programObject, infoLen, &infoLen, infoLog);
GLint headLen = strlen("Invoke ");
strcpy_s(infoLog, headLen + 3, "Invoke "); //这里长度必须+1,要覆盖'\0',否则越界,vs2019边界检查更严格
/********* (1)src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
/*********(2)strcat返回值有什么作用? 链式传递:strcat(a, strcat(b, c));
/********* 最重要的是,strcat函数不检查这些。*********/
//strcat(infoLog, "Invoke ");
//strcat_s(infoLog, msg, strlen(msg)+1);
int strMsgSize = strlen(msg);
int strInfoSize = strlen(infoLog);
//注意!!!strcat_s()第二个参数的大小是 src+des+1总和大小,+1是'\0'的大小
int retStatue = strcat_s(infoLog, strMsgSize + strInfoSize + 1, msg);
esLogMessage(" failed:Error message:%s\n", infoLog);
free(infoLog);
}
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"
"uniform float u_offset; \n"
"out vec4 v_color; \n"
"void main() \n"
"{ \n"
" v_color = a_color; \n"
" gl_Position = a_position; \n"
" gl_Position.x += u_offset; \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"
"}";
3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex
//GLfloat vertices[3 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE)] =
//{
// 0.0f, 0.5f, 0.0f, // v0 position
// 1.0f, 0.0f, 0.0f, 1.0f, // c0 color
// -0.5f, -0.5f, 0.0f, // v1 position
// 0.0f, 1.0f, 0.0f, 1.0f, // c1 color
// 0.5f, -0.5f, 0.0f, // v2 position
// 0.0f, 0.0f, 1.0f, 1.0f, // c2 color
//};
GLuint programObject = 0;
programObject = esLoadProgram(vShaderStr, fShaderStr);
userData->offsetLoc = glGetUniformLocation(programObject, "u_offset");
if (programObject == GL_FALSE)
{
PrintLogMessage(esContext, esLoadProgram);
return GL_FALSE;
}
/*userData->offsetLoc = glGetUniformLocation(programObject, "u_offset");*/
// Store the program object
userData->programObject = programObject;
userData->vboIds[0] = 0;
userData->vboIds[1] = 0;
glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
return GL_TRUE;
}
//
// vertices - pointer to a buffer that contains vertex
// attribute data
// vtxStride - stride of attribute data / vertex in bytes
// numIndices - number of indices that make up primitive
// drawn as triangles
// indices - pointer to element index buffer.
//
//这里没有用到EsContext上下文变量
void DrawPrimitiveWithoutVBOs(GLfloat* vertices,
GLint vtxStride,
GLint numIndices,
GLushort* indices)
{
GLfloat* vtxBuf = vertices;
这里没有用到顶点缓冲区对象VBO,所以没有用到环境上下文ESContext变量
//ESContext* esContext;
//UserData* userData = esContext->userData;
//glGenBuffers(2, userData->vboIds);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
这里没有用到glBufferData
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_POS_INDX);
glEnableVertexAttribArray(VERTEX_COLOR_INDX);
/*glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride * sizeof(GLfloat), (GLvoid*)VERTEX_POS_INDX);*/
/*glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, (GLvoid*)0);*/
glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
vtxBuf += VERTEX_POS_SIZE;
//glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE,
// sizeof(GLushort) * numIndices, (GLvoid*)(3)); //3:表示颜色索引 1.0f, 0.0f, 0.0f, 1.0f, // c0 color
glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, indices);
//glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, vertices);
glDisableVertexAttribArray(VERTEX_POS_INDX);
glDisableVertexAttribArray(VERTEX_COLOR_INDX);
}
//使用顶点缓冲区对象绘制基本图元
void DrawPrimitiveWithVBOs(ESContext* esContext,
GLint numVertices, GLfloat* vtxBuf,
GLint vtxStride, GLint numIndices, GLushort* indices)
{
UserData* userData = esContext->userData;
GLuint offset = 0;
// vboIds[0] - used to store vertex attribute data
// vboIds[l] - used to store element indices
if (userData->vboIds[0] == 0 && userData->vboIds[1] == 0)
{
// Only allocate on the first draw
//第一次绘制时,创建顶点缓冲区对象
glGenBuffers(2, userData->vboIds);
glBindBuffer(GL_ARRAY_BUFFER, userData->vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, vtxStride * numVertices, vtxBuf, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * numIndices, indices, GL_STATIC_DRAW);
}
//不是第一次绘制,所以这时候已经有了顶点缓冲区数据了,所以就不用创建顶点缓冲区数据了,
//所以就不用再调用glBufferData()函数了
glBindBuffer(GL_ARRAY_BUFFER, userData->vboIds[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1]);
/*glBufferData(GL_ARRAY_BUFFER, vtxStride * numVertices, vtxBuf, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * numIndices, indices, GL_STATIC_DRAW);*/
glEnableVertexAttribArray(VERTEX_POS_INDX);
glEnableVertexAttribArray(VERTEX_COLOR_INDX);
/*glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE,
GL_FLOAT, GL_FALSE, vtxStride * numVertices, (GLvoid*)0);*/
glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, (GLvoid*)offset);
offset += VERTEX_POS_SIZE * sizeof(GLfloat);
/*glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE,
GL_FLOAT, GL_FALSE, sizeof(GLushort) * numIndices,
(GLvoid*)(3 * sizeof(GLushort)));*/
glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, (GLvoid*)offset);
//userData->vboIds[1];是以序号方式绘制三角形,所以是0开始
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, (GLvoid*)0);
glDisableVertexAttribArray(VERTEX_POS_INDX);
glDisableVertexAttribArray(VERTEX_COLOR_INDX);
//恢复到默认绑定状态
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Draw(ESContext* esContext)
{
UserData* userData = esContext->userData;
// 3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex
GLfloat vertices[3 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE)] =
{
-0.5f, 0.5f, 0.0f, // v0
1.0f, 0.0f, 0.0f, 1.0f, // c0
-1.0f, -0.5f, 0.0f, // v1
0.0f, 1.0f, 0.0f, 1.0f, // c1
0.0f, -0.5f, 0.0f, // v2
0.0f, 0.0f, 1.0f, 1.0f, // c2
};
// Index buffer data
GLushort indices[3] = { 0, 1, 2 };
glViewport(0, 0, esContext->width, esContext->height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(userData->programObject);
glUniform1f(userData->offsetLoc, 0.0f);
//不用顶点缓冲区对象
/*DrawPrimitiveWithoutVBOs(vertices, sizeof(GLushort) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
3, indices);*/
DrawPrimitiveWithoutVBOs(vertices, sizeof(GLfloat) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
VERTEX_POS_SIZE, indices);
// Offset the vertex positions so both can be seen
glUniform1f(userData->offsetLoc, 1.0f);
//使用顶点缓冲区对象
/*DrawPrimitiveWithVBOs(esContext, 3, vertices,
sizeof(GLushort) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
3, indices);*/
DrawPrimitiveWithVBOs(esContext, VERTEX_POS_SIZE, vertices,
sizeof(GLfloat) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
VERTEX_POS_SIZE, indices);
}
void Shutdown(ESContext* esContext)
{
UserData* userData = esContext->userData;
glDeleteProgram(userData->programObject);
glDeleteBuffers(2, userData->vboIds);
}
int esMain(ESContext* esContext)
{
esContext->userData = malloc(sizeof(UserData));
if (esContext->userData == NULL)
{
PrintLogMessage(esContext, "malloc(sizeof(UserData)");
return GL_FALSE;
}
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
//注意!!!!这里一定要先创建openGLES窗口,然后再初始化openGLES,切记切记!!!!
/*否则报错:FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GLES32Api when calling glCreateShader
FATAL - Exception thrown in GLES32Api::glGetProgramInfoLog->FATAL: No EGL context available for type GLES32Api when calling glGetProgramInfoLog
failed : Error message : Invoke ? "
FATAL - Exception thrown in GLES32Api::glGetProgramInfoLog->FATAL : No EGL context available for type GLES32Api when calling glGetProgramInfoLog
failed : Error message : Invoke Init()*/
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
if (!Init(esContext))
{
PrintLogMessage(esContext, "Init()");
//return GL_FALSE;
}
GLint createWindowSataus = esCreateWindow(esContext, "openGLES3.0Example_6_VertexBufferObjects", 400, 300, ES_WINDOW_RGB);
if (createWindowSataus == GL_FALSE)
{
PrintLogMessage(esContext, "esCreateWindow");
return GL_FALSE;
}
esRegisterDrawFunc(esContext, Draw);
esRegisterShutdownFunc(esContext, Shutdown);
return GL_TRUE;
}
聪明的你一定一眼就看到问题的所在,而我却用了半天的时间,才找到问题症结。
2.定位出错的源码
从上面的代码调试中可以看到:是创建shader出错了,于是我赶快检查顶点着色器和片元着色器看是不是哪里代码出错!
shader = glCreateShader ( type );
const char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 a_position; \n"
"layout(location = 1) in vec4 a_color; \n"
"uniform float u_offset; \n"
"out vec4 v_color; \n"
"void main() \n"
"{ \n"
" v_color = a_color; \n"
" gl_Position = a_position; \n"
" gl_Position.x += u_offset; \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"
"}";
确认过眼神,的确没错,那为什么加载shader程序出错了呢?
3.于是我赶快看vs2019的配置时候有错,再次确认了头文件,lib库文件、dll库文件,依然没有错误
头文件配置
静态lib库配置
动态库dll配置
注意!!!!这里只能建空工程项目,并且是x64位,因为我用的模拟器是x64位的
这些配置都是正确的,但程序依然报错
解决
最后发现问题原因:一定要先用openGLES创建窗口,然后再初始化openGLES
正确的代码
#include "esUtil.h"
//#include "esUtil_win.h"
//#include <string.h> //c编译器
typedef struct
{
// Handle to a program object
GLuint programObject;
// VertexBufferObject Ids
GLuint vboIds[2];
// x-offset uniform location
GLuint offsetLoc;
} 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
//打印日志信息
void PrintLogMessage(ESContext* esContext, char* msg)
{
UserData* userData = esContext->userData;
//GLint infoLen = GL_INFO_LOG_LENGTH;
GLint infoLen = 512;
char* infoLog = malloc(sizeof(char) * 512);
glGetProgramInfoLog(userData->programObject, infoLen, &infoLen, infoLog);
GLint headLen = strlen("Invoke ");
strcpy_s(infoLog, headLen + 3, "Invoke "); //这里长度必须+1,要覆盖'\0',否则越界,vs2019边界检查更严格
/********* (1)src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
/*********(2)strcat返回值有什么作用? 链式传递:strcat(a, strcat(b, c));
/********* 最重要的是,strcat函数不检查这些。*********/
//strcat(infoLog, "Invoke ");
//strcat_s(infoLog, msg, strlen(msg)+1);
int strMsgSize = strlen(msg);
int strInfoSize = strlen(infoLog);
//注意!!!strcat_s()第二个参数的大小是 src+des+1总和大小,+1是'\0'的大小
int retStatue = strcat_s(infoLog, strMsgSize + strInfoSize + 1, msg);
esLogMessage(" failed:Error message:%s\n", infoLog);
free(infoLog);
}
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"
"uniform float u_offset; \n"
"out vec4 v_color; \n"
"void main() \n"
"{ \n"
" v_color = a_color; \n"
" gl_Position = a_position; \n"
" gl_Position.x += u_offset; \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"
"}";
3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex
//GLfloat vertices[3 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE)] =
//{
// 0.0f, 0.5f, 0.0f, // v0 position
// 1.0f, 0.0f, 0.0f, 1.0f, // c0 color
// -0.5f, -0.5f, 0.0f, // v1 position
// 0.0f, 1.0f, 0.0f, 1.0f, // c1 color
// 0.5f, -0.5f, 0.0f, // v2 position
// 0.0f, 0.0f, 1.0f, 1.0f, // c2 color
//};
GLuint programObject = 0;
programObject = esLoadProgram(vShaderStr, fShaderStr);
userData->offsetLoc = glGetUniformLocation(programObject, "u_offset");
if (programObject == GL_FALSE)
{
PrintLogMessage(esContext, esLoadProgram);
return GL_FALSE;
}
/*userData->offsetLoc = glGetUniformLocation(programObject, "u_offset");*/
// Store the program object
userData->programObject = programObject;
userData->vboIds[0] = 0;
userData->vboIds[1] = 0;
glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
return GL_TRUE;
}
//
// vertices - pointer to a buffer that contains vertex
// attribute data
// vtxStride - stride of attribute data / vertex in bytes
// numIndices - number of indices that make up primitive
// drawn as triangles
// indices - pointer to element index buffer.
//
//这里没有用到EsContext上下文变量
void DrawPrimitiveWithoutVBOs(GLfloat* vertices,
GLint vtxStride,
GLint numIndices,
GLushort* indices)
{
GLfloat* vtxBuf = vertices;
这里没有用到顶点缓冲区对象VBO,所以没有用到环境上下文ESContext变量
//ESContext* esContext;
//UserData* userData = esContext->userData;
//glGenBuffers(2, userData->vboIds);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
这里没有用到glBufferData
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_POS_INDX);
glEnableVertexAttribArray(VERTEX_COLOR_INDX);
/*glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride * sizeof(GLfloat), (GLvoid*)VERTEX_POS_INDX);*/
/*glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, (GLvoid*)0);*/
glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
vtxBuf += VERTEX_POS_SIZE;
//glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE,
// sizeof(GLushort) * numIndices, (GLvoid*)(3)); //3:表示颜色索引 1.0f, 0.0f, 0.0f, 1.0f, // c0 color
glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, vtxBuf);
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, indices);
//glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, vertices);
glDisableVertexAttribArray(VERTEX_POS_INDX);
glDisableVertexAttribArray(VERTEX_COLOR_INDX);
}
//使用顶点缓冲区对象绘制基本图元
void DrawPrimitiveWithVBOs(ESContext* esContext,
GLint numVertices, GLfloat* vtxBuf,
GLint vtxStride, GLint numIndices, GLushort* indices)
{
UserData* userData = esContext->userData;
GLuint offset = 0;
// vboIds[0] - used to store vertex attribute data
// vboIds[l] - used to store element indices
if (userData->vboIds[0] == 0 && userData->vboIds[1] == 0)
{
// Only allocate on the first draw
//第一次绘制时,创建顶点缓冲区对象
glGenBuffers(2, userData->vboIds);
glBindBuffer(GL_ARRAY_BUFFER, userData->vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, vtxStride * numVertices, vtxBuf, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * numIndices, indices, GL_STATIC_DRAW);
}
//不是第一次绘制,所以这时候已经有了顶点缓冲区数据了,所以就不用创建顶点缓冲区数据了,
//所以就不用再调用glBufferData()函数了
glBindBuffer(GL_ARRAY_BUFFER, userData->vboIds[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1]);
/*glBufferData(GL_ARRAY_BUFFER, vtxStride * numVertices, vtxBuf, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * numIndices, indices, GL_STATIC_DRAW);*/
glEnableVertexAttribArray(VERTEX_POS_INDX);
glEnableVertexAttribArray(VERTEX_COLOR_INDX);
/*glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE,
GL_FLOAT, GL_FALSE, vtxStride * numVertices, (GLvoid*)0);*/
glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, (GLvoid*)offset);
offset += VERTEX_POS_SIZE * sizeof(GLfloat);
/*glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE,
GL_FLOAT, GL_FALSE, sizeof(GLushort) * numIndices,
(GLvoid*)(3 * sizeof(GLushort)));*/
glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE,
vtxStride, (GLvoid*)offset);
//userData->vboIds[1];是以序号方式绘制三角形,所以是0开始
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, (GLvoid*)0);
glDisableVertexAttribArray(VERTEX_POS_INDX);
glDisableVertexAttribArray(VERTEX_COLOR_INDX);
//恢复到默认绑定状态
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void Draw(ESContext* esContext)
{
UserData* userData = esContext->userData;
// 3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex
GLfloat vertices[3 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE)] =
{
-0.5f, 0.5f, 0.0f, // v0
1.0f, 0.0f, 0.0f, 1.0f, // c0
-1.0f, -0.5f, 0.0f, // v1
0.0f, 1.0f, 0.0f, 1.0f, // c1
0.0f, -0.5f, 0.0f, // v2
0.0f, 0.0f, 1.0f, 1.0f, // c2
};
// Index buffer data
GLushort indices[3] = { 0, 1, 2 };
glViewport(0, 0, esContext->width, esContext->height);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(userData->programObject);
glUniform1f(userData->offsetLoc, 0.0f);
//不用顶点缓冲区对象
/*DrawPrimitiveWithoutVBOs(vertices, sizeof(GLushort) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
3, indices);*/
DrawPrimitiveWithoutVBOs(vertices, sizeof(GLfloat) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
VERTEX_POS_SIZE, indices);
// Offset the vertex positions so both can be seen
glUniform1f(userData->offsetLoc, 1.0f);
//使用顶点缓冲区对象
/*DrawPrimitiveWithVBOs(esContext, 3, vertices,
sizeof(GLushort) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
3, indices);*/
DrawPrimitiveWithVBOs(esContext, VERTEX_POS_SIZE, vertices,
sizeof(GLfloat) * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE),
VERTEX_POS_SIZE, indices);
}
void Shutdown(ESContext* esContext)
{
UserData* userData = esContext->userData;
glDeleteProgram(userData->programObject);
glDeleteBuffers(2, userData->vboIds);
}
int esMain(ESContext* esContext)
{
esContext->userData = malloc(sizeof(UserData));
if (esContext->userData == NULL)
{
PrintLogMessage(esContext, "malloc(sizeof(UserData)");
return GL_FALSE;
}
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
//注意!!!!这里一定要先创建openGLES窗口,然后再初始化openGLES,切记切记!!!!
/*否则报错:FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GLES32Api when calling glCreateShader
FATAL - Exception thrown in GLES32Api::glGetProgramInfoLog->FATAL: No EGL context available for type GLES32Api when calling glGetProgramInfoLog
failed : Error message : Invoke ? "
FATAL - Exception thrown in GLES32Api::glGetProgramInfoLog->FATAL : No EGL context available for type GLES32Api when calling glGetProgramInfoLog
failed : Error message : Invoke Init()*/
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
/********************************************************************************************/
GLint createWindowSataus = esCreateWindow(esContext, "openGLES3.0Example_6_VertexBufferObjects", 400, 300, ES_WINDOW_RGB);
if (createWindowSataus == GL_FALSE)
{
PrintLogMessage(esContext, "esCreateWindow");
return GL_FALSE;
}
if (!Init(esContext))
{
PrintLogMessage(esContext, "Init()");
//return GL_FALSE;
}
esRegisterDrawFunc(esContext, Draw);
esRegisterShutdownFunc(esContext, Shutdown);
return GL_TRUE;
}