2D-texture based volume rendering - c++

I found a wonderful volume rendering tutorial on the internet:
volume rendering tutorial
. The sample code is written in Windows and since I am working on a Mac, I tried to write my own code according to my understanding. For now, my program just arranges the 2D frame from -1 to 1 in Z axis without applying alpha and blend. So if everything goes well, I should be able to see the first slice. However, when I run the program, I get something weird.
My code:
//
// VolumeRendering.cpp
// Volume_Rendering
//
// Created by HOBBY on 4/5/14.
// Copyright (c) 2014 Yihao Jiang. All rights reserved.
//
#include <GLTools.h>
#include <GL/glew.h>
#include <Opengl/gl.h>
#include <glut/glut.h>
#include <fstream>
#include "VolumeRendering.h"
#include <GLMatrixStack.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
int m_uImageCount;
int m_uImageWidth;
int m_uImageHeight;
GLuint* m_puTextureIDs;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrame cameraFrame;
GLFrustum viewFrustum;
GLBatch myBatch;
GLGeometryTransform transformPipeline;
GLShaderManager shaderManager;
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
GLdouble aspectRatio = (GLdouble)(w)/(GLdouble)(h);
if (w <= h)
{
viewFrustum.SetOrthographic(-1.0f, 1.0f, -(1.0f/aspectRatio), 1.0f/aspectRatio, -1.0f, 1.0f);
}
else
{
viewFrustum.SetOrthographic(-1.0f, 1.0f, -(1.0f * aspectRatio), 1.0f * aspectRatio, -1.0f, 1.0f);
}
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
void SetupRC()
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
shaderManager.InitializeStockShaders();
glEnable(GL_DEPTH_TEST);
const char* filePath = "/Users/WensarHobby/Documents/Codes/workspace/Volume_Rendering/Volume_Rendering/head256x256x109";
if(!InitTextures2D(filePath))
{
printf("InitTexture error");
}
}
bool InitTextures2D(const char* filePath)
{
std::fstream myFile;
myFile.open(filePath, std::ios::in | std::ios::binary);
m_uImageCount = 109;
m_uImageWidth = 256;
m_uImageHeight = 256;
// Holds the texuture IDs
m_puTextureIDs = new GLuint[m_uImageCount];
// Holds the luminance buffer
char* chBuffer = new char[m_uImageWidth * m_uImageHeight];
char* chRGBABuffer = new char[m_uImageWidth * m_uImageHeight * 4];
glGenTextures(m_uImageCount, (GLuint*)m_puTextureIDs);
// Read each frames and construct the texture
for( int nIndx = 0; nIndx < m_uImageCount; ++nIndx )
{
// Read the frame
myFile.read(chBuffer, m_uImageWidth*m_uImageHeight);
// Set the properties of the texture.
glBindTexture( GL_TEXTURE_2D, m_puTextureIDs[nIndx] );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
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_LUMINANCE, m_uImageWidth, m_uImageHeight , 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE,(GLvoid *) chBuffer);
glBindTexture( GL_TEXTURE_2D, 0 );
}
delete[] chBuffer;
delete[] chRGBABuffer;
return true;
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
{}
if (key == GLUT_KEY_DOWN)
{
}
if (key == GLUT_KEY_LEFT)
{
}
if (key == GLUT_KEY_RIGHT)
{
}
glutPostRedisplay();
}
void RenderScene(void)
{
static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f };
static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
for(int nIndx=0; nIndx <m_uImageCount;++nIndx)
{
glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]);
MakeQuads(nIndx);
glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]);
}
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
transformPipeline.GetModelViewMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos, vWhite, 0);
myBatch.Draw();
modelViewMatrix.PopMatrix();
glutSwapBuffers();
}
void MakeQuads(int quads_index)
{
myBatch.Begin(GL_QUADS, 4, 1);
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(quads_index, 0.0f, 0.0f);
myBatch.Vertex3f(-1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(quads_index, 1.0f, 0.0f);
myBatch.Vertex3f(1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(quads_index, 0.0f, 1.0f);
myBatch.Vertex3f(-1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(quads_index, 1.0f, 1.0f);
myBatch.Vertex3f(1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
myBatch.End();
}
void ShutdownRC(void)
{
glDeleteTextures(m_uImageCount, (GLuint*)m_puTextureIDs);
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(400, 400);
glutCreateWindow("Volume_Rendering");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}
And this is my weird result:
I am new to OpenGL and volume rendering, in my opinion, there should be something wrong with my use of the shader manager. But I am not so sure. Anyone can tell me where the problem is? Thank you very much.

Finally, I figure it out! I was right and the problem lies in function MultiTexCoord2f(). The first parameter of this function here should always be 0 rather than quads_index. No multitextures here!! The new code looks like this:
#include <GLTools.h>
#include <GL/glew.h>
#include <Opengl/gl.h>
#include <glut/glut.h>
#include <fstream>
#include "VolumeRendering.h"
#include <GLMatrixStack.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
int m_uImageCount;
int m_uImageWidth;
int m_uImageHeight;
GLuint* m_puTextureIDs;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLFrame cameraFrame;
GLFrame objectFrame;
GLFrustum viewFrustum;
GLBatch myBatch;
GLGeometryTransform transformPipeline;
GLShaderManager shaderManager;
void ChangeSize(int w, int h)
{
glViewport(0, 0, w, h);
viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
void SetupRC()
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
shaderManager.InitializeStockShaders();
glEnable(GL_DEPTH_TEST);
const char* filePath = "/Users/WensarHobby/Documents/Codes/workspace/Volume_Rendering/Volume_Rendering/head256x256x109";
if(!InitTextures2D(filePath))
{
printf("InitTexture error");
}
cameraFrame.MoveForward(-7.0f);
}
bool InitTextures2D(const char* filePath)
{
std::fstream myFile;
myFile.open(filePath, std::ios::in | std::ios::binary);
m_uImageCount = 109;
m_uImageWidth = 256;
m_uImageHeight = 256;
// Holds the texuture IDs
m_puTextureIDs = new GLuint[m_uImageCount];
// Holds the luminance buffer
char* chBuffer = new char[m_uImageWidth * m_uImageHeight];
//char* chRGBABuffer = new char[m_uImageWidth * m_uImageHeight * 4];
glGenTextures(m_uImageCount, m_puTextureIDs);
// Read each frames and construct the texture
for( int nIndx = 0; nIndx < m_uImageCount; ++nIndx )
{
// Read the frame
myFile.read(chBuffer, m_uImageWidth*m_uImageHeight);
// Set the properties of the texture.
glBindTexture( GL_TEXTURE_2D, m_puTextureIDs[nIndx] );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
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_LUMINANCE, m_uImageWidth, m_uImageHeight , 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE,(GLvoid *) chBuffer);
glBindTexture( GL_TEXTURE_2D, 0 );
}
delete[] chBuffer;
// delete[] chRGBABuffer;
return true;
}
void SpecialKeys(int key, int x, int y)
{
glutPostRedisplay();
}
void RenderScene(void)
{
static GLfloat vLightPos [] = { 1.0f, 1.0f, 0.0f };
static GLfloat vWhite [] = { 1.0f, 1.0f, 1.0f, 1.0f };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
modelViewMatrix.PushMatrix();
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
M3DMatrix44f mObjectFrame;
objectFrame.GetMatrix(mObjectFrame);
modelViewMatrix.MultMatrix(mObjectFrame);
for(int nIndx=0; nIndx <m_uImageCount;++nIndx)
{
glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]);
MakeQuads(nIndx);
glBindTexture(GL_TEXTURE_2D, m_puTextureIDs[nIndx]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
transformPipeline.GetModelViewMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos, vWhite, 0);
myBatch.Draw();
}
modelViewMatrix.PopMatrix();
glutSwapBuffers();
}
void MakeQuads(int quads_index)
{
myBatch.Begin(GL_QUADS, 4, 1);
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
myBatch.Vertex3f(-1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
//myBatch.Vertex3f(-1.0f, -1.0f, 1.0f);
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
myBatch.Vertex3f(1.0f, -1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
//myBatch.Vertex3f(1.0f, -1.0f, 1.0f);
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
myBatch.Vertex3f(1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
//myBatch.Vertex3f(1.0f, 1.0f, 1.0f);
myBatch.Normal3f(0.0f, 0.0f, -1.0f);
myBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
myBatch.Vertex3f(-1.0f, 1.0f, 1.0f - (GLfloat)(quads_index/m_uImageCount));
//myBatch.Vertex3f(-1.0f, 1.0f, 1.0f);
myBatch.End();
}
void ShutdownRC(void)
{
glDeleteTextures(m_uImageCount, (GLuint*)m_puTextureIDs);
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(400, 400);
glutCreateWindow("Volume_Rendering");
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}

Related

C++ Opengl with SDL2_image texture showing white only

I'm trying to display a spinning cube with 6 different textures (all jpg and jpeg) using SDL library. But the program only shows white squares only. Anyone can please explain what happened to these textures?
each function behavior
opengl_init(): init opengl settings
init(): init SDL settings including opengl_init()
clean_up(): runs right before program ends
RenewTexture(): here I want to map texture with this function
main(): about drawing vertexes and playing each frame with spinning function
const int window_width = 1024;
const int window_height = 1024;
const int SCREEN_BPP = 32;
SDL_Event event;
SDL_Window* win = NULL;
SDL_Renderer* renderer = NULL;
GLuint texId[6];
SDL_GLContext context;
/****** Name Space for Game Variables ******/
namespace var
{
int frame_start_time = 0;
int frame_current_time = 0;
int frame_count = 0;
}
/****** Initializes Core OpenGL Features ******/
bool opengl_init()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (640.0 / 480.0), 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
std::cout << glGetError << std::endl;
if (glGetError() != GL_NO_ERROR)
{
return false;
}
return true;
}
/****** Initializes SDL, OpenGL and Video and Window ******/
bool init()
{
//if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
return false;
}
win = SDL_CreateWindow("WINDOW", 100, 100, window_width, window_height, SDL_WINDOW_OPENGL);
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
context = SDL_GL_CreateContext(win);
if (opengl_init() == false)
{
return false;
}
}
/* Removes objects before game closes */
void clean_up()
{
SDL_Quit();
}
void RenewTexture(SDL_Surface* tmpimg, int index) {
GLubyte* map = (GLubyte*)tmpimg->pixels;
glBindTexture(GL_TEXTURE_2D, texId[index]);
int w, h;
w = tmpimg->w;
h = tmpimg->h;
/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);*/
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB,
w, h, 0,
GL_RGB, GL_UNSIGNED_BYTE,
map
);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glBindTexture(GL_TEXTURE_2D, texId[index]);
}
int main(int argc, char* args[])
{
std::vector<SDL_Surface*> image;
GLfloat rotation = 0.0f;
bool quit = false;
if (init() == false)
{
return 1;
}
const char* ImageNames[6] = { "res/KGU-logo.jpg", "res/Me.jpeg", "res/beach-1838501.jpg", "res/bench-560435.jpg", "res/wolf-1341881_1920.jpg", "res/spring-bird-2295434.jpg" };
for (int i = 0; i < 6; i++) {
SDL_RWops* tmprwop = SDL_RWFromFile(ImageNames[i], "rb");
SDL_Surface* tmpimg = IMG_LoadJPG_RW(tmprwop);
image.push_back(tmpimg);
}
for(int i=0;i<6;i++)
glGenTextures(1, &texId[i]);
/*SDL_Rect position;
position.x = 1;
position.y = 1;
position.h = 10;
position.w = 10;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, SDL_CreateTextureFromSurface(renderer, image.at(0)), NULL, &position);
SDL_RenderPresent(renderer);*/
/****** Main Game Loop ******/
while (quit == false)
{
/****** Get Most Current Time ******/
var::frame_start_time = SDL_GetTicks();
/****** Draw Rectangle ******/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -6.0f);
glRotatef(rotation, 1.0f, 1.0f, 0.0f);
RenewTexture(image.at(0), 0);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(0, 0);
glTexCoord2f(1.0, 0.0); glVertex2f(550, 0);
glTexCoord2f(1.0, 1.0); glVertex2f(550, 550);
glTexCoord2f(0.0, 1.0); glVertex2f(0, 550);
glEnd();
RenewTexture(image.at(0), 0);
glBegin(GL_QUADS);
/* Cube Top */
//glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
RenewTexture(image.at(1), 1);
/* Cube Bottom */
//glColor4f(1.0f, 0.5f, 0.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
RenewTexture(image.at(2), 2);
/* Cube Front */
//glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
RenewTexture(image.at(3), 3);
/* Cube Back */
//glColor4f(0.0f, 1.0f, 0.5f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
RenewTexture(image.at(4), 4);
/* Cube Left Side */
//glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
RenewTexture(image.at(5), 5);
/* Cube Right Side */
//glColor4f(0.15f, 0.25f, 0.75f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd();
rotation -= 0.5f;
/****** Check for Key & System input ******/
while (SDL_PollEvent(&event))
{
/****** Application Quit Event ******/
if (event.type == SDL_QUIT)
{
quit = true;
}
}
/****** Update Screen And Frame Counts ******/
SDL_GL_SwapWindow(win);
var::frame_count++;
var::frame_current_time = SDL_GetTicks();
/****** Frame Rate Handle ******/
if ((var::frame_current_time - var::frame_start_time) < (1000 / 60))
{
var::frame_count = 0;
SDL_Delay((1000 / 60) - (var::frame_current_time - var::frame_start_time));
}
}
clean_up();
return 0;
}
Edit
Solved via changing all glTexCoord3f() to glTexCoord2f() and it worked... my fault :D
additionaly, I misunterstood glEnable(GL_TEXTURE_3D) so changed to glEnable(GL_TEXTURE_2D), and checked all opengl errors via error check function
void errorcheck() {
int errormsg;
if ((errormsg = glGetError()) != GL_NO_ERROR)
{
std::cout << "glerror: " << errormsg << std::endl;
exit(0);
}
}

