Текстура SkyBox не отображается (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, я ничего не получаю, я вижу только черный ящик.

0

Решение

Не должен ли третий аргумент cgGetNamedProgramParameter быть именем параметра «tex» вместо имени функции? (http://http.developer.nvidia.com/Cg/cgGetNamedProgramParameter.html)

(Извините, если я здесь совсем, я обычно использую GLSL)

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);
}
0