- OPENGL3

CP07:贴图

>>理解Element Buffer Object(EBO), 理解glDrawElements()

例如上图要绘制一个长方形,上一篇- OPENGL2 - 最后一章用的glDrawArrays(GL_QUADS,0 ,NPTS) 绘制。

此章绘制用glDrawElements().如上图,绘制可以为2个三角形,那就是绘制6个顶点。

// triangle indices
static GLuint indices[6] = {
    0, 1, 3,  // FIRST TRIANGLE
    1, 2, 3   // SECOND TRIANGLE
};

第一种方法:直接绘制方法就是在main loop中:

glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , indices);  // draw six verticles

第二种方法:

如果建立了EBO对象就不用这么绘制可以先创建 EBO:

glCreateBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glNamedBufferStorage(EBO, sizeof(indices), indices , 0);

然后在main loop中写:

 glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL);  // draw six verticles

显然第一种简单。

#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>


using namespace std;

const int NPTS = 4;
static GLuint VBO,VAO,EBO;

// load shader
static LoadShader shader;

// Texture
static GLuint  texture;



void init(){
    static const GLfloat verticles[NPTS][8] = {
        // positions          // colors           // texture coords
         {0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f},   // top right
         {0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f},   // bottom right
        {-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f},   // bottom left
        {-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f}    // top left
    };



    GLuint indices[6] = {
        0, 1, 3,  // FIRST TRIANGLE
        1, 2, 3   // SECOND TRIANGLE
    };



    shader.load("shader.vert","shader.frag");
    shader.use();

    // Vertex Array Object
    glCreateVertexArrays(1,&VAO);
    glBindVertexArray(VAO);

   // Vertex Buffer Object
    glCreateBuffers(1,&VBO);
    glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
    glBindBuffer(GL_ARRAY_BUFFER,VBO);

    // Create Element buffer object
    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);



    // position Attrib
    glVertexAttribPointer(0,                        // LOCATION
                          3,                        // vector is 3 length
                          GL_FLOAT,                 // float type
                          GL_FALSE,                 // not normalized
                          8 * sizeof(float),        // stride
                          (void*)0 );               // offset
    glEnableVertexAttribArray(0);

    // color Attrib
    glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(3* sizeof(float)) );
    glEnableVertexAttribArray(1);


    // st Attrib
    glVertexAttribPointer(2,2, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(6* sizeof(float)) );
    glEnableVertexAttribArray(2);

    //glGenTextures(1,&texture);
    glCreateTextures(GL_TEXTURE_2D, 1, &texture); // same as above method
    glBindTexture(GL_TEXTURE_2D, texture);

    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // same as above methods
    glTextureParameteri(texture, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTextureParameteri(texture, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTextureParameteri(texture, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTextureParameteri(texture, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


    // load imag
    int width,height,nchans;
    unsigned char *data = stbi_load("texture_02.jpg",&width, &height, &nchans, 0);
    cout << "WIDTH:" << width << "HEIGHT:" <<height <<endl;
    if(data){
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateTextureMipmap(texture);

    }
    else{
        cout << "Load texture error" <<endl;
    }
    stbi_image_free(data);


}

void display(){

    static const float black[] = {0.2f, 0.3f, 0.3f, 1.0f};
    glClearBufferfv(GL_COLOR,0,black);
    //glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    //glClear(GL_COLOR_BUFFER_BIT);


    //glBindTexture(GL_TEXTURE_2D, texture);
    glBindVertexArray(VAO);
    //glDrawArrays(GL_QUADS,0 ,NPTS);
    glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL);  // draw six verticles
}

int main()
{
    cout << sizeof(float) <<endl;
    glfwInit();
    GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
    glfwMakeContextCurrent(window);
    glewInit();

    init();


    while(!glfwWindowShouldClose(window)){
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}
main.cpp

>> 两个贴图时候的情况:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,texture2);
GLint texture1_location = glGetUniformLocation(shader.shaderProgram, "texture1");
GLint texture2_location = glGetUniformLocation(shader.shaderProgram, "texture2");
glUniform1i(texture1_location,0);
glUniform1i(texture2_location,1);

 mask.png:

 wendy.jpg:

 

OGL:

 

#version 450 core
layout ( location = 0 ) in vec4 vPosition; // c++ pos
layout ( location = 1 ) in vec4 vColor;  // c++ attribute color
layout ( location = 2 ) in vec2 vTexCoord; // c++ attribute st

//out vec4 ourColor; // OUT TO OUR ->fragment
//out vec2 ourTexCoord; // OUT TO OUR ->fragment
out block{
    vec4 ourColor;
    vec2 ourTexCoord;
};
void main(){
    gl_Position = vPosition;
    ourColor = vColor;
    ourTexCoord = vTexCoord;
}
shader.vert
#version 450 core
out vec4 fColor;  // out to our fragment shader color

//in vec4 ourColor; // from the vertex shader src
//in vec2 ourTexCoord;
in block{
    vec4 ourColor;
    vec2 ourTexCoord;
};
uniform sampler2D texture1;
uniform sampler2D texture2;  // Mask Texture

void main(){
    vec4 df = texture(texture1,ourTexCoord);
    vec4 mask = texture(texture2,ourTexCoord);

    fColor = mix( df , vec4(0,0.5,0.5,1),  mask.a );
}
shader.frag
#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>


using namespace std;

const int NPTS = 4;
static GLuint VBO,VAO,EBO;

// load shader
static LoadShader shader;

static GLuint texture1,texture2;
void processInput(GLFWwindow *window);

void init(){
    static const GLfloat verticles[NPTS][8] = {
        // positions          // colors           // texture coords
         {0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f},   // top right
         {0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f},   // bottom right
        {-0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f},   // bottom left
        {-0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f}    // top left
    };



    GLuint indices[6] = {
        0, 1, 3,  // FIRST TRIANGLE
        1, 2, 3   // SECOND TRIANGLE
    };



    shader.load("shader.vert","shader.frag");
    shader.use();

    // Vertex Array Object
    glCreateVertexArrays(1,&VAO);
    glBindVertexArray(VAO);

   // Vertex Buffer Object
    glCreateBuffers(1,&VBO);
    glNamedBufferStorage(VBO,sizeof(verticles),verticles, 0 );
    glBindBuffer(GL_ARRAY_BUFFER,VBO);

    // Create Element buffer object
    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);



    // position Attrib
    glVertexAttribPointer(0,                        // LOCATION
                          3,                        // vector is 3 length
                          GL_FLOAT,                 // float type
                          GL_FALSE,                 // not normalized
                          8 * sizeof(float),        // stride
                          (void*)0 );               // offset
    glEnableVertexAttribArray(0);

    // color Attrib
    glVertexAttribPointer(1,3, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(3* sizeof(float)) );
    glEnableVertexAttribArray(1);


    // st Attrib
    glVertexAttribPointer(2,2, GL_FLOAT,GL_FALSE,8 * sizeof(float), (void*)(6* sizeof(float)) );
    glEnableVertexAttribArray(2);


    // ------------------ LOADING TEXTURE1  ---------------------------------
    // Texture
    //glGenTextures(1,&texture);
    glCreateTextures(GL_TEXTURE_2D, 1, &texture1); // same as above method
    glBindTexture(GL_TEXTURE_2D, texture1);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    // same as above methods
    //glTextureParameteri(texture1, GL_TEXTURE_WRAP_S, GL_REPEAT);
    //glTextureParameteri(texture1, GL_TEXTURE_WRAP_T, GL_REPEAT);
    //glTextureParameteri(texture1, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //glTextureParameteri(texture1, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    stbi_set_flip_vertically_on_load(true);
    int width,height,nchans;
    unsigned char *data = stbi_load("wendy.jpg",&width, &height, &nchans, 0);
    cout << "Texture1 WIDTH:" << width << "HEIGHT:" <<height <<endl;
    if(data){
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width,height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateTextureMipmap(texture1);

    }
    else{
        cout << "Load texture1 error" <<endl;
    }
    stbi_image_free(data);


    // ------------------ LOADING TEXTURE2  ---------------------------------

    glCreateTextures(GL_TEXTURE_2D,1 , &texture2);
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTextureParameteri(texture2, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTextureParameteri(texture2, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTextureParameteri(texture2, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTextureParameteri(texture2, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    data = stbi_load("mask.png",&width, &height, &nchans, 0);
    cout << "Texture2 WIDTH:" << width << "HEIGHT:" <<height <<endl;
    if(data){
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width,height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateTextureMipmap(texture2);

    }
    else{
        cout << "Load texture2 error" <<endl;
    }

    shader.use();
    stbi_image_free(data); // free image2 mem

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,texture1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D,texture2);
    GLint texture1_location = glGetUniformLocation(shader.shaderProgram, "texture1");
    GLint texture2_location = glGetUniformLocation(shader.shaderProgram, "texture2");
    glUniform1i(texture1_location,0);
    glUniform1i(texture2_location,1);


    cout << "tex1 loc:" <<texture1_location <<endl;
    cout << "tex2 loc:" <<texture1_location <<endl;

}

void display(){

    static const float black[] = {0.2f, 0.3f, 0.3f, 1.0f};
    glClearBufferfv(GL_COLOR,0,black);
    //glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    //glClear(GL_COLOR_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D,texture1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D,texture2);
    shader.use();
    glBindVertexArray(VAO);
    //glDrawArrays(GL_QUADS,0 ,NPTS);
    glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL);  // draw six verticles
}

int main()
{
    cout << sizeof(float) <<endl;
    glfwInit();
    GLFWwindow *window =glfwCreateWindow(1280,720,"Triangles",NULL,NULL);
    glfwMakeContextCurrent(window);
    glewInit();

    init();


    while(!glfwWindowShouldClose(window)){
        display();
        processInput(window);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}
main.cpp

同样做个测试,如果给材质中作个

#version 450 core
out vec4 fColor;  // out to our fragment shader color

//in vec4 ourColor; // from the vertex shader src
//in vec2 ourTexCoord;
in block{
    vec4 ourColor;
    vec2 ourTexCoord;
};
uniform sampler2D texture1;
uniform sampler2D texture2;  // Mask Texture
uniform sampler2D texture3;  // Test


void main(){
    vec4 df = texture(texture1,ourTexCoord);
    vec4 mask = texture(texture2,ourTexCoord);
    vec4 test = texture(texture3,ourTexCoord);
    fColor = test;
}

源码中只读取了2个贴图,第一个是wendy.jpg,第二个是mask.png,可以看到 OPENGL是他妈的先读取的贴图就是是0,然后一次递增。

GLint texture1_location = glGetUniformLocation(shader.shaderProgram, "texture1");
GLint texture2_location = glGetUniformLocation(shader.shaderProgram, "texture2");
GLint texture3_location = glGetUniformLocation(shader.shaderProgram, "texture3");


glUniform1i(texture1_location,0);
glUniform1i(texture2_location,1);
glUniform1i(texture3_location,0);  // 0 is wendy.png , 1 is mask.png

 OPENGL右手坐标系!了解下

 

CP08:

GLM简单的测试:

#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>


#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
int main(){
    glm::vec4 vec(5.0f, 0.0f, 0.0f, 1.0f) ;
    glm::mat4 trans = glm::mat4(1.0f);
    trans= glm::translate(trans,glm::vec3(1.0f,2.0f,3.0f));
    vec = trans * vec;
    cout << vec.x << " " << vec.y << " " << vec.z <<endl;
    cout <<*glm::value_ptr(vec)<<  *(glm::value_ptr(vec)+1) << *(glm::value_ptr(vec) + 2)<< endl;

    glm::vec3 dir1(1.0f,0.0f,0.0f);
    glm::vec3 dir2(0.0f,0.0f,1.0f);
    float dot_result = glm::dot(dir1,dir2);
    cout << dot_result <<endl;


    glm::vec3 crs_result = glm::cross(dir2,dir1);
    cout << crs_result.x << " "<< crs_result.y <<" "<< crs_result.z << endl;

    glm::vec3 p1(1.0f);
    glm::vec3 p2(2.0f);
    float dot_result2 = glm::dot(p1,p2);
    cout << dot_result2 << endl;

    return 0;
}
GLM_TEST

GLM+OGL:

vert:

#version 450 core
layout ( location = 0 ) in vec4 vPosition; // c++ pos
layout ( location = 1 ) in vec2 vTexCoord; // c++ attribute st
out vec2 ourTexCoord; // OUT TO OUR ->fragment
uniform mat4 transform;
void main(){
    gl_Position = transform * vPosition;
    ourTexCoord = vTexCoord;
}

fs:

#version 450 core
out vec4 fColor;  // out to our fragment shader color
in vec2 ourTexCoord;

uniform sampler2D texture1;

void main(){
    vec4 df = texture(texture1,ourTexCoord);
    fColor = df;
}
View Code

 main.cpp

#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>


#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
const int  NPTS = 4;
static GLuint VAO,VBO,EBO;
static LoadShader shader;
void init();
void display();
void showFPS(GLFWwindow *);




void init(){
    GLfloat  verticels[NPTS][5] = {
        // positions          // texture coords
        {0.5f,  0.5f, 0.0f,    1.0f, 1.0f},   // top right
        {0.5f, -0.5f, 0.0f,    1.0f, 0.0f},   // bottom right
        {-0.5f, -0.5f, 0.0f,   0.0f, 0.0f},   // bottom left
        {-0.5f,  0.5f, 0.0f,   0.0f, 1.0f}    // top left
    };
    GLuint indices[6] = {
            0, 1, 3,  // FIRST TRIANGLE
            1, 2, 3   // SECOND TRIANGLE
        };
    shader.load("shader.vert","shader.frag");
    shader.use();

    glCreateVertexArrays(1, &VAO);
    glCreateBuffers(1, &VBO);
    glCreateBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0);
    glBufferData(GL_ARRAY_BUFFER,sizeof(verticels), verticels, GL_STATIC_DRAW);



    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);

    // VERTEX POINTS ATTRIBUTES
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),  (void*)0); // POS at location 0
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1
    glEnableVertexAttribArray(1);




    cout << "GEN Texture
";
    // loading one texture
    GLuint textureID;
    glCreateTextures(GL_TEXTURE_2D,1 , &textureID);
    glBindTexture(GL_TEXTURE_2D,textureID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    unsigned char *data = stbi_load("wendy.jpg", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    cout << "FREE IMAGE
";
    stbi_image_free(data);

}

void display(){
    glm::mat4 transform = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
    //transform = glm::translate(transform, glm::vec3(0.5f, -0.5f, 0.0f));
    transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
    GLuint transformlocation = glGetUniformLocation(shader.shaderProgram, "transform");

    glUniformMatrix4fv(transformlocation, 1, GL_FALSE, glm::value_ptr(transform));

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    shader.use();
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL);  // draw six verticles
}


int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(1280,720,"HelloWorld",NULL,NULL);
    glfwMakeContextCurrent(window);
    glewInit();
    init();
    while(!glfwWindowShouldClose(window)){
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}
View Code

CP09:

 一些重要的空间概念在这篇文章里。

对于GLM 传递到uniform的矩阵作者做了3种形式,实际上是一样的:

// create transformations
glm::mat4 model         = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
glm::mat4 view          = glm::mat4(1.0f);
glm::mat4 projection    = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
view  = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
        // retrieve the matrix uniform locations
unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model");
unsigned int viewLoc  = glGetUniformLocation(ourShader.ID, "view");
        // pass them to the shaders (3 different ways)
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
        // note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once.
ourShader.setMat4("projection", projection);

1,实现Projection * View * Model * verticlesP 

2,尝试 实现用键盘控制 W A S D

键盘控制就是使用glfw

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
    {
        offset_w_s += 0.02f;
    }
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
    {
        offset_w_s -= 0.02f;
    }
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
    {
        offset_a_d += 0.02f;
    }
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
    {
        offset_a_d -= 0.02f;
    }
}
#version 450 core
layout ( location = 0 ) in vec4 vPosition; // c++ pos
layout ( location = 1 ) in vec2 vTexCoord; // c++ attribute st
out vec2 ourTexCoord; // OUT TO OUR ->fragment
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
    gl_Position = projection *view * model * vPosition;
    ourTexCoord = vTexCoord;
}
shader.vert
#version 450 core
out vec4 fColor;  // out to our fragment shader color
in vec2 ourTexCoord;