How to load texture Opengl?

I found a useful post at this site, where some code is used to load a BMP
This code should load the header, read out infos, go further, read data, generate texture and bin it. But it doesnt work. What am I doing wrong ?
Texture Declaration :
GLuint texture[1];
BMP Loading :
void LoadTexture(char *filename)
{
FILE * file = fopen(filename,"rb");
unsigned char header[54];
unsigned int dataPos;
unsigned int imageSize;
unsigned int width, height;
fread(header,1,54,file);
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
if (imageSize==0) {
imageSize=width*height*3;
}
if (dataPos==0) {
dataPos=54;
}
unsigned char data[imageSize];
fseek(file, SEEK_SET, 53);
fread(data,1,imageSize,file);
fclose(file);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
}
EDIT : I printed out some values read from the header. The header seems to be read properly.
Drawing :
int DrawGLScene(GLvoid)
{
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glTranslatef(0.0f,0.0f,-5.0f);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glFlush();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return 1;
}
Finally, after browsing the internet quite a lot, I found this working example :
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <math.h>
GLuint texture[2];
struct Image {
unsigned long sizeX;
unsigned long sizeY;
char *data;
};
typedef struct Image Image;
#define checkImageWidth 64
#define checkImageHeight 64
GLubyte checkImage[checkImageWidth][checkImageHeight][3];
void makeCheckImage(void){
int i, j, c;
for (i = 0; i < checkImageWidth; i++) {
for (j = 0; j < checkImageHeight; j++) {
c = ((((i&0x8)==0)^((j&0x8)==0)))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
}
}
}
int ImageLoad(char *filename, Image *image) {
FILE *file;
unsigned long size; // size of the image in bytes.
unsigned long i; // standard counter.
unsigned short int planes; // number of planes in image (must be 1)
unsigned short int bpp; // number of bits per pixel (must be 24)
char temp; // temporary color storage for bgr-rgb conversion.
// make sure the file is there.
if ((file = fopen(filename, "rb"))==NULL){
printf("File Not Found : %s\n",filename);
return 0;
}
// seek through the bmp header, up to the width/height:
fseek(file, 18, SEEK_CUR);
// read the width
if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
//printf("Width of %s: %lu\n", filename, image->sizeX);
// read the height
if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
printf("Error reading height from %s.\n", filename);
return 0;
}
//printf("Height of %s: %lu\n", filename, image->sizeY);
// calculate the size (assuming 24 bits or 3 bytes per pixel).
size = image->sizeX * image->sizeY * 3;
// read the planes
if ((fread(&planes, 2, 1, file)) != 1) {
printf("Error reading planes from %s.\n", filename);
return 0;
}
if (planes != 1) {
printf("Planes from %s is not 1: %u\n", filename, planes);
return 0;
}
// read the bitsperpixel
if ((i = fread(&bpp, 2, 1, file)) != 1) {
printf("Error reading bpp from %s.\n", filename);
return 0;
}
if (bpp != 24) {
printf("Bpp from %s is not 24: %u\n", filename, bpp);
return 0;
}
// seek past the rest of the bitmap header.
fseek(file, 24, SEEK_CUR);
// read the data.
image->data = (char *) malloc(size);
if (image->data == NULL) {
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i=0;i<size;i+=3) { // reverse all of the colors. (bgr -> rgb)
temp = image->data[i];
image->data[i] = image->data[i+2];
image->data[i+2] = temp;
}
// we're done.
return 1;
}
Image * loadTexture(){
Image *image1;
// allocate space for texture
image1 = (Image *) malloc(sizeof(Image));
if (image1 == NULL) {
printf("Error allocating space for image");
exit(0);
}
if (!ImageLoad("NeHe.bmp", image1)) {
exit(1);
}
return image1;
}
void myinit(void)
{
glClearColor (0.5, 0.5, 0.5, 0.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
Image *image1 = loadTexture();
if(image1 == NULL){
printf("Image was not returned from loadTexture\n");
exit(0);
}
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Create Texture
glGenTextures(2, texture);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //scale linearly when image bigger than texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //scale linearly when image smalled than texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0,
GL_RGB, GL_UNSIGNED_BYTE, image1->data);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, 3, checkImageWidth,
checkImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,&checkImage[0][0][0]);
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_FLAT);
}
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glutSolidTeapot(1.0);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(2.41421, 1.0, -1.41421);
glTexCoord2f(0.0, 1.0);
glVertex3f(2.41421, -1.0, -1.41421);
glEnd();
glutSwapBuffers();
}
void myReshape(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}
void keyboard (unsigned char key, int x, int y){
switch (key) {
case 27: // “esc” on keyboard
exit(0);
break;
default: // “a” on keyboard
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Texture Mapping - Programming Techniques");
myinit();
glutReshapeFunc (myReshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Review how you read data. dataPos, size and others may be set after reading the BMP. It's a relative position defined in the header of the image file.
And then review glTexImage2D(). Your are passing datainstead of dataPos.

OpenGL texture loading with soil help need

Here is the code. Please help guys
#include <GL/glut.h>
#include <iostream>
#include <math.h>
#include "SOIL.h"
using namespace std;
GLuint texture[1];
int LoadGLTextures()
{
texture[0] = SOIL_load_OGL_texture
(
"NeHe.bmp",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y
);
if(texture[0] == 0)
return false;
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
return true;
}
void ChangeSize(int w, int h)
{
if(h == 0)
{
h = 1;
}
float ratio = 1.0f * w/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,w,h);
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,6.0,
0.0,0.0,0.0,
0.0f,1.0f,0.0f);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glFlush();
}
void idle(void)
{
glutPostRedisplay();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
glutCreateWindow("ZC");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(display);
glutIdleFunc(idle);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}
I dont get errors, but not loading the texture.
You forgot to call LoadGLTextures in your main program. I ran your program with this change:
glEnable(GL_DEPTH_TEST);
LoadGLTextures(); //<-- added this
glutMainLoop();
}
and things worked fine.
I provided my own NeHe.bmp file, since you didn't link to one. It could also fail if your .bmp file is bad in some way.

