2016-11-24 21 views
0

我真的有噩夢來實現我在OpenGles 2.0中所要求的 在發佈代碼引用之前,讓我告訴我需要什麼。切換一個以上的着色器程序(在OpenGL-ES 2.0中)

我有2D紋理片段着色器。在紋理的頂部,我想繪製紅色線。我能夠畫線,但着色爲紅色不起作用。

着色器聲明:

static const char s_v_shader[] = 
    "attribute vec4 vPosition; \n" 
    "attribute vec2 my_Texcoor;  \n" 
    "uniform mat4 u_TransMatrix; \n" 
    "varying vec2 vTexcoor;   \n" 
    "void main() \n" 
    "{ \n" 
    " vTexcoor = my_Texcoor;  \n" 
    " gl_Position = u_TransMatrix*vPosition; \n" 
    "} \n"; 

    static const char s_f_shader[] = 
    "precision mediump float;\n" 
    "uniform sampler2D my_Sampler;     \n" 
    "varying vec2 vTexcoor;       \n" 
    "void main() \n" 
    "{ \n" 
    " vec4 tex = texture2D(my_Sampler, vTexcoor); \n" 
    " gl_FragColor = tex;       \n" 
    "} \n"; 

紋理我從相機中無限循環渲染視頻幀的頂部。 在渲染視頻之前,我使用下面的代碼設置2D紋理的座標。

現在,我將解釋我的代碼主要功能

main() 

    { 
    const GLfloat vertices[][2] = { 
     { -1.0f, -1.0f}, 
     { 1.0f, -1.0f}, 
     { -1.0f, 1.0f}, 
     { 1.0f, 1.0f} 
    }; 

    const GLfloat texcoords[][2] = { 
     { 0.0f, 1.0f}, 
     { 1.0f, 1.0f}, 
     { 0.0f, 0.0f}, 
     { 1.0f, 0.0f} 
    }; 
    GLfloat transformMatrix[16] = 
    { 
     1.0f, 0.0f, 0.0f, 0.0f, 
     0.0f, 1.0f, 0.0f, 0.0f, 
     0.0f, 0.0f, 1.0f, 0.0f, 
     0.0f, 0.0f, 0.0f, 1.0f 
    }; 

     // setup OpenGl environment...... 
     Setup_coordinates() 

    } 

    Setup_coordinates() 
    { 
     LoadShaders(s_v_shader, s_f_shader); 

-- Complete function defined below 
     // By now I should be using shader program. 

     // Grab location of shader attributes. 


    GLint locVertices = glGetAttribLocation(programHandle, "vPosition"); 
       GLint locTexcoord = glGetAttribLocation(programHandle, "my_Texcoor"); 

      // Transform Matrix is uniform for all vertices here. 
       GLint locTransformMat = glGetUniformLocation(programHandle, "u_TransMatrix"); 
       GLint locSampler = glGetUniformLocation(programHandle, "my_Sampler");  

      /* Create the texture. */ 
       glGenTextures(1, &gTexObj); 
       glBindTexture(GL_TEXTURE_2D, gTexObj); 
       if (gTexObj == 0) 
       { 
        printf("Could not load the texture \n"); 
        return -1; 
       } 

       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);  

       glUniformMatrix4fv(locTransformMat, 1, GL_FALSE, transformMatrix); 

       glUniform1i(locSampler, 0); 

       glClearColor(0.0f, 0.5f, 0.0f, 0.0f); 
       glClear(GL_COLOR_BUFFER_BIT); 


      while(1) -- Infinite loop to render video frames on 2D texture and draw red color line. 
      { 
       // enable vertex arrays to push the data. 


    glEnableVertexAttribArray(locVertices); 
       glEnableVertexAttribArray(locTexcoord); 

       // set data in the arrays. 
       glVertexAttribPointer(locVertices, 2, GL_FLOAT, GL_FALSE, 0, &vertices[0][0]); 
       glVertexAttribPointer(locTexcoord, 2, GL_FLOAT, GL_FALSE, 0, &texcoords[0][0]); 

      Render video frames logic goes here................................... 
      Each frame of video is abosultely rendering fine. 

      glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

     Now comes the tricky part to draw the line and color it with red. 



float red_left_1[] = 
    { 
     -0.85f, -0.9f, -0.6f, -0.5f, 
    }; 
     glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, red_left_1); 
     glEnableVertexAttribArray (1); 

     glDrawArrays (GL_LINES , 0, 2); 
     glLineWidth(width_test); 

     } 

     } 