uniform sampler2D texture1;

void main(){
    vec4 df = texture(texture1,ourTexCoord);
    fColor = df;
}
shader.frag
#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>


#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const unsigned int SRC_WIDTH = 800;
const unsigned int SRC_HEIGHT = 600;

const int  NPTS = 4;
static GLuint VAO,VBO,EBO;
static LoadShader shader;
void init();
void display();
void showFPS(GLFWwindow *);


void processInput(GLFWwindow *window);
void framebuffer_size_callback(GLFWwindow* window, int width, int height);

static float offset_w_s = -1.0f;
static float offset_a_d = 0.0f;


void init(){
    GLfloat  verticels[NPTS][5] = {
        // positions          // texture coords
        {0.5f,  0.5f, 0.0f,    1.0f, 1.0f},   // top right
        {0.5f, -0.5f, 0.0f,    1.0f, 0.0f},   // bottom right
        {-0.5f, -0.5f, 0.0f,   0.0f, 0.0f},   // bottom left
        {-0.5f,  0.5f, 0.0f,   0.0f, 1.0f}    // top left
    };
    GLuint indices[6] = {
            0, 1, 3,  // FIRST TRIANGLE
            1, 2, 3   // SECOND TRIANGLE
        };
    shader.load("shader.vert","shader.frag");
    shader.use();

    glCreateVertexArrays(1, &VAO);
    glCreateBuffers(1, &VBO);
    glCreateBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0);
    glBufferData(GL_ARRAY_BUFFER,sizeof(verticels), verticels, GL_STATIC_DRAW);



    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);

    // VERTEX POINTS ATTRIBUTES
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),  (void*)0); // POS at location 0
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1
    glEnableVertexAttribArray(1);




    cout << "GEN Texture
