我已经尝试了一切让OpenGL 3.2在我的游戏引擎中使用CG着色器进行渲染,但我没有运气。所以我决定做一个简单的小项目,但仍然着色器不起作用。从理论上讲,我的测试项目应该只呈现一个红色三角形,但它是白色的,因为着色器没有做任何事情。
我会在这里发布代码:
#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 :(得分:5)
我编译了代码并获得了相同的结果。所以我添加了CG error handler来获取更多信息:
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文档,不得使用GL_EXTENSIONS调用glGetString
,不推荐使用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上下文与以前的OpenGL版本兼容,但3.2不兼容。
经过一些互联网挖掘后,我发现你可以用SDL创建这种兼容的OpenGL上下文,只需在代码中添加这一行:
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
恕我直言,CG工具包需要此类兼容性配置文件。
答案 1 :(得分:0)
“Cg 3.1上下文尚不支持前向兼容的OpenGL上下文!”
来源: http://3dgep.com/introduction-to-shader-programming-with-cg-3-1/
由于Cg项目似乎被放弃了,它也不太可能发生。