• OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用_棋盘纹理贴图


    读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了

    代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退出也会First-chance exception 

    glTexParameterf写错成glTextureParameteri

    随手来个链接https://www.opengl.org/sdk/docs/man/html/glTexParameter.xhtml

    //
    // 绘制一个旋转的OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用
    // 使用空闲回调函数增加旋转的角度
    //  立方体的旋转角度被发送到用于实现立方体旋转的顶点着色器中
    
    #include "Angel.h"
    #pragma comment(lib, "glew32.lib")
    
    typedef Angel::vec4  color4;
    typedef Angel::vec4  point4;
    
    
    
    const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)
    
    point4 points[NumVertices];
    vec3 normals[NumVertices];//法向量标记
    
    // Vertices of a unit cube centered at origin, sides aligned with axes
    point4 vertices[8] = {
        point4(-0.5, -0.5, 0.5, 1.0),
        point4(-0.5, 0.5, 0.5, 1.0),
        point4(0.5, 0.5, 0.5, 1.0),
        point4(0.5, -0.5, 0.5, 1.0),
        point4(-0.5, -0.5, -0.5, 1.0),
        point4(-0.5, 0.5, -0.5, 1.0),
        point4(0.5, 0.5, -0.5, 1.0),
        point4(0.5, -0.5, -0.5, 1.0)
    };
     
    
    
    
    const int texturesize = 64; //新增或有更改
    GLuint textureloc;//新增或有更改
    GLubyte imageRBG[texturesize][texturesize][3];//新增或有更改
    vec2 tex_coords[NumVertices];//新增或有更改
    
    void imageinit()//新增或有更改
    {
        for (int i = 0; i < 64; i++)
        {
            for (int j = 0; j < 64; j++)
            {
                GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0) )*255;
                imageRBG[i][j][0] = imageRBG[i][j][1] = imageRBG[i][j][2] = c;
            }
        }
        glGenTextures(1, &textureloc);//产生一个纹理对象标志符并存在地址textureloc中
    
        glBindTexture(GL_TEXTURE_2D, textureloc);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturesize, texturesize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageRBG);
        //target90FL_TEXTURE_[1,2,3]D或者GL_TEXTURE_CUBE_MAP;level,iformat,width,height,border,format,type,&textureeloc;
        
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//写错成glTextureParameteri
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, textureloc);
    
    }//新增或有更改
    
    
    
    
    
    
    
    
    
    
    
    // Array of rotation angles (in degrees) for each coordinate axis
    //enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
    //enum { Xdist = 0, Ydist = 1, Zdist = 2, NumAxes1 = 3 };
    color4 gr = color4(1.0, 1.0, 1.0, 1.0); 
    color4 onecolor = color4(1.0, 0.0, 0.0, 1.0);
    color4 light_ex;
    int      Axi = 0;//Xaxis;
    GLfloat  Thet[3] = { 0.0, 0.0, 0.0 };
    //GLfloat  Atha[3] = { 0.0, 0.0, 0.0 };
    GLfloat Disx = 0;
    GLfloat Dis = 0;
    GLfloat fd = 1;
    
    GLuint  thet;  // The location of the "theta" shader uniform variable
    GLuint atha;
    GLuint direct;
    GLuint f;
    GLuint vam;
    //----------------------------------------------------------------------------
    
    // quad generates two triangles for each face and assigns colors
    //    to the vertices
    int Index = 0;
    void
    quad(int a, int b, int c, int d)
    {
        vec4 u = vertices[b] - vertices[a];
        vec4 v = vertices[c] - vertices[b];
        vec3 normal = normalize(cross(u, v));//normalize叉乘得到法向量
        normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;////新增或有更改
        normals[Index] = normal; points[Index] = vertices[b]; tex_coords[Index] = vec2(0.0, 1.0); Index++;////新增或有更改
        normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;////新增或有更改
        normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;////新增或有更改
        normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;////新增或有更改
        normals[Index] = normal; points[Index] = vertices[d]; tex_coords[Index] = vec2(1.0, 0.0); Index++;////新增或有更改
    }
    
    //----------------------------------------------------------------------------
    
    // generate 12 triangles: 36 vertices and 36 colors
    void
    colorcube()
    {
        quad(1, 0, 3, 2);
        quad(2, 3, 7, 6);
        quad(3, 0, 4, 7);
        quad(6, 5, 1, 2);
        quad(4, 5, 6, 7);
        quad(5, 4, 0, 1);
    }
    
    //----------------------------------------------------------------------------
    
    // OpenGL initialization
    void
    init()
    {
        colorcube();//新增或有更改
        imageinit();//新增或有更改
    
        // Create a vertex array object
        GLuint vao;
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);
    
        // Create and initialize a buffer object
        GLuint buffer;
        glGenBuffers(1, &buffer);
    
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals) + sizeof(tex_coords), NULL, GL_STATIC_DRAW);//
    
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
        glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(normals), normals);
        glBufferSubData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals), sizeof(tex_coords), tex_coords);//新增或有更改
    
        // Load shaders and use the resulting shader program
        GLuint program = InitShader("vshader.glsl", "fshader.glsl");
        glUseProgram(program);
    
        // set up vertex arrays
        GLuint vPosition = glGetAttribLocation(program, "vPosition");
        glEnableVertexAttribArray(vPosition);
        glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0,BUFFER_OFFSET(0));
    
        GLuint vNormal = glGetAttribLocation(program, "vNormal");
        glEnableVertexAttribArray(vNormal);
        glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));
    
    
        GLuint vTexCoord = glGetAttribLocation(program, "vtexCoord");////新增或有更改
        glEnableVertexAttribArray(vTexCoord);////新增或有更改
        glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points) + sizeof(normals)));////新增或有更改
    
        //初始化光照参数la,ld,ls环境,漫反射,镜面反射
        point4 light_position(0.0, 0.0, 2.0,-0.0);
        //color4 light_ambient(1.0,0.0,0.0,1.0);//R红_G绿_B蓝
        color4 light_diffuse(1.0, 1.0, 1.0, 1.0);
        color4 light_specular(1.0, 1.0, 1.0, 1.0);
    
        
        color4 material_ambient(1.0, 0.0, 1.0, 1.0);
        color4 material_diffuse(1.0, 0.8, 0.0, 1.0);
        color4 material_specular(1.0, 0.8, 0.0, 1.0);
        float material_shininess = 20.0;//高光系数 高金属 低塑料
        
        light_ex = material_ambient;
        //color4 ambient_product = light_ambient*material_ambient;
        color4 diffuse_product = light_diffuse*material_diffuse;
        color4 specular_product = light_specular*material_specular;
    
        glUniform4fv(glGetUniformLocation(program, "DiffuseProduct"), 1, diffuse_product);
        glUniform4fv(glGetUniformLocation(program, "SpecularProduct"), 1, specular_product);
        glUniform4fv(glGetUniformLocation(program, "LightPosition"), 1, light_position);
        glUniform1f(glGetUniformLocation(program,"Shininess"),material_shininess);
    
        vam = glGetUniformLocation(program, "AmbientProduct");
        thet = glGetUniformLocation(program, "theta");
        atha = glGetUniformLocation(program, "athat");
        direct = glGetUniformLocation(program, "direct");
        f = glGetUniformLocation(program, "ff");
    
    
        
        glUniform1i(glGetUniformLocation(program, "texture"), 1);//新增或有更改
        //texture在vshader里面,后面的1对应glActiveTexture(GL_TEXTURE1);
        //如果0,那么对应glActiveTexture(GL_TEXTURE0);
        //如果3,那么对应glActiveTexture(GL_TEXTURE3);
    
    
    
        glEnable(GL_DEPTH_TEST);///开启深度缓存测试
        glEnable(GL_CULL_FACE);///启动多边形剔除功能
        
        //glOrtho(1.0, 0.0, 0.0, 1.0, 0.0, 1.0);
    
    }
    
    //----------------------------------------------------------------------------
    
    void
    display(void)
    {
    
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        //glMatrixMode(GL_PROJECTION);
        //glMatrixMode(GL_MODELVIEW);
        //glLoadIdentity(); 
        //gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0);
        glUniform4fv(vam, 1, light_ex*onecolor);
        glUniform3fv(thet, 1, Thet);
        glUniform1f(atha, Disx);
        glUniform1f(direct, Dis);//传递单个的 
        glUniform1f(f, fd);  
        glDrawArrays(GL_TRIANGLES, 0, NumVertices);
        glClearColor(gr[0], gr[1], gr[2], gr[3]);
        glFlush(); 
    }
    
    
    void ProcessMenu(int value)
    {
        if (value == 0)
            exit(0);
    
        if (value == 100)
        {
            gr = vec4(1.0f, 1.0f, 1.0f, 1.0f);
            onecolor = vec4(1.0, 0.0, 1.0, 1.0);
        }
        else{
    
            switch (value)
            {
            case 21:gr = vec4(0.75f, 0.0f, 1.0f, 1.0f); break;
            case 22:gr = vec4(0.75f, 0.75f, 1.0f, 1.0f); break;
            case 23:gr = vec4(1.75f, 1.75f, 0.75f, 1.0f); break;
            case 24:gr = vec4(1.75f, 1.0f, 1.55f, 1.0f); break;
            case 25:gr = vec4(0.0f, 1.0f, 0.75f, 0.0f); break;
            case 1:onecolor = color4(0.0, 0.0, 0.0, 1.0); break;//黑色
            case 2:onecolor = color4(0.0, 0.0, 1.0, 1.0); break;//蓝色
            case 3:onecolor = color4(1.0, 0.0, 1.0, 1.0); break;//品红色
            case 4:onecolor = color4(0.0, 1.0, 1.0, 1.0); break;//青色
            }
        }
        glutSwapBuffers();
        glutPostRedisplay();
    }
    
    //----------------------------------------------------------------------------
    
    void
    keyboard(unsigned char key, int x, int y)
    { 
        switch (key) {
        case 'x':    Axi = 0; break; //Xaxis;  break;
        case 'y':    Axi = 1; break;//Yaxis;  break;
        case 'z':    Axi = 2; break;//Zaxis;  break;选择对应的x,y,z旋转角度来变化
        case 'f':fd += 0.1; break;//Xdist; break;
        case 's':fd -= 0.1; break;//Ydist; break;
        case 033: // Escape Key
        case 'q': case 'Q':
            exit(EXIT_SUCCESS);
            break;
        }
        if (fd == 0)fd = 0.1;
    }
    void SpecialKeys(int key, int x, int y)
    { 
        switch (key) {
        case GLUT_KEY_UP:Dis += 0.01;  break;
        case GLUT_KEY_DOWN:Dis -= 0.01;  break;//Ydist; break;
        case GLUT_KEY_LEFT:Disx -= 0.01;   break; 
        case GLUT_KEY_RIGHT:Disx += 0.01;   break;//Xdist; break;
        case 033: // Escape Key
        case 'q': case 'Q':
            exit(EXIT_SUCCESS);
            break;
        }
    }
    
    //----------------------------------------------------------------------------
    
    
    //----------------------------------------------------------------------------
    
    void
    idle(void)
    {
        Thet[Axi] += 0.01;
    
        if (Thet[Axi] > 360.0) {
            Thet[Axi] -= 360.0;
        }
        glutSwapBuffers();
        glutPostRedisplay();
    }
    
    
    
    
    //----------------------------------------------------------------------------
    
    int
    main(int argc, char **argv)
    {
         
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
        glutInitWindowSize(512, 512);
        glutInitContextVersion(3, 1);
        //这里在舍友的电脑上用3,2可以用,在我的电脑上会出现
        //freeglut(dll地址):unableto create OpenGL3.2 context(flags 0, profile 1)
        //我改成3,1就可以了。不知道会不会是版本问题。这里用的是比较旧的版本freeglut。
    
        glutInitContextProfile(GLUT_CORE_PROFILE);
        glutCreateWindow("Color Cube");
    
        glewExperimental = true;
        glewInit(); 
        int nGlutColorMenu1 = glutCreateMenu(ProcessMenu);
        glutAddMenuEntry("black", 1);
        glutAddMenuEntry("blue", 2);
        glutAddMenuEntry("magenta", 3);
        glutAddMenuEntry("cyan", 4);
    
        int nGlutColorMenu2 = glutCreateMenu(ProcessMenu);
        glutAddMenuEntry("background1", 21);
        glutAddMenuEntry("background2", 22);
        glutAddMenuEntry("background3", 23);
        glutAddMenuEntry("background4", 24);
        glutAddMenuEntry("background5", 25);
    
        int nGlutColorMenu3 = glutCreateMenu(ProcessMenu);
        glutAddMenuEntry("return", 100);
    
        int nGlutColorMenu = glutCreateMenu(ProcessMenu);
        glutAddSubMenu("coclor", nGlutColorMenu1);
        glutAddSubMenu("background", nGlutColorMenu2);
        glutAddSubMenu("return", nGlutColorMenu3);
        glutAttachMenu(GLUT_RIGHT_BUTTON);
        init();
        glutDisplayFunc(display);
        glutSpecialFunc(SpecialKeys);
        glutKeyboardFunc(keyboard);
        //glutMouseFunc(mouse);
        glutIdleFunc(idle);
         
    
        glutMainLoop();
        return 0;
    }

    vshader.glsl

    #version 150
    
    in vec2 vtexCoord;////新增或有更改
    in  vec4 vPosition;
    in vec3 vNormal;
    
    out vec2 texCoord;////新增或有更改
    out vec4 color;
    
    
    uniform vec4 AmbientProduct,DiffuseProduct,SpecularProduct;
    uniform vec4 LightPosition;
    uniform float Shininess;
    uniform vec3 theta;
    uniform float athat;
    uniform float direct;
    uniform float ff;
    void main() 
    { 
       texCoord=vtexCoord;////新增或有更改
        vec3 angles = radians( theta );
        vec3 c = cos( angles );
        vec3 s = sin( angles );
    
         mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
                0.0,  c.x,  s.x, 0.0,
                0.0, -s.x,  c.x, 0.0,
                0.0,  0.0,  0.0, 1.0 );
    
        mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
                0.0, 1.0,  0.0, 0.0,
                s.y, 0.0,  c.y, 0.0,
                0.0, 0.0,  0.0, 1.0 );
    
        // Workaround for bug in ATI driver
        ry[1][0] = 0.0;
        ry[1][1] = 1.0;
    
        mat4 rz = mat4( c.z, s.z, 0.0, 0.0,
                -s.z,  c.z, 0.0, 0.0,
                0.0,  0.0, 1.0, 0.0,
                0.0,  0.0, 0.0, 1.0 );
    
        // Workaround for bug in ATI driver
        rz[2][2] = 1.0;
        
        //color = vColor; 
        mat4 t=mat4(1.0,0.0,0.0,0.0,
        0.0,1.0,0.0,0.0,
        0.0,0.0,1.0,0.0,
        athat,direct,0.0,1.0); 
           
        mat4 sf=mat4(ff,0.0,0,0,
        0.0,ff,0.0,0.0,
        0.0,0.0,ff,0.0,
        0.0,0.0,0.0,1.0); 
        mat4 modeview=t*rx*rz*ry;
        vec3 pos=(modeview*vPosition).xyz;
    
        vec3 L=normalize(LightPosition.xyz-pos);
        vec3 E=normalize(-pos);
        vec3 H=normalize(L+E);
    
        vec3 N=normalize(modeview*vec4(vNormal,0.0)).xyz;
    
        
        vec4 ambient=AmbientProduct;
                                
        float Kd=max(dot(L,N),0.0);
        vec4 diffuse=Kd*DiffuseProduct;
           float Ks=pow(max(dot(N,H),0.0),Shininess);
           vec4 specular=Ks*SpecularProduct;
        if(dot(L,N)<0.0)
    
         specular=vec4(0.0,0.0,0.0,1.0);
        gl_Position =modeview*sf*vPosition;
        color=ambient+diffuse+specular;
        color.a=1.0;
    } 

    fshader.glsl

    #version 150
    in vec2 texCoord;////新增或有更改
    in  vec4 color;
    out vec4 fColor;
    
    uniform sampler2D texture;////新增或有更改
    void main() 
    { 
    
        fColor = color*texture2D(texture,texCoord);////新增或有更改
    } 

    InitShader.cpp 

    #include "Angel.h"
    
    namespace Angel {
    
    // Create a NULL-terminated string by reading the provided file
    static char*
    readShaderSource(const char* shaderFile)
    {
        //FILE* fp = fopen(shaderFile, "r");
        //由于vs甚么安全性的原因,不让使用fopen,用下面的fopen_s代替;
        FILE *fp;
        fopen_s(&fp, shaderFile, "r");
    
    
        if ( fp == NULL ) { return NULL; }
    
        fseek(fp, 0L, SEEK_END);
        long size = ftell(fp);
    
        fseek(fp, 0L, SEEK_SET);
        char* buf = new char[size + 1];
        fread(buf, 1, size, fp);
    
        buf[size] = '';
        fclose(fp);
    
        return buf;
    }
    
    
    // Create a GLSL program object from vertex and fragment shader files
    GLuint
    InitShader(const char* vShaderFile, const char* fShaderFile)
    {
        struct Shader {
        const char*  filename;
        GLenum       type;
        GLchar*      source;
        }  shaders[2] = {
        { vShaderFile, GL_VERTEX_SHADER, NULL },
        { fShaderFile, GL_FRAGMENT_SHADER, NULL }
        };
    
        GLuint program = glCreateProgram();
        
        for ( int i = 0; i < 2; ++i ) {
        Shader& s = shaders[i];
        s.source = readShaderSource( s.filename );
        if ( shaders[i].source == NULL ) {
            std::cerr << "Failed to read " << s.filename << std::endl;
            exit( EXIT_FAILURE );
        }
    
        GLuint shader = glCreateShader( s.type );
        glShaderSource( shader, 1, (const GLchar**) &s.source, NULL );
        glCompileShader( shader );
    
        GLint  compiled;
        glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
        if ( !compiled ) {
            std::cerr << s.filename << " failed to compile:" << std::endl;
            GLint  logSize;
            glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logSize );
            char* logMsg = new char[logSize];
            glGetShaderInfoLog( shader, logSize, NULL, logMsg );
            std::cerr << logMsg << std::endl;
            delete [] logMsg;
    
            exit( EXIT_FAILURE );
        }
    
        delete [] s.source;
    
        glAttachShader( program, shader );
        }
    
        /* link  and error check */
        glLinkProgram(program);
    
        GLint  linked;
        glGetProgramiv( program, GL_LINK_STATUS, &linked );
        if ( !linked ) {
        std::cerr << "Shader program failed to link" << std::endl;
        GLint  logSize;
        glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logSize);
        char* logMsg = new char[logSize];
        glGetProgramInfoLog( program, logSize, NULL, logMsg );
        std::cerr << logMsg << std::endl;
        delete [] logMsg;
    
        exit( EXIT_FAILURE );
        }
    
        /* use program object */
        glUseProgram(program);
    
        return program;
    }
    
    }  // Close namespace Angel block

     
  • 相关阅读:
    RUNOOB.COM-python网络编程-(python3.5.0)
    windows查看服务
    计算机网络里的一些理解
    如果面试有傻逼问道oracle怎么启动的
    推荐一个学习数据库的地方
    电脑中的驱动程序是什么,是干什么的
    Raspberry Pi 4B 之 Python开发
    Ubuntu20.04+EdgexFoundry边缘计算微服务搭建-----遇到的问题-----make build 被墙问题
    Raspberry Pi 4B + Ubuntu 20.04 server for arm64 的wifi配置
    关于PicoNeo开发环境的Unity3D+AndroidSDK配置
  • 原文地址:https://www.cnblogs.com/xujiayu/p/5519879.html
Copyright © 2020-2023  润新知