";
    // loading one texture
    GLuint textureID;
    glCreateTextures(GL_TEXTURE_2D,1 , &textureID);
    glBindTexture(GL_TEXTURE_2D,textureID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    unsigned char *data = stbi_load("wendy.jpg", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    cout << "FREE IMAGE
";
    stbi_image_free(data);

}

void display(){
    glm::mat4 model = glm::mat4(1.0f);
    glm::mat4 view = glm::mat4(1.0f);
    glm::mat4 projection = glm::mat4(1.0f);


    model = glm::rotate(model, glm::radians(-55.0f),glm::vec3(1.0f,0.0f,0.0f));

    view = glm::translate(view,glm::vec3(offset_a_d, 0.0f ,offset_w_s)); // BIND KEY


    projection = glm::perspective(glm::radians(45.0f),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);


    GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model");
    GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view");
    GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection");

    glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));

    //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]);
    glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection));

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    shader.use();
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6 , GL_UNSIGNED_INT , NULL);  // draw six verticles
}


int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL);
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    glewInit();
    init();

    // RENDER--------------
    while(!glfwWindowShouldClose(window)){
        processInput(window);
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
    {
        offset_w_s += 0.02f;
    }
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
    {
        offset_w_s -= 0.02f;
    }
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
    {
        offset_a_d += 0.02f;
    }
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
    {
        offset_a_d -= 0.02f;
    }
}
main.cpp

