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

工程源码下载地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值