《OpenGL ES 2.0 Programming Guide》第9章 “最简单的本地纹理+VBO”示例代码【C语言版】

举报
ShaderJoy 发表于 2021/12/30 00:35:01 2021/12/30
【摘要】 由于《OpenGL ES 2.0 Programming Guide》原书第9章并没有提供相关的示例,为了加深理解,遂自己实现了一份C语言版本作为练习,希望能够帮助到同样喜欢OpenGL ES 2.0的同学。 废话不多说,直接上代码: #include <stdlib.h>#include "esUtil.h...

废话不多说,直接上代码:



  
  1. #include <stdlib.h>
  2. #include "esUtil.h"
  3. #define VERTEX_POS_SIZE 3 // x, y and z
  4. #define TEXCOORD_SIZE 2 // u,v
  5. #define INDICES_SIZE 6
  6. typedef struct
  7. {
  8. // Handle to a program object
  9. GLuint programObject;
  10. // Attribute locations
  11. GLint positionLoc;
  12. GLint texCoordLoc;
  13. // Sampler location
  14. GLint samplerLoc;
  15. // Texture handle
  16. GLuint textureId;
  17. // VertexBufferObject Ids ☆
  18. GLuint vboIds[2];
  19. } UserData;
  20. ///
  21. // Load texture from disk
  22. //
  23. GLuint LoadTexture ( char *fileName )
  24. {
  25. int width, height;
  26. char *buffer = esLoadTGA ( fileName, &width, &height );
  27. GLuint texId;
  28. if ( buffer == NULL )
  29. {
  30. esLogMessage ( "Error loading (%s) image.\n", fileName );
  31. return 0;
  32. }
  33. glGenTextures ( 1, &texId );
  34. glBindTexture ( GL_TEXTURE_2D, texId );
  35. glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer );
  36. glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  37. glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  38. glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  39. glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  40. free ( buffer );
  41. return texId;
  42. }
  43. ///
  44. // Initialize the shader and program object
  45. //
  46. int Init ( ESContext *esContext )
  47. {
  48. char *fileName = "../Fieldstone.tga";
  49. UserData *userData = (UserData *)esContext->userData;
  50. const char vShaderStr[] =
  51. "attribute vec4 a_position; \n"
  52. "attribute vec2 a_texCoord; \n"
  53. "varying vec2 v_texCoord; \n"
  54. "void main() \n"
  55. "{ \n"
  56. " gl_Position = a_position; \n"
  57. " v_texCoord = a_texCoord; \n"
  58. "} \n";
  59. const char fShaderStr[] =
  60. "precision mediump float; \n"
  61. "varying vec2 v_texCoord; \n"
  62. "uniform sampler2D s_texture; \n"
  63. "void main() \n"
  64. "{ \n"
  65. " gl_FragColor = texture2D( s_texture, v_texCoord );\n"
  66. "} \n";
  67. // Load the shaders and get a linked program object
  68. userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
  69. // Get the attribute locations
  70. userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
  71. userData->texCoordLoc = glGetAttribLocation ( userData->programObject, "a_texCoord" );
  72. // Get the sampler location
  73. userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );
  74. // Load the texture ☆
  75. userData->textureId = LoadTexture(fileName);
  76. // Init VBO ids ☆
  77. userData->vboIds[0] = 0;
  78. userData->vboIds[1] = 0;
  79. glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
  80. return TRUE;
  81. }
  82. ///
  83. // Draw a triangle using the shader pair created in Init()
  84. //
  85. void Draw ( ESContext *esContext )
  86. {
  87. UserData *userData = (UserData *)esContext->userData;
  88. GLfloat vVertices[] = { -1.f, 1.f, 0.0f, // Position 0
  89. 0.0f, 0.0f, // TexCoord 0
  90. -1.f, -1.f, 0.0f, // Position 1
  91. 0.0f, 1.0f, // TexCoord 1
  92. 1.f, -1.f, 0.0f, // Position 2
  93. 1.0f, 1.0f, // TexCoord 2
  94. 1.f, 1.f, 0.0f, // Position 3
  95. 1.0f, 0.0f // TexCoord 3
  96. };
  97. GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
  98. int numVertices = 4;
  99. // vboIds[0] - used to store vertex position AND texture coordination
  100. // vboIds[1] - used to store vertex indices
  101. // run only once ☆
  102. if ( userData->vboIds[0] == 0 && userData->vboIds[1] == 0)
  103. {
  104. // Only allocate on the first draw
  105. glGenBuffers ( 2, userData->vboIds );
  106. glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] );
  107. glBufferData ( GL_ARRAY_BUFFER, (VERTEX_POS_SIZE + TEXCOORD_SIZE) * sizeof(GLfloat) * numVertices,
  108. vVertices, GL_STATIC_DRAW );
  109. glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1] );
  110. glBufferData ( GL_ELEMENT_ARRAY_BUFFER, INDICES_SIZE * sizeof(GLushort),
  111. indices, GL_STATIC_DRAW );
  112. }
  113. // Set the viewport
  114. glViewport ( 0, 0, esContext->width, esContext->height );
  115. // Clear the color buffer
  116. glClear ( GL_COLOR_BUFFER_BIT );
  117. // Use the program object
  118. glUseProgram ( userData->programObject );
  119. // Load the vertex position
  120. glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] );
  121. glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
  122. GL_FALSE, (VERTEX_POS_SIZE + TEXCOORD_SIZE) * sizeof(GLfloat), 0 );
  123. // Load the texture coordinate
  124. glBindBuffer ( GL_ARRAY_BUFFER, userData->vboIds[0] );
  125. glVertexAttribPointer ( userData->texCoordLoc, 2, GL_FLOAT,
  126. GL_FALSE, (VERTEX_POS_SIZE + TEXCOORD_SIZE) * sizeof(GLfloat), (void*)(VERTEX_POS_SIZE * sizeof(GLfloat)));
  127. glEnableVertexAttribArray ( userData->positionLoc );
  128. glEnableVertexAttribArray ( userData->texCoordLoc );
  129. // Bind the texture
  130. glActiveTexture ( GL_TEXTURE0 );
  131. glBindTexture ( GL_TEXTURE_2D, userData->textureId );
  132. // Set the sampler texture unit to 0
  133. glUniform1i ( userData->samplerLoc, 0 );
  134. glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, userData->vboIds[1] );
  135. glDrawElements ( GL_TRIANGLES, INDICES_SIZE, GL_UNSIGNED_SHORT, 0);
  136. eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
  137. glDisableVertexAttribArray ( userData->positionLoc );
  138. glDisableVertexAttribArray ( userData->texCoordLoc );
  139. glBindBuffer ( GL_ARRAY_BUFFER, 0 );
  140. glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 );
  141. }
  142. ///
  143. // Cleanup
  144. //
  145. void ShutDown ( ESContext *esContext )
  146. {
  147. UserData *userData = (UserData *)esContext->userData;
  148. <span style="white-space:pre"> // Delete Buffers
  149. glDeleteBuffers ( 2, userData->vboIds );</span>
  150. // Delete texture object
  151. glDeleteTextures ( 1, &userData->textureId );
  152. // Delete program object
  153. glDeleteProgram ( userData->programObject );
  154. }
  155. int main ( int argc, char *argv[] )
  156. {
  157. ESContext esContext;
  158. UserData userData;
  159. esInitContext ( &esContext );
  160. esContext.userData = &userData;
  161. esCreateWindow ( &esContext, "Simple VBO Texture 2D", 512, 512, ES_WINDOW_RGB );
  162. if ( !Init ( &esContext ) )
  163. return 0;
  164. esRegisterDrawFunc ( &esContext, Draw );
  165. esMainLoop ( &esContext );
  166. ShutDown ( &esContext );
  167. }





文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/52425155

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。