CP10:

1,理解ZBUFFER

glEnable(GL_DEPTH_TEST); 
// RENDER LOOP CODE:
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

2,理解R S T 顺序

for (unsigned int i = 0; i < 10; i++)
{
// calculate the model matrix for each object and pass it to shader before drawing
        glm::mat4 model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
        ourShader.setMat4("model", model);
       glDrawArrays(GL_TRIANGLES, 0, 36);
}

 如上,对一个model矩阵操作 位移,操作旋转, 结果是不可预期的。经过测试,代码确实是以原点旋转位移过的物体。

如果我想先旋转, 然后再位移

for (unsigned int i = 0; i < 10; i++)
    {
        // RULE : RST
        // FIRST WE ROTATION
        glm::mat4 tempRot = glm::mat4(1.0f);
        tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f));
        // then translate
        glm::mat4 tempTrans = glm::mat4(1.0f);
        tempTrans = glm::translate(tempTrans,cubePositions[i]);

        // final combine one matrix
        glm::mat4 model = glm::mat4(1.0f);
        model = tempTrans * tempRot;
        // send to opengl
        GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model");
        glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));
        glDrawArrays(GL_TRIANGLES,0,36);
    }

ALL CODE:

#version 450 core
layout ( location = 0 ) in vec4 vPosition; // c++ pos
layout ( location = 1 ) in vec2 vTexCoord; // c++ attribute st
out vec2 ourTexCoord; // OUT TO OUR ->fragment
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
    gl_Position = projection *view * model * vPosition;
    ourTexCoord = vTexCoord;
}
shader.vert
#version 450 core
out vec4 fColor;  // out to our fragment shader color
in vec2 ourTexCoord;

