OpenGL, SOIL, Textures and Transparent backgrounds - c++

I can't seem to get the transparent background on my image to load as transparent. It's always white instead. I'm still fairly new to OpenGL/SOIL so if I did something stupid don't be mad :/ Does it have to do with my flag on the load being RGB instead of RGBA?
void Scene::loadTexShips()
{
texShips[0] = SOIL_load_OGL_texture(
"Textures/Carrier.png",
SOIL_LOAD_LA,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB
);
if (texShips[0] == 0)
{
printf("SOIL loading error: '%s'\n", SOIL_last_result());
}
}
void Scene::drawShips()
{
glColor4ub(255, 255, 255, 255);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glLoadIdentity();
glTranslatef(6.0f, 2.0f, -12.0f);
glBindTexture(GL_TEXTURE_2D, texShips[0]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-4.0f, -3.0f, 2.0);
glTexCoord2f(0, 1);
glVertex3f(-4.0f, -2.3, 2.0);
glTexCoord2f(1, 1);
glVertex3f(-1.0, -2.3, 2.0);
glTexCoord2f(1, 0);
glVertex3f(-1.0, -3.0, 2.0);
glEnd();
glDisable(GL_TEXTURE_2D);
}

Related

OpenGL images not displaying properly with some window sizes

I'm new to OpenGL and am trying to display images. I've got the "Load image from file" part done and am now trying to bind it to my shape (GL_TRIANGLES). Sometimes the image get's displayed correctly, but sometimes it does not. I've realized that it depends on the window size, so if I resize the window I can get a clear image. Here are some screenshots of how the screen looks:
Working:
Broken:
Here's my draw loop:
void display() {
// tick the frame counter
frame++;
start_time = clock();
// update screen
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
update_screen(width, height);
// clear screen
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, png::get_textures()[1]);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glBegin(GL_TRIANGLES);
glVertex2f(1000, 1000);
glVertex2f(0, 1000);
glVertex2f(0, 0);
glVertex2f(1000, 1000);
glVertex2f(1000, 0);
glVertex2f(0, 0);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glFlush();
glutSwapBuffers();
elapsed_time = ((clock() - start_time) / (double(CLOCKS_PER_SEC) / 10000));
// tick all entities
player.tick(elapsed_time);
glutPostRedisplay();
}
Also, if I remove glEnable(GL_TEXTURE_GEN_S) or glEnable(GL_TEXTURE_GEN_T); or both, the image gets completely blue or gray.
Edit: Oh, and I'm using PNG files, in case that maters.
Well, I feel sheepish!
I forgot to add glTexCoord2f...
hear's my new file just in case someone else forgot their brain somewhere. :)
void display() {
// tick the frame counter
frame++;
start_time = clock();
// update screen
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
update_screen(width, height);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
// clear screen
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, png::get_textures()[3]);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(1000, 0);
glTexCoord2f(1, 1); glVertex2f(1000, 1000);
glTexCoord2f(0, 1); glVertex2f(0, 1000);
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
glFlush();
glutSwapBuffers();
elapsed_time = ((clock() - start_time) / (double(CLOCKS_PER_SEC) / 10000));
// tick all entities
player.tick(elapsed_time);
glutPostRedisplay();
}

openGL - testure mapping cube fails

