带有 GLFW 和 GLEW 的 OpenGL 不渲染立方体? C++、GLM
OpenGL with GLFW and GLEW not rendering cube? C++, GLM
我对 OpenGL、GLFW 或 GLEW 的经验不多,因此我对这些库的故障排除能力很弱 none。我设法渲染了一个三角形 ([-1, -1, 0], [1, -1, 0], [0, 1, 0]) 但是当使用立方体的顶点属性坐标以及颜色属性时它似乎没有渲染。我的代码、着色器和矩阵运算可能有很多错误。我希望我能更清楚地了解我在做什么,这样我就可以对我的错误进行更具描述性的描述。目前上面的代码只渲染了 window。我最初遵循 https://learnopengl.com/ 并获得了第一个教程,下面的代码是我的“测试”文件,我试图自己重新实现一些元素。如果有帮助,可以与该教程共享很多复制粘贴的部分。
如有任何见解或建议,我们将不胜感激。
Main Source
#include "global.hpp"
using namespace std;
using namespace glm;
static const GLfloat g_color_buffer_data[] = {
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
};
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, // triangle 1 : end
1.0f, 1.0f,-1.0f, // triangle 2 : begin
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f, // triangle 2 : end
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};
extern const char* VertexShader = R"(
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
uniform mat4 MVP;
out vec3 fragmentColor;
//out vec2 UV;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
//UV = vertexUV;
fragmentColor = vertexColor;
}
)";
extern const char* FragmentShader = R"(
#version 330 core
in vec3 fragmentColor;
out vec3 color;
void main(){
//color = vec3(1,0,0);
color = fragmentColor;
}
)";
static const float tri_vertex_array[] = {
-.8, .8, 0,
-.8, -.8, 0,
.8, -.8, 0
};
int main()
{
if (!glfwInitFull()) {
printf("Unable To Init\n");
return 1;
}
uint width = 1200, height = 720;
GLFWwindow* window = glfwCreateWindow(width, height, "ME", 0, 0);
if (!window)
return -1;
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return 0;
//
GLuint VertexArrayId;
glGenVertexArrays(1, &VertexArrayId);
glBindVertexArray(VertexArrayId);
//
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
//glBufferData(GL_ARRAY_BUFFER, sizeof(tri_vertex_array), tri_vertex_array, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint colorBuffer;
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
GLuint vertexShaderId = compileShader(VertexShader, GL_VERTEX_SHADER);
GLuint fragmentShaderId = compileShader(FragmentShader, GL_FRAGMENT_SHADER);
GLuint programId = glCreateProgram();
linkShader(programId, vertexShaderId);
linkShader(programId, fragmentShaderId);
// maybe nessacary?
//glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LESS);
glEnable(GL_CULL_FACE);
glViewport(0, 0, width, height);
//vec3 cameraPos = vec3(0.f, 0.f, 3.f);
//vec3 cameraTarget = vec3(0.f, 0.f, 0.f);
//vec3 cameraDirection = normalize(cameraPos - cameraTarget);
//
//vec3 up = vec3(0.f, 1.f, 0.f);
//vec3 right = normalize(
// cross(
// up,
// cameraDirection
// )
//);
//
//vec3 cameraUp = cross(cameraDirection, right);
//
//mat4 view = lookAt(
// vec3(4.f, 3.f, 3.f),
// vec3(0.f, 0.f, 0.f),
// vec3(0.f, 1.f, 0.f)
//);
mat4 projection = perspective(radians(45.f), width / (float)height, .1f, 100.f);
mat4 view = lookAt(
vec3(4, 3, -3),
vec3(0, 0, 0),
vec3(0, 1, 0)
);
mat4 model = mat4(1.0f); // identity
mat4 mvp = projection * view * model;
GLuint mvpId = glGetUniformLocation(programId, "MVP");
do {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.f, .4f, 0.f);
glUseProgram(programId);
//gluLookAt(
// 4, 3, 3,
// 0, 0, 0,
// 0, 1, 0
//);
glUniformMatrix4fv(mvpId, 1, 0, &mvp[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
NULL
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glDrawArrays(GL_TRIANGLES, 0, 3*12);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
} while (
!glfwWindowShouldClose(window)
&&
!glfwGetKey(window, GLFW_KEY_ESCAPE)
);
glfwTerminate();
}
global.hpp
#ifndef _glfw3_h_
// opengl extensions
#include <GL/glew.h>
// opengl utility / wrapper
#include <GLFW/glfw3.h>
// operations in space
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#endif // !_glfw3_h_
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <fstream>
#include <random>
#include <ctime>
#include <cmath>
static void glfwErrorCb(int errorCode, const char* error) {
printf("GLFW Error Thrown\n -> %d\n%s\n", errorCode, error);
}
static bool glfwInitFull() {
srand(time(0));
if (!glfwInit())
return 0;
glfwSetErrorCallback(glfwErrorCb);
glewExperimental = true;
glfwWindowHint(GLFW_SAMPLES, 4); // anti-aliasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // no-old-gl
return 1;
}
static GLuint compileShader(const char* content, GLenum type) {
GLuint shaderId = glCreateShader(type);
GLint returnValBuf;
glShaderSource(shaderId, 1, &content, NULL);
glCompileShader(shaderId);
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &returnValBuf);
if (returnValBuf == GL_FALSE) {
printf("Unable To Compile Shader\n```\n%s\n```\n\nInfo Log:\n", content);
GLint logLen;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen <= 0)
return 0;
char* infoBuffer = new char[logLen + 1];
infoBuffer[logLen] = '[=11=]';
glGetShaderInfoLog(shaderId, logLen, &returnValBuf, infoBuffer);
printf("%s\n", infoBuffer);
delete[] infoBuffer;
return 0;
}
return shaderId;
}
static GLuint linkShader(GLuint programId, GLuint shaderId) {
glAttachShader(programId, shaderId);
glLinkProgram(programId);
GLint returnValBuf;
glGetProgramiv(programId, GL_LINK_STATUS, &returnValBuf);
if (returnValBuf == GLFW_FALSE) {
printf("Unable To Link Shader\nInfo Log:\n");
GLint logLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen <= 0)
return 0;
char* infoBuffer = new char[logLen + 1];
infoBuffer[logLen] = '[=11=]';
glGetProgramInfoLog(programId, logLen, &returnValBuf, infoBuffer);
printf("%s\n", infoBuffer);
delete[] infoBuffer;
}
glDetachShader(programId, shaderId);
glDeleteShader(shaderId);
return programId;
}
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ullong;
#pragma once
问题是您为每个着色器单独调用 linkShader
。可以多次 link 一个程序。然而,函数 linkShader
将着色器附加到程序, link es 程序并将着色器与程序分离。因此,顶点和片段着色器永远不会同时附加。
附加顶点和片段着色器并调用linkShader
一次:
static GLuint linkShader(GLuint programId) {
glLinkProgram(programId);
GLint returnValBuf;
glGetProgramiv(programId, GL_LINK_STATUS, &returnValBuf);
if (returnValBuf == GLFW_FALSE) {
printf("Unable To Link Shader\nInfo Log:\n");
GLint logLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen <= 0)
return 0;
char* infoBuffer = new char[logLen + 1];
infoBuffer[logLen] = '[=10=]';
glGetProgramInfoLog(programId, logLen, &returnValBuf, infoBuffer);
printf("%s\n", infoBuffer);
delete[] infoBuffer;
}
return programId;
}
int main()
{
// [...]
GLuint vertexShaderId = compileShader(VertexShader, GL_VERTEX_SHADER);
GLuint fragmentShaderId = compileShader(FragmentShader, GL_FRAGMENT_SHADER);
GLuint programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
linkShader(programId);
glDetachShader(programId, vertexShaderId);
glDeleteShader(vertexShaderId);
glDetachShader(programId, fragmentShaderId);
glDeleteShader(fragmentShaderId);
// [...]
}
我对 OpenGL、GLFW 或 GLEW 的经验不多,因此我对这些库的故障排除能力很弱 none。我设法渲染了一个三角形 ([-1, -1, 0], [1, -1, 0], [0, 1, 0]) 但是当使用立方体的顶点属性坐标以及颜色属性时它似乎没有渲染。我的代码、着色器和矩阵运算可能有很多错误。我希望我能更清楚地了解我在做什么,这样我就可以对我的错误进行更具描述性的描述。目前上面的代码只渲染了 window。我最初遵循 https://learnopengl.com/ 并获得了第一个教程,下面的代码是我的“测试”文件,我试图自己重新实现一些元素。如果有帮助,可以与该教程共享很多复制粘贴的部分。
如有任何见解或建议,我们将不胜感激。
Main Source
#include "global.hpp"
using namespace std;
using namespace glm;
static const GLfloat g_color_buffer_data[] = {
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
};
static const GLfloat g_vertex_buffer_data[] = {
-1.0f,-1.0f,-1.0f, // triangle 1 : begin
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, // triangle 1 : end
1.0f, 1.0f,-1.0f, // triangle 2 : begin
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f, // triangle 2 : end
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};
extern const char* VertexShader = R"(
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
uniform mat4 MVP;
out vec3 fragmentColor;
//out vec2 UV;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
//UV = vertexUV;
fragmentColor = vertexColor;
}
)";
extern const char* FragmentShader = R"(
#version 330 core
in vec3 fragmentColor;
out vec3 color;
void main(){
//color = vec3(1,0,0);
color = fragmentColor;
}
)";
static const float tri_vertex_array[] = {
-.8, .8, 0,
-.8, -.8, 0,
.8, -.8, 0
};
int main()
{
if (!glfwInitFull()) {
printf("Unable To Init\n");
return 1;
}
uint width = 1200, height = 720;
GLFWwindow* window = glfwCreateWindow(width, height, "ME", 0, 0);
if (!window)
return -1;
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return 0;
//
GLuint VertexArrayId;
glGenVertexArrays(1, &VertexArrayId);
glBindVertexArray(VertexArrayId);
//
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
//glBufferData(GL_ARRAY_BUFFER, sizeof(tri_vertex_array), tri_vertex_array, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
GLuint colorBuffer;
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
GLuint vertexShaderId = compileShader(VertexShader, GL_VERTEX_SHADER);
GLuint fragmentShaderId = compileShader(FragmentShader, GL_FRAGMENT_SHADER);
GLuint programId = glCreateProgram();
linkShader(programId, vertexShaderId);
linkShader(programId, fragmentShaderId);
// maybe nessacary?
//glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LESS);
glEnable(GL_CULL_FACE);
glViewport(0, 0, width, height);
//vec3 cameraPos = vec3(0.f, 0.f, 3.f);
//vec3 cameraTarget = vec3(0.f, 0.f, 0.f);
//vec3 cameraDirection = normalize(cameraPos - cameraTarget);
//
//vec3 up = vec3(0.f, 1.f, 0.f);
//vec3 right = normalize(
// cross(
// up,
// cameraDirection
// )
//);
//
//vec3 cameraUp = cross(cameraDirection, right);
//
//mat4 view = lookAt(
// vec3(4.f, 3.f, 3.f),
// vec3(0.f, 0.f, 0.f),
// vec3(0.f, 1.f, 0.f)
//);
mat4 projection = perspective(radians(45.f), width / (float)height, .1f, 100.f);
mat4 view = lookAt(
vec3(4, 3, -3),
vec3(0, 0, 0),
vec3(0, 1, 0)
);
mat4 model = mat4(1.0f); // identity
mat4 mvp = projection * view * model;
GLuint mvpId = glGetUniformLocation(programId, "MVP");
do {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.f, .4f, 0.f);
glUseProgram(programId);
//gluLookAt(
// 4, 3, 3,
// 0, 0, 0,
// 0, 1, 0
//);
glUniformMatrix4fv(mvpId, 1, 0, &mvp[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
NULL
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
glDrawArrays(GL_TRIANGLES, 0, 3*12);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glfwSwapBuffers(window);
glfwPollEvents();
} while (
!glfwWindowShouldClose(window)
&&
!glfwGetKey(window, GLFW_KEY_ESCAPE)
);
glfwTerminate();
}
global.hpp
#ifndef _glfw3_h_
// opengl extensions
#include <GL/glew.h>
// opengl utility / wrapper
#include <GLFW/glfw3.h>
// operations in space
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#endif // !_glfw3_h_
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <fstream>
#include <random>
#include <ctime>
#include <cmath>
static void glfwErrorCb(int errorCode, const char* error) {
printf("GLFW Error Thrown\n -> %d\n%s\n", errorCode, error);
}
static bool glfwInitFull() {
srand(time(0));
if (!glfwInit())
return 0;
glfwSetErrorCallback(glfwErrorCb);
glewExperimental = true;
glfwWindowHint(GLFW_SAMPLES, 4); // anti-aliasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // no-old-gl
return 1;
}
static GLuint compileShader(const char* content, GLenum type) {
GLuint shaderId = glCreateShader(type);
GLint returnValBuf;
glShaderSource(shaderId, 1, &content, NULL);
glCompileShader(shaderId);
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &returnValBuf);
if (returnValBuf == GL_FALSE) {
printf("Unable To Compile Shader\n```\n%s\n```\n\nInfo Log:\n", content);
GLint logLen;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen <= 0)
return 0;
char* infoBuffer = new char[logLen + 1];
infoBuffer[logLen] = '[=11=]';
glGetShaderInfoLog(shaderId, logLen, &returnValBuf, infoBuffer);
printf("%s\n", infoBuffer);
delete[] infoBuffer;
return 0;
}
return shaderId;
}
static GLuint linkShader(GLuint programId, GLuint shaderId) {
glAttachShader(programId, shaderId);
glLinkProgram(programId);
GLint returnValBuf;
glGetProgramiv(programId, GL_LINK_STATUS, &returnValBuf);
if (returnValBuf == GLFW_FALSE) {
printf("Unable To Link Shader\nInfo Log:\n");
GLint logLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen <= 0)
return 0;
char* infoBuffer = new char[logLen + 1];
infoBuffer[logLen] = '[=11=]';
glGetProgramInfoLog(programId, logLen, &returnValBuf, infoBuffer);
printf("%s\n", infoBuffer);
delete[] infoBuffer;
}
glDetachShader(programId, shaderId);
glDeleteShader(shaderId);
return programId;
}
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ullong;
#pragma once
问题是您为每个着色器单独调用 linkShader
。可以多次 link 一个程序。然而,函数 linkShader
将着色器附加到程序, link es 程序并将着色器与程序分离。因此,顶点和片段着色器永远不会同时附加。
附加顶点和片段着色器并调用linkShader
一次:
static GLuint linkShader(GLuint programId) {
glLinkProgram(programId);
GLint returnValBuf;
glGetProgramiv(programId, GL_LINK_STATUS, &returnValBuf);
if (returnValBuf == GLFW_FALSE) {
printf("Unable To Link Shader\nInfo Log:\n");
GLint logLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);
if (logLen <= 0)
return 0;
char* infoBuffer = new char[logLen + 1];
infoBuffer[logLen] = '[=10=]';
glGetProgramInfoLog(programId, logLen, &returnValBuf, infoBuffer);
printf("%s\n", infoBuffer);
delete[] infoBuffer;
}
return programId;
}
int main()
{
// [...]
GLuint vertexShaderId = compileShader(VertexShader, GL_VERTEX_SHADER);
GLuint fragmentShaderId = compileShader(FragmentShader, GL_FRAGMENT_SHADER);
GLuint programId = glCreateProgram();
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
linkShader(programId);
glDetachShader(programId, vertexShaderId);
glDeleteShader(vertexShaderId);
glDetachShader(programId, fragmentShaderId);
glDeleteShader(fragmentShaderId);
// [...]
}