uniform sampler2D texture1;

void main(){
    vec4 df = texture(texture1,ourTexCoord);
    fColor = df;
}
shader.frag
#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>


#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const unsigned int SRC_WIDTH = 800;
const unsigned int SRC_HEIGHT = 600;

const int  NPTS = 4;
static GLuint VAO,VBO,EBO;
static LoadShader shader;
void init();
void display();
void showFPS(GLFWwindow *);


void processInput(GLFWwindow *window);
void framebuffer_size_callback(GLFWwindow* window, int width, int height);

static float offset_w_s = -1.0f;
static float offset_a_d = 0.0f;


// world space positions of our cubes
static  glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
};


void init(){
    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    glEnable(GL_DEPTH_TEST);

    GLuint indices[6] = {
            0, 1, 3,  // FIRST TRIANGLE
            1, 2, 3   // SECOND TRIANGLE
        };
    shader.load("shader.vert","shader.frag");
    shader.use();

    glCreateVertexArrays(1, &VAO);
    glCreateBuffers(1, &VBO);
    glCreateBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW);



    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);

    // VERTEX POINTS ATTRIBUTES
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),  (void*)0); // POS at location 0
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1
    glEnableVertexAttribArray(1);




    cout << "GEN Texture
";
    // loading one texture
    GLuint textureID;
    glCreateTextures(GL_TEXTURE_2D,1 , &textureID);
    glBindTexture(GL_TEXTURE_2D,textureID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    unsigned char *data = stbi_load("wendy.png", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    cout << "FREE IMAGE
";
    stbi_image_free(data);

}

void display(){
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



    glm::mat4 view = glm::mat4(1.0f);
    glm::mat4 projection = glm::mat4(1.0f);



    GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view");
    GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection");
    view = glm::translate(view,glm::vec3(offset_a_d, 0.0f ,offset_w_s)); // BIND KEY
    projection = glm::perspective(glm::radians(45.0f),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);

    //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]);
    glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection));



    for (unsigned int i = 0; i < 10; i++)
    {
        // RULE : RST
        // FIRST WE ROTATION
        glm::mat4 tempRot = glm::mat4(1.0f);
        tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f));
        // then translate
        glm::mat4 tempTrans = glm::mat4(1.0f);
        tempTrans = glm::translate(tempTrans,cubePositions[i]);

        // final combine one matrix
        glm::mat4 model = glm::mat4(1.0f);
        model = tempTrans * tempRot;
        // send to opengl
        GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model");
        glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));
        glDrawArrays(GL_TRIANGLES,0,36);
    }


}


