在三维空间里创建10个物体,并可以自由缩放,移动视角

来源:互联网 发布:服装软件有哪些 编辑:程序博客网 时间:2024/05/10 22:50

继续学习OpenGL,实现了在窗口内画出了N个物体,并放置在某个3维坐标,同时添加了camera,可以自由移动camera(camera为一个FPS的camera,只能在XZ平面移动,如果想要抛开这个限制,只需在camera.h中,把position.y = 0去掉)。

还有一个问题,没有解决: 如果加载的图片是一个 342 * 256 的图片,运行的时候图片会出现倾斜,变成灰色的情况?为何?

下面是个部分的代码:

main.cpp

#include <iostream>// GLEW#define GLEW_STATIC#include <glew.h>// GLFW#include <glfw3.h>// Other Libs#include <SOIL.h>#include <glm/gtc/type_ptr.hpp>// Other includes#include "Shader.h"#include "Camera.h"// Window dimensionsconst GLuint WIDTH = 800, HEIGHT = 600;// Function prototypesvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);void mouse_callback(GLFWwindow* window, double xpos, double ypos);void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);void do_movement();//CameraCamera camera(glm::vec3(0.0f, 0.0f, 3.0f));bool keys[1024];GLfloat lastX = WIDTH / 2, lastY = HEIGHT / 2;bool firstMouse = true;GLfloat deltaTime = 0.0f;GLfloat lastFrame = 0.0f;// Holds uniform value of texture mixGLfloat mixValue = 0.2f;int main(){// Init GLFWglfwInit();// Set all the required options for GLFWglfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);glfwWindowHint(GLFW_SAMPLES, 4);// Create a GLFWwindow object that we can use for GLFW's functionsGLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);glfwMakeContextCurrent(window);// Set the required callback functionsglfwSetKeyCallback(window, key_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);//OptionsglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions// Initialize GLEW to setup the OpenGL Function pointersglewExperimental = GL_TRUE;glewInit();// Define the viewport dimensionsglViewport(0, 0, WIDTH, HEIGHT);//setup some openGL optionsglEnable(GL_DEPTH_TEST);// Build and compile our shader programShader ourShader("default.vs", "default.frag");// Set up vertex data (and buffer(s)) and attribute pointersGLfloat 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};GLuint indices[] = {  // Note that we start from 0!0, 1, 3, // First Triangle1, 2, 3  // Second Triangle};// World space positions of our cubesglm::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)};GLuint VBO, VAO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);//glGenBuffers(1, &EBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);// Position attributeglVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);glEnableVertexAttribArray(0);// Color attributeglVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glEnableVertexAttribArray(1);// TexCoord attribute//glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));//glEnableVertexAttribArray(2);glBindVertexArray(0); // Unbind VAO  // Load and create a texture GLuint texture1;GLuint texture2;// ====================// Texture 1// ====================glGenTextures(1, &texture1);glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object// Set our texture parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);// Set texture wrapping to GL_REPEATglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);// Set texture filteringglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// Load, create texture and generate mipmapsint width, height;unsigned char* image = SOIL_load_image("container.jpg", &width, &height, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // ===================glGenTextures(1, &texture2);glBindTexture(GL_TEXTURE_2D, texture2);// Set our texture parametersglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);// Set texture filteringglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// Load, create texture and generate mipmapsimage = SOIL_load_image("wuhan.jpg", &width, &height, 0, SOIL_LOAD_RGB);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);SOIL_free_image_data(image);glBindTexture(GL_TEXTURE_2D, 0);// Game loopwhile (!glfwWindowShouldClose(window)){//Set frame timeGLfloat currentFrame = (GLfloat)glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functionsglfwPollEvents();do_movement();// Render// Clear the colorbufferglClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Activate shaderourShader.Use();// Bind Textures using texture unitsglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture1);glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, texture2);glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1);//Create camera transformationglm::mat4 view;view = camera.GetViewMatrix();glm::mat4 projection;projection = glm::perspective(camera.Zoom, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 1000.0f);//Get the uniform locationsGLint modelLoc = glGetUniformLocation(ourShader.Program, "model");GLint viewLoc = glGetUniformLocation(ourShader.Program, "view");GLint projectionLoc = glGetUniformLocation(ourShader.Program, "projection");glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));// Draw containerglBindVertexArray(VAO);//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);for (GLuint i = 0; i < 10; i++){glm::mat4 model;model = glm::translate(model, cubePositions[i]);GLfloat angle = 20.f * i;if (i % 3 == 0){angle = (GLfloat)glfwGetTime() * 50.0f;}model = glm::rotate(model, angle, glm::vec3(1.0f, 0.3f, 0.5f));glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));glDrawArrays(GL_TRIANGLES, 0, 36);}glBindVertexArray(0);// Swap the screen buffersglfwSwapBuffers(window);// Set current value of uniform mixglUniform1f(glGetUniformLocation(ourShader.Program, "mixValue"), mixValue);}// Properly de-allocate all resources once they've outlived their purposeglDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);// Terminate GLFW, clearing any resources allocated by GLFW.glfwTerminate();return 0;}// Is called whenever a key is pressed/released via GLFWvoid key_callback(GLFWwindow* window, int key, int scancode, int action, int mode){cout << key << endl;if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (action == GLFW_PRESS)keys[key] = true;else if (action == GLFW_RELEASE)keys[key] = false;// Change value of uniform with arrow keys (sets amount of textre mix)if (key == GLFW_KEY_UP && action == GLFW_PRESS){mixValue += 0.1f;if (mixValue >= 1.0f)mixValue = 1.0f;}if (key == GLFW_KEY_DOWN && action == GLFW_PRESS){mixValue -= 0.1f;if (mixValue <= 0.0f)mixValue = 0.0f;}}void do_movement(){if (keys[GLFW_KEY_W])camera.ProcessKeyboard(FORWARD, deltaTime);if (keys[GLFW_KEY_S])camera.ProcessKeyboard(BACKWARD, deltaTime);if (keys[GLFW_KEY_A])camera.ProcessKeyboard(LEFT, deltaTime);if (keys[GLFW_KEY_D])camera.ProcessKeyboard(RIGHT, deltaTime);}void mouse_callback(GLFWwindow* window, double xpos, double ypos){if (firstMouse){lastX = xpos;lastY = ypos;firstMouse = false;}GLfloat xoffset = xpos - lastX;GLfloat yoffset = lastY - ypos;   // Reversed since y-coordinates go from bottom to leftlastX = xpos;lastY = ypos;camera.ProcessMouseMovement(xoffset, yoffset);}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset){camera.ProcessMouseScroll(yoffset);}