When I load next image using SOIL, it will replace all the images I load before

This is part of my coding, a simple balloon clicking game. I have a background image and another image for balloon, the code seems to replace all my previous loaded image. Helppppp
GLuint tex_2d;
GLuint tex_bg;
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(800, 800);
glutInitWindowPosition(100, 100);
glutCreateWindow("Lab Assignment");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return EXIT_SUCCESS;
}
This is where I put the coding for image loading, tex_bg is background.bmp for background, and tex_2d is for balloon image. Image loaded for tex_2d replaced the background image which is loaded earlier than it.
void init()
{
tex_bg = SOIL_load_OGL_texture
(
"background.bmp",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
tex_2d = SOIL_load_OGL_texture
(
"balloonImage.bmp",
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
if (tex_2d == 0 || tex_bg == 0)
{
printf( "SOIL loading error: '%s'\n", SOIL_last_result() );
exit(0);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
void drawQuadOutline()
{
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glBindTexture(GL_TEXTURE_2D, tex_bg);
glNormal3f(0, 1, 0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
drawQuadOutline();
drawCircleOutline(balloon[balloonBurst]);
glutSwapBuffers();
}
void drawCircleOutline(Circle o)
{
float angle;
glEnable(GL_TEXTURE_2D);
glBegin(GL_POLYGON);
glBindTexture(GL_TEXTURE_2D, tex_2d);
for(angle=0.0f; angle<360.0f; angle+=2.0f)
{
float radian = angle * (pi/180.0f);
float xcos = (float)cos(radian);
float ysin = (float)sin(radian);
float x = xcos * o.r + o.pos.x;
float y = ysin * o.r + o.pos.y;
float tx = xcos * 0.5f + 0.5f;
float ty = ysin * 0.5f + 0.5f;
glTexCoord2f(tx, ty);
glVertex2f(x, y);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
Is it problem with my coding? or misuse of SOIL function?
The problem with your coding is that you call glBindTexture(...) in-between glBegin (...) and glEnd (...).
That is invalid; if you checked glGetError (...) you would know this.
You need to re-write this code:
glBegin(GL_POLYGON);
glBindTexture(GL_TEXTURE_2D, tex_2d);
...
glBegin(GL_QUADS);
glBindTexture(GL_TEXTURE_2D, tex_bg);
To this:
glBindTexture(GL_TEXTURE_2D, tex_2d);
glBegin(GL_POLYGON);
...
glBindTexture(GL_TEXTURE_2D, tex_bg);
glBegin(GL_QUADS);

OpenGL Texturing a Quad

I am stuck in this texturing problem. I have a created a quad as the ground and I want to fill its texture with a grass image. But, when I try to set MultiTexCoord2f values, I get Segmentation Fault error. I couldn't find the reason. What am I doing wrong here?
SetupRC(){
floorBatch.Begin(GL_QUADS, 4);
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-50.0f, 0.0f, -50.0f);
floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
floorBatch.Vertex3f(50.0f, 0.0f, -50.0f);
floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
floorBatch.Vertex3f(-50.0f, 0.0f, 50.0f);
floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
floorBatch.Vertex3f(50.0f, 0.0f, 50.0f);
floorBatch.End();
glGenTextures(1, textures);
// Grass floor
pBytes = gltReadTGABits("Grass.tga", &nWidth, &nHeight, &nComponents, &format);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth, nHeight, 0,
format, GL_UNSIGNED_BYTE, pBytes);
glGenerateMipmap(GL_TEXTURE_2D);
free(pBytes);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
RenderScene(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
static GLfloat vFloorColor[] = { 0.0f, 1.0f, 0.0f, 1.0f};
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
mModelview.PushMatrix(mCamera);
mModelview.Translate( 0.0f, -0.3f, -2.5f);
mModelview.PushMatrix();
mModelview.Translate( 0.0f, -0.3f, 0.0f);
mModelview.PushMatrix();
glBindTexture(GL_TEXTURE_2D, textures[0]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(), vFloorColor, 0);
floorBatch.Draw();
mModelview.PopMatrix();
mModelview.PopMatrix();
mModelview.PushMatrix();
}
main()
{
gltSetWorkingDirectory(argv[0]); //
glutInit(&argc, argv); //opengl initialization
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); //display mode set
glutInitWindowSize(800, 600); //window size
glutCreateWindow("Neighbourhood"); // title ile pencereyi yarattik
glutReshapeFunc(ChangeSize); // pencere boyutu degisince cagrilan fonksiyonun adi
glutDisplayFunc(RenderScene); // her bir frame icin cagrilan fonksiyonun adi
glutSpecialFunc(SpecialKeys);
// Add menu entries to change filter
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("GL_NEAREST",0);
glutAddMenuEntry("GL_LINEAR",1);
glutAddMenuEntry("GL_NEAREST_MIPMAP_NEAREST",2);
glutAddMenuEntry("GL_NEAREST_MIPMAP_LINEAR", 3);
glutAddMenuEntry("GL_LINEAR_MIPMAP_NEAREST", 4);
glutAddMenuEntry("GL_LINEAR_MIPMAP_LINEAR", 5);
glutAttachMenu(GLUT_RIGHT_BUTTON);
GLenum err = glewInit(); // bu ne a.q.
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC(); // opengle ozel kendimizce ayarlari initialize edecegimiz fonksiyon
glutMainLoop(); // opengl calisiyor
ShutdownRC();
return 0;
}
In glBatch.Begin() function, you should tell the function the number of textures you want to use. The third parameter here is the number of textures.
I don't know why but changing that part to this solved the problem;
floorBatch.Begin(GL_TRIANGLE_STRIP, 4, 2);
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-50.0f, 0.0f, -50.0f);
floorBatch.MultiTexCoord2f(0 , 1.0f, 0.0f);
floorBatch.Vertex3f(50.0f, 0.0f, -50.0f);
floorBatch.MultiTexCoord2f(0 , 0.0f, 1.0f);
floorBatch.Vertex3f(-50.0f, 0.0f, 50.0f);
floorBatch.MultiTexCoord2f(0 , 1.0f, 1.0f);
floorBatch.Vertex3f(50.0f, 0.0f, 50.0f);
floorBatch.End();