int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL);
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    glewInit();
    init();

    // RENDER--------------
    while(!glfwWindowShouldClose(window)){
        processInput(window);
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
    {
        offset_w_s += 0.05f;
    }
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
    {
        offset_w_s -= 0.05f;
    }
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
    {
        offset_a_d += 0.05f;
    }
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
    {
        offset_a_d -= 0.05f;
    }
}
main.cpp

CP11

1,CamSpace/ViewSpace

2,LookAt Matrix:

 3,实现教程中得键盘控制 W A S D

#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <cmath>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const unsigned int SRC_WIDTH = 800;
const unsigned int SRC_HEIGHT = 600;

const int  NPTS = 4;
static GLuint VAO,VBO,EBO;
static LoadShader shader;
void init();
void display();
void showFPS(GLFWwindow *);


void processInput(GLFWwindow *window);
void framebuffer_size_callback(GLFWwindow* window, int width, int height);






// camera
static glm::vec3 cameraPos   = glm::vec3(0.0f, 0.0f,  3.0f);
static glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
static glm::vec3 cameraUp    = glm::vec3(0.0f, 1.0f,  0.0f);



// timing
static float deltaTime = 0.0f;    // time between current frame and last frame
static float lastFrame = 0.0f;



// world space positions of our cubes
static  glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
};


void init(){
    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    glEnable(GL_DEPTH_TEST);

    GLuint indices[6] = {
            0, 1, 3,  // FIRST TRIANGLE
            1, 2, 3   // SECOND TRIANGLE
        };
    shader.load("shader.vert","shader.frag");
    shader.use();

    glCreateVertexArrays(1, &VAO);
    glCreateBuffers(1, &VBO);
    glCreateBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW);



    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);

    // VERTEX POINTS ATTRIBUTES
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),  (void*)0); // POS at location 0
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1
    glEnableVertexAttribArray(1);




    cout << "GEN Texture
";
    // loading one texture
    GLuint textureID;
    glCreateTextures(GL_TEXTURE_2D,1 , &textureID);
    glBindTexture(GL_TEXTURE_2D,textureID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    unsigned char *data = stbi_load("wendy.png", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    cout << "FREE IMAGE
";
    stbi_image_free(data);

}

void display(){
    // per-frame time logic
            // --------------------
    float currentFrame = glfwGetTime();
    deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;


    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



    glm::mat4 view = glm::mat4(1.0f);
    glm::mat4 projection = glm::mat4(1.0f);



    GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view");
    GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection");

    projection = glm::perspective(glm::radians(45.0f),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);

    //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]);

    glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection));

    // view matrix
    view = glm::lookAt(cameraPos , cameraPos + cameraFront , cameraUp);
    glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view));



    for (unsigned int i = 0; i < 10; i++)
    {
        // RULE : RST
        // FIRST WE ROTATION
        glm::mat4 tempRot = glm::mat4(1.0f);
        tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f));
        // then translate
        glm::mat4 tempTrans = glm::mat4(1.0f);
        tempTrans = glm::translate(tempTrans,cubePositions[i]);

        // final combine one matrix
        glm::mat4 model = glm::mat4(1.0f);
        model = tempTrans * tempRot;
        // send to opengl
        GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model");
        glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));
        glDrawArrays(GL_TRIANGLES,0,36);


    }


}


