我在我的简单OpenGL项目中添加了非常简单的GLSL着色器,但它不起作用。
#include <python3.6m/Python.h>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <vector>
#include <fstream>
#include <sstream>
using namespace glm;
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path){
// Создаем шейдеры
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Загружаем код Вершинного Шейдера из файла
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if (VertexShaderStream.is_open()) {
std::stringstream sstr;
sstr << VertexShaderStream.rdbuf();
VertexShaderCode = sstr.str();
VertexShaderStream.close();
}
// Загружаем код Фрагментного шейдера из файла
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if (FragmentShaderStream.is_open()){
std::stringstream sstr;
sstr << FragmentShaderStream.rdbuf();
FragmentShaderCode = sstr.str();
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Компилируем Вершинный шейдер
printf("Компиляция шейдера: %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Выполняем проверку Вершинного шейдера
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
}
// Компилируем Фрагментный шейдер
printf("Компиляция шейдера: %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Проверяем Фрагментный шейдер
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
}
// Создаем шейдерную программу и привязываем шейдеры к ней
fprintf(stdout, "Создаем шейдерную программу и привязываем шейдеры к ней\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Проверяем шейдерную программу
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
int main(int argc, char *argv[]) {
// Инициализируем GLFW
if (!glfwInit()) {
fprintf( stderr, "Ошибка при инициализации GLFW\n" );
return -1;
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_SAMPLES, 4); // Включаем сглаживание
glEnable(GL_MULTISAMPLE);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Мы хотим использовать OpenGL 3.3
// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Мы не хотим старый OpenGL
// Открыть окно и создать в нем контекст OpenGL
GLFWwindow* window; // (В сопроводительном исходном коде эта переменная является глобальной)
window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
if (window == NULL) {
fprintf( stderr, "Невозможно открыть окно GLFW. Если у вас Intel GPU, то он не поддерживает версию 3.3. Попробуйте версию уроков для OpenGL 2.1.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Инициализируем GLEW
glewExperimental=true; // Флаг необходим в Core-режиме OpenGL
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Невозможно инициализировать GLEW\n");
return -1;
}
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Массив 3 векторов, которые являются вершинами треугольника
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.5f, 1.0f, 0.0f,
};
// Это будет идентификатором нашего буфера вершин
GLuint vertexbuffer;
// Создадим 1 буфер и поместим в переменную vertexbuffer его идентификатор
glGenBuffers(1, &vertexbuffer);
// Сделаем только что созданный буфер текущим
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Передадим информацию о вершинах в OpenGL
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
// Включим режим отслеживания нажатия клавиш, для проверки ниже
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Создать и откомпилировать нашу шейдерную программу
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
do {
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Устанавливаем наш шейдер текущим
// glUseProgram(programID);
// Рисуем треугольник...
// Указываем, что первым буфером атрибутов будут вершины
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // Атрибут 0. Подробнее об этом будет рассказано в части, посвященной шейдерам.
3, // Размер
GL_FLOAT, // Тип
GL_FALSE, // Указывает, что значения не нормализованы
0, // Шаг
(void*) nullptr // Смещение массива в буфере
);
// Вывести треугольник!
glDrawArrays(GL_TRIANGLES, 0, 3); // Начиная с вершины 0, всего 3 вершины -> один треугольник
glDisableVertexAttribArray(0);
// Сбрасываем буферы
glfwSwapBuffers(window);
glfwPollEvents();
} // Проверяем нажатие клавиши Escape или закрытие окна
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
}
我看到黑色的窗口(如果我写
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
否则我看到错误:
编译着色器:SimpleVertexShader.vertexshader 0:1(10):错误:不支持GLSL 3.30。支持的版本为:1.10、1.20、1.30、1.00 ES和3.00 ES
*编译着色器:SimpleFragmentShader.fragmentshader * 创建着色器程序并链接... 错误:与未编译/未专业化的着色器链接
)
顶点着色器:
#version 300 es
layout(location = 0) in vec3 vertexPosition_modelspace;
void main(){
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
片段着色器:
#version 300 es
precision mediump float;
layout(location = 0) out vec3 color;
void main() {
color = vec3(1,0,0);
}
答案 0 :(得分:1)
GLuint programID = ...
您实际上已经成功创建并链接了程序对象,但从未对其进行激活。您必须在抽奖电话之前的某个地方添加glUseProgram(programID)
。