Shader.h

#pragma once#ifndef SHADER_H#define SHADER_H#include <string>#include <fstream>#include <sstream>#include <iostream>#include <glew.h>#include <SOIL.h>using namespace std;class Shader{public:GLuint Program;Shader(const GLchar *vertexPath, const GLchar *fragmentPath){string vertexCode, fragmentCode;ifstream vShaderFile, fShaderFile;vShaderFile.exceptions(ifstream::badbit);fShaderFile.exceptions(ifstream::badbit);try {vShaderFile.open(vertexPath);fShaderFile.open(fragmentPath);stringstream vShaderStream, fShaderStream;vShaderStream << vShaderFile.rdbuf();fShaderStream << fShaderFile.rdbuf();vShaderFile.close();fShaderFile.close();vertexCode = vShaderStream.str();fragmentCode = fShaderStream.str();}catch (std::ifstream::failure e){cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << endl;}const GLchar *vShaderCode = vertexCode.c_str();const GLchar *fShaderCode = fragmentCode.c_str();GLint success;GLchar infoLog[512];GLuint vertexShader, fragmentShader;vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vShaderCode, NULL);glCompileShader(vertexShader);glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);if (!success){glGetShaderInfoLog(vertexShader, 512, NULL, &infoLog[1]);cout << "ERROR_CREATE_SHADER\n" << infoLog << endl;}fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fShaderCode, NULL);glCompileShader(fragmentShader);Program = glCreateProgram();glAttachShader(Program, vertexShader);glAttachShader(Program, fragmentShader);glLinkProgram(Program);glGetProgramiv(Program, GL_LINK_STATUS, &success);if (!success){glGetProgramInfoLog(Program, 512, NULL, infoLog);cout << "ERROR_CREATE_PROGRAM\n" << infoLog << endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);}void Use(){glUseProgram(this->Program);}};#endif // !SHADER_H

Camera.h