int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL);
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    glewInit();
    init();

    // RENDER--------------
    while(!glfwWindowShouldClose(window)){
        processInput(window);
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);

    float cameraSpeed = 2.5 * deltaTime;
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
        cameraPos += cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
        cameraPos -= cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}
main.cpp

CP12

1,实现Maya得控制视角方式

2,修改了教程得控制视角方式,测试了众多得事件

3,跟QT得事件实际上套路类似,而且更加简单,C语言callback使用起来就是那么难用。

#define GLEW_STATIC
// GLEW

#include <GL/glew.h>
#include <cstdlib>
#undef GLFW_DLL
// GLFW
#include <GLFW/glfw3.h>
#include <iostream>
#include "LoadShader.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include <cmath>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

const unsigned int SRC_WIDTH = 800;
const unsigned int SRC_HEIGHT = 600;

const int  NPTS = 4;
static GLuint VAO,VBO,EBO;
static LoadShader shader;
void init();
void display();
void showFPS(GLFWwindow *);


void processInput(GLFWwindow *window);
void framebuffer_size_callback(GLFWwindow* window, int width, int height); // framezize
void mouse_callback(GLFWwindow* window, double xpos, double ypos); // Maya Alt+LeftMouse
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); // Test not used!


// camera
static glm::vec3 cameraPos   = glm::vec3(0.0f, 0.0f,  3.0f);
static glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
static glm::vec3 cameraUp    = glm::vec3(0.0f, 1.0f,  0.0f);
static float yaw   = -90.0f;    // yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right so we initially rotate a bit to the left.
static float pitch =  0.0f;
static float lastX =  float(SRC_WIDTH) / 2.0;
static float lastY =  float(SRC_HEIGHT) / 2.0;
static float fov   =  45.0f; // default fov
static bool firstMouse = true;

// timing
static float deltaTime = 0.0f;    // time between current frame and last frame
static float lastFrame = 0.0f;



// world space positions of our cubes
static  glm::vec3 cubePositions[] = {
        glm::vec3( 0.0f,  0.0f,  0.0f),
        glm::vec3( 2.0f,  5.0f, -15.0f),
        glm::vec3(-1.5f, -2.2f, -2.5f),
        glm::vec3(-3.8f, -2.0f, -12.3f),
        glm::vec3( 2.4f, -0.4f, -3.5f),
        glm::vec3(-1.7f,  3.0f, -7.5f),
        glm::vec3( 1.3f, -2.0f, -2.5f),
        glm::vec3( 1.5f,  2.0f, -2.5f),
        glm::vec3( 1.5f,  0.2f, -1.5f),
        glm::vec3(-1.3f,  1.0f, -1.5f)
};


void init(){
    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
         0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
         0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
         0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
         0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f, 1.0f
    };

    glEnable(GL_DEPTH_TEST);

    GLuint indices[6] = {
            0, 1, 3,  // FIRST TRIANGLE
            1, 2, 3   // SECOND TRIANGLE
        };
    shader.load("shader.vert","shader.frag");
    shader.use();

    glCreateVertexArrays(1, &VAO);
    glCreateBuffers(1, &VBO);
    glCreateBuffers(1, &EBO);

    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    //glNamedBufferStorage(VBO,sizeof(verticels), verticels, 0);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW);



    glCreateBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glNamedBufferStorage(EBO, sizeof(indices), indices , 0);

    // VERTEX POINTS ATTRIBUTES
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float),  (void*)0); // POS at location 0
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); // ST at location 1
    glEnableVertexAttribArray(1);




    cout << "GEN Texture
";
    // loading one texture
    GLuint textureID;
    glCreateTextures(GL_TEXTURE_2D,1 , &textureID);
    glBindTexture(GL_TEXTURE_2D,textureID);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height, nrChannels;
    stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
    unsigned char *data = stbi_load("wendy.png", &width, &height, &nrChannels, 0);
    if (data)
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    cout << "FREE IMAGE
";
    stbi_image_free(data);

}

