Related
I am trying the texture mapping feature of OpenGL and the texture is displayed on the screen but not on the area that I set.
The area is a quad with 100.0 length and the texture is displayed only on the bottom.
When using GL_RGB in glTexImage2D, only one third of the quad is filled and when I change it to GL_RGBA, it becomes one quarter of the quad.
Main parameters declaration:
BYTE* m_pBMPBuffer;
int m_iWidth;
int m_iHeight;
GLuint m_uiTexture;
Code for setting up the texture mapping:
void CTextureMappingView::InitializeTexture()
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &m_uiTexture);
glBindTexture(GL_TEXTURE_2D, m_uiTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_iWidth, m_iHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, m_pBMPBuffer);
}
Buffer Initialization:
m_iWidth = 64;
m_iHeight = 64;
m_pBMPBuffer = new BYTE[m_iWidth * m_iHeight * 3];
for (int i = 0 ; i < m_iWidth * m_iHeight ; i += 3)
{
m_pBMPBuffer[i] = 255;
m_pBMPBuffer[i + 1] = 0;
m_pBMPBuffer[i + 2] = 0;
}
Rendering:
void CTextureMappingView::RenderScene()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(XAngle, 1.0f, 0.0f, 0.0f);
glRotatef(YAngle, 0.0f, 1.0f, 0.0f);
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, m_uiTexture);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 0.0);
glVertex3d(0.0, 0.0, 0.0);
glTexCoord2d(0.0, 1.0);
glVertex3d(0.0, 100.0, 0.0);
glTexCoord2d(1.0, 1.0);
glVertex3d(100.0, 100.0, 0.0);
glTexCoord2d(1.0, 0.0);
glVertex3d(100.0, 0.0, 0.0);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
Current result:
You only initialize a third of your texture:
for (int i = 0 ; i < m_iWidth * m_iHeight ; i += 3)
You should go up to m_iWidth * m_iHeight * 3 since that's what you allocated.
[Objectives] I need to write to a CubeMap's specific mipmap level in OpenGL 4+. Each mipmap levels is blurrier the deeper the level is.
[Problem] The problem is that I have the same image over all mipmap levels if I write only on level 0, and nothing at all if I try to write only on other mipmap level.
[Update] I'm pretty sure the problem is textureLod always clamp to the base LOD 0. Whatever mipmap level I try to get through it, it returns the base LOD.
Here is my cubemap generation (I'm trying to have 6 mipmap levels, counting the base):
GLuint PreFilteredEnvTex;
glGenTextures(1, &PreFilteredEnvTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, PreFilteredEnvTex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 5);
for (int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, 0);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
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_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);
Utils::checkGlError("Generate PreFilteredEnvMap");
And here an example of my attempt to write to each mipmap levels :
//Compute pre filtered environnement maps
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, fboManager["fx"]);
glViewport(0, 0, screenWidth, screenHeight);
glClear(GL_COLOR_BUFFER_BIT);
const int MIPMAPLEVELS = 6;
const int MIPMAPBASELEVELSIZE = 512;
int MipMapTextureSize;
glBindVertexArray(vaoManager["cube"]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture_id);
Shader* PreEnvFilter = shaderManager["PreEnvFilter"];
PreEnvFilter->use();
glm::vec3 EyePosition = glm::vec3(0.f);
// Light space matrices
glm::mat4 CubeMapProjection = glm::perspective(glm::radians(90.f), 1.f, 1.f, 100.f);
std::vector<glm::mat4> worldToLight;
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
for (GLuint i = 0; i < 6; ++i)
PreEnvFilter->SetMatrix4(("ViewMatrix[" + to_string(i) + "]").c_str(), worldToLight[i]);
PreEnvFilter->SetInt("EnvMapSampler", 0);
PreEnvFilter->SetMatrix4("Model", glm::mat4());
//For each faces compute all mipmaps levels
for (unsigned int j = 0; j < MIPMAPLEVELS; ++j)
{
//For each mipmap level, render the filtered environnement in it
MipMapTextureSize = std::max(1, MIPMAPBASELEVELSIZE / (1 << j));
glViewport(0, 0, MipMapTextureSize, MipMapTextureSize);
//glViewport(0, 0, MIPMAPBASELEVELSIZE, MIPMAPBASELEVELSIZE);
float roughness = (j + 0.5f) / MIPMAPLEVELS;
PreEnvFilter->SetFloat("Roughness", roughness);
//Bind to the current buffer
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, PreFilteredEnvTex, j);
glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, (void*)0);
}
PreEnvFilter->unuse();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
Utils::checkGlError("Initialize PreFilteredEnvMap");
I'm sure my shader is working, because if I'm looping over all mipmap levels and drawing only to the base level I have a good looking result :
The result if I'm only writing to level 0 for all mipmap levels
The cubemap is printed with the following fragment shader (TexCoords is modified according to the face I want to draw) :
#version 430
uniform int MipMapLevel;
uniform samplerCube CubeMap;
in vec3 TexCoords;
out vec4 Color;
void main()
{
Color = textureLod(CubeMap, TexCoords, MipMapLevel);
}
And if I'm writing to all mipmap levels, I have the same image on all mipmap levels (actually if I write only to level 0 I have the same result on all mipmap levels as well )
Same result, different mipmap levels
My conclusion is as followed :
My mipmap generation is not good, but I've read the specs and glGenerateMipmap should have done the job
I have a problem when trying to bind the mipmap level throught glFramebufferTexture, but once again it doesn't seems wrong to me
My shader to draw the cubemap is not working as I think it should ? I've never used textureLod before, but as far as I know, I am using it right here, right ?
If someone as already done something similar, I would really appreciate some help ! After all the time I spent on it, I'm still not able to do this simple thing in OpenGL when I did it whithout problems in DX11 :(
P.S : OpenGL does not report any errors
After trying almost everything, I've finally make it works by generating my cubemap as follow :
GLuint PreFilteredEnvTex;
glGenTextures(1, &PreFilteredEnvTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, PreFilteredEnvTex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 5);
for (int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
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);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
I've change the min filter to GL_LINEAR_MIPMAP_LINEAR and call glGenerateMipmap at the end, instead of doing like in this link.
Thanks for your interest :)
Well, I've done a test to see if it works the shadowmapping using two light source. Something is wrong, the first shadowmap make a correct shade, but the second shadowmap not. This is the complete code.
FUNCTIONS
void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z){
glLoadIdentity();
gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
}
void setTextureMatrix1(){
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE6);
glLoadIdentity();
glLoadMatrixd(bias);
glMultMatrixd (projection);
glMultMatrixd (modelView);
glMatrixMode(GL_MODELVIEW);
}
void setTextureMatrix2(){
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE7);
glLoadIdentity();
glLoadMatrixd(bias);
glMultMatrixd (projection);
glMultMatrixd (modelView);
glMatrixMode(GL_MODELVIEW);
}
void startTranslate1(float x,float y,float z){
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE6);
glPushMatrix();
glTranslatef(x,y,z);
}
void startTranslate2(float x,float y,float z){
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE7);
glPushMatrix();
glTranslatef(x,y,z);
}
void endTranslate(){
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void drawObjects1(){
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-35,2,-35);
glVertex3f(-35,2, 15);
glVertex3f( 15,2, 15);
glVertex3f( 15,2,-35);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
startTranslate1(0,4,-5);
glutSolidCube(4);
endTranslate();
}
void drawObjects2(){
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-35,2,-35);
glVertex3f(-35,2, 15);
glVertex3f( 15,2, 15);
glVertex3f( 15,2,-35);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
startTranslate2(0,4,-5);
glutSolidCube(4);
endTranslate();
}
MAIN
int main(){
GLuint depthTextureId;
glGenTextures(1, &depthTextureId);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fboId;
GLenum FBOstatus;
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);
FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
/////////////////////////////////////////////////////////////////////
GLuint depthTextureId2;
glGenTextures(1, &depthTextureId2);
glBindTexture(GL_TEXTURE_2D, depthTextureId2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fboId2;
GLenum FBOstatus2;
glGenFramebuffersEXT(1, &fboId2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId2);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId2, 0);
FBOstatus2 = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus2 != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GLfloat angulo = 0.0;
GLfloat posZ = 0.0;
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
MAIN LOOP
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(5.0,15.0,0.0,-5.0,0.0,-5.0);
glCullFace(GL_FRONT);
drawObjects1();
setTextureMatrix1();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId2);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2]);
glCullFace(GL_FRONT);
drawObjects2();
setTextureMatrix2();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glViewport(0,0,640,480);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glUseProgram(p);
glUniform1i(shadowMapUniform,6);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_2D,depthTextureId);
glUniform1i(shadowMapUniform2,7);
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D,depthTextureId2);
glCullFace(GL_BACK);
setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2]);
drawObjects1();
glBindTexture(GL_TEXTURE_2D,0);
glUseProgram(0);
VERTEX SHADER
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
void main(){
ShadowCoord1 = gl_TextureMatrix[6] * gl_Vertex;
ShadowCoord2 = gl_TextureMatrix[7] * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
}
FRAGMENT SHADER
uniform sampler2D ShadowMap;
uniform sampler2D ShadowMap2;
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
varying vec3 pvertice;
void main(){
vec4 shadowCoordinateWdivide1 = ShadowCoord1 / ShadowCoord1.w ;
vec4 shadowCoordinateWdivide2 = ShadowCoord2 / ShadowCoord2.w ;
shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;
float distanceFromLight1 = texture2D(ShadowMap,shadowCoordinateWdivide1.st).z;
float distanceFromLight2 = texture2D(ShadowMap2,shadowCoordinateWdivide2.st).z;
float shadow1 = 1.0;
if (ShadowCoord1.w > 0.0){
shadow1 = distanceFromLight1 < shadowCoordinateWdivide1.z ? 0.5 : 1.0 ;
}
float shadow2 = 1.0;
if (ShadowCoord2.w > 0.0){
shadow2 = distanceFromLight2 < shadowCoordinateWdivide2.z ? 0.5 : 1.0 ;
}
gl_FragColor = mix(shadow1,shadow2,0.5) * gl_Color;
}
What is wrong? This looks like...
If I try to move around the object it looks bad.
While with a single light in the same position it looks like this.
If I try to move around the object this looks good.
Thanks.
Those bias impact self shadowing, try setting them a bit higher.
shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;
I'm trying to understand how to load a texture in OpenGL and I wrote this very simple code:
GLuint texture;
void loadTexture() {
GLubyte data[] = { 255,0,0,
0,255,0,
0,255,0,
255,0,0 };
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
int chk = gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, 2, 2, GL_RGB, GL_UNSIGNED_BYTE, data );
if (chk!=0)
printf("error code = %d\n",chk);
else
printf("success\n");
}
I use loadTexture() to load the texture in memory. The texture, in this sample, is extremely simple, but at the moment it doesn't matter.
void drawTexturedSquare() {
glEnable( GL_TEXTURE_2D );
glBegin (GL_QUADS);
glTexCoord2f (0.0, 0.0);
glNormal3f(0, 0, 1);
glVertex3f (0.0, 0.0, 0.0);
glTexCoord2f (1.0, 0.0);
glNormal3f(0, 0, 1);
glVertex3f (10.0, 0.0, 0.0);
glTexCoord2f (1.0, 1.0);
glNormal3f(0, 0, 1);
glVertex3f (10, 10, 0.0);
glTexCoord2f (0.0, 1.0);
glNormal3f(0, 0, 1);
glVertex3f (0.0, 10, 0.0);
glEnd ();
glDisable( GL_TEXTURE_2D);
}
I would like to apply this simple texture to a square. I call function drawTexturedSquare() from inside a draw() function where I already called
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
The problem is that this is the result I get
while I expected the square to be green in main diagonal (upper-left to lower-right) and red is secondary diagonal (upper-right to lower-left). May someone explain me why?
Besides, every time I run the program I get a different result:
I do not understand where this blue comes out...May someone help me?
Each row of your data needs to be 4-byte aligned. Either pad each row with 0 0, or use a RGBA texture.
If you don't want to do the aforementioned, you can use:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
The reason your color is changing is that since you don't pad your rows correctly, OpenGL reads past the end of the array.
You may want to try GL_NEAREST for GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER
As it is right now, OpenGL is interpolating between the colors, creating a gradient (since your texture is being stretched from 2x2 to however big your screen is)
This doesn't explain why you're getting different results for your texture each time though.
I've tried to research this on Google but there doesn't appear to me to be any coherent simple answers. Is this because it's not simple, or because I'm not using the correct keywords?
Nevertheless, this is the progress I've made so far.
Created 8 vertices to form 2 squares.
Created a texture with a 200 bit alpha value (so, about 80% transparent).
Assigned the same texture to each square, which shows correctly.
Noticed that when I use a texture with 255 alpha, it appears brighter.
The init is something like the following:
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, textureIds);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
int i, j;
GLubyte pixel;
for (i = 0; i < TEXTURE_HEIGHT; i++)
{
for (j = 0; j < TEXTURE_WIDTH; j++)
{
pixel = ((((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255);
texture[i][j][0] = pixel;
texture[i][j][1] = pixel;
texture[i][j][2] = pixel;
texture[i][j][3] = 200;
}
}
glBindTexture(GL_TEXTURE_2D, textureIds[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
TEXTURE_WIDTH, TEXTURE_HEIGHT,
0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
This is somewhat similar to the code snippet from page 417 in the book, OpenGL Programming Guide, and creates a check pattern.
And then, the display function contains...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// Use model view so that rotation value is literal, not added.
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// ... translation, etc ...
glBindTexture(GL_TEXTURE_2D, textureIds[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, +1.0, 0.0); // top left
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0); // bottom left
glTexCoord2f(1.0, 1.0); glVertex3f(+1.0, -1.0, 0.0); // bottom right
glTexCoord2f(1.0, 0.0); glVertex3f(+1.0, +1.0, 0.0); // top right
glEnd();
// not neccecary to repeat, just good practice
glBindTexture(GL_TEXTURE_2D, textureIds[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.5, +1.0, -1.0); // top left
glTexCoord2f(0.0, 1.0); glVertex3f(-0.5, -1.0, -1.0); // bottom left
glTexCoord2f(1.0, 1.0); glVertex3f(+1.5, -1.0, -1.0); // bottom right
glTexCoord2f(1.0, 0.0); glVertex3f(+1.5, +1.0, -1.0); // top right
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
SwapBuffers();
So, this renders a 2nd square in the background; I can see this but it looks like they're being blended with the background (I assume this because they are darker with 200 bit alpha than 255 bit) instead of the texture behind...
As you can see, no transparency... How can I fix this?
So the other answer which was here but was deleted mentioned this - Generally, for alpha blending to work correctly you need to sort the objects from far to near in the coordinate system of the camera.
This is why your polygons are blended with the background. You can confirm that this is indeed the problem by disabling the depth test. Without depth test all the fragments are displayed and you'll be able to see the alpha blending.
More on this in this page.