OpenGL 无法在启用深度缓冲区的情况下进行 3D 绘制
OpenGL not drawing in 3D with depth buffers enabled
我花了 2 周的时间试图让 OpenGL 在 3D 中绘制立方体,但无论我做什么,它从未真正绘制出立方体。如果我使用 glEnable(DEPTH_TEST) 启用深度测试,它根本不会呈现任何内容。如果我注释掉该函数,它会渲染所有顶点,就好像 z 值都为 0。我完全被卡住了,不知道我做错了什么。
这是我的主文件:https://pastebin.com/D8cEcJ4g
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex Attribute **
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//** Color Attribute **
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 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);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.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);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
RAW Paste Data
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex Attribute **
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//** Color Attribute **
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 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);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.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);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
片段着色器:
#version 430 core
in vec3 outColor;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D Texture;
uniform sampler2D Texture2;
uniform float currentTime;
void main()
{
//vec3 colorTemp = outColor * abs(sin(currentTime));
//color = vec4(colorTemp, 1.0f) ;
//color = texture(ourTexture, TexCoord) * vec4(outColor, 1.0f) * abs(sin(currentTime)) ;
color = mix(texture(Texture, TexCoord), texture(Texture2, TexCoord), 0.2) * vec4(outColor, 1.0f) * abs(sin(currentTime));
}
顶点着色器:
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
out vec3 outColor;
out vec2 TexCoord;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(void)
{
gl_Position = projection * view * model * transform * vec4(position, 1.0);
outColor = color;
TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
}
If I comment out that function, it renders all the vertices as if the z-values were all 0
嗯,那是因为......他们是:
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
[...]
transform = glm::scale(transform, vScaleVec);
[...]
gl_Position = projection * view * model * transform * vec4(position, 1.0);
您使用 z=0
进行缩放,这意味着您将所有顶点移动到 z = 0 平面中。所以在你的第一个转换步骤之后它已经是平坦的(这也意味着 transform
是一个奇异矩阵,第三行和第三列都是零)。您在代码中注释掉的额外变换步骤,以及着色器中应用的所有其他矩阵,不会改变其中任何一个,对象仍然是一个平面,无论您预先或 post-乘以它,他们只是移动那个平面。
我不知道你想要多少缩放,但按 0 缩放几乎不是一个好主意,1 是缩放操作的中性元素。
此外,为什么在着色器中将 model
和 transform
作为单独的矩阵?在 3d 计算机图形学中,模型矩阵通常包含将对象从其自身的本地模型 space 映射到世界 space 所需的所有变换。即使您需要在内部跟踪转换的不同部分,在 gpu 上的实际渲染过程中通常不需要这些,并且应该在 CPU 上将所有这些相乘,然后将累积的转换作为model
矩阵到着色器。
我花了 2 周的时间试图让 OpenGL 在 3D 中绘制立方体,但无论我做什么,它从未真正绘制出立方体。如果我使用 glEnable(DEPTH_TEST) 启用深度测试,它根本不会呈现任何内容。如果我注释掉该函数,它会渲染所有顶点,就好像 z 值都为 0。我完全被卡住了,不知道我做错了什么。
这是我的主文件:https://pastebin.com/D8cEcJ4g
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex Attribute **
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//** Color Attribute **
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 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);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.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);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
RAW Paste Data
#include "Dependencies\glew\glew.h"
#include "Dependencies\freeglut\freeglut.h"
#include "Dependencies\soil\SOIL.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include "ShaderLoader.h";
#include "Camera.h"
#define BUTTON_UP 0
#define BUTTON_DOWN 1
GLuint program;
GLuint vao, vbo, ebo;
GLuint texture, texture2;
unsigned char keyState[255];
glm::vec3 vPosTrans = glm::vec3(-0.50f, -0.50f, 0.0f);//source
glm::vec3 vPosInit = vPosTrans;
glm::vec3 vPosDest = glm::vec3(0.50f, 0.50f, 0.0f);//destination
glm::vec3 vCurrentPos = vPosTrans;
bool Dest1or2 = true;
const GLfloat WIDTH = 800.0f, HEIGHT = 600.0f;
Camera* camera;
void init(){
camera = new Camera(180.0f, WIDTH, HEIGHT, 0.0f, 100.0f);
ShaderLoader shaderLoader;
program = shaderLoader.CreateProgram("CoordSystem_Texture_QUAD.vs", "CoordSystem_Texture_QUAD.fs");
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Set up vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] = {
//position //color //texture coord //Normals
-1.01f, -1.01f, -1.01f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, -0.0f, 0.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 0.0f, -0.0f, 1.0f, 0.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
// Fill in the back face vertex data.
-1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.01f, -1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the top face vertex data.
-1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.01f, 1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the bottom face vertex data.
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.01f, -1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
// Fill in the left face vertex data.
-1.01f, -1.01f, 1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.01f, 1.01f, -1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
// Fill in the right face vertex data.
1.01f, -1.01f, -1.01f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
1.01f, 1.01f, -1.01f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.01f, 1.01f, 1.01f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1.01f, -1.01f, 1.01f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f,
};
GLuint indices[] = {
// front
0, 1, 2,
0, 2, 3,
// top
4, 5, 6,
4, 6, 7,
// back
8, 9, 10,
8, 10, 11,
// bottom
12, 13, 14,
12, 14, 15,
// left
16, 17, 18,
16, 18, 19,
// right
20, 21, 22,
20, 22, 23,
};
//** VAO **
// Generate vertex arrow object
glGenVertexArrays(1, &vao);
// Bind the Vertex Array Object to openGl context
glBindVertexArray(vao);//otherwise glVertexAttribPointer
//** VBO **
// Then bind and set vertex buffer(s).
// First paramter is how many buffers we have to create
glGenBuffers(1, &vbo);
// bind VBO to binding point, here it is GL_ARRAY_BUFFER
// there are other binding points
glBindBuffer(GL_ARRAY_BUFFER, vbo);//bind to context
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertices),// GPU need to know how much memory needs to be allocated
vertices,//copy data to GPU
GL_STATIC_DRAW);// How to use the buffer - buffer is created and modified once
//** EBO **
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices),
indices,
GL_STATIC_DRAW);
// ** Attributes **
//** Vertex Attribute **
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
//** Color Attribute **
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * 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);
// It's always a good thing to unbind any buffer/array to prevent strange bugs
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//** Load and bind texture 1
//--------------------------
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
int width, height;
unsigned char* image = SOIL_load_image("wall.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);
// ** Load and Bind Texture 2
//---------------------------
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
//** loadImage and create texture
// Load image, create texture and generate mipmaps
unsigned char* image2 = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image2);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(image2);
glBindTexture(GL_TEXTURE_2D, 0);
// Set texture wrapping to GL_REPEAT (usually basic wrapping method)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void render(){
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw our first triangle
glUseProgram(program);
//bind
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "Texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glUniform1i(glGetUniformLocation(program, "Texture2"), 1);
glBindVertexArray(vao);
// Draw Elements intead of vertex array
glDrawArrays(GL_QUADS, 0, 24);
//glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void update(){
GLfloat cameraSpeed = 0.05f;
camera->setCameraSpeed(cameraSpeed);
//currentTime uniform
GLfloat currentTime = glutGet(GLUT_ELAPSED_TIME);
currentTime = currentTime / 1000;
GLint currentTimeLocation = glGetUniformLocation(program, "currentTime");
glUniform1f(currentTimeLocation, currentTime);
//transforms
glm::mat4 transform = glm::mat4(1.0f);
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f);
glm::mat4 model = glm::mat4(1.0);
if (keyState[(unsigned char)'w'] == BUTTON_DOWN) {
camera->moveForward();
std::cout << "e";
}
if (keyState[(unsigned char)'s'] == BUTTON_DOWN) {
camera->moveBack();
std::cout << "A";
}
camera->Update();
//glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);
glm::mat4 projection = camera->getProjectionMatrix();
glm::mat4 view = glm::lookAt(camera->getCameraPos(), camera->getCameraPos() + camera->getCameraFront(), camera->getCameraUp());
//glm::mat4 view = glm::lookAt(glm::vec3(1, 1, 0), glm::vec3(0, 1, 0), glm::vec3(0, 0, 1));
GLfloat radius = 3.5f;
GLfloat camX = sin(currentTime) * radius;
GLfloat camZ = cos(currentTime) * radius;
//glm::mat4 view = glm::lookAt(
// glm::vec3(camX, 0.0, camZ),
// glm::vec3(0.0, 0.0, 0.0),
// glm::vec3(0.0, 1.0, 0.0));
transform = glm::scale(transform, vScaleVec);
glm::vec3(0.65f, 0.65f, 0.65f);
//transform = glm::rotate(transform, 90.0f, glm::vec3(0.0, 0.0, 1.0));
if (vCurrentPos == vPosDest && Dest1or2 == true )
{
Dest1or2 = false;
}
else if (vCurrentPos == vPosTrans && Dest1or2 == false)
{
Dest1or2 = true;
}
if(Dest1or2)
vCurrentPos = glm::mix(vCurrentPos, vPosDest, currentTime * 0.01f);
else
vCurrentPos = glm::mix(vCurrentPos, vPosTrans, currentTime*0.01f);
//transform = glm::translate(transform, vCurrentPos);
//transform = glm::translate(transform, glm::vec3(-0.51f, -0.51f, 0.0f));
//transform = glm::rotate(transform, ((GLfloat)currentTime / 100) * 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// RTS
GLuint transformLoc = glGetUniformLocation(program, "transform");
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));
GLint modelLoc = glGetUniformLocation(program, "model");
GLint viewLoc = glGetUniformLocation(program, "view");
GLint projLoc = glGetUniformLocation(program, "projection");
// Pass them to the shaders
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(camera->getViewMatrix()));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(camera->getProjectionMatrix()));
//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y) {
keyState[key] = BUTTON_DOWN;
//printf("key pressed: %d \n", key);
}
void keyboard_up(unsigned char key, int x, int y) {
keyState[key] = BUTTON_UP;
}
int main(int argc, char **argv){
// init glut
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(300, 200);
glutInitWindowSize(800, 600);
glutCreateWindow("QUAD EBO");
//init GLEW
glewInit();
init();
//clear
glClearColor(1.0, 0.0, 0.0, 1.0);//clear red
// register callbacks
glutDisplayFunc(render);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboard_up);
glutIdleFunc(update);
glutMainLoop();
return 0;
}
片段着色器:
#version 430 core
in vec3 outColor;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D Texture;
uniform sampler2D Texture2;
uniform float currentTime;
void main()
{
//vec3 colorTemp = outColor * abs(sin(currentTime));
//color = vec4(colorTemp, 1.0f) ;
//color = texture(ourTexture, TexCoord) * vec4(outColor, 1.0f) * abs(sin(currentTime)) ;
color = mix(texture(Texture, TexCoord), texture(Texture2, TexCoord), 0.2) * vec4(outColor, 1.0f) * abs(sin(currentTime));
}
顶点着色器:
#version 430 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;
out vec3 outColor;
out vec2 TexCoord;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(void)
{
gl_Position = projection * view * model * transform * vec4(position, 1.0);
outColor = color;
TexCoord = vec2(texCoord.x, 1.0 - texCoord.y);
}
If I comment out that function, it renders all the vertices as if the z-values were all 0
嗯,那是因为......他们是:
glm::vec3 vScaleVec = glm::vec3(0.51f, 0.51f, 0.0f); [...] transform = glm::scale(transform, vScaleVec); [...] gl_Position = projection * view * model * transform * vec4(position, 1.0);
您使用 z=0
进行缩放,这意味着您将所有顶点移动到 z = 0 平面中。所以在你的第一个转换步骤之后它已经是平坦的(这也意味着 transform
是一个奇异矩阵,第三行和第三列都是零)。您在代码中注释掉的额外变换步骤,以及着色器中应用的所有其他矩阵,不会改变其中任何一个,对象仍然是一个平面,无论您预先或 post-乘以它,他们只是移动那个平面。
我不知道你想要多少缩放,但按 0 缩放几乎不是一个好主意,1 是缩放操作的中性元素。
此外,为什么在着色器中将 model
和 transform
作为单独的矩阵?在 3d 计算机图形学中,模型矩阵通常包含将对象从其自身的本地模型 space 映射到世界 space 所需的所有变换。即使您需要在内部跟踪转换的不同部分,在 gpu 上的实际渲染过程中通常不需要这些,并且应该在 CPU 上将所有这些相乘,然后将累积的转换作为model
矩阵到着色器。