void display(){
    // per-frame time logic
            // --------------------
    float currentFrame = glfwGetTime();
    deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;


    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



    glm::mat4 view = glm::mat4(1.0f);
    glm::mat4 projection = glm::mat4(1.0f);



    GLuint view_location = glGetUniformLocation(shader.shaderProgram, "view");
    GLuint projection_location = glGetUniformLocation(shader.shaderProgram, "projection");

    projection = glm::perspective(glm::radians(fov),float(SRC_WIDTH) / float(SRC_HEIGHT),0.1f,  1000.0f);

    //glUniformMatrix4fv(view_location,1, GL_FALSE, &view[0][0]);

    glUniformMatrix4fv(projection_location,1, GL_FALSE, glm::value_ptr(projection));

    // view matrix
    view = glm::lookAt(cameraPos , cameraPos + cameraFront , cameraUp);
    glUniformMatrix4fv(view_location,1, GL_FALSE, glm::value_ptr(view));



    for (unsigned int i = 0; i < 10; i++)
    {
        // RULE : RST
        // FIRST WE ROTATION
        glm::mat4 tempRot = glm::mat4(1.0f);
        tempRot = glm::rotate(tempRot, float(glfwGetTime()*0.3f + float(i) ),glm::vec3(1.00f,0.0f,0.0f));
        // then translate
        glm::mat4 tempTrans = glm::mat4(1.0f);
        tempTrans = glm::translate(tempTrans,cubePositions[i]);

        // final combine one matrix
        glm::mat4 model = glm::mat4(1.0f);
        model = tempTrans * tempRot;
        // send to opengl
        GLuint model_location = glGetUniformLocation(shader.shaderProgram, "model");
        glUniformMatrix4fv(model_location, 1, GL_FALSE, glm::value_ptr(model));
        glDrawArrays(GL_TRIANGLES,0,36);


    }


}


int main()
{
    glfwInit();
    GLFWwindow *window = glfwCreateWindow(SRC_WIDTH,SRC_HEIGHT ,"HelloWorld",NULL,NULL);
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    glfwSetCursorPosCallback(window,mouse_callback);
    glfwSetScrollCallback(window, scroll_callback);
    //glfwSetKeyCallback(window, key_callback);  // Key event


    //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
    glewInit();
    init();

    // RENDER--------------
    while(!glfwWindowShouldClose(window)){
        processInput(window);
        display();
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);

    float cameraSpeed = 2.5 * deltaTime;
    if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
        cameraPos += cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
        cameraPos -= cameraSpeed * cameraFront;
    if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
        cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
    if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
        cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}

// ROTATE VIEW DIR
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{
 int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
 int key_state = glfwGetKey(window,GLFW_KEY_LEFT_ALT);

 if( mouse_state == GLFW_PRESS && key_state== GLFW_PRESS) {
    if (firstMouse){
           lastX = xpos;
           lastY = ypos;
           firstMouse = false;
       }

       float xoffset = xpos - lastX;
       float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
       lastX = xpos;
       lastY = ypos;

       float sensitivity = 0.2f; // change this value to your liking
       xoffset *= sensitivity;
       yoffset *= sensitivity;

       yaw += xoffset;
       pitch += yoffset;

       // make sure that when pitch is out of bounds, screen doesn't get flipped
       if (pitch > 89.0f)
           pitch = 89.0f;
       if (pitch < -89.0f)
           pitch = -89.0f;

       glm::vec3 front;
       front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
       front.y = sin(glm::radians(pitch));
       front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
       cameraFront = glm::normalize(front);
    }
 if (key_state == GLFW_RELEASE || mouse_state == GLFW_RELEASE){
     firstMouse = true;
 }

}


void scroll_callback(GLFWwindow *window, double xoffset, double yoffset){
    //cout << "scroll_callback
" << xoffset << " " << yoffset <<endl;
    if(fov >= 1.0f && fov <= 45.0f){
        fov -= yoffset;
    }
    if(fov <=1.0f){
        fov = 1.0f;
    }
    if(fov >= 45.0f){
        fov = 45.0f;
    }
}


//
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{

    //cout << "--->" << xpos << "/" << ypos <<endl;
    int mouse_state = glfwGetMouseButton(window,GLFW_MOUSE_BUTTON_LEFT);
    if (key == GLFW_KEY_LEFT_ALT && (action == GLFW_PRESS||action == GLFW_REPEAT) )
    {
    }

}
View Code
原文地址:https://www.cnblogs.com/gearslogy/p/12287447.html