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

0

Я пытался выполнить свертку на графическом процессоре с использованием GLSL, OpenGL, GLFW3. Но я продолжаю получать ERROR: One or more attached shaders not successfully compiled. Я думал, что правильно прикрепил шейдеры, может ли кто-нибудь увидеть, где моя ошибка?

Другая проблема - это самая высокая версия GLSL. У меня есть 120, я не уверен, что это может быть частью проблемы?

Или я просто сосать при прикреплении шейдеров.

Ниже приведен следующий код: шейдер фрагмента, шейдер вершин, код вызова, makefile.

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
  • 1
    Многие компиляторы GLSL не рассматривают const float step_w = 1.0/width; постоянная. Например, если вы попытаетесь его квалифицировать таким образом на компиляторе NV, он откажется компилировать, потому что width uniform . Можете ли вы распечатать журнал информации о шейдере после попытки скомпилировать шейдер?
  • 1
    Кроме того, не используйте glIsShader (obj) чтобы выяснить, является ли переданное имя объектом или программой шейдера. Цель этой функции не в том, чтобы идентифицировать тип объекта, которым является имя (которое фактически потенциально невозможно), а в том, идентифицирует ли имя зарезервированный объект. Для вас вполне возможно иметь программу GLSL с именем 1 и шейдер GLSL с именем 1 , glIsShader (...) вернет GL_TRUE если вы передадите 1 , но это не говорит о том, что вы пытались идентифицировать шейдер ; это могла быть программа с именем 1 . Короче говоря, разделите вашу функцию printLog .
Теги:
opencv
opengl
glsl
convolution

1 ответ

1

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню