I am currently using the Code::Blocks IDE, c++, opengl and SDL to make a game- and I have hit a severe block in road, if you will. I am using SDL_image to load these jpg images for the textures, but they just will not load. Currently, I have tried placing them in every folder in the project, even places where it would supposedly make no difference. I have tried running both the debug and release versions from the IDE, by double-clicking the executable, and by running the executable from the command line. They all produce the same error: Could not load image: "the path to my image". I have tried using full paths, I have tried using relative paths, I have tried just about everything. I have tried various image formats, to no success. Other useful information may be: I am using ubuntu 11.04, I am using GIMP to create the images, and this is my code in complete (I'm sure most of it is irrelevant, but I am just putting it all down just-in-case):
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <Cg/cg.h>// NEW: Cg Header
#include <Cg/cgGL.h>// NEW: Cg OpenGL Specific Header
#include <iostream>
#include <math.h>
#include <string>
#include "../include/Camera.h"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Keydown booleans
bool key[321];
Uint8 *keystate;
float fogDensity = 0.02f;
static float fog_color[] = { 0.8f, 0.8f, 0.8f, 1.0f };
// Process pending events
bool events()
{
SDL_Event event;
if( !SDL_PollEvent(&event) ){
return true;
}
switch( event.type )
{
case SDL_KEYDOWN : key[ event.key.keysym.sym ]=true; break;
case SDL_KEYUP : key[ event.key.keysym.sym ]=false; break;
case SDL_QUIT : return false; break; //one-per-keypress
}
keystate = SDL_GetKeyState(NULL); //continuous
return true;
}
// Initialze OpenGL perspective matrix
void setup(int width, int height)
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glEnable( GL_DEPTH_TEST );
gluPerspective( 45, (float)width/height, 0.1, 100 );
glMatrixMode( GL_MODELVIEW );
}
Camera* cam = new Camera();
GLuint rocktexture; // This is a handle to our texture object
GLuint earthtexture;
//add some default materials here
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 0.0f, 1.0f, 0.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
void MouseUpdate() {
int x, y;
SDL_GetMouseState(&x,&y);
SDL_WarpMouse(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
cam->yaw+=(x-WINDOW_WIDTH/2)*0.2;
cam->pitch+=(y-WINDOW_HEIGHT/2)*0.2;
if(cam->pitch<-90) {
cam->pitch=-90;
}
if(cam->pitch>90) {
cam->pitch=90;
}
}
static void display(void)
{
while(events())
{
MouseUpdate();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(cam->pitch,1.0,0.0,0.0); //rotate our camera on the x-axis (left and right)
glRotatef(cam->yaw,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(cam->camx,cam->camy,cam->camz); //translate the screen to the position of our camera
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0);
//glColor4f(1,1,1,0.5);
glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
//glDisable(GL_CULL_FACE);
glBindTexture(GL_TEXTURE_2D, rocktexture);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2i(0,0);glVertex3f(-32,0,32);
glTexCoord2i(1,0);glVertex3f(32,0,32);
glTexCoord2i(1,1);glVertex3f(32,0,-32);
glTexCoord2i(0,1);glVertex3f(-32,0,-32);
glEnd();
//glEnable(GL_CULL_FACE);
glPopMatrix();
/*glPushMatrix();
GLUquadric* earth = gluNewQuadric();
gluQuadricTexture(earth, true);
gluQuadricDrawStyle(earth, GLU_FILL);
gluQuadricNormals(earth, GLU_SMOOTH);
gluQuadricOrientation(earth, GLU_OUTSIDE);
gluSphere(earth, 1, 16, 16);
gluDeleteQuadric(earth);
glPopMatrix();*/
glFlush();
SDL_GL_SwapBuffers();
if (key[SDLK_ESCAPE] || key[SDLK_q])
{
std::cout<<"Game Ended."<<std::endl;
exit(0);
}
if (keystate[SDLK_w])
{
cam->camx-=sin(cam->yaw*M_PI/180)/4;
cam->camz+=cos(cam->yaw*M_PI/180)/4;
}
if (keystate[SDLK_s])
{
cam->camx+=sin(cam->yaw*M_PI/180)/4;
cam->camz-=cos(cam->yaw*M_PI/180)/4;
}
if (keystate[SDLK_a])
{
cam->camx+=cos(cam->yaw*M_PI/180)/4;
cam->camz+=sin(cam->yaw*M_PI/180)/4;
}
if (keystate[SDLK_d])
{
cam->camx-=cos(cam->yaw*M_PI/180)/4;
cam->camz-=sin(cam->yaw*M_PI/180)/4;
}
}
}
// Load the OpenGL texture
GLuint loadImage(std::string path, GLuint tx,SDL_Surface* sur)
{
GLenum texture_format;
GLint nOfColors;
if ((sur = SDL_LoadBMP(path.c_str())))
{
// Check that the image's width is a power of 2
if ((sur->w & (sur->w - 1)) != 0)
{
printf("warning: image's width is not a power of 2\n");
}
// Also check if the height is a power of 2
if ((sur->h & (sur->h - 1)) != 0)
{
printf("warning: image's height is not a power of 2\n");
}
// get the number of channels in the SDL surface
nOfColors = sur->format->BytesPerPixel;
if (nOfColors == 4) // contains an alpha channel
{
if (sur->format->Rmask == 0x000000ff)
{
texture_format = GL_RGBA;
}
else
{
texture_format = GL_BGRA;
}
}
else if (nOfColors == 3) // no alpha channel
{
if (sur->format->Rmask == 0x000000ff)
{
texture_format = GL_RGB;
}
else
{
texture_format = GL_BGR;
}
}
else
{
printf("warning: the image is not truecolor.. this will probably break\n");
// this error should not go unhandled
}
// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &tx );
// Bind the texture object
glBindTexture( GL_TEXTURE_2D, tx );
// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, 3, sur->w, sur->h, 0, GL_BGR, GL_UNSIGNED_BYTE, sur->pixels);
//build mip-maps
gluBuild2DMipmaps(tx, 3, sur->w, sur->h, texture_format, GL_UNSIGNED_BYTE, sur->pixels);
}
else
{
printf("SDL could not load image: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// Free the SDL_Surface only if it was successfully created
if (sur)
{
SDL_FreeSurface(sur);
}
delete &texture_format;
delete &nOfColors;
return tx;
}
/* Program entry point */
int main(int argc, char *argv[])
{
cam->camz=-5;
cam->camy=-1;
if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
{
std::cout<<"Unable to initialize SDL: %s\n"<<SDL_GetError()<<std::endl;
return 1;
}
const SDL_VideoInfo* info = SDL_GetVideoInfo();
int vidFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER;
if (info->hw_available) {vidFlags |= SDL_HWSURFACE;}
else {vidFlags |= SDL_SWSURFACE;}
//int bpp = info->vfmt->BitsPerPixel;
SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, vidFlags);
SDL_WM_SetCaption( "Treason", NULL);
SDL_WarpMouse(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);
gluLookAt(cam->camx,cam->camy,cam->camz,0,0,0,0,1,0);
glClearColor(0, 0, 0, 0);//background color white
float lmodel_ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
float local_view[] = { 0.0f };
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
glLightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_DITHER);
//glHint(GL_PHONG_HINT_WIN, GL_NICEST);
glShadeModel(GL_SMOOTH);//GL_PHONG_WIN
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
/* glEnable(GL_FOG);
glHint(GL_FOG_HINT, GL_NICEST);
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP);
glFogf(GL_FOG_DENSITY, fogDensity);
glFogfv(GL_FOG_COLOR, fog_color);*/
// glEnable(GL_STENCIL_TEST);
//glStencilFunc(GL_KEEP, GL_KEEP, GL_INCR);
SDL_Surface *rocktexsur;
rocktexture = loadImage("rock.jpg", rocktexture, rocktexsur);
SDL_Surface *earthtexsur;
earthtexture = loadImage("earth.jpg", earthtexture, earthtexsur);
setup(WINDOW_WIDTH, WINDOW_HEIGHT);
display();
glDeleteTextures(1, &rocktexture);
glDeleteTextures(1, &earthtexture);
return 0;
}
So if you find anything or know any reason why it would return an "SDL could not load image" Error, please respond! I can't continue on my project until this is resolved because it produces a segfault.
SDL by itself can only load BMP images, and it will return an error if you load anything but a BMP in using the function SDL_LoadBMP(). In order to load JPEGs, you need to use the supplemental library SDL_image, which is available at http://www.libsdl.org/projects/SDL_image/ . As JJG answered, the prototype for the function you have to use is:
SDL_Surface *IMG_Load( const char* );
rather than SDL_LoadBMP().
Not an expert on SDL or C++. But I just spent a minute looking over my tiny program I made a while back. I used:
some_image = IMG_Load( "someimage.jpg" );
Related
I have this project for Win/Linux that has to use OpenGL 1.3 because later on will be ported to another platform that only supports that version.
I have a basic scene with a directional light and using GL_COLOR_MATERIAL but all the polys are rendered completely black and I cannot find what is causing them to render like that. This is the code I'm using to set up OGL and SDL:
static si GaGlSdlSetup()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) return 0;
GaPrPrintToConsole("\nSDL Properly initiated");
l_sdl_window = SDL_CreateWindow("Window Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL
/*SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL*/);
if (l_sdl_window == NULL)
return 0;
GaPrPrintToConsole("\nWindow created");
// Create an OpenGL context associated with the window.
SDL_GLContext glcontext = SDL_GL_CreateContext(l_sdl_window);
if (glcontext == NULL)
return 0;
GaPrPrintToConsole("\nContext created");
return 1;
}
static si GaGlSetup()
{
const float amb = 0.2f;
const float LightAmbient[4] = { amb, amb, amb, 1.0f };
const float LightDiffuse[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
const float LightPosition[4] = { 1.0f, 2000.0f, 2.0f, 0.0f };
glClearColor(0.3, 0.3, 0.8, 0);
glClearDepth(1.0);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 35000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_POLYGON_OFFSET_FILL);
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
return 1;
}
And this is the basic rendering code. I have confirmed the values for the l_red, l_green and l_blue change according to each vertex and are within the range [0,1], and I'm currently rendering polys without any texture:
static si GaGlRender()
{
glClearColor(0.3, 0.3, 0.8, 0);
glClearDepth(1.0);
glBegin(GL_QUADS);
.
.
.
glColor3f(l_red, l_green, l_blue);
glVertex3f(l_mesh_vector_1->vx, l_mesh_vector_1->vy, l_mesh_vector_1->vz);
.
.
.
glColor3f(l_red, l_green, l_blue);
glVertex3f(l_mesh_vector_2->vx, l_mesh_vector_2->vy, l_mesh_vector_2->vz);
.
.
.
glColor3f(l_red, l_green, l_blue);
glVertex3f(l_mesh_vector_3->vx, l_mesh_vector_3->vy, l_mesh_vector_3->vz);
.
.
.
glColor3f(l_red, l_green, l_blue);
glVertex3f(l_mesh_vector_4->vx, l_mesh_vector_4->vy, l_mesh_vector_4->vz);
glEnd();
.
.
.
SDL_GL_SwapWindow(window);
}
Any idea what could be the problem?
EDIT1:
I added the directional light because I could not get any vertex color to be displayed by using only GL_COLOR_MATERIAL, disabling the lights and leaving only GL_COLOR_MATERIAL displays the same result
EDIT2:
Found the culprit: glDisable(GL_TEXTURE_2D) I thought you could leave it on and it would affect only textured polys, but apparently not...
in image appearing red opaque but i set the glColor3f(1.0f, 0.0f, 0.0f);
//command compiler g++ console tested with Visual Studio Code
//g++ GL01Hello.cpp -o GL01Hello.exe -L"C:/MinGW/freeglut/lib" -lglu32 -lopengl32 -lfreeglut -I"C:\MinGW\freeglut\include\GL"
/*
* GL01Hello.cpp:With Load Background Image and Poligon Test OpenGL/GLUT C/C++ Setup
* Tested Visual Studio Code with MinGW
* To compile with -lfreeglut -lglu32 -lopengl32 and
*/
#include <windows.h> // for MS Windows
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <ctime>
#include <freeglut.h> // GLUT, include glu.h and gl.h
using namespace std;
float spin = 0.0;
GLuint texture = 0;
int w1 = 0;
int h1 = 0;
// for random color primitive polygon
//static GLubyte redc,greenc,bluec;
bool prim_polygonmode = false;
// glut_load_image
GLuint LoadTexture( const char * filename )
{
GLuint texture;
int width, height;
unsigned char * data;
FILE * file;
file = fopen( filename, "rb" );
if(!file)
std::cout<<"File not Found"<<std::endl;
if ( file == NULL ) return 0;
width = 1360;
height = 768;
data = (unsigned char *)malloc( width * height * 3 );
//int size = fseek(file,);
fread( data, width * height * 3, 1, file );
fclose( file );
for(int i = 0; i < width * height ; ++i)
{
int index = i*3;
unsigned char B,R;
B = data[index];
R = data[index+2];
data[index] = R;
data[index+2] = B;
}
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );//Necessary for correct elements value 4 default
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST );
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 );
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,GL_RGB, GL_UNSIGNED_BYTE, data );
free( data );
return texture;
}
/* Initialize OpenGL Graphics just n this case for colors */
void initGL() {
// Set "clearing" or background color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
//randomnumber color by ctime library
srand(time(NULL));
//redc = rand()%255;
//greenc = rand()%255;
//bluec = rand()%255;
}
/* Called back when there is no other event to be handled */
void idle() {
spin = spin + 0.075;
if (spin > 360.0)
spin = 0;
glutPostRedisplay(); // Post a re-paint request to activate display()
}
/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer
// Compute aspect ratio of the new window
w1 = width;
h1 = height;
if (height == 0) height = 1; // To prevent divide by 0
GLfloat aspect = (GLfloat)width / (GLfloat)height;
// Set the viewport to cover the new window
glViewport(0, 0, width, height);
// Set the aspect ratio of the clipping area to match the viewport
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix
glLoadIdentity();
if (width >= height) {
// aspect >= 1, set the height from -1 to 1, with larger width
gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
} else {
// aspect < 1, set the width to -1 to 1, with larger height
gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
}
}
void orthogonalStart()
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-w1/2, w1/2, -h1/2, h1/2);
glMatrixMode(GL_MODELVIEW);
}
void orthogonalEnd()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void background()
{
glBindTexture( GL_TEXTURE_2D, texture );
orthogonalStart();
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonOffset(1,1);
// texture width/height
const int iw = 1360;
const int ih = 768;
glPushMatrix();
glTranslatef( -iw/2, -ih/2, 0 );
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f); // always default color white stars, if no this line will random color same of polygon
glTexCoord2i(0,0); glVertex2i(0, 0);
glTexCoord2i(1,0); glVertex2i(iw, 0);
glTexCoord2i(1,1); glVertex2i(iw, ih);
glTexCoord2i(0,1); glVertex2i(0, ih);
glEnd();
glPopMatrix();
orthogonalEnd();
}
void display() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClear(GL_COLOR_BUFFER_BIT);// Clear the color buffer (background
glEnable( GL_TEXTURE_2D );
background();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// A SQUARE PARAMETERS
if (prim_polygonmode) { // draw polygon mode lines
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
} else {
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonOffset(1,1);
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glRotatef(spin , 0., 0., 1.);
glTranslatef(50.0, 50.0, 0);
glTranslatef(-50.0, -50.0, 0);
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
//glColor3ub(redc, greenc, bluec); // Random red green blue value
glColor3f(1.0f, 0.0f, 0.0f); // Random red green blue value
glVertex2f(-0.5f, -0.5f); // x, y default 0.5f values
glVertex2f( 0.5f, -0.5f);
glVertex2f( 0.5f, 0.5f);
glVertex2f(-0.5f, 0.5f);
glEnd();
//angle += 5.0f;
glPopMatrix();
// glFlush(); // Render now
glutSwapBuffers(); // Double buffered - swap the front and back buffers
}
/* Callback handler for special-key event */
void specialKeys(int key, int x, int y) {
switch (key) {
case GLUT_KEY_F1: // F1: Toggle wireframe and solid polygon
prim_polygonmode = !prim_polygonmode; // Toggle state
break;
}
}
/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
glutInit(&argc, argv); // Initialize GLUT
glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
glutInitWindowSize(1360, 768); // Set the window's initial width & height
glutInitWindowPosition(0, 0);
// Position the window's initial top-left corner
glutCreateWindow("OpenGL Setup Test"); // Create a window with the given title
glutSpecialFunc(specialKeys); // Register callback handler for special-key event
glutDisplayFunc(display); // Register display callback handler for window re-paint
glutReshapeFunc(reshape);
glutIdleFunc(idle);
// GLuint texture;
texture = LoadTexture( "stars.bmp" );
initGL();
glutMainLoop();// Enter the event-processing loop
//Free our texture
glDeleteTextures( 1, &texture );
return 0;
}
This code have a set background and small animation of square.
Dont know wihy cant set more the solid colors. Then the wireframe square i got a very litle line red need got the bright color red.Maybe any filte, ou buffer causing that?
if possible please help me.
OpenGL is a state engine. Once a state is set, it is persistent until it is change again.
This means if 2 dimensional texturing is enabled, all the following geometry is "textured".
Note, when glVertex2f is called then the current texture coordinate is associated with the vertex coordinate. If you don't explicitly set a texture coordinate, then the last texture coordinate which was set is still the current texture coordinate and will be associated to the vertex coordinate. This may cause a random like behavior.
If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
That all means:
If you want to draw a geometry with a texture then enable texturing and set a "white" color:
glEnable(GL_TEXTURE_2D)
glColor3f(1.0f, 1.0f, 1.0f);
background();
If you want to draw a uniform colored geometry, then set the color and disable texturing:
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
// [...]
glEnd();
I have trouble displaying a texture using OpenGL and C++. I am loading the texture from a RGB Raw file, binding it to a texture, but when I am trying to display the texture on a quad, the texture is white. I am using glGetError and it catches no errors. Here is my code:
#include <iostream>
#include <windows.h> // Standard header for MS Windows applications
#include <GL/gl.h> // Open Graphics Library (OpenGL) header
#include <GL/glut.h> // The GL Utility Toolkit (GLUT) Header
using namespace std;
typedef struct {
int width;
int height;
char* title;
float field_of_view_angle;
float z_near;
float z_far;
} glutWindow;
glutWindow win;
float rotation, distance1;
bool light=TRUE;
bool trans=FALSE;
GLuint tex;
void drawFlatFace(float size)
{
glBegin(GL_QUADS);
glTexCoord2f (0, 0);
glVertex3f(-size, -2*size, size);
glTexCoord2f (1.0, 0);
glVertex3f(size, -2*size, size);
glTexCoord2f (1.0, 1.0);
glVertex3f(size, 2*size, size);
glTexCoord2f (0, 1.0);
glVertex3f(-size, 2*size, size);
glEnd();
}
void drawBlock(float size){
glColor3f(1.0f,1.0f,1.0f);
glPushMatrix();
drawFlatFace (size);
glRotatef (90, 0, 1, 0);
drawFlatFace (size);
glRotatef (90, 0, 1, 0);
drawFlatFace (size);
glRotatef (90, 0, 1, 0);
drawFlatFace (size);
glPopMatrix();
}
GLuint loadTexture(const char * filename) {
GLuint text[1];
GLubyte* bits = new GLubyte[512*256*3];
FILE *file;
fopen_s(&file,filename,"rb");
fread(&bits,(512*256*3),1,file);
fclose(file);
glGenTextures(1,&text[0]);
glBindTexture(GL_TEXTURE_2D,text[0]);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0, 3,256,512,0,GL_RGB,GL_UNSIGNED_BYTE,bits);
free(bits);
return text[0];
}
void display()
{
GLenum err;
err = glGetError();
if (err != GL_NO_ERROR)
{
cerr << "OpenGL error: " << gluErrorString(err) << endl;
}
tex=loadTexture("tex.raw");
glBindTexture(GL_TEXTURE_2D,tex);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
glLoadIdentity();
gluLookAt( 10+distance1 ,1.4,0, 0,0,0, 0,1,0); // Define a viewing transformation
glRotatef(rotation, 0.f, 1.f, 0.f);
drawBlock(3);
if (light) glEnable(GL_LIGHTING); // Enable Lighting
else glDisable(GL_LIGHTING); // Disable Lighting
if (trans) glEnable (GL_BLEND); // Enable Transparency
else glDisable(GL_BLEND); // Disable Transparency
glutSwapBuffers();
}
void initialize ()
{
glMatrixMode(GL_PROJECTION); // select projection matrix
glViewport(0, 0, win.width, win.height); // set the viewport
glLoadIdentity(); // reset projection matrix
GLfloat aspect = (GLfloat) win.width / win.height;
gluPerspective(win.field_of_view_angle, aspect, win.z_near, win.z_far); // set up a perspective projection matrix
glMatrixMode(GL_MODELVIEW); // specify which matrix is the current matrix
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // specify implementation-specific hints
GLfloat amb_light[] = { 0.3, 0.3, 0.3, 1.0 };
GLfloat diffuse[] = { 0.4, 0.4, 0.4, 1.0 };
GLfloat specular[] = { 0.5, 0.5, 0.5, 1.0 };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, amb_light );
glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
GLfloat light_position[] = { 1.0, 1.0, 0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable( GL_LIGHT0 );
glEnable( GL_COLOR_MATERIAL );
glEnable( GL_LIGHTING );
//glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
void keyboard ( int key, int mousePositionX, int mousePositionY )
{
switch ( key )
{
case GLUT_KEY_DOWN:
if (distance1<9){
distance1=distance1+.3;
}
break;
case GLUT_KEY_UP:
if (distance1>-9){
distance1=distance1-.3;
}
break;
case GLUT_KEY_LEFT:
rotation=rotation-2;
break;
case GLUT_KEY_RIGHT:
rotation=rotation+2;
break;
case GLUT_KEY_PAGE_UP:
light=TRUE;
break;
case GLUT_KEY_PAGE_DOWN:
light=FALSE;
break;
case GLUT_KEY_HOME:
trans=TRUE;
break;
case GLUT_KEY_END:
trans=FALSE;
break;
default:
break;
}
}
int main(int argc, char **argv)
{
// set window values
win.width = 800;
win.height = 600;
win.title = "Test Texture";
win.field_of_view_angle = 45;
win.z_near = 1.0f;
win.z_far = 500.0f;
// initialize and run program
glutInit(&argc, argv); // GLUT initialization
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); // Display Mode
glutInitWindowSize(win.width,win.height); // set window size
glutCreateWindow(win.title); // create Window
// Callback functions
glutDisplayFunc(display); // register Display Function
glutIdleFunc( display ); // register Idle Function
glutSpecialFunc( keyboard ); // register Keyboard Handler
initialize();
glutMainLoop(); // run GLUT mainloop
return 0;
}
I want to add that the Raw file is displayed correctly when loaded in IrfanView as 256x512, 24BPP, RGB (the size is 393,216 bytes or 3*512*256)
This line:
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Shouldn't be in your main intialisation, but instead needs to be done when setting up the texture itself (i.e. after binding).
You may also want to set the MAG_FILTER, and the texture coordinate wrapping modes, as a general rule.
Also, you appear to be loading the texture every time you render. Don't do that, performance will be terrible and you'll run out of memory as GL will keep allocating new textures.
I want to start working with OpenGL 3+ and 4 but I'm having problems getting Glew to work. I have tried to include the glew32.lib in the Additional Dependencies and I have moved the library, and .dll into the main folder so there shouldn't be any path problems. The errors I'm getting are:
Error 5 error LNK2019: unresolved external symbol __imp__glewInit referenced in function "void __cdecl init(void)" (?init##YAXXZ) C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 4 error LNK2019: unresolved external symbol __imp__glewGetErrorString referenced in function "void __cdecl init(void)" (?init##YAXXZ) C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 3 error LNK2001: unresolved external symbol __imp____glewGenBuffers C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 1 error LNK2001: unresolved external symbol __imp____glewBufferData C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
Error 2 error LNK2001: unresolved external symbol __imp____glewBindBuffer C:\Users\Mike\Desktop\Test Folder\ModelLoader through VBO\ModelLoader\main.obj ModelLoader
And here is most of my code:
#define NOMINMAX
#include <vector>
#include <memory>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <Windows.h>
#include <cstdio>
#include <time.h>
#include "GL\glew.h"
#include "glut.h"
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "opengl32.lib")
using namespace std;
GLsizei screen_width, screen_height;
float camera[3] = {0.0f, 10.0f, -15.0f};
float xPos = 0;
float yPos = 10;
float zPos = -15;
float orbitDegrees = 0;
clock_t sTime;
float fPS;
int fCount;
GLdouble* modelV;
GLdouble* projM;
GLint* vPort;
//Lights settings
GLfloat light_ambient[]= { 0.1f, 0.1f, 0.1f, 0.1f };
GLfloat light_diffuse[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light_position[]= { 100.0f, 0.0f, -10.0f, 1.0f };
//Materials settings
GLfloat mat_ambient[]= { 0.5f, 0.5f, 0.0f, 0.0f };
GLfloat mat_diffuse[]= { 0.5f, 0.5f, 0.0f, 0.0f };
GLfloat mat_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_shininess[]= { 1.0f };
typedef struct Vectors {
float x;
float y;
float z;
}Vector;
typedef struct Polys {
Vector v;
Vector vt;
Vector vn;
int texture;
} Poly;
vector<Vector> vecs;
vector<Vector> normVecs;
vector<Vector> textVecs;
vector<Poly> polyList;
void loadModel(string filepath);
void createTex(string ref);
void render();
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
void render()
{
}
void createTex(string ref)
{
}
void loadModel(string filepath)
{
}
void resize (int p_width, int p_height)
{
if(screen_width==0 && screen_height==0) exit(0);
screen_width=p_width; // Obtain the new screen width values and store it
screen_height=p_height; // Height value
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear both the color and the depth buffer so to draw the next frame
glViewport(0,0,screen_width,screen_height); // Viewport transformation
glMatrixMode(GL_PROJECTION); // Projection transformation
glLoadIdentity(); // Initialize the projection matrix as identity
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,1.0f,10000.0f);
glutPostRedisplay(); // This command redraw the scene (it calls the same routine of glutDisplayFunc)
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This clear the background color to dark blue
glMatrixMode(GL_MODELVIEW); // Modeling transformation
glPushMatrix();
glLoadIdentity(); // Initialize the model matrix as identity
gluLookAt(xPos, yPos, zPos, /* look from camera XYZ */
0, yPos, 0, /* look at the origin */
0, 1, 0); /* positive Y up vector */
glRotatef(orbitDegrees, 0.f, 1.0f, 0.0f);
//glTranslatef(0.0,0.0,-20); // We move the object forward (the model matrix is multiplied by the translation matrix)
//rotation_x = 30;
//rotation_x = rotation_x + rotation_x_increment;
//rotation_y = rotation_y + rotation_y_increment;
//rotation_z = rotation_z + rotation_z_increment;
//if (rotation_x > 359) rotation_x = 0;
//if (rotation_y > 359) rotation_y = 0;
//if (rotation_z > 359) rotation_z = 0;
// glRotatef(rotation_x,1.0,0.0,0.0); // Rotations of the object (the model matrix is multiplied by the rotation matrices)
//glRotatef(rotation_y,0.0,1.0,0.0);
// glRotatef(rotation_z,0.0,0.0,1.0);
//if (objarray[0]->id_texture!=-1)
//{
// glBindTexture(GL_TEXTURE_2D, objarray[0]->id_texture); // We set the active texture
// glEnable(GL_TEXTURE_2D); // Texture mapping ON
// printf("Txt map ON");
//}
//else
// glDisable(GL_TEXTURE_2D); // Texture mapping OFF
glGetDoublev(GL_PROJECTION_MATRIX, modelV);
glGetDoublev(GL_PROJECTION_MATRIX, projM);
glGetIntegerv(GL_VIEWPORT, vPort);
if(clock() > sTime)
{
fPS = fCount;
fCount = 0;
sTime = clock() + CLOCKS_PER_SEC;
}
render();
glDisable(GL_LIGHTING);
GLdouble pos[3];
gluUnProject(100, yPos, -14, modelV, projM, vPort, &pos[0], &pos[1], &pos[2]);
char buffer2[255];
int pAmmount = sprintf(buffer2,"FPS: %.2f", fPS);
//glRasterPos3f(pos[0], pos[1], pos[2]);
for(int i = 0; i < pAmmount; i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, buffer2[i]);
}
glEnable(GL_LIGHTING);
/*glPopMatrix();
glPushMatrix();
glTranslatef(5.0,0.0,-20.0);
objarray[1]->render();*/
glPopMatrix();
glFlush(); // This force the execution of OpenGL commands
glutSwapBuffers(); // In double buffered mode we invert the positions of the visible buffer and the writing buffer
fCount++;
}
void keyboard(unsigned char k, int x, int y)
{
switch(k)
{
case 'w':
yPos++;
break;
case 's':
yPos--;
break;
case 'a':
xPos--;
break;
case 'd':
xPos++;
break;
case 'q':
orbitDegrees--;
break;
case 'e':
orbitDegrees++;
break;
case 'z':
zPos--;
break;
case 'x':
zPos++;
break;
}
}
void initWindow(GLsizei screen_width, GLsizei screen_height)
{
glClearColor(0.0, 0.0, 0.0, 0.0); // Clear background color to black
// Viewport transformation
glViewport(0,0,screen_width,screen_height);
// Projection transformation
glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations
glLoadIdentity(); // We initialize the projection matrix as identity
gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,1.0f,10000.0f); // We define the "viewing volume"
gluLookAt(camera[0], camera[1], camera[2], /* look from camera XYZ */
0, 0, 0, /* look at the origin */
0, 1, 0); /* positive Y up vector */
try
{
//loadModel("Goku habit dechiré.obj");
loadModel("Flooring.obj");;
}
catch(string& filepath)
{
cerr << "Model could not be loaded: " << filepath << endl;
filepath = "Model could not be loaded: " + filepath;
wostringstream sString;
sString << filepath.c_str();
MessageBox(HWND_DESKTOP, sString.str().c_str(), L"Error: loadModel(string filepath)", MB_OK);
}
//Lights initialization and activation
glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_specular);
glLightfv (GL_LIGHT1, GL_POSITION, light_position);
glEnable (GL_LIGHT1);
glEnable (GL_LIGHTING);
//Materials initialization and activation
glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_specular);
glMaterialfv (GL_FRONT, GL_POSITION, mat_shininess);
//Other initializations
glShadeModel(GL_SMOOTH); // Type of shading for the polygons
//glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Texture mapping perspective correction
//glEnable(GL_TEXTURE_2D); // Texture mapping ON
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
glEnable(GL_CULL_FACE); // Enable the back face culling
glEnable(GL_DEPTH_TEST); // Enable the depth test
glEnable(GL_NORMALIZE);
/*float* matrix = new float[16];
glGetFloatv(GL_PROJECTION_MATRIX, matrix);
for(int i = 0; i < 4; i++)
{
cout << matrix[0] << " " << matrix[1] << " " << matrix[2] << " " << matrix[3] << endl;
matrix += 3;
}*/
modelV = new GLdouble[16];
projM = new GLdouble[16];
vPort = new GLint[4];
sTime = clock() + CLOCKS_PER_SEC;
}
void init()
{
GLenum GlewInitResult;
GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult) {
fprintf(
stderr,
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE);
}
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
}
int main(int argc, char **argv)
{
screen_width = 800;
screen_height = 800;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(screen_width,screen_height);
glutInitWindowPosition(0,0);
glutCreateWindow("ModelLoader");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc (resize);
glutKeyboardFunc(keyboard);
//glutKeyboardFunc(keyboard);
//glutSpecialFunc(keyboard_s);
initWindow(screen_width, screen_height);
init();
glutMainLoop();
return 0;
}
You have a linkage problem. You are not providing to the linker the correct path to the glew lib file. For this reason the linker is not able to find the compiled code of the functions you are calling.
From your log it seems you are working on Windows. If you are using Visual Studio, right click on you project. Select Linker, and then Input. Verify that Additional dependencies contains the path to glew lib.
Notice that the dll is not required at linking time. This will be loaded only at run time (remember to put it in the same folder as your executable or in a path listed in your system path).
This has been fixed. The problem was only represented on the machine I was using in University. The problem was that the machine had an older .dll which was conflicting with the .dll that I had in the solution files. It was installed in the System files of the machine. As such it was producing these errors.
I should probably check for such a thing next time.
Not sure how it will help you but, you might give a try and statically link your project to a ".a" library. or it's .lib on windows. If there are unresolved symbol it means it tried to link to a library and not really to a dll.
If it was using the dll, it would probably fail at runtime.
I'm trying to modify the sample code for loading 3d model included in ASSIMP's sample code, by using GLUT instead of WGL. However, i got a problem with the texture, as illustrated below:
while it is supposed to be as illustrated below:
and the code for drawing the 3d model listed below:
void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale){
unsigned int i;
unsigned int n=0, t;
struct aiMatrix4x4 m = nd->mTransformation;
m.Scaling(aiVector3D(scale, scale, scale), m);
// update transform
m.Transpose();
glPushMatrix();
glMultMatrixf((float*)&m);
// draw all meshes assigned to this node
for (; n < nd->mNumMeshes; ++n){
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
if(mesh->mNormals == NULL){
glDisable(GL_LIGHTING);
}
else {
glEnable(GL_LIGHTING);
}
if(mesh->mColors[0] != NULL) {
glEnable(GL_COLOR_MATERIAL);
}
else {
glDisable(GL_COLOR_MATERIAL);
}
for (t = 0; t < mesh->mNumFaces; ++t) {
const struct aiFace* face = &mesh->mFaces[t];
GLenum face_mode;
switch(face->mNumIndices) {
case 1: face_mode = GL_POINTS; break;
case 2: face_mode = GL_LINES; break;
case 3: face_mode = GL_TRIANGLES; break;
default: face_mode = GL_POLYGON; break;
}
glBegin(face_mode);
for(i = 0; i < face->mNumIndices; i++){
int vertexIndex = face->mIndices[i]; // get group index for current index
if(mesh->mColors[0] != NULL)
Color4f(&mesh->mColors[0][vertexIndex]);
if(mesh->mNormals != NULL)
if(mesh->HasTextureCoords(0)){
glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1- mesh->mTextureCoords[0][vertexIndex].y);
}
glNormal3fv(&mesh->mNormals[vertexIndex].x);
glVertex3fv(&mesh->mVertices[vertexIndex].x);
}
glEnd();
}
}
// draw all children
for (n = 0; n < nd->mNumChildren; ++n) {
recursive_render(sc, nd->mChildren[n], scale);
}
glPopMatrix();
}
apply_material function, almost exactly the same as ASSIMP provided sample
void apply_material(const struct aiMaterial *mtl)
{
float c[4];
GLenum fill_mode;
int ret1, ret2;
struct aiColor4D diffuse;
struct aiColor4D specular;
struct aiColor4D ambient;
struct aiColor4D emission;
float shininess, strength;
int two_sided;
int wireframe;
unsigned int max; // changed: to unsigned
int texIndex = 0;
aiString texPath; //contains filename of texture
if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)) {
unsigned int texId = textureIdMap[texPath.data];
glBindTexture(GL_TEXTURE_2D, texId);
}
set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
color4_to_float4(&diffuse, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
color4_to_float4(&ambient, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
color4_to_float4(&specular, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
color4_to_float4(&emission, c);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
max = 1;
ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
max = 1;
ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS))
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
else {
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
}
max = 1;
if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
fill_mode = wireframe ? GL_LINE : GL_FILL;
else
fill_mode = GL_FILL;
glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
max = 1;
if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
glEnable(GL_CULL_FACE);
else
glDisable(GL_CULL_FACE);
}
and also loadGLtextures function, i don't think it is related with culling tough.
int LoadGLTextures(const aiScene* scene) {
ILboolean success;
/* initialization of DevIL */
ilInit();
/* scan scene's materials for textures */
for (unsigned int m=0; m<scene->mNumMaterials; ++m) {
int texIndex = 0;
aiString path; // filename
aiReturn texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
while (texFound == AI_SUCCESS) {
//fill map with textures, OpenGL image ids set to 0
textureIdMap[path.data] = 0;
// more textures?
texIndex++;
texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
}
}
int numTextures = textureIdMap.size();
/* create and fill array with DevIL texture ids */
ILuint* imageIds = new ILuint[numTextures];
ilGenImages(numTextures, imageIds);
/* create and fill array with GL texture ids */
GLuint* textureIds = new GLuint[numTextures];
glGenTextures(numTextures, textureIds); /* Texture name generation */
/* get iterator */
std::map<std::string, GLuint>::iterator itr = textureIdMap.begin();
printf("TextureIDMap Begin %i\n", textureIdMap.begin());
int i=0;
for (; itr != textureIdMap.end(); ++i, ++itr) {
//save IL image ID
std::string filename = (*itr).first; // get filename
(*itr).second = textureIds[i]; // save texture id for filename in map
printf("Texture loaded: %s\n",filename.c_str());
printf("Texture ID Map End: %i\n",textureIdMap.end());
ilBindImage(imageIds[i]); /* Binding of DevIL image name */
ilEnable(IL_ORIGIN_SET);
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
success = ilLoadImage((ILstring)filename.c_str());
if (success) {
/* Convert image to RGBA */
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
/* Create and load textures to OpenGL */
glBindTexture(GL_TEXTURE_2D, textureIds[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ilGetInteger(IL_IMAGE_WIDTH),
ilGetInteger(IL_IMAGE_HEIGHT), 0, GL_RGBA, GL_UNSIGNED_BYTE,
ilGetData());
}
else
printf("Couldn't load Image: %s\n", filename.c_str());
}
/* Because we have already copied image data into texture data we can release memory used by image. */
ilDeleteImages(numTextures, imageIds);
//Cleanup
delete [] imageIds;
delete [] textureIds;
//return success;
return true;
}
Lighthouse 3D has given an example for doing this, however, at the moment i can not implement GLSL and VAO to my program. Any solution? Thanks in advance.
I've found the workaround. I changed how to access textures in recursive_render function using the following code :
glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, mesh->mTextureCoords[0][vertexIndex].y);
instead of:
glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1-mesh->mTextureCoords[0][vertexIndex].y);
This is not a problem with textures. Your problem is coming from backface culling (at least it seems like it since you can kind of see inside the duck). Either your polygons are wound in the wrong order, or your backface culling is set up incorrectly. If you post the code where you set the backface culling, we can see exactly what is wrong.
There could also be the possibility that some of your normals are facing inwards (which can also result from polygon winding). That would explain why your duck's beak is pitch black.
I'm pretty sure the problem is the texture is being 'flipped' along Y axis. That's why your '1-y' works. It can be fixed by flipping the texture along Y while loading. Though I'm not yet sure why 'cause only stumbled upon this problem today.
I'm not sure if this helps but you can flip UV coordinates when importing a model
const aiScene* scene = importer.ReadFile(path, aiProcess_FlipUVs);