I am trying something quite easy, normally: applying a texture on the different surfaces of a cube.
I am able to apply it but it seems as if he just takes an average of the colors of my image.
why please?
my code:
void MyGLWidget::drawCube()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity();
// glPushMatrix();
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.5, 0, 0.0);
glRotatef(getCubeAngle(), 0.0f, 1.0f, 0.0f);
glTranslatef(0, 0, 0);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glVertex3f(-0.1, 0.1,-0.1 );//upper left corner
glVertex3f(0.1, 0.1,-0.1); //uper right
glVertex3f(0.1,-0.1,-0.1 ); // down left
glVertex3f(-0.1,-0.1,-0.1); // down right
/* other code to create rest of the cube*/
glEnd();
glFlush();
// glPopMatrix();
}
void MyGLWidget::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(height *1./width, 1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
void MyGLWidget::myTextureMapping()
{
QImage t;
QImage b;
if(!b.load("..../myImage.bmp"))
{qDebug("error with image\n");}
t = QGLWidget::convertToGLFormat(b);
glGenTextures( 1, &texture[0] );
glBindTexture( GL_TEXTURE_2D, texture[0] );
glTexImage2D( GL_TEXTURE_2D, 0, 3, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits() );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
void MyGLWidget::initializeGL()
{
myTextureMapping();
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
EDIT:
added those tex coordinates:
glTexCoord2f(-0.1, 0.1);
glVertex3f(-0.1, 0.1,0 );//upper left corner
glTexCoord2f(0.1, 0.1);
glVertex3f(0.1, 0.1,0); //uper right
glTexCoord2f(0.1, -0.1);
glVertex3f(0.1,-0.1,0 ); // down left
glTexCoord2f(-0.1, -0.1);
glVertex3f(-0.1,-0.1,0); // down right
But my image is bigger than the face of my cube:
source image : http://imgur.com/h48QARM
result in software: http://imgur.com/rxvK0Ot
You should be providing the texture co-ordinates for each vertex. What you have right now is just a position data for the Quad, texture co-ordinates are missing.
Have a look at this :
OpenGL Textured Cube Not Being Mapped Correctly
Try this :
glTexCoord2f(0, 0);
glVertex3f(-0.1, 0.1,0 );//upper left corner
glTexCoord2f(1, 0);
glVertex3f(0.1, 0.1,0); //uper right
glTexCoord2f(0, 1);
glVertex3f(-0.1,-0.1,0 ); // down left
glTexCoord2f(1, 1);
glVertex3f(0.1,-0.1,0); // down right
Isn't the texture coordinates wrong? To me it seems like you're going -0.1 to 0.1, while texture coordinates normally are defined in the interval [0,1].

Transparency Opengl+SDL not working C++

I've been trying to get transparency working with SDL+ OpenGL.
Here are my functions that initialize OpenGL and SDL, draw an image, and create a texture
void initGL()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0.0, Screen_Width,Screen_Height, 0.0, 1.0, -1.0 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, Screen_Width, Screen_Height);
}
void initSDL()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Bob=SDL_SetVideoMode(0, 0, 32, SDL_OPENGL);
Screen_Width= Bob->w;
Screen_Height= Bob->h;
SDL_WM_SetCaption("Project", NULL);;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
}
void Texture::draw(int x1, int y1,int x2, int y2,std::string filename)
{
glClear( GL_COLOR_BUFFER_BIT );
CreateTexture(filename.c_str());
glEnable( GL_TEXTURE_2D );
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, Tex);
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f);
glVertex2f( 0.f, 0.f );
glTexCoord2f(1.f, 0.f);
glVertex2f( 1920.f, 0.f );
glTexCoord2f(1.f, 1.f);
glVertex2f( 1920.f, 1080.f );
glTexCoord2f(0.f, 1.f);
glVertex2f( 0.f, 1080.f );
glEnd();
glDisable(GL_TEXTURE_2D);
SDL_GL_SwapBuffers();
}
void Texture::CreateTexture(std::string filename)
{
SDL_Surface* image =NULL;
image=IMG_Load( filename.c_str() );
glClearColor( 0, 0, 0, 0 );
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glGenTextures(1, &Tex);
glBindTexture(GL_TEXTURE_2D, Tex);
int mode = GL_RGB;
if(image->format->BytesPerPixel == 4)
mode = GL_RGBA;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 4, image->w, image->h, 0, mode, GL_UNSIGNED_BYTE, image- >pixels);
SDL_FreeSurface(image);
}
You can check the texture format is should be RGBA and you can test a white texture(RGB(255,255,255)) that has alpha channel of 128, so the whole texture is just white with alpha half white. Drawing this on a black background should result a half white texture being drawn.
Also the vertex positions might not be right, you could try something like this (with identity matrix for projection and world transform) to see if everything is in order with opengl setup
glTexCoord2f(0.f, 0.f);
glVertex2f( 0.25f, 0.25f );
glTexCoord2f(1.f, 0.f);
glVertex2f( 0.25f,0.5f );
glTexCoord2f(1.f, 1.f);
glVertex2f( 0.5f,0.5f );
glTexCoord2f(0.f, 1.f);
glVertex2f( 0.5f,0.25f );
Hope this helps.
Razvan.
You're drawing exactly one quad, with one texture. What exactly do you expect to be visible in the translucent parts? The background color?
Or your desktop, or the windows beneath? That takes quite some additional work.
First you need a compositor running (on Windows this requires Windows Vista with Aero or later).
And the window must be configured in a way, that its alpha channel is actually considered when compositing; AFAIK SDL doesn't take those preparations.

Black screen in LWJGL

