笔记:OpenGL SuperBible - Shaders

OpenGL shaders are written in a language called the OpenGL Shading Language, orGLSL

The compiler for this language is built into OpenGL. The sourcecode for your shader is placed into ashader object and compiled, and then multiple shader objects can be linked together to form aprogram object.

Each program object can contain shaders for one or moreshader stages.The shader stages of OpenGL are vertex shaders, tessellation control andevaluation shaders, geometry shaders, fragment shaders, and compute shaders. 

The minimal useful pipeline configuration consists only of a vertex shader, but if you wish to see any pixels on the screen, you will also need a fragment shader. 


Vertex Shader:

#version 430 core
void main(void)
{
gl_Position = vec4(0.0, 0.0, 0.5, 1.0);
}
注解:

1、#version430 coredeclaration, tells the shader complier that we use version 4.3 of shading language.

The keyword core indicates that we only intend to use features from thecore profile of OpenGL. 

2、Declaration of main fund: where the shader starts executing.

3、gl_Positionrepresents the output position of the vertex in the Vertex Shader.

All variables that start withgl_are part of OpenGL and connect shaders to each otheror to the various parts of fixed functionality in OpenGL. 

gl_Position = vec4(0.0, 0.0, 0.5, 1.0)places the vertex in the middle of OpenGL'sclip space.


Fragment Shader:

#version 410 core
out vec4 color;
void main(void) {
color = vec4(0.0, 0.8, 1.0, 1.0); }
注解:

1、out vec4color;  declares colour as an output var using the out keyword.

In fragmentshaders, the value of output variables will be sent to the window or screen.In themain function, it assigns a constant to this output. 

By default, thatvalue goes directly onto the screen.


Now, compile the 2 shaders together into a program:
GLuint compile_shaders(void)
{
    GLuint vertex_shader;
    GLuint fragment_shader;
    GLuint program;
    // Source code for vertex shader
    static const GLchar * vertex_shader_source[] = {
        "#version 430 core \n"
        " \n"
        "void main(void) \n"
        "{ \n"
        "    gl_Position = vec4(0.0, 0.0, 0.5, 1.0);        \n"
        "} \n"
    };
    // Source code for fragment shader
    static const GLchar * fragment_shader_source[] = {
        "#version 430 core \n"
        " \n"
        "out vec4 color; \n"
        " \n"
        "void main(void) \n"
        "{ \n"
        "    color = vec4(0.0, 0.8, 1.0, 1.0);              \n"
        "} \n"
    };
    // Create and compile vertex shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertex_shader, 1, vertex_shader_source, NULL); glCompileShader(vertex_shader);
    // Create and compile fragment shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragment_shader, 1, fragment_shader_source, NULL); glCompileShader(fragment_shader);
    // Create program, attach shaders to it, and link it
    program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);
    // Delete the shaders as the program has them now
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);
    return program;
}
注解:

  • glCreateShader()creates an empty shader object, ready to acceptsource code and be compiled.
  • glShaderSource()hands shader source code to the shader object sothat it can keep a copy of it.
  • glCompileShader()compiles whatever source code is contained inthe shader object.
  • glCreateProgram()creates a program object to which you can attachshader objects.
  • glAttachShader()attaches a shader object to a program object.
  • glLinkProgram()links all of the shader objects attached to a programobject together. 
  • glDeleteShader()deletes a shader object. Once a shader has beenlinked into a program object, the program contains the binary codeand the shader is no longer needed. 

The shader code is included in the program as constant strings that are passed to glShaderSource(), which copies them into the shader objects created by glCreateShader()The shader object stores a copy of our source code, andthen when we call glCompileShader(), it compiles the GLSL shader sourcecode into an intermediate binary representation, which is also stored inthe shader object. The program object represents the linked executablethat we will use for rendering. We attach our shaders to the programobject usingglAttachShader() and then callglLinkProgram(), which linksthe objects together into code that can be run on the graphics processor. Thecompile_shaders function returns the newly created program object. 

When we call this function, we need to keep the returned program objectsomewhere so that we can use it to draw things. Also, we really don’t wantto recompile the whole program every time we want to use it. So, we needa function that is called once when the program starts up. Thesb6application framework provides just such a function:application::startup(), which we can override in our sampleapplication and perform any one-time setup work. 

One final thing that we need to do before we can draw anything is tocreate avertex array object (VAO), which is an object that represents thevertex fetch stage of the OpenGL pipeline and is used to supply input tothe vertex shader. As our vertex shader doesn’t have any inputs right now,we don’t need to do much with the VAO. Nevertheless, we still need tocreate the VAO so that OpenGL will let us draw. To create the VAO, we callthe OpenGL functionglGenVertexArrays(), and to attach it to ourcontext, we callglBindVertexArray(). Their prototypes are

void glGenVertexArrays(GLsizei n,
GLuint * arrays);
void glBindVertexArray(GLuint array); 

The vertex array object maintains all of the state related to the input tothe OpenGL pipeline. 

Add them to startup() function:

class my_application : public sb6::application {
public:
// <snip>
void startup()
{
rendering_program = compile_shaders(); glGenVertexArrays(1, &vertex_array_object); glBindVertexArray(vertex_array_object);
}
void shutdown()
{
glDeleteVertexArrays(1, &vertex_array_object); glDeleteProgram(rendering_program); glDeleteVertexArrays(1, &vertex_array_object);
}
private:
GLuint rendering_program; GLuint vertex_array_object;
};

From startup(), we callcompile_shadersand store theresulting program object in the rendering_programmember variable inour class.  

shutdown() delete the program object ( shader objects, program objects, vertex array object ) that we created at start-up. 


Now that we have a program, we need to execute the shaders in it and actually get todrawing something on the screen.  

// Our rendering function
void render(double currentTime) {
const GLfloat color[] = { (float)sin(currentTime) * 0.5f + 0.5f, (float)cos(currentTime) * 0.5f + 0.5f,
                                          0.0f, 1.0f };
                glClearBufferfv(GL_COLOR, 0, color);
                // Use the program object we created earlier for rendering
                glUseProgram(rendering_program);
                // Draw one point
                glDrawArrays(GL_POINTS, 0, 1);
            }

glUseProgram() tell OpenGL to use our program object for rendering 

glDrawArrays():(drawing command) sends vertices into the OpenGL pipeline.  原型:

void glDrawArrays(GLenum mode, GLint first,
                              GLsizei count);

mode tells OpenGLwhat type of graphics primitive we want to render. 

count the number of vertices to render. 


In order to make our point a little more visible, we can ask OpenGL todraw it a little larger than a single pixel. To do this, we’ll call theglPointSize()function, whose prototype is 

void glPointSize(GLfloat size);

This function sets the diameter of the point in pixels to the value you specify insize.  


REFERENCE: Ch 1, Using Shaders, OpenGL SuperBible 6th




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值