2012-12-26 44 views
1

我已經嘗試了一切,以獲得OpenGL 3.2呈現與CG着色器在我的遊戲引擎,但我沒有運氣。所以我決定做一個最基本的項目,但仍然着色器不起作用。從理論上講,我的測試項目應該渲染一個紅色的三角形,但它是白色的,因爲着色器沒有做任何事情。爲什麼CG着色器不能使用GL 3.2?

我會張貼在這裏的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <vector> 
#include <string> 
#include <GL/glew.h> 
#include <Cg/cg.h> 
#include <Cg/cgGL.h> 
#include <SDL2/SDL.h> 

int main() 
{ 
    SDL_Window *mainwindow; 
    SDL_GLContext maincontext; 

    SDL_Init(SDL_INIT_VIDEO); 

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 

    mainwindow = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); 

    maincontext = SDL_GL_CreateContext(mainwindow); 

    glewExperimental = GL_TRUE; 
    glewInit(); 

    _CGcontext* cgcontext; 
    cgcontext = cgCreateContext(); 
    cgGLRegisterStates(cgcontext); 

    CGerror error; 
    CGeffect effect; 
    const char* string; 
    std::string shader; 

    shader = 
      "struct VS_INPUT" 
      "{" 
      " float3 pos    : ATTR0;" 
      "};" 

      "struct FS_INPUT" 
      "{" 
      " float4 pos     : POSITION;" 
      " float2 tex     : TEXCOORD0;" 
      "};" 

      "struct FS_OUTPUT" 
      "{" 
      " float4 color    : COLOR;" 
      "};" 

      "FS_INPUT VS(VS_INPUT In)" 
      "{" 
      " FS_INPUT Out;" 
      " Out.pos = float4(In.pos, 1.0f);" 
      " Out.tex = float2(0.0f, 0.0f);" 
      " return Out;" 
      "}" 

      "FS_OUTPUT FS(FS_INPUT In)" 
      "{" 
      " FS_OUTPUT Out;" 
      " Out.color = float4(1.0f, 0.0f, 0.0f, 1.0f);" 
      " return Out;" 
      "}" 

      "technique t0" 
      "{" 
      " pass p0" 
      " {" 
      "  VertexProgram = compile gp4vp VS();" 
      "  FragmentProgram = compile gp4fp FS();" 
      " }" 
      "}"; 

    effect = cgCreateEffect(cgcontext, shader.c_str(), NULL); 
    error = cgGetError(); 
    if(error) 
    { 
     string = cgGetLastListing(cgcontext); 
     fprintf(stderr, "Shader compiler: %s\n", string); 
    } 

    glClearColor (0.0, 0.0, 1.0, 1.0); 
    glClear (GL_COLOR_BUFFER_BIT); 

    float* vert = new float[9]; 

    vert[0] = 0.0; vert[1] = 0.5; vert[2] =-1.0; 
    vert[3] =-1.0; vert[4] =-0.5; vert[5] =-1.0; 
    vert[6] = 1.0; vert[7] =-0.5; vert[8]= -1.0; 

    unsigned int m_vaoID; 
    unsigned int m_vboID; 

    glGenVertexArrays(1, &m_vaoID); 
    glBindVertexArray(m_vaoID); 

    glGenBuffers(1, &m_vboID); 

    glBindBuffer(GL_ARRAY_BUFFER, m_vboID); 
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), vert, GL_STATIC_DRAW); 

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glEnableVertexAttribArray(0); 

    CGtechnique tech = cgGetFirstTechnique(effect); 
    CGpass pass = cgGetFirstPass(tech); 
    while (pass) 
    { 
     cgSetPassState(pass); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 
     cgResetPassState(pass); 
     pass = cgGetNextPass(pass); 
    } 

    glDisableVertexAttribArray(0); 

    glBindVertexArray(0); 

    delete[] vert; 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glDeleteBuffers(1, &m_vboID); 
    glDeleteVertexArrays(1, &m_vaoID); 

    SDL_GL_SwapWindow(mainwindow); 
    SDL_Delay(2000); 

    SDL_GL_DeleteContext(maincontext); 
    SDL_DestroyWindow(mainwindow); 
    SDL_Quit(); 

    return 0; 
} 

我在做什麼錯?

+0

什麼,我知道CG = Nvidia着色器,另外OpenGL支持GLSL作爲着色語言而不是CG。 – user1797612

+0

@ user1797612 CG可以同時用於OpenGL和Direct3D。 –

回答

5

我編譯了代碼並得到了相同的結果。所以我增加了一個CG error handler,以獲得更多的信息的比特:

void errorHandler(CGcontext context, CGerror error, void * appdata) { 
    fprintf(stderr, "%s\n", cgGetErrorString(error)); 
} 
... 
cgSetErrorHandler(&errorHandler, NULL); 

cgSetPassStatecgResetPassState被稱爲我得到了以下錯誤消息:

技術沒有通過驗證。

當然,不是非常有用的信息。所以我使用GLIntercept來跟蹤所有OpenGL對日誌文件的調用。

這一次,當glewInit叫我在日誌文件中出現以下錯誤信息:

glGetString(GL_EXTENSIONS)= NULL glGetError()= GL_INVALID_ENUM

據OpenGL的文檔,glGetString不能用GL_EXTENSIONS調用,在3.0中不推薦使用,必須使用glGetStringi

最後,我發現這個問題的GLEW庫:http://sourceforge.net/p/glew/bugs/120/

我刪除GLEW依賴和與gl3.h(和最近glcorearb.h)進行測試。我得到了同樣的錯誤,但是這次調用cgGLRegisterStates

我也試過CG trace.dll,只是爲了獲得同樣的錯誤(7939 = 0x1F03 = GL_EXTENSIONS):

glGetString 
    { 
    input: 
    name = 7939 
    output: 
    return = NULL 
    } 

然後,我測試的OpenGL 3.1(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);),並發現它是工作的罰款:

glGetString(GL_EXTENSIONS)= 「GL_AMD_multi_draw_indirec ...」

即,3.1上下文WA s與以前的OpenGL版本兼容,但不是3.2。

在一些互聯網上挖我發現,您可以創建這種類型與SDL兼容OpenGL上下文的,剛剛加入這一行代碼後:

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); 

恕我直言,CG工具包需要這種類型的相容性分佈的。 「

+0

我不想創建兼容性配置文件,我已經知道我可以做到這一點。 GL3頭,它仍然不起作用我不認爲問題是與GL_EXTENSIONS,但它聽起來像你可能會與「技術沒有通過驗證。「我需要一個使用純粹核心配置文件的解決方案。 – SteveDeFacto

+0

@SteveDeFacto對我來說,「技術沒有通過驗證」錯誤出現,因爲GLEW庫失敗,然後'glCreateProgram','glCreateShader',...永遠不會被調用。你可以用'cgIsTechniqueValidated'函數來測試它。要使用核心配置文件,我需要下載GLEW源代碼,應用補丁並再次測試。順便說一句,你有沒有試過GLIntercept或類似的? –

+0

試試這個,而不是glew: http://www.opengl.org/registry/api/gl3.h 它是用於OpenGL核心配置文件,仍然無法正常工作。 – SteveDeFacto