Я пытался выполнить свертку на GPU с использованием GLSL, OpenGL, GLFW3. Но я продолжаю получать ERROR: One or more attached shaders not successfully compiled
, Я думал, что правильно прикрепил шейдеры, кто-нибудь может увидеть, где может быть моя ошибка?
Другая проблема — самая высокая версия GLSL, которую я имею, это 120, я не уверен, может ли это быть частью проблемы?
Или я просто отстой в прикреплении шейдеров.
Ниже приведен следующий код: фрагментный шейдер, вершинный шейдер, код вызова, make-файл.
toon.frag
#define KERNEL_SIZE 9
uniform sampler2D colorMap;
uniform float height;
uniform float width;
const float kernel[KERNEL_SIZE] = {1.0/16.0, 2.0/16.0, 1.0/16.0,
2.0/16.0, 4.0/16.0, 2.0/16.0,
1.0/16.0, 2.0/16.0, 1.0/16.0};
const float step_w = 1.0/width;
const float step_h = 1.0/height;
const vec2 offset[KERNEL_SIZE] = {
vec2(-step_w, -step_h), vec2(0.0, -step_h), vec2(step_w, -step_h),
vec2(-step_w, 0.0), vec2(0.0, 0.0), vec2(step_w, 0.0),
vec2(-step_w, step_h), vec2(0.0, step_h), vec2(step_w, step_h)
};
void main(void)
{
int i = 0;
vec4 sum = vec4(0.0);
for( i=0; i<KERNEL_SIZE; i++ )
{
vec4 tmp = texture2D(colorMap, gl_TexCoord[0].st + offset[i]);
sum += tmp * kernel[i];
sum.a = 1.0;
}
gl_FragColor = sum;
}
toon.vert
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}
convShader.cpp
#include <GLFW/glfw3.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
static GLuint texName;
GLuint v,f,p;
int height;
int width;
char *textFileRead(char *fn) {FILE *fp;
char *content = NULL;
int count=0;
if (fn != NULL) {
fp = fopen(fn,"rt");
if (fp != NULL) {
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '\0';
}
fclose(fp);
}
}
return content;
}
void printLog(GLuint obj)
{
int infologLength = 0;
int maxLength;
if(glIsShader(obj))
glGetShaderiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
else
glGetProgramiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
char infoLog[maxLength];
if (glIsShader(obj))
glGetShaderInfoLog(obj, maxLength, &infologLength, infoLog);
else
glGetProgramInfoLog(obj, maxLength, &infologLength, infoLog);
if (infologLength > 0)
printf("%s\n",infoLog);
}
void initImage(cv::Mat Image)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, Image.cols, Image.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, Image.data);
}
static void error_callback(int error, const char* description)
{
fputs(description, stderr);
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
if (action == GLFW_PRESS)
{
switch (key)
{
case GLFW_KEY_UP:
alpha *= 2;
break;
case GLFW_KEY_DOWN:
alpha /= 2;
break;
case GLFW_KEY_SPACE:
alpha *= -1;
break;
}
}
}
void setShaders() {
char *vs = NULL,*fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead("toon.vert");
fs = textFileRead("toon.frag");
const char * ff = fs;
const char * vv = vs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,v);
glLinkProgram(p);
glUseProgram(p);
}
int main(void)
{
GLFWwindow* window;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
cv::Mat image = cv::imread("lena.tiff");
width = image.cols;
height = image.rows;
window = glfwCreateWindow(width, height, "Simple example", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window))
{
//int height, width;
float ratio;
//glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float) height;
glViewport(0, 0, width, height);
setShaders();
initImage(image);
glActiveTexture(GL_TEXTURE0);
GLint loc1 = glGetUniformLocation(p, "colorMap");
glUniform1i(loc1, 0);
GLint loc2 = glGetUniformLocation(p,"height");
glUniform1f(loc2,(float)height);
GLint loc3 = glGetUniformLocation(p,"width");
glUniform1f(loc3,(float)width);
printLog(p);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
//glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f);
//glOrtho(0, width, 0, height, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
/*
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, height, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(width, height, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(width, 0.0, 0.0);
*/
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}
Makefile
convShader: convShader.cpp
g++ -o convShader convShader.cpp -I/usr/local/include -L/usr/local/lib -ltextfile -lglfw3 -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -lopencv_core -lopencv_highgui
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ НЕ ОТВЕТ, но не сработает как комментарий
Добавьте ниже после обеих ваших строк glCompileShader
char buffer[1000];
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if ((infoLen > 1) && (infoLen < 1000)) {
glGetShaderInfoLog(shader, infoLen, NULL, buffer);
printf("ERROR: %s", buffer)
}
}
Это даст вам ошибки компиляции в вашем шейдере и позволит вам отладить этот аспект. ПРИМЕЧАНИЕ. Вы можете сделать то же самое после шага ссылки с помощью GL_LINK_STATUS, чтобы помочь отладить проблемы со ссылками.