我已经开始使用OpenGL进行教学,本课是关于使用glm
进行三角形平移的。但是,每当我编译程序时,都会出现以下错误
0(9) : error C1068: too much data in type constructor (0) : error C2003: incompatible options for link`.
同样,我是OpenGL新手, 本教程使用的是3.6版,而我使用的是4.6版,所以我不知道这是否可能是一个问题,下面的代码希望您能为我提供帮助(全部一页一页)。
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
//Window dimensions
const GLint SCREEN_WIDTH = 1280, SCREEN_HEIGHT = 900;
GLuint VAO, VBO, shader, uniformModel;
bool isMovingLeft = true;
float triOffset = 0.f;
float triMaxOffset = 0.7;
float triIncrement = 0.005;
//Vertex shader
static const char* vShader = "\n\
#version 460 \n\
\n\
layout(location = 0) in vec3 pos; \n\
\n\
uniform mat4 model; \n\
\n\
void main() { \n\
gl_Position = vec4(0.4 * pos.x + model, 0.4 * pos.y, pos.z, 1.0); \n\
}; \n\
";
//Fragment shader
static const char* fShader = "\n\
#version 460 \n\
\n\
out vec4 color; \n\
\n\
void main() { \n\
color = vec4(0.f, 1.f, 0.f, 1.f); \n\
}; \n\
";
void createTriangle() {
//Vertices of the triangle
GLfloat vertices[] = {
-1.f, -1.f, 0.f,
1.f, -1.f, 0.f,
0.f, 1.f, 0.f
};
//Binding it
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Information
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
//Unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void addShader(GLuint theProgram, const char* shaderCode, GLenum shaderType) {
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetProgramiv(theShader, GL_COMPILE_STATUS, &result);
if (result != GL_FALSE) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
}
glAttachShader(theProgram, theShader);
}
void compileShaders() {
shader = glCreateProgram();
if (shader != GL_TRUE) {
std::cout << "Shader program error!\n";
}
//Adding shaders
addShader(shader, vShader, GL_VERTEX_SHADER);
addShader(shader, fShader, GL_FRAGMENT_SHADER);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
//Linking shader
glLinkProgram(shader);
//Shader linking status
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (result != GL_TRUE) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cout << "Error linking program! " << eLog << '\n';
}
//Gets shader ID and then combines `uniformModel` with `model`
uniformModel = glGetUniformLocation(shader, "model");
}
int main() {
//Initialize GLFW
if (glfwInit() != GLFW_TRUE) {
std::cout << "GLFW init failed\n";
glfwTerminate();
}
//Setup GLFW window properties
//OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); //Large version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); //Small version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Detects any old OpenGL code, this will throw an error
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Allows forward compatibility (between differnt OS)
//Creating window
GLFWwindow* window;
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "OpenGL Test Window", NULL, NULL);
glfwSetWindowPos(window, 250, 100);
if (window == NULL) {
std::cout << "GLFW window creation failed!\n";
glfwTerminate();
}
//Get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(window, &bufferWidth, &bufferHeight);
//Set context for GLEW to use (can change between which window)
glfwMakeContextCurrent(window);
//Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "Glew init failed!\n";
glfwDestroyWindow(window);
glfwTerminate();
}
//Setup viewport size
glViewport(0, 0, bufferWidth, bufferHeight);
createTriangle();
compileShaders();
//Main game loop
while (!glfwWindowShouldClose(window)) {
//Get + Handle user input events
glfwPollEvents();
if (isMovingLeft) {
triOffset += triIncrement;
}
else {
triOffset -= triIncrement;
}
if (abs(triOffset) >= triMaxOffset) {
isMovingLeft = !isMovingLeft;
}
//Clear window
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
//Matrix 4x4
glm::mat4 model;
model = glm::translate(model, glm::vec3(triOffset, triOffset, 0.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(window);
}
}
答案 0 :(得分:1)
制服model
的类型为mat4
。您必须通过顶点着色器中的矩阵来变换顶点坐标:
`gl_Position = vec4(0.4 * pos.x + model, 0.4 * pos.y, pos.z, 1.0);
gl_Position = model * vec4(0.4 * pos.x, 0.4 * pos.y, pos.z, 1.0);
您没有得到错误,因为addShader
中存在问题。着色器对象的编译错误可以通过glGetShaderiv
而不是glGetProgramiv
来获得。如果着色器编译成功,则结果为GL_TRUE
而不是GL_FALSE
:
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
}
此外,glm::mat4 model;
给出了未初始化的矩阵。要获得Identity matrix,您必须将单个标量(1.0)传递给矩阵构造函数:
glm::mat4 model(1.0f);