I'm currently porting a game of which the code is very obfuscated due to porting from C to Java.
My problem is that some users report a black screen and no other problems (sound is working fine e.g.), with no errors showing a problem. On my pc it runs fine, and it makes for a hell of debugging.
I was wondering if anyone can post a (list of) reason(s) this might be occurring. I've read somewhere one of the issues could be using a 32 bits Java on a 64 bits system.
My code below, also opensourced at: https://code.google.com/p/jake2t/
private void renderSideBySide() {
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, sbsFboId);
// Render side by side
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glViewport(0,0,width,height);
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE);
int shaderId = sbsShader.getId();
glDisable(GL_TEXTURE_2D);
ARBShaderObjects.glUseProgramObjectARB(shaderId);
if (postFboTextureLocation[0] < 0) {
postFboTextureLocation[0] = ARBShaderObjects.glGetUniformLocationARB(shaderId, "leftTexture");
}
if (postFboTextureLocation[1] < 0) {
postFboTextureLocation[1] = ARBShaderObjects.glGetUniformLocationARB(shaderId, "rightTexture");
}
if (postFboDepthTextureLocation[0] < 0) {
postFboDepthTextureLocation[0] = ARBShaderObjects.glGetUniformLocationARB(shaderId, "leftDepthTexture");
}
if (postFboDepthTextureLocation[1] < 0) {
postFboDepthTextureLocation[1] = ARBShaderObjects.glGetUniformLocationARB(shaderId, "rightDepthTexture");
}
// Load the images with the colors and the depth values
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, postFboTextureId[0]);
ARBShaderObjects.glUniform1iARB(postFboTextureLocation[0], 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, postFboTextureId[1]);
ARBShaderObjects.glUniform1iARB(postFboTextureLocation[1], 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, postFboDepthTexture[0]);
ARBShaderObjects.glUniform1iARB(postFboDepthTextureLocation[0], 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, postFboDepthTexture[1]);
ARBShaderObjects.glUniform1iARB(postFboDepthTextureLocation[1], 3);
glBegin (GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2i (0, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex2i (width, 0);
glTexCoord2f(1.0f, 1.0f);
glVertex2i (width, height);
glTexCoord2f(0.0f, 1.0f);
glVertex2i (0, height);
glEnd();
ARBShaderObjects.glUseProgramObjectARB(0);
// Rendering with warping
glPopMatrix();
glPopAttrib();
unbindFBO();
}
public void drawPostFBOs() {
renderSideBySide();
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glViewport(0,0,width,height);
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_TEXTURE_2D);
int shaderId = riftShader.getId();
ARBShaderObjects.glUseProgramObjectARB(shaderId);
if (sbsFboTextureLocation < 0) {
sbsFboTextureLocation = ARBShaderObjects.glGetUniformLocationARB(shaderId, "tex");
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, sbsFboTextureId);
ARBShaderObjects.glUniform1iARB(sbsFboTextureLocation, 0);
glBegin (GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2i (0, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex2i (width, 0);
glTexCoord2f(1.0f, 1.0f);
glVertex2i (width, height);
glTexCoord2f(0.0f, 1.0f);
glVertex2i (0, height);
glEnd();
ARBShaderObjects.glUseProgramObjectARB(0);
glPopMatrix();
glPopAttrib();
}
The common problems that OpenGL 3+ programmer doesn't consider when coding are:
OpenGL Extensions
use of ARB and EXT extension.
use of correct OGL extension.
use multiple implementation of different OGL extensions. Here is an example using C++:
#ifndef _MESA_INVERT_
/*** ... some codes here ... ***/
#else
/*** ... alt some codes here ... ***/
#endif
Check if the video card support the following extension using:
glxinfo - Linux and MacOS X based system.
glview - Windows based system.

OpenGL 2d texture render issue

I am trying to load and draw a 2d texture using OpenGL with GLFW and SOIL. I have this code, but I only get one solid color (which seems to come from the texture).
I have tested whether the .png loads with an example that came with SOIL, and it worked fine so there has to be some issue in my code.
This is my code:
#include <cstdio>
#include "GL/glfw.h"
#include "SOIL.h"
// function declarations
void drawscene();
void idlefunc();
void updatedisplay();
// global data
GLuint texture; // our example texture
int main(int argc, char **argv) {
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return 1;
}
if (!glfwOpenWindow(640, 480, 0, 0, 0, 0, 16, 0, GLFW_WINDOW)) {
fprintf(stderr, "Failed to open GLFW window\n");
return 1;
}
// enable vsync (if available)
glfwSwapInterval(1);
// load textures
texture = SOIL_load_OGL_texture(
"tex.png",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_DDS_LOAD_DIRECT
);
// check for an error during the texture loading
if (!texture) {
printf("SOIL loading error: '%s'\n", SOIL_last_result());
}
while (glfwGetWindowParam(GLFW_OPENED)) {
idlefunc();
}
// if we get here something went wrong
return 0;
}
// this function gets called every frame
void idlefunc() {
updatedisplay();
drawscene();
}
// set up te display
void updatedisplay() {
int screen_width, screen_height;
glfwGetWindowSize(&screen_width, &screen_height);
if (screen_height <= 0) screen_height = 1;
if (screen_width <= 0) screen_width = 1;
glViewport(0, 0, screen_width, screen_height);
glClearColor(0.02f, 0.02f, 0.02f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, screen_width, screen_height, 0.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// displacement trick for exact pixelization
glTranslatef(0.375f, 0.375f, 0.0f);
}
// draw the scene in this function
void drawscene() {
glBindTexture(GL_TEXTURE_2D, texture);
glPushMatrix();
glTranslatef(10.0f, 10.0f, 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 128.0f);
glVertex2f(0.0f, 128.0f);
glTexCoord2f(128.0f, 128.0f);
glVertex2f(128.0f, 128.0f);
glTexCoord2f(128.0f, 0.0f);
glVertex2f(128.0f, 0.0f);
glEnd();
glPopMatrix();
glfwSwapBuffers();
}
Found the issue (thanks to user786653). No matter the vertex coords, the tex coords are between 0.0 and 1.0. This is the fixed code:
// draw the scene in this function
void drawscene() {
glBindTexture(GL_TEXTURE_2D, texture);
glPushMatrix();
glTranslatef(10.0f, 10.0f, 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(0.0f, 128.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(128.0f, 128.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(128.0f, 0.0f);
glEnd();
glPopMatrix();
glfwSwapBuffers();
}