c++ - 无法获得简单的 2D 着色器以在 C++ openGL 中绘制红色三角形(无编译器错误)
问题描述
我使用了 openGL、GLEW 和 GLFW3。在 openGl 3.0 mesa 中,使用了默认着色器并绘制了一个白色三角形。在 4.2 中,屏幕保持黑色。没有生成错误消息。
该问题不是由于将片段着色器错误标记为顶点着色器,反之亦然。
该程序包含3个功能:
(1) compileShader,它应该将着色器类型和源代码作为 std::string 并返回带有编译代码的着色器 ID。
(2) createProgram,获取顶点着色器和片段着色器的源代码,并返回编译和附加着色器的程序ID。
(3) 和 main,其中两个着色器源代码都定义为字符串。
对不起,谢谢。
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
static unsigned int compileShader(unsigned int type, std::string const& sourceCode){
unsigned int shaderId = glCreateShader(type);
const char* source = sourceCode.c_str();
glShaderSource(shaderId, 1, &source, nullptr);
glCompileShader(shaderId);
int result;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE){
if (type == GL_FRAGMENT_SHADER) std::cout<<"Fragment\n";
else std::cout<<"Vertex";
std::cout<<"SHADER COMPILATION FAILED!"<<std::endl;
int logLength;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLength);
char* infoLog = new char[logLength];
glGetShaderInfoLog(shaderId, logLength, NULL, infoLog);
std::cout<<infoLog<<std::endl;
delete[] infoLog;
glDeleteShader(shaderId);
return 0;
}
return shaderId;
}
static unsigned int createProgram(std::string const& vertexCode, std::string const& fragmentCode){
unsigned int vsId = compileShader(GL_VERTEX_SHADER, vertexCode);
unsigned int fsId = compileShader(GL_FRAGMENT_SHADER, fragmentCode);
unsigned int programId = glCreateProgram();
glAttachShader(programId, vsId);
glAttachShader(programId, fsId);
glLinkProgram(programId);
glValidateProgram(programId);
glDeleteShader(vsId);
glDeleteShader(fsId);
return programId;
}
int main()
{
GLFWwindow* window;
if (!glfwInit())
{
std::cout<<"GLFW initialization failed";
return -1;
}
///switches to opengl 4.2!
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
glewInit();
std::cout << "OpenGL " << glGetString(GL_VERSION) << "\n" << std::endl;
float positions[6] = {
0.5f, 0.5f,
-0.5f, 0.5f,
0.0f, 0.0f
};
unsigned int buffer = 1;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); //enables the xy attrib of position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); //specifies layout of xy attrib
std::string vertexSource = R"(
#version 330 core
layout(location=0) in vec4 position;
void main(){
gl_Position = position;
}
)";
std::string fragmentSource = R"(
#version 330 core
layout(location=0) out vec4 color;
void main(){
color = vec4(1.0, 0.0, 0.0, 1.0);
}
)";
unsigned int programId = createProgram(vertexSource, fragmentSource);
glUseProgram(programId);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
解决方案
问题不在于着色器程序,而是您使用的是核心配置文件OpenGL Context ( GLFW_OPENGL_CORE_PROFILE
)。因此,您必须创建一个命名的顶点数组对象。默认 VAO (0) 在核心配置文件上下文中无效。
通过以下方式生成顶点数组对象名称glGenVertexArrays
并通过以下方式创建和绑定对象glBindVertexArray
:
unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0); //enables the xy attrib of position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); //specifies layout of xy attrib
推荐阅读
- javascript - 离线时如何抓取javascript图表?
- php - PHP变量“模板”?
- android - ionic 3:设备上带有 Android 应用程序的灰色暗屏
- javascript - 使用带有输入文本字段的循环 idb 获取无限循环
- python-3.x - 我的用户验证有问题
- python - Python 未检测到已安装的 selenium
- docker - Jenkins - 无法在 Docker 容器中执行阶段
- java - 子 ExpandableListView 中的 EditText 值重复
- javascript - 当一个表的数据被复制到另一个表时切换按钮
- php - Datetimepicker 时间和日期转换