Graphics: AMD Radeon HD 7900 Series
Running: Windows 7(64 bit)
Program: CodeBlocks(32 bit)
OpenGL Library: GLee
This is where I setup the window. Its an SDL window using OpenGL rendering.
void Init(int w, int h, bool fullScr)
{
if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
}
winW = w*scale;
winH = h*scale;
original_winW = w;
origianl_winH = h;
putenv("SDL_VIDEO_WINDOW_POS");
putenv("SDL_VIDEO_CENTERED=1");
getenv("SDL_VIDEO_WINDOW_POS");
getenv("SDL_VIDEO_CENTERED");
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 ); // *new*
//Sets up the screen and displays the window
screen = SDL_SetVideoMode( winW, winH, 32, SDL_OPENGL | (fullScr*SDL_FULLSCREEN) ); // *changed*
screenRect.x = 0;
screenRect.y = 0;
screenRect.w = winW;
screenRect.h = winH;
SDL_ShowCursor(false);
SetGLState();
}
This is the SetGLState() mentioned above.
void SetGLState(){
glEnable( GL_TEXTURE_2D ); //Enable 2d texturing
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); //Set clear color (rgba)
glViewport( 0, 0, winW, winH ); //Set the viewport
glClear( GL_COLOR_BUFFER_BIT ); //Clear back buffer?
glMatrixMode( GL_PROJECTION ); //Set to projection
glLoadIdentity();
glOrtho(0.0f, winW, winH, 0.0f, -1.0f, 1.0f); //Create orthogonal projection matrix
glMatrixMode( GL_MODELVIEW ); //Set back to model view
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
This is where the images are drawn to the screen
void DrawImage(GLSurface image, float x, float y)
{
// Bind the texture to which subsequent calls refer to
if(boundTexture != image.Surface){glBindTexture( GL_TEXTURE_2D, image.Surface ); boundTexture = image.Surface; }
glReadPixels(x,y,image.w*2,image.h*2,GL_UNSIGNED_BYTE,NULL,NULL);
glLoadIdentity();
glScalef(scale,scale,1);
glRotatef(image.rotation[0], 1.0f, 0.0f, 0.0f);
glRotatef(image.rotation[1], 0.0f, 1.0f, 0.0f);
glRotatef(image.rotation[2], 0.0f, 0.0f, 1.0f);
if(scale == 7.5)x += 48;
glBegin( GL_QUADS );
//Bottom-left vertex (corner)
glColor3b(127,127,127);
glTexCoord2i( 0, 0 ); //Position on texture to begin interpolation
glVertex3f( x, y, 0.f ); //Vertex Coords
//Bottom-right vertex (corner)
glTexCoord2i( 1, 0 );
glVertex3f( x+image.w, y, 0.f );
//Top-right vertex (corner)
glTexCoord2i( 1, 1 );
glVertex3f( x+image.w, y+image.h, 0.f );
//Top-left vertex (corner)
glTexCoord2i( 0, 1 );
glVertex3f( x, y+image.h, 0.f );
glEnd();
}
This window doesn't draw anything, and I can't figure out why. I haven't looked at this code in awhile, but I know that on a previous install of windows, I had it working. All of my other projects run, but this one doesn't. It just renders a blank screen. The weird thing is--I have a resize function for this window. When that function gets called, the screen displays a white screen instead of a black one.
Edit**
This code is called at the end once everything has been drawn to the screen. It was already included in my code.
void Flip(){
SDL_GL_SwapBuffers();
glClear( GL_COLOR_BUFFER_BIT );
}
All the state set in SetGLState is drawing state. Call it from the DrawImage function. Most importantly, glClear must be put in the draw function, it doesn't make sense anywhere else.
That call to glReadPixels makes no sense.
And you must swap the buffers when done SDL_SwapBuffers (IIRC, haven't used SDL in some time).
Related
how can i draw in 2D coordinates instead of vertex coordinate system, as this =>
drawPoint(50 , 100 , 0.01f);
this is my code , a background texture and a point
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
double w = glutGet( GLUT_WINDOW_WIDTH ) / 300.0;
double h = glutGet( GLUT_WINDOW_HEIGHT ) / 300.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho( -1 * w/2, 1 * w/2, -1 * h/2, 1 * h/2, w/2, -h/2);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-w/2.f, -h/2.f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( w/2.f, -h/2.f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( w/2.f, h/2.f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-w/2.f, h/2.f, 0.0f);
glEnd();
drawPoint(50 , 100 , 0.01f);
glutSwapBuffers();
}
the function DrawPoint => draws circles
void drawPoint(GLfloat x, GLfloat y, GLfloat radius){
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
int i;
int triangleAmount = 20; //# of triangles used to draw circle
//GLfloat radius = 0.8f; //radius
GLfloat twicePi = 2.0f * 3.1415;
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(x, y); // center of circle
for(i = 0; i <= triangleAmount;i++) {
glVertex2f(
x + (radius * cos(i * twicePi / triangleAmount)),
y + (radius * sin(i * twicePi / triangleAmount))
);
}
glEnd();
glEnable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
}
So I don't know if I have to change the DrawPoint function.
UPDATE : this is my main source
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInit(&argc, argv);
glutInitWindowSize(widthX, heightY);
glutCreateWindow("prg");
glutReshapeFunc(resize);
glutDisplayFunc(Draw);
glutKeyboardFunc(keyPressed);
glutKeyboardUpFunc(keyUp);
texture[0] = SOIL_load_OGL_texture
(
"img.jpg",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glEnable(GL_TEXTURE_2D);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glutMainLoop();
UPDATE 2 :
if in this way is impossible, is there a method that transform an x and y into a vector ?, so for example :
DrawPoint(VectConvert(50),VectConvert(100),0.01f);
I am not sure if this is right answer. I edited your code, try this:
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// You divided your window width and height by 300 which seems to be wrong
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Create ortho 2d
// The last two parameters are near and far planes
// Since you are using only 2D you should keep them at 0.0 and 1.0
glOrtho( -1 * w/2.0, 1 * w/2.0, -1 * h/2.0, 1 * h/2.0, 0.0f, 1.0f);
// Mirror Y axis
glScalef(1, -1, 1);
// Now your coordinate system starts at center of your window
// You need to move it to the left top corner
glTranslatef(-(w/2.0f), -(h/2.0f), 0.0f);
texture[0] = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
(
"img.jpg",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_POLYGON);
// You need also to mirror your Y coordinates for texture
glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f , 0.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(w , 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(w , h , 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f , h , 0.0f);
glEnd();
drawPoint(50 , 100 , 0.01f);
glutSwapBuffers();
}
Also, do not load your texture from file every frame. It is overkill for your GPU.
Just set an ortogonal projection as you need it:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, w, h, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Please note a few things here:
This assumes that w and h are actually the width and height of your viewport.
I put this into the GL_PROJECTION matrix. That is where this stuff belongs. (Although it might not be critical in your use case).
I set the near and far planes to -1 and 1 respectively. I don't know what you actually will need, but your values didn't make any sense.
That will set up a coordinate system where the pixel centers are actually exactly between two integer values, and integer values denote the middle between two adjacent pixels, so (0,0) will be the top left corner of the top left pixel, and (w,h) the bottom right corner of the bottom left pixel.
You also could set up a mapping that maps the integers to the pixel centers, like glOrtho(-0.5, w-0.5, h-0.5, -0.5, -1, 1). Now (0,0) is the center of the top left pixel, and (w,h) is outside the screen, (w-1,h-1) is the center of the bottom right pixel.
I'm trying to render a set of 200 RGB frames. For doing the same i'm creating a texture of height 416 and width 240. However i just get a black screen with the print statements working in the background.
Below is my code:
#include <stdio.h>
#include <stdlib.h>
#include "glew.h"
#include "glfw.h"
#include "glaux.h"
int index;
AUX_RGBImageRec texture1;
GLuint texture;
unsigned long long pos;
unsigned char *guibuffer;
HDC hDC = NULL;
void initGL(void)
{
int maxSz;
int maxwidth = 416;
int maxheight = 240;
if( !glfwInit() )
{
exit( EXIT_FAILURE );
}
// if( !glfwOpenWindow(4096, 2118, 0,0,0,0,0,0, GLFW_WINDOW ) )
if( !glfwOpenWindow(maxwidth, maxheight, 0,0,0,0,0,0, GLFW_WINDOW ) ) //GLFW_FULLSCREEN
{
glfwTerminate();
exit( EXIT_FAILURE );
}
glfwSetWindowTitle("sample");
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxSz);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
hDC= wglGetCurrentDC();
#if 1
{ // TSS
HWND hCurrentWindow = GetActiveWindow();
char szTitle[256]="sample";
//SetWindowText(hCurrentWindow,szTitle );
// SetWindowLongA (hCurrentWindow , GWL_STYLE, (GetWindowLongA (hCurrentWindow , GWL_STYLE) & ~(WS_CAPTION)));
SetWindowLongA (hCurrentWindow, GWL_STYLE, (WS_VISIBLE));
}
#endif
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
}
int GL_Disply()
{
FILE *fptr=fopen("E:\\myRGB.rgb","rb");
fseek(fptr,pos,SEEK_SET);
fread(guibuffer,sizeof(unsigned char),sizeof(unsigned char)*416*240*3,fptr);
pos+=416*240*3;
texture1.sizeX =416;
texture1.sizeY =240;
texture1.data = guibuffer;
glDepthFunc(GL_ALWAYS);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
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_RGB, texture1.sizeX, texture1.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBegin(GL_QUADS);
//glNormal3f( 0.0f, 0.0f, 0.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
// Swap front and back rendering buffers
glfwSwapBuffers();
glDeleteTextures(1, &texture);
}
int main(int argc, char *argv[])
{
initGL(); // GL initialization
/* CPU memory allocation using C - malloc */
guibuffer=(unsigned char*)malloc(sizeof(unsigned char)*416*240*3);
for(index=0;index<200;index++)
{
printf("frame %d displayed....\r",index);
GL_Disply();
}
return 0;
}
Can anyone please tell me where i'm going wrong?
You are not passing data (last parameter) to the glTexImage2D function. I guess you would want to pass data readed from your E:\myRGB.rgb file.
It may have something to do with the matrix stack. I think you want to be in glMatrixMode (GL_MODELVIEW) when you draw stuff, not GL_PROJECTION, and you may need to set up your matrices correctly. Though, glMatrixMode, glBegin, glEnd, glTexCoord, glVertex3f, is the old fixed function way of rendering. Using shaders is the modern way of rendering with OpenGL.
If i comment out DrawGLScene(), i see a large shaded triangle, if I comment out drawtri() i see a square texture drawn. But I am not able to combine both - when both func's are called, I see only triangle outline and the texture is rendered with a strong red filter applied.
What could be the problem?
void DrawGLScene()
{
int x, y;
float float_x, float_y, float_xb, float_yb;
float x0=0,y0=0,x1=10,y1=10,z=-3;
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glEnable(GL_TEXTURE_2D);
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-12.0f); // move 12 units into the screen.
glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
glPolygonMode(GL_BACK, GL_FILL);
glPolygonMode(GL_FRONT, GL_LINE);
glBegin(GL_QUADS);
glTexCoord2f( 0,0);
glVertex3f( x0, y0, z );
glTexCoord2f( 0, 1 );
glVertex3f( x0, y1, z );
glTexCoord2f( 1, 1);
glVertex3f( x1, y1, z );
glTexCoord2f( 1, 0 );
glVertex3f( x1, y0,z );
glEnd();
glDisable(GL_TEXTURE_2D);
// since this is double buffered, swap the buffers to display what just got drawn.
// glutSwapBuffers();
}
void drawtri() {
glBegin(GL_TRIANGLES);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
}
void zdisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen and Depth Buffer
glLoadIdentity();
glTranslatef(0.0f,0.0f,-3.0f);
//drawtri();
DrawGLScene();
glutSwapBuffers();
}
The red filter is caused by the applied color:
glColor3f(0.0f,0.0f,1.0f);
Reset the color to white before drawing the quad:
glColor3f(1.0f,1.0f,1.0f);
The outline is caused by the following specification:
glPolygonMode(GL_FRONT, GL_LINE);
Specify fill mode:
glPolygonMode(GL_FRONT, GL_FILL);
When calling both functions, did you actually call the methods in the order in which the code shows them? Because I suspect that the order was reversed. If I'm right, I think you must reset the glPolygonMode when drawing the triangle. Try adding glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) before the call to glBegin(GL_TRIANGLES).
I have started learning OpenGL using NeHe tutorials for a little while.This is the code for lesson 6.It should load a bmp image and use it as texture for the cube I'm drawing.But It doesn't work properly and the cube remains white at all.The function for loading the image is "loadGLTextures".Can anyone help?
My image bit depth is 24.I'm working with Visual Studio 2010.
#include <Windows.h>
#include <stdio.h>
#include <gl\GL.h>
#include <gl\GLU.h>
#include <SDL\SDL.h>
#pragma comment(lib , "SDL.lib")
#pragma comment(lib , "SDLmain.lib")
#pragma comment(lib , "OPENGL32.lib")
#pragma comment(lib , "glu32.lib")
//height , width and bit depth
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define SCREEN_BPP 16
//SDL surface
SDL_Surface* surface;
//Texture storage.
GLuint texture[1];
//Quit func.
void Quit(int returnCode)
{
SDL_Quit();
exit(returnCode);
}
//This function will load a bitmap image.
bool loadGLTextures(void)
{
SDL_Surface* textureImage;
textureImage = SDL_LoadBMP("123.bmp");
if(!textureImage)
{
fprintf(stderr , "Couldn't load %s.\n" , "123.bmp");
return false;
}
else
{
//Create the texture.
glGenTextures(1 , &texture[0]);
//Typical texture generation using data from the bitmap.
glBindTexture(GL_TEXTURE_2D , texture[0]);
//Generate the texture.
glTexImage2D(GL_TEXTURE_2D , 0 , 3 , textureImage->w ,
textureImage->h , 0 , GL_RGB , GL_UNSIGNED_BYTE ,
textureImage->pixels);
//Linear filtering.
glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR);
//Free up the memory.
if(textureImage)
SDL_FreeSurface(textureImage);
return true;
}
}
//All of the drawing goes throw this.
int drawGLScene(void)
{
static float xrot = 0 , yrot = 0 , zrot = 0;
//Clear screen and depth buffer.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f , 0.0f , -5.0f);
glRotatef(xrot , 1.0f , 0.0f , 0.0f);
glRotatef(yrot , 0.0f , 1.0f , 0.0f);
glRotatef(zrot , 0.0f , 0.0f ,1.0f);
//Select the texture.
glBindTexture(GL_TEXTURE_2D , texture[0]);
glBegin(GL_QUADS);
//Front:
//Bottom left of the texture and quad.
glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
//Bottom right fo the texture and quad.
glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , 1.0f);
//Top right of the texture and quad.
glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
//Top left of the texture and quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
//Back:
//Bottom left of the texture and quad.
glTexCoord2f(0.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
//Bottom right of the texture and quad.
glTexCoord2f(1.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
//Top right of the texture and the quad.
glTexCoord2f(1.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
//Top left of the texture and the quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
//Top:
//Top right of the texture and quad.
glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
//Top left of the texture and quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
//Bottom left of the texture and quad.
glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
//Bottom right of the texture and quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
//Bottom:
//Top left of the texture and quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
//Bottom left of the texture and quad.
glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
//Bottom right of the texture and quad.
glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
//Top right of the texture and quad.
glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , -1.0f , 1.0f);
//Right:
//Bottom right of the texture and quad.
glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
//Top right of the texture and quad.
glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
//Top left of the texture and quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
//Bottom left of the texture and quad.
glTexCoord2f(0.0f , 0.0f); glVertex3f(1.0f , -1.0f , 1.0f);
//Left:
//Bottom left of the texture and quad.
glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
//Bottom right of the texture and quad.
glTexCoord2f(1.0f , 0.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
//Top right of the texture and quad.
glTexCoord2f(1.0f , 1.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
//Top left of the texture and quad.
glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
glEnd();
SDL_GL_SwapBuffers();
xrot += 0.1;
yrot += 0.1;
zrot += 0.1;
return true;
}
//This function will reset our viewport after a windows resize.
int resizeWindow(int width , int height)
{
//Height / width ration.
float ratio;
//Protect against a division by zero.
if(height == 0)
height = 1;
ratio = width / height;
//Setup viewport
glViewport(0 , 0 , width , height);
//Change to the projection matrix and reset it.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//set perspective.
gluPerspective(45.0f , ratio , 0.1f , 100.0f);
//Change to model view matrix and reset it.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return true;
}
//Toggle fullScreen.
void toggleFullscreen(SDL_Surface* screen)
{
int videoFlags = screen->flags;
(videoFlags & SDL_FULLSCREEN) == SDL_FULLSCREEN ? videoFlags ^= SDL_FULLSCREEN : videoFlags |= SDL_FULLSCREEN;//NICE!!
screen = SDL_SetVideoMode(SCREEN_WIDTH , SCREEN_HEIGHT , SCREEN_BPP , videoFlags);
resizeWindow(surface->w , surface->h);
drawGLScene();
}
//OpenGL initialization.
int initGL(void)
{
if(!loadGLTextures())
return false;
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D); //Enable texture mapping.
glClearColor(0.0f , 0.0f , 0.0f , 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
//Nice perspective.
glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);
return true;
}
//This func will handle any key inputs.
void handleKeyPress(SDL_keysym* keysym)
{
switch(keysym->sym)
{
case SDLK_ESCAPE:
Quit(0);
break;
case SDLK_F1:
toggleFullscreen(surface);
break;
case SDLK_r:
drawGLScene();
break;
default:
break;
}
return;
}
int main(int argc , char* argv[])
{
//Flags to pass to SDL_SetVideoMode : awsome!! ints can be compiled.
int videoFlags;
//Event
SDL_Event event;
//Holds information about display.
const SDL_VideoInfo* videoInfo;
//Is window active?
bool isActive = true;
//SDL initialization.
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr , "SDL video initialization failed : %s\n" , SDL_GetError());
Quit(1);
}
//Fetch the video info.
videoInfo = SDL_GetVideoInfo();
if(!videoInfo)
{
fprintf(stderr , "Video query failed : %s\n" , SDL_GetError());
Quit(1);
}
//Add flags to pass to SDL_SetVideoMode.
videoFlags = SDL_OPENGL; //Enable OpenGL in SDL.
videoFlags |= SDL_GL_DOUBLEBUFFER; //Enable double buffering.
videoFlags |= SDL_HWPALETTE; //Store the palette in hardware.
videoFlags |= SDL_RESIZABLE; //Enable window resizing.
//This checks to see if surfaces can be stored in hardware.
videoInfo->hw_available ? videoFlags |= SDL_HWSURFACE : SDL_SWSURFACE;
//This checks if harware blits can be done.
if(videoInfo->blit_hw)
videoFlags |= SDL_HWACCEL;
//Set OpenGL double buffering.
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER , 1);
surface = SDL_SetVideoMode(SCREEN_WIDTH , SCREEN_HEIGHT , 16 , videoFlags);
//verify the surface.
if(!surface)
{
fprintf(stderr , "Video mode set failed : %s\n" , SDL_GetError());
Quit(1);
}
SDL_WM_SetCaption("OpenGL-Sample" , 0);
//initialize OpenGL
if(initGL() == false)
{
fprintf(stderr , "Could not initialize OpenGL.\n");
Quit(1);
}
//Main loop
while(1)
{
//Handle the events in the queue.
if(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_ACTIVEEVENT:
if(event.active.gain == 0)
isActive = false;
else
isActive = true;
break;
case SDL_VIDEORESIZE:
//Handle resize event.
surface = SDL_SetVideoMode(event.resize.w , event.resize.h , SCREEN_BPP , videoFlags);
if(!surface)
{
fprintf(stderr , "Could not get a surface after resize : %s\n" , SDL_GetError());
Quit(1);
}
resizeWindow(event.resize.w , event.resize.h);
break;
case SDL_KEYDOWN:
handleKeyPress(&event.key.keysym);
break;
case SDL_QUIT:
Quit(0);
default:
break;
}
}
if(isActive)
drawGLScene();
}
}
This is the image I'm trying to load.
I use the SOIL library, http://www.lonesock.net/soil.html,
It's a very easy to use OpenGL texture loader library, you don't have to
worry about the image format or make any loading code yourself, it will do it all for you.
Loading a texture is as easy as this:
int textureID = SOIL_load_OGL_texture("img.png", SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS);
if(textureID == 0) { cout << "Failed to load texture!" << endl };
I was able to get your program to produce a texture (although it was mirrored) by changing:
textureImage->h , 0 , GL_RGB , GL_UNSIGNED_BYTE ,
to:
textureImage->h , 0 , GL_RGBA , GL_UNSIGNED_BYTE ,
Getting that field wrong unfortunately does not produce any error. It may cause your program to crash if you attempt to tell the GL that the image data is bigger than it really is, but passing GL_RGB instead of GL_RGBA has the effect of saying it's smaller than it really is.
Keep in mind that SDL_LoadBMP() doesn't attempt to convert the image data, so you have to make sure the format of the BMP file is what the program expects. you probably need to use GL_RGBA or GL_RGB.
Everything depends on your image's format. As Michael said SDL_LoadBMP does not convert the image data. So you can't be sure which flag you should pass.
I recommend you to use SDL_Image library. Which converts all the image formats to one specific format. Then you can use (for example) GL_RGBA flag and make sure everything works!
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();
}