SkyBox纹理未显示(NVIDIA CG)

时间:2013-05-29 17:13:35

标签: c++ opengl shader nvidia cg

这是我的Box.cpp代码:

using namespace std;
#include <stdio.h>
#include "Box.h"


void MyErrorCallback(void)

{

const char* errorString = cgGetErrorString(cgGetError());

printf("Cg error: %s", errorString);

}

Box::Box(CGcontext cgContext, const char* fxFname) {
cgVProfile = cgGLGetLatestProfile( CG_GL_VERTEX );
cgVProgram = cgCreateProgramFromFile(cgContext, CG_SOURCE, fxFname, cgVProfile, "main", 0);
cgGLLoadProgram(cgVProgram);
cgTexProg = cgCreateProgramFromFile(cgContext, CG_SOURCE, fxFname, cgVProfile, "texProg", 0);
cgGLLoadProgram(cgTexProg);
if(!(shaderTexture = cgGetNamedProgramParameter(cgTexProg,CG_GLOBAL,"tex")))
{
    fprintf(stderr, "Cannot get a handle to a shader parameter\n");
    exit(EXIT_FAILURE);
}
cgGLSetupSampler( shaderTexture, setTexture());

cgWVP   = cgGetNamedParameter( cgVProgram, "wvp" );
model = glm::mat4(1.0f);
// set up geometry
static const GLfloat vertices[] = {
        // Front face
        -30.0, -30.0,  30.0,
        30.0, -30.0,  30.0,
        30.0,  30.0,  30.0,
        -30.0,  30.0,  30.0,

        // Back face
        -30.0, -30.0, -15.0,
        -30.0,  30.0, -30.0,
        30.0,  30.0, -30.0,
        30.0, -30.0, -30.0,

        // Top face
        -30.0,  30.0, -30.0,
        -30.0,  30.0,  30.0,
        30.0,  30.0,  30.0,
        30.0,  30.0, -30.0,

        // Bottom face
        -30.0, -30.0, -30.0,
        30.0, -30.0, -30.0,
        30.0, -30.0,  30.0,
        -30.0, -30.0,  30.0,

        // Right face
        30.0, -30.0, -30.0,
        30.0,  30.0, -30.0,
        30.0,  30.0,  30.0,
        30.0, -30.0,  30.0,

        // Left face
        -30.0, -30.0, -30.0,
        -30.0, -30.0,  30.0,
        -30.0,  30.0,  30.0,
        -30.0,  30.0, -30.0
};
static const GLushort indices[] = {
        0,  1,  2,
        0,  2,  3,
        4,  5,  6,
        4,  6,  7,
        8,  9,  10,
        8,  10, 11,
        12, 13, 14,
        12, 14, 15,
        16, 17, 18,
        16, 18, 19,
        20, 21, 22,
        20, 22, 23

};

glGenBuffers( 1, & vertexbuffer );
glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
glBufferData( GL_ARRAY_BUFFER, 72 * sizeof(GLfloat), & vertices[0], GL_STATIC_DRAW );

glGenBuffers( 1, & indexbuffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexbuffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, 36 * sizeof(GLushort), & indices[0], GL_STATIC_DRAW );
}

Box::~Box() {
glDeleteBuffers( 1, & vertexbuffer );
glDeleteBuffers( 1, & indexbuffer );
}




void Box::render(const glm::mat4 vp){
cgSetErrorCallback(MyErrorCallback);
cgGLEnableProfile(cgVProfile);
cgGLBindProgram(cgVProgram);
cgGLSetMatrixParameterfc(cgWVP, glm::value_ptr(vp*model));
cgGLBindProgram(cgTexProg);


// 1rst attribute buffer : vertices
glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexbuffer );

glEnableVertexAttribArray( 0 );
glVertexAttribPointer(
        0,                  // attribute number; must match the layout in the shader
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized
        0,                  // stride
        (void*)0            // array buffer offset
);
cgGLEnableTextureParameter( shaderTexture );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glDrawElements( GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (GLvoid*)0 );
glDisableVertexAttribArray( 0 );
cgGLDisableTextureParameter( shaderTexture );
}