#include <vector>#include <glew.h>#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>using namespace::std;// Defines several possible options for camera movement. Used as abstraction to // stay away from window-system specific input methodsenum Camera_Movement {FORWARD,BACKWARD,LEFT,RIGHT};//Default camera valudsconst GLfloat YAW = -90.0f;const GLfloat PITCH = 0.0f;const GLfloat SPEED = 3.0f;const GLfloat SENSITIVTY = 0.15f;const GLfloat ZOOM = 45.0f;//An abstract camera class that processes input and calculates the corresponding//Eular Angles, Vectors and Matrices for use in OPENGLclass Camera{public://Camera Attributesglm::vec3 Position;glm::vec3 Front;glm::vec3 Up;glm::vec3 Right;glm::vec3 WorldUp;//Eular AnglesGLfloat Yaw;GLfloat Pitch;//Camera optionsGLfloat MovementSpeed;GLfloat MouseSensitivity;GLfloat Zoom;//Constructor with vectorsCamera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM){this->Position = position;this->WorldUp = up;this->Yaw = yaw;this->Pitch = pitch;this->updateCameraVectors();}//Constructor with Scalar valuesCamera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw, GLfloat pitch) : Front(glm::vec3(0.0f, 0.0f, -1.0f)), MovementSpeed(SPEED), MouseSensitivity(SENSITIVTY), Zoom(ZOOM){this->Position = glm::vec3(posX, posY, posZ);this->WorldUp = glm::vec3(upX, upY, upZ);this->Yaw = yaw;this->Pitch = pitch;this->updateCameraVectors();}//Return the view matrix calculate using Eular Angles and the LookAt Matrixglm::mat4 GetViewMatrix(){return glm::lookAt(this->Position, this->Position + this->Front, this->Up);}//Processes input received from any keyboard-like input system. Accepts input parameter in the form of camera defined ENUMvoid ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime){GLfloat velocity = this->MovementSpeed * deltaTime;if (direction == FORWARD)this->Position += this->Front * velocity;if (direction == BACKWARD)this->Position -= this->Front * velocity;if (direction == LEFT)this->Position -= this->Right * velocity;if (direction == RIGHT)this->Position += this->Right * velocity;//real FPS camera, staying on XZ planethis->Position.y = 0.0f;}//Processes input received from a mouse input system. Expects the offset value in both the x and y direction.void ProcessMouseMovement(GLfloat xoffset, GLfloat yoffset, GLboolean constrainPitch = true){xoffset *= this->MouseSensitivity;yoffset *= this->MouseSensitivity;this->Yaw += xoffset;this->Pitch += yoffset;//Make sure that wen pitch is out of bounds, screen doesn't get flippedif (constrainPitch){if (this->Pitch > 89.0f)this->Pitch = 89.0f;if (this->Pitch < -89.0f)this->Pitch = -89.0f;}//Update Front, Right and Up Vectros using the updated Eular anglesthis->updateCameraVectors();}//Processes input received from a mouse scroll-wheel event. Only requires input on the vertical wheel-axisvoid ProcessMouseScroll(GLfloat fov){if (this->Zoom > 1.0f && this->Zoom <= 45.0f)this->Zoom -= fov;if (this->Zoom <= 1.0f)this->Zoom = 1.0f;if (this->Zoom >= 45.0f)this->Zoom = 45.0f;}private:// Calculates the front vector from the Camera's (updated) Eular Anglesvoid updateCameraVectors(){//Calculate the new Front vectorglm::vec3 front;front.x = cos(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));front.y = sin(glm::radians(this->Pitch));front.z = sin(glm::radians(this->Yaw)) * cos(glm::radians(this->Pitch));this->Front = glm::normalize(front);//Also re-calculate the Right and Up vectorthis->Right = glm::normalize(glm::cross(this->Front, this->WorldUp));this->Up = glm::normalize(glm::cross(this->Right, this->Front));}};

default.vs:

#version 330 corelayout (location = 0) in vec3 position;layout (location = 1) in vec2 texCoord;out vec2 TexCoord;uniform mat4 model;uniform mat4 view;uniform mat4 projection;void main(){gl_Position = projection * view * model * vec4(position, 1.0f);TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);}

default.frag:

#version 330 corein vec2 TexCoord;out vec4 color;uniform sampler2D ourTexture1;uniform sampler2D ourTexture2;uniform float mixValue;void main(){color = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), mixValue);}


今天去公司询问了师傅~纹理变化的原因很有可能确实和分辨率有关系,因为测试的所有数据确实符合一个规律:分辨率的width

1.若能被4整除,则显示正常;

2.结果为0.75, 则倾斜

3.结果为0.5,则倾斜 且 变灰色

具体原因还为弄清楚

342 * 256(1.335)倾斜,变色高拉长150 * 256(0.585)       倾斜,变色300 * 256(1.171)       正常342 * 257倾斜,变色343 * 256(1.339)       倾斜342 * 342       倾斜,变色344 * 256(1.343)       倾斜342 * 684(0.5)      倾斜,变色345 * 256(1.347)       倾斜,变色370 * 256(1.445)       倾斜,变色高缩短342 * 255(1.341)       倾斜,变色385 * 256          倾斜,变色342 * 125(2.736)       倾斜,变色390 * 256(1.523)       倾斜,变色         400 * 263(1.523)正常 343 * 125(2.744)       倾斜391 * 256(1.527)       倾斜341 * 125(2.728)       倾斜,变色(出现横条)395 * 256(1.542)       倾斜330 * 125              倾斜,变色(出现横条)398 * 256(1.554)       倾斜,变色325 * 125(2.816)       倾斜,变色(出现横条)399 * 256(1.558)       倾斜323 * 125(2.584)       倾斜400 * 256(1.562)       正常322 * 125(2.576)       倾斜,变色(出现横条)600 * 256(2.343)       正常321 * 125(2.568)       倾斜,变色(出现横条)800 * 256(3.125)       正常320 * 125(2.560)       正常300 * 125(2.400)       正常



0 0