void LoadShaders(const char * vShader, const char * pShader) 
    { 
     vertShaderNum = glCreateShader(GL_VERTEX_SHADER); 
     pixelShaderNum = glCreateShader(GL_FRAGMENT_SHADER); 

     if (CompileShader(vShader, vertShaderNum) == 0) 
     { 
      printf("%d: PS compile failed.\n", __LINE__); 
      return; 
     } 

     if (CompileShader(pShader, pixelShaderNum) == 0) 
     { 
      printf("%d: VS compile failed.\n", __LINE__); 
      return; 
     } 

     programHandle = glCreateProgram(); 

     glAttachShader(programHandle, vertShaderNum); 
     glAttachShader(programHandle, pixelShaderNum); 

     // Bind vPosition to attribute 0 
     glBindAttribLocation (programHandle, 0, "vPosition"); 

     glLinkProgram(programHandle); 
     // Check if linking succeeded. 
     GLint linked = 0; 
     glGetProgramiv(programHandle, GL_LINK_STATUS, &linked); 
     if (!linked) 
     { 
      printf("%d: Link failed.\n", __LINE__); 
      // Retrieve error buffer size. 
      GLint errorBufSize, errorLength; 
      glGetShaderiv(programHandle, GL_INFO_LOG_LENGTH, &errorBufSize); 

      char * infoLog = (char*)malloc(errorBufSize * sizeof (char) + 1); 
      if (infoLog) 
      { 
       // Retrieve error. 
       glGetProgramInfoLog(programHandle, errorBufSize, &errorLength, infoLog); 
       infoLog[errorBufSize + 1] = '\0'; 
       fprintf(stderr, "%s", infoLog); 

       free(infoLog); 
      } 

      return; 
     } 
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
     glUseProgram(programHandle); 
    } 

大多數天才的人民的建議宣佈一個以上着色器同上,但與統一vec4顏色更換制服sampler2D my_Sampler。

void main() 
    { 
    gl_FragColor = color 
    } 

然後同時顯示出紋理和繪圖使用glUseProgram彩色線條這些着色器程序之間切換。

我試過了,絕對放棄了,因爲切換到繪製線的着色器程序無法正常工作。

+0

你有沒有考慮過生成一個紅色的紋理(1x1與一個紅色像素),並切換到繪製線時? – david

+0

@大衛不,我沒有嘗試過。你可以請張貼代碼片段來做到這一點? –

回答

0

這是用於生成可用於您的線的彩色1x1紋理的代碼(請參閱mainSetup_coordinates)。有了這個解決方案,你不需要另一個着色器。

GLuint lineTexture; 
glGenTextures(1, &lineTexture); 
unsigned char red[4] = { 255, 0, 0, 255}; 
glBindTexture(GL_TEXTURE_2D, lineTexture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, red); 
glBindTexture(GL_TEXTURE_2D, 0); 

在致電glDrawArrays之前,請使用此選項切換到正確的紋理。

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, <lineTexture or gTexObj>); 
glUniform1i(locSampler, 0); 

一個更通用的解決方案(我個人實現我的OpenGL項目)是創建一個白色的質地,添加顏色均勻,着色器和乘用的Texture2D返回值的統一。使用此方法,您可以使用相同的白色紋理創建不同的彩色線條和圖形,只需更改顏色均勻。對於視頻幀,您將發送白色,像素將保持不變。這將需要對代碼進行非常少的更改,如果您認爲聽起來更好,我相信您可以弄明白。 :)

+0

非常感謝。你很棒。你是天才。你的邏輯奏效! 。用你的邏輯,我可以繪製彩色線。最後一個問題,我怎樣才能繪製黃色線。 –

+0

如果您想要使用顏色統一解決方案,只需發送黃色(1.f,1.f,0.f,1.f)或(255,255,0,255)的RGBA值而不是紅色。如果不是,請複製第一個片段並更改紅色數組值。 :) – david

+0

是的大衛,做了詭計。再次感謝一噸。 –

相關問題