I recently read whole bunch of articles i failed to make my cubemap reflections.
So basically in my opinion the idea is like that:
-generate a cubemap texture
-set all cubemap sides (put pictures in it)
-get cubemap color at (reflectionvector(vertexpos - camerapos, vertex_normal); within fragment shader
that black color was supposed to be a water with cubemap reflection of a skydome.
so i initialize a cubemap texture wtih:
void InitCubeMapTextures()
{
glActiveTexture(GL_TEXTURE3);
glGenTextures(1, &CUBEMAP_TEXTURE);
glBindTexture(GL_TEXTURE_CUBE_MAP, CUBEMAP_TEXTURE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE0);
}
then to update the cubemap i use (hold on for a moment its a long piece of code dont mind i use glReadPixels - i was trying framebuffers (rendering to texture), glcopyteximage etc. since with glreadpixels i could write a simple tga file and see if anything is drawn ( and yes cube map textures shoudl be updated - at least pixels are valid)
void AquireCubemap()
{
gluPerspectiveA(ACTUAL_PROJECTION, 90.0f, 1.0f, 1000.0f, 1000.0f * 1000.0f * 1000.0f);
glActiveTexture(GL_TEXTURE3);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, 128, 128);
glBindTexture(GL_TEXTURE_CUBE_MAP, CUBEMAP_TEXTURE);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
TSpecCamera * cube_cam = new TSpecCamera();
cube_cam->SetCamera(t3dpoint<float>(0.0,0.0,0.0),t3dpoint<float>(100.0,0.0,0.0),t3dpoint<float>(0.0,0.0,100.0),t3dpoint<float>(0.0,1.0,0.0));
cube_cam->lookatpoint = true;
cube_cam->pos = t3dpoint<float>(0.0f, 0.0f, 0.0f);
unsigned char * pdata = new unsigned char[viewport_size*viewport_size*4];
//X cubemap
cube_cam->lap = t3dpoint<float>(100.0f, 0.0f, 0.0f);
cube_cam->SetView();
SkyDome->Draw(cube_cam);
glReadPixels(0, 0, viewport_size, viewport_size, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, viewport_size, viewport_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glClear(GL_COLOR_BUFFER_BIT);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// unsigned char * pdata = new unsigned char[viewport_size * viewport_size * 4];
//AnsiString fname = appdir+"shaders\cubemap_X_plus.tga";
// glReadPixels(0,0,viewport_size,viewport_size,GL_RGBA,GL_UNSIGNED_BYTE,pdata);
// WriteTga(fname.c_str(), viewport_size, viewport_size, 32, pdata);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-X cubemap
cube_cam->lap = t3dpoint<float>(-100.0f, 0.0f, 0.0f);
cube_cam->SetView();
SkyDome->Draw(cube_cam);
glReadPixels(0, 0, viewport_size, viewport_size, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, viewport_size, viewport_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glClear(GL_COLOR_BUFFER_BIT);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Y cubemap
cube_cam->lap = t3dpoint<float>(0.0f, 100.0f, 0.0f);
cube_cam->SetView();
SkyDome->Draw(cube_cam);
glReadPixels(0, 0, viewport_size, viewport_size, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, viewport_size, viewport_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glClear(GL_COLOR_BUFFER_BIT);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-Y cubemap
cube_cam->lap = t3dpoint<float>(0.0f, -100.0f, 0.0f);
cube_cam->SetView();
SkyDome->Draw(cube_cam);
glReadPixels(0, 0, viewport_size, viewport_size, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, viewport_size, viewport_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glClear(GL_COLOR_BUFFER_BIT);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Z cubemap
cube_cam->lap = t3dpoint<float>(0.0f, 0.0f, 100.0f);
cube_cam->SetView();
SkyDome->Draw(cube_cam);
glReadPixels(0, 0, viewport_size, viewport_size, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, viewport_size, viewport_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glClear(GL_COLOR_BUFFER_BIT);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-Z cubemap
cube_cam->lap = t3dpoint<float>(0.0f, 0.0f, -100.0f);
cube_cam->SetView();
SkyDome->Draw(cube_cam);
glReadPixels(0, 0, viewport_size, viewport_size, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, viewport_size, viewport_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pdata);
glClear(GL_COLOR_BUFFER_BIT);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glActiveTexture(GL_TEXTURE0);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
delete cube_cam;
}
//----------------------------------------------------------------------------------------------
as maybe you can see i use cubemap texture in GL_TEXTURE3
procedure draws skydome and fetches the image to the texture
then i call actuall drawing code
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "cubemap"), 3);
draw_water();
glUseProgram(0);
every uniform has valid location and i pass all data (Including normals to the buffer) - thats for sure because i checked that in different shader
now shaders:
VP
attribute vec3 Vpos;
attribute vec2 Vtexcoord;
attribute vec3 Vnormal;
attribute vec4 Vcolor;
attribute float Vheight;
uniform vec4 MVP1;
uniform vec4 MVP2;
uniform vec4 MVP3;
uniform vec4 MVP4;
uniform vec3 u_cameraPosition;
vec4 vertexClip;
varying vec3 u_normalMap;
varying vec3 vertex_position;
varying vec3 REFLECTED_VEC;
float dp43(vec4 matrow, vec3 p)
{
return ( (matrow.x*p.x) + (matrow.y*p.y) + (matrow.z*p.z) + matrow.w );
}
vec3 Reflect_vec(vec3 incoming, vec3 normal)
{
return incoming - 2.0*dot(incoming, normal)*normal;
}
void main()
{
vec3 new_pos = Vpos + vec3(0.0,Vheight,0.0);
vertexClip.x = dp43(MVP1, new_pos);
vertexClip.y = dp43(MVP2, new_pos);
vertexClip.z = dp43(MVP3, new_pos);
vertexClip.w = dp43(MVP4, new_pos);
vec3 Incidence = new_pos - u_cameraPosition;
REFLECTED_VEC = Reflect_vec(Incidence, Vnormal); //if normalzied returns same thing
gl_Position = vertexClip;
}
FP
varying vec3 REFLECTED_VEC;
uniform samplerCube cubemap;
void main()
{
vec3 cube_col = textureCube(cubemap, REFLECTED_VEC).rgb;
gl_FragColor = vec4(cube_col, 1.0);
}
Yo!