1

ゲーム エンジンの CG シェーダーで OpenGL 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;
}

私は何を間違っていますか?

4

2 に答える 2

5

コードをコンパイルして同じ結果が得られました。そこで、もう少し情報を取得するためにCGエラーハンドラーを追加しました。

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

cgSetPassStateとが呼び出されたときcgResetPassState、次のエラーメッセージが表示されました。

テクニックは検証に合格しませんでした。

もちろん、あまり有益ではありません。そこで、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はが呼び出されました。

同じエラー(7939 = 0x1F03 = )を取得するために、 CGtrace.dllも試しました。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コンテキストは以前のOpenGLバージョンと互換性がありましたが、3.2は互換性がありませんでした。

インターネットを少し掘り下げた後、コードに次の行を追加するだけで、SDLを使用してこのタイプの互換性のあるOpenGLコンテキストを作成できることがわかりました。

SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);

IMHO、CG Toolkitには、このタイプの互換性プロファイルが必要です。

于 2012-12-28T18:05:26.783 に答える
0

「Cg 3.1 コンテキストは、前方互換性のある OpenGL コンテキストをまだサポートしていません!」

ソース: http://3dgep.com/introduction-to-shader-programming-with-cg-3-1/

Cg プロジェクトが放棄されているように見えるので、それも起こりそうにありません。

于 2014-10-23T01:06:58.487 に答える