Это мой код 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, я ничего не получаю, я вижу только черный ящик.
Не должен ли третий аргумент cgGetNamedProgramParameter быть именем параметра «tex» вместо имени функции? (http://http.developer.nvidia.com/Cg/cgGetNamedProgramParameter.html)
(Извините, если я здесь совсем, я обычно использую GLSL)
Я вижу две проблемы там … Во-первых, вы не должны забывать удалить 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);
}