Свертка шейдера не подойдет?

Я пытался выполнить свертку на 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

0

Решение

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ НЕ ОТВЕТ, но не сработает как комментарий

Добавьте ниже после обеих ваших строк 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, чтобы помочь отладить проблемы со ссылками.

1

Другие решения