计算机图形学第三章习题可编程管线实现

   买了人民邮电计算机图形学实用教程,但是一直懒得看,现在决定利用CSDN博客平台来督促自己。

   上网搜了下,大多数人都是用老式的固定管线,没看到有谁用现代OpenGL,看了算法实现,尝试改成着色器的,结果发现很多博客里面算法实现貌似有问题,还是自己看教材吧,教材上的算法写得很清楚了,一步一步实现即可。

   刚买到苏小红教授主编的这本图形学实用教程的时候,看到SetPixel函数我就晕菜了,搞坨不清是咋回事,后来才知道SetPixel是windows下的函数,看了其他人博客里面用固定管线实现其实很简单,就是调用glBegin(GL_POINTS);  glVertex2i(x,y)。

改成着色器很简单,代码是我学习learnopengl的时候拿自己整的工程改的。DDA法和中点画线法.

DDA数值微分画线算法:

教材里面的算法x的增量是1,但是OpenGL里面标准化设备坐标是一个x、y和z值在-1.0到1.0的一小段空间,所以我把增量改成0.1,还可以更小。

运行结果:

void bges::CGfxRenderDDADrawLine::startUp()

{

    vertexArrayID = 0;

    glGenVertexArrays(1, &vertexArrayID);

    glBindVertexArray(vertexArrayID);

    // Create and compile our GLSL program from the shaders

    Shader shader;

 programID =shader.LoadShaders("/home/study/learnopengl/MyProject/shaderFile/SimpleVertexShader.vertexshader","/home/study/learnopengl/MyProject/shaderFile/SimpleFragmentShader.fragmentshader" );

    static GLfloat lineVertex_Buffer_Data[292] = {0.0};

    //{0.00000,1.000000,0.250000,0.500000};

    this->length = GetLineDDAData(-1.0,0.0,0.45,0.41,lineVertex_Buffer_Data);

    static GLfloat lineVertexX[13] = {0.0};

    static GLfloat lineVertexY[13] = {0.0};

    vertexbuffer = 0;

    glGenBuffers(1, &vertexbuffer);

    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    glBufferData(GL_ARRAY_BUFFER, sizeof(lineVertex_Buffer_Data),

     lineVertex_Buffer_Data, GL_STATIC_DRAW);

    // 1rst attribute buffer : vertices

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,0,(void*)0);

}

int bges::CGfxRenderDDADrawLine::GetLineDDAData(float x1,float y1,float x2,float y2, GLfloat vertex_buffer_data[])

{

    int length = 0,k = 0;

    float x = x1;

float y = y1;

    float dx = abs(x2 - x1);

    float dy = abs(y2 - y1);

    float m = dy / dx;

length = dx - dy >= 0 ? dx : dy;

int yinit = length / 0.01;

    vertex_buffer_data[ k ] = x;

    vertex_buffer_data[ k + yinit ] = y;

    //printf("%f,%f\n",x,y);

    //vertex_buffer_data[ k + 2 ] = 0.0f;

    k = 1;

    for(int i = 1;i < yinit;i++){

        if(dx - dy > 0 && x1 - x2 < 0.0){

            x += 0.1;

            y += m;

            vertex_buffer_data[ k ] = x;

     vertex_buffer_data[ k + yinit ] = y;

     //vertex_buffer_data[ k + 2 ] = 0.0f;

            printf("%f,%f\n",x,y);

            k++;

        }

    }

    return length / 0.1;

}

渲染也很简单

void bges::CGfxRenderDDADrawLine::Render(double currentTime)

{

    glClear( GL_COLOR_BUFFER_BIT );

    // Use our shader

    glUseProgram(programID);

    glBindVertexArray(vertexArrayID);

    glDrawArrays(GL_LINE_STRIP, 0, 4);

    //glDisableVertexAttribArray(0);

    // Swap buffers

    glfwSwapBuffers(window);

    glfwPollEvents();

}

顶点着色器

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;

void main(){

    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;

}

片元着色器

#version 330 core

// Ouput data
out vec3 color;

void main()
{

    // Output color = red
    color = vec3(1,0,0);

}

中点画线法:

void bges::CGfxRenderDDADrawLine::GetLineDatMLDAData(float x1,float y1,float x2,float y2, GLfloat lineVertexX[],GLfloat lineVertexY[])

{

    float a = y1 - y2;

    float b = x2 - x1;

    float d = 2 * a + b;

    float deta1 = 2 * a;

    float deta2 = 2 * (a + b);

    float x = x1,y = y1;

    lineVertexX[ 0 ] = x;

    lineVertexY[ 0 ] = y;

    int i = 1;

    for(;;)

    {

        if(x - x2 < 0.000001){

            if(d - 0.0000001 < 0){

                x = x + 0.1;

                y = y + 0.1;

                d = d + deta2;

            }

            else {

                x = x + 0.1;

                d = d + deta1;

            }

            lineVertexX[ i ] = x;

            lineVertexY[ i ] = y;

            printf("%f,%f\n",x,y);

            i++;

        }

        else{

            return;

        }

    }

}

中点画线法运行结果:

猜你喜欢

转载自blog.csdn.net/tankweight/article/details/82958145