OpenGL ES2.0 Programming Guide - chapter 2:Hello Triangle: An OpenGL ES2.0 example

Chapter 2:Hello Triangle: An OpenGL ES2.0 example

This chapter goes over the basics of the required steps how to drawn a triangle to commonly demonstrate the necessary steps.

Hello Triangle Example

Remember though, OpenGL ES 2.0 is fully shader based, which means you can’t draw any geometry without having the appropriate shaders loaded and bound.
Below shows the main steps about how to drawn a triangle.

declare an ESContext and initialize it.

ESContext esContext; 
UserData userData;
esInitialize(&esContext); 
esContext.userData = &userData;

The ESContext is passed into all of the ES framework utility functions and contains all of the necessary information about the program that the ES framework needs.

The reason for passing around a context is that the sample programs and the ES code framework do not need to use any global data.

The ESContext has a member variable named userData that is a void*. Each of the sample programs will store any of the data that are needed for the application in userData.

The other elements in the ESContext structure are intended only to be read by the user application. Other data in the ESContext structure include information such as the window width and height, EGL context, and callback function pointers.

create the window

esCreateWindow(&esContext, "Hello Triangle", 320, 240, ES_WINDOW_RGB);

esCreateWindow funciton use EGL to create an on-screen render surface that is attached to a window.

initialize everything needed to run the program.

if(!Init(&esContext)) {
    return 0;
}

Init function do the following works:

  • load and compile vertex & fragment shader
GLbyte vShaderStr[] =
"attribute vec4 vPosition; \n" 
"void main()               \n"
"{                         \n"
" gl_Position = vPosition; \n"
"};                        \n";

GLbyte fShaderStr[] =
"precision mediump float; \n" 
"void main()              \n" 
"{                        \n" 
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" 
"}                        \n";

...

GLuint shader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER); 

...

// Load the shader source 
glShaderSource(shader, 1, &vShaderStr, NULL);
glShaderSource(fragment, 1, &fShaderStr, NULL);

// Compile the shader 
glCompileShader(shader);
glCompileShader(fragment);

The gl_FragColor is a special built-in variable that contains the final output color for the fragment shader.
从代码可知:vPosition为attribute 0, fragment shader只是将颜色设置为 (1.0, 0.0, 0.0, 1.0)。

  • create program
GLuint programObject = glCreateProgram();
  • attach shader to program
glAttachShader(programObject, shader); 
glAttachShader(programObject, fragment);
  • bind vPosition to attribute 0
    glBindAttribLocation binds the vPosition attribute declared in the vertex shader to location 0
// Bind vPosition to attribute 0 
glBindAttribLocation(programObject, 0, "vPosition");
  • link the program
// Link the program 
glLinkProgram(programObject);
  • clear color buffer(与glClear的区别)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

register a callback function that will be called to render the frame.

esRegisterDrawFunc(&esContext, Draw);

After setting above, we can set drawing parameters.

  • set viewport
    glViewport informs OpenGL ES of the origin, width, and height of the 2D rendering surface that will be drawn to.
UserData *userData = esContext->userData; 
GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
                      -0.5f, -0.5f, 0.0f, 
                      0.5f, -0.5f, 0.0f};
// Set the viewport: left-top x, left-top y, width, height
glViewport(0, 0, esContext->width, esContext->height);
  • clear color buffer

In OpenGL ES, there are multiple types of buffers that are involved in drawing: color, depth, and stencil.
In the Hello Triangle example, only the color buffer is drawn to. At the beginning of each frame, we clear the color buffer using the glClear function.

// Clear the color buffer 
glClear(GL_COLOR_BUFFER_BIT);
  • use the program object
// Use the program object 
glUseProgram(programObject);
  • load the vertex data and draw
    The vertex positions need to be loaded to the GL and connected to the vPosition attribute declared in the vertex shader.
    As you will remember, earlier we bound the vPosition variable to attribute location 0.
// Load the vertex data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); glEnableVertexAttribArray(0);

glDrawArrays(GL_TRIANGLES, 0, 3);
  • swap buffer to smoothly draw primitives.
    Double buffering is adopted to avoid seeing artifacts as partial updates to the framebuffer where displayed.
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);

This function informs EGL to swap the front buffer and back buffer. The parameters sent to eglSwapBuffers are the EGL display and surface. These two parameters represent the physical display and the rendering surface, respectively.

enter into the main message processing loop until the window is closed

esMainLoop(&esContext);

难点

  • 理解attribute值设置的问题(vPosition的值如何设置),及attribute与location对应关系。
  • 理解glClear与glClearColor区别
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值