0
点赞
收藏
分享

微信扫一扫

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL


前言

        openGLES3.0报错,信息如下:

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_顶点缓冲区对象

 

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_#define_02

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.定位出错的源码

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_顶点缓冲区对象_03

 从上面的代码调试中可以看到:是创建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库文件,依然没有错误

头文件配置

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_ide_04

  静态lib库配置

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_ide_05

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_#define_06

 动态库dll配置

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_#define_07

注意!!!!这里只能建空工程项目,并且是x64位,因为我用的模拟器是x64位的

这些配置都是正确的,但程序依然报错

解决

      最后发现问题原因:一定要先用openGLES创建窗口,然后再初始化openGLES

FATAL - Exception thrown in GLES32Api::glCreateShader -> FATAL: No EGL context available for type GL_#define_08

 正确的代码

#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;
}

​​工程源码下载地址​​

举报
0 条评论