void Box::loabBMPTexture( const char* imagepath, GLenum target )
{
cgSetErrorCallback(MyErrorCallback);
FILE*    fh = NULL;

fh = fopen( imagepath, "rb" );
assert( fh );

char header[54];

if ( fread(header, 1, 54, fh ) != 54 )
{
    exit(EXIT_FAILURE);
}


// get the resolution of the image
const ushort* pWidth = (const ushort*) & header[18];
const ushort* pHeight = (const ushort*) & header[22];
ushort width = abs( *pWidth );
ushort height = abs( *pHeight );


uint data_size = width * height * 3;
char * data = new char[ data_size ];
assert(data);

if ( fread(data, 1, data_size, fh ) != data_size )
{
    exit(EXIT_FAILURE);
}

// switch the order of the RGB channels
for ( uint i = 0; i < data_size; i += 3 )
{
    char tmp = data[i];
    data[i] = data[i+2];
    data[i+2] = tmp;
}

glTexImage2D(
        target,                                        // GLenum target
        0,                                            //  GLint level
        GL_RGB,                                        // GLint internalformat
        width,                                        //  GLsizei width
        height,                                        // GLsizei height
        0,                                            // GLint border
        GL_RGB,                                        // GLenum format
        GL_UNSIGNED_BYTE,                            // GLenum type
        data                                        // const GLvoid *pixels
);

delete [] data;
}

GLuint Box::setTexture(){
GLuint tex;  //variable for texture
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0);
//Define all 6 faces
loabBMPTexture("./back.bmp",GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
loabBMPTexture("./front.bmp",GL_TEXTURE_CUBE_MAP_POSITIVE_Y);

loabBMPTexture("./left.bmp",GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
loabBMPTexture("./top.bmp",GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
loabBMPTexture("./right.bmp",GL_TEXTURE_CUBE_MAP_POSITIVE_X);
loabBMPTexture("./top.bmp",GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);

return tex;
}

这是着色器:

struct outdata {
float4 pos  : POSITION;
float4 col  : COLOR0;
};

//vertex shader
outdata main(float4 pos : POSITION, uniform float4x4 wvp) {
outdata OUT;

OUT.pos = mul(wvp, pos);
OUT.col = float4 (0.3,1,0,0);

return OUT;
}

//fragment shader
float4 texProg(uniform samplerCUBE tex, float3 pos : TEXCOORD0) : COLOR {
return texCUBE(tex,pos);
}

顶点着色器工作正常,我可以看到场景中的方框线。 但是当我试图添加BMP纹理时,我什么都没得到,我看到的只是一个黑盒子。

2 个答案:

答案 0 :(得分:0)

cgGetNamedProgramParameter的第三个参数不应该是参数名“tex”而不是函数Name吗? (http://http.developer.nvidia.com/Cg/cgGetNamedProgramParameter.html

(如果我完全离开这里,我通常会使用GLSL)

答案 1 :(得分:0)

我发现有两个问题......首先,你不应该忘记删除glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );,否则你只会获得边界线。

其次,正如@Daniel所解释的那样,您应该将纹理坐标绑定到片段着色器中的语义匹配。例如:

struct outdata {
  float4 pos  : POSITION;
  float4 col  : COLOR0;
  float3 uvs  : TEXCOORD0;
};

//vertex shader
outdata main(float4 pos : POSITION, 
  uniform float4x4 wvp) 
{
  outdata OUT;

  OUT.pos = mul(wvp, pos);
  OUT.col = float4 (0.3, 1, 0, 1);
  OUT.uvs = OUT.pos.xyz;

  return OUT;
}

//fragment shader
float4 texProg(uniform samplerCUBE tex, 
  float4 pos : POSITION,
  float4 col : COLOR0
  float3 uvs : TEXCOORD0) : COLOR 
{
  return col * texCUBE(tex, uvs);
}