Idea:
I have been trying to develop code which can take several (ten) slices of 2D images and render them as a 3D texture. I have so far used glTexImage3D and glTexSubImage3D upon suggestions from my previous post here: OpenGL - 'glTexSubImage3D': identifier not found
I have been based my work off of NeHe's texture mapping tutorial here: http://nehe.gamedev.net/tutorial/lesson_06_texturing_update/47002/
The flow of function calls in the NeHe's tutorial in main() proceeds like this: CreateGLWindow(), InitGL(), LoadGLTextures(), DrawGLScene(). I have only made changes to the code commencing upwards from DrawGLScene() while, everything below that function is the same as in my code.
Problem:
Everything in the code seemingly looks right but, there is nothing being rendered on the screen. I have spent two days on this trying to get it to work to no avail. What am I missing? Is there something that I am doing incorrectly?
EDITED CODE
#include "windows.h"
#include "stdio.h"
#include "gl\gl.h"
#include "gl\glu.h"
#include "GLext.h"
#include "SOIL.h"
HDC hDC=NULL;
HGLRC hRC=NULL;
HWND hWnd=NULL;
HINSTANCE hInstance;
bool keys[256];
bool active=TRUE;
bool fullscreen=TRUE;
GLfloat xrot;
GLfloat yrot;
GLfloat zrot;
GLuint m_nTexId;
unsigned char tex;
int h = 1024;
int w = 256;
int slices = 10;
GLfloat dOrthoSize = 1.0f;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// EDIT HERE
PFNGLTEXIMAGE3DPROC TexImage3D;
PFNGLTEXSUBIMAGE3DPROC TexSubImage3D;
PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D;
int LoadGLTextures()
{
glGenTextures(1,(GLuint*)&m_nTexId );
if(m_nTexId == 0)
return false;
glBindTexture( GL_TEXTURE_3D, m_nTexId );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
return true;
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height==0)
{
height=1;
}
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int InitGL(GLvoid)
{
if (!LoadGLTextures())
{
return FALSE;
}
glEnable(GL_TEXTURE_3D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// EDIT HERE
TexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
TexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) wglGetProcAddress("glTexSubImage3D");
CopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) wglGetProcAddress("glCopyTexSubImage3D");
return TRUE;
}
#define MAP_3DTEXT( TexIndex ) \
glTexCoord3f(0.0f, 0.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(-dOrthoSize,-dOrthoSize,TexIndex);\
glTexCoord3f(1.0f, 0.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(dOrthoSize,-dOrthoSize,TexIndex);\
glTexCoord3f(1.0f, 1.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(dOrthoSize,dOrthoSize,TexIndex);\
glTexCoord3f(0.0f, 1.0f, ((float)TexIndex+1.0f)/2.0f); \
glVertex3f(-dOrthoSize,dOrthoSize,TexIndex);
int DrawGLScene(GLvoid)
{
PFNGLTEXIMAGE3DPROC glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) wglGetProcAddress("glTexSubImage3D");
PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) wglGetProcAddress("glCopyTexSubImage3D");
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//glEnable( GL_ALPHA_TEST );
//glAlphaFunc( GL_GREATER, 0.2f );
//glEnable(GL_BLEND);
//glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt(0,0,-300,0,0,1,0,1,0);
glEnable(GL_TEXTURE_3D);
glBindTexture( GL_TEXTURE_3D, m_nTexId );
TexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, w, h , slices, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
glTranslatef( 0.0f, 0.0f, 100.0f );
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170090.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.0f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170091.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 2, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.1f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170092.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 3, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.2f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170093.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 4, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.3f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170094.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 5, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.4f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char)SOIL_load_image("Data/PA_170095.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 6, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.5f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170096.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 7, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.6f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170097.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 8, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.7f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170098.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 9, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.8f );
glEnd();
glBegin(GL_QUADS);
tex = (unsigned char) SOIL_load_image("Data/PA_170099.png", &w, &h, NULL, 0);
TexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 10, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
MAP_3DTEXT( 0.9f );
glEnd();
return TRUE;
}
Look at the function call TexSubImage3D, the argument depth is always 1, and you are incrementing only zoffset. Please keep the zoffset 0 and provide the depth/layer values from 8th argument (depth).
TexSubImage3D( enum target, int level, int xoffset,
int yoffset, int zoffset, sizei width, sizei height,
sizei depth, enum format, enum type, const
void *data );
Related
I'm trying to make a 3D shooter. I think the image is loading because its dimensions are displayed, but it is not displayed as a texture. The program compiles and runs without errors but no texture. I do not know where I am making a mistake.
main.cpp:
#include "Functions.h"
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(wnd_width, wnd_height);
glutInitWindowPosition(300, 100);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glutCreateWindow("OpenGL my");
glutDisplayFunc(display);
glutIdleFunc(Idle);
glutSpecialFunc(KeyPressed);
TextureInit();
glutMainLoop();
return 0;
}
functions.h
#define STB_IMAGE_IMPLEMENTATION
#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
#include "point.h"
#include "camera.h"
int wnd_width=1300;
int wnd_height=900;
GLdouble aspect = wnd_width/wnd_height;
Camera cam;
unsigned int texture;
float text_coords[] = {0,0, 1,0, 1,1, 0,1};
void DrawFloor();
void DrawWall(float x, float width, float height);
void KeyPressed(int key, int x, int y);
void TextureInit();
void display();
void Idle();
void display(){
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.view.x, cam.view.y, cam.view.z,
0, 0.5, 0);
glBegin(GL_QUADS);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, text_coords);
//glColor3f(0, 0, 0.7);
DrawFloor();
//glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glutSwapBuffers();
}
void Idle(){
}
void DrawFloor(){
glVertex3d(1, 0, 2.5);
glVertex3d(1, 0, 0);
glVertex3d(-1, 0, 0);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: { cam.MoveForward(); break; }
case GLUT_KEY_DOWN: { cam.MoveBack(); break; }
case GLUT_KEY_LEFT: {cam.TurnLeft(); break; }
case GLUT_KEY_RIGHT: {cam.TurnRight(); break; }
}
cam.PrintPosition();
glutPostRedisplay();
}
void TextureInit(){
int width, height, cnt;
unsigned char* data = stbi_load("whitemarble.jpg", &width, &height, &cnt, 0);
if(data==nullptr) std::cout<< "NO\n";
else std::cout<<width<<'\t'<<height<<'\n';
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
0, GL_RGB, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(data);
}
redone. Now it works. Thanks. But the picture is very stretched.
#define STB_IMAGE_IMPLEMENTATION
#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
#include "point.h"
#include "camera.h"
int wnd_width=1300;
int wnd_height=900;
GLdouble aspect = wnd_width/wnd_height;
Camera cam;
unsigned int texture;
float text_coords[] = {0,0, 1,0, 1,1, 0,1};
void DrawFloor();
void DrawWall(float x, float width, float height);
void KeyPressed(int key, int x, int y);
void TextureInit();
void display();
void Idle();
void TextureInit(){
int width, height, cnt;
unsigned char* data = stbi_load("whitemarble.jpg", &width, &height, &cnt, 0);
if(data==nullptr) std::cout<< "NO\n";
else std::cout<<width<<'\t'<<height<<'\n';
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(data);
}
void display(){
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.view.x, cam.view.y, cam.view.z,
0, 0.5, 0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBegin(GL_QUADS);
DrawFloor();
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glutSwapBuffers();
}
void DrawFloor(){
glTexCoord2d(0, 0);
glVertex3d(1, 0, 2.5);
glTexCoord2d(1, 0);
glVertex3d(1, 0, 0);
glTexCoord2d(1, 1);
glVertex3d(-1, 0, 0);
glTexCoord2d(0, 1);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: { cam.MoveForward(); break; }
case GLUT_KEY_DOWN: { cam.MoveBack(); break; }
case GLUT_KEY_LEFT: {cam.TurnLeft(); break; }
case GLUT_KEY_RIGHT: {cam.TurnRight(); break; }
}
cam.PrintPosition();
glutPostRedisplay();
}
void Idle(){
}```
Your code is causing several Only a subset of GL commands can be used between glBegin and glEnd. You have to call glBegin immediately before specifying the vertices:
void display(){
glClearColor(0.6, 0.8, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, aspect, 0.1, 3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
cam.view.x, cam.view.y, cam.view.z,
0, 0.5, 0);
// glBegin(GL_QUADS); // <--- DELETE
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, text_coords);
glBegin(GL_QUADS); // <--- INSERT
//glColor3f(0, 0, 0.7);
DrawFloor();
//glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glutSwapBuffers();
}
You cannot mix fix function attributes and glBegin/glEnd sequences. Use glTexCoord instead:
glTexCoord2d(0, 0);
glVertex3d(1, 0, 2.5);
glTexCoord2d(1, 0);
glVertex3d(1, 0, 0);
glTexCoord2d(1, 1);
glVertex3d(-1, 0, 0);
glTexCoord2d(0, 1);
glVertex3d(-1, 0, 2.5);
I'm having problems opening a bmp image to a texture using OpenGl
Here is the loadTexture func:
GLuint loadTexture() {
FILE *f;
int imageSize,rd;
f = fopen(filename, "rb");
if(f == 0){
printf("Couldn't open file\n");
exit(-1);
}
GLubyte header[54];
fread(header, 54,1,f);
if(header[0] != 'B' || header[1] != 'M'){
printf("File not bitmap\n");
exit(1);
}
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;
data = new unsigned char [imageSize];
fread(data,1,imageSize,f);
fclose(f);
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
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);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); return textureID;
}
The function always returns 0, but there is no error (I looked at glGetError() as well)
When trying to load the texture anyway:
glClear(GL_COLOR_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
//BOTTOM LEFT - red
glBindTexture(GL_TEXTURE_2D,texture);
glViewport(0,0,256,256);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(-1,1);
glTexCoord2f(1,0);
glVertex2f(-1,-1);
glTexCoord2f(0,1);
glVertex2f(1,-1);
glTexCoord2f(1,1);
glVertex2f(1,1);
glEnd();
I get a white square and not the picture..
This is my init func:
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(512, 512);
glutCreateWindow("Sample");
glEnable(GL_TEXTURE_2D);
glOrtho(-1.0,1.0,-1.0,1.0,2.0,-2.0);
glClearColor(0,0,0,0);
texture = loadTexture();
printf("Texture: %d\n",texture);
glutDisplayFunc(mydisplay);
glutMainLoop();
Any thoughts?
You don't get a current GL context with GLUT until glutCreateWindow() successfully returns. glutInitDisplayMode() is not sufficient.
All the GL functions you call in loadTexture() require a current GL context to function.
Move texture = loadTexture(); to somewhere after glutCreateWindow() and before glutMainLoop();.
Also, if you're going to be using 3-component BGR/RGB make sure to use glPixelStorei() to set GL_UNPACK_ALIGNMENT to 1 (instead of the default 4) before your glTexImage2D() call.
Here's the simplest thing that works on my system:
// http://glew.sourceforge.net/
#include <GL/glew.h>
#include <GL/glut.h>
GLuint loadTexture()
{
const unsigned char data[] =
{
255, 0, 0, 0, 255, 0,
0, 0, 255, 255, 255, 255,
};
const GLsizei width = 2;
const GLsizei height = 2;
GLuint textureID = 0;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
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);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
return textureID;
}
GLuint texture = 0;
void display()
{
glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, 2, -2 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
glBegin(GL_QUADS);
glTexCoord2f( 0, 0 );
glVertex2i( -1, -1 );
glTexCoord2f( 1, 0 );
glVertex2i( 1, -1 );
glTexCoord2f( 1, 1 );
glVertex2i( 1, 1 );
glTexCoord2f( 0, 1 );
glVertex2i( -1, 1 );
glEnd();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glewInit();
texture = loadTexture();
glutDisplayFunc( display );
glutMainLoop();
return 0;
}
Problem: I've been trying to figure out this error in OpenGL that I keep getting with glTexSubImage3D. VS2010 throws the error: glTexSubImage3D: identifier not found
Usage: I am trying to create a 3D texture with ten slices (images) placed along the z-dimension. It is similar to the question in this post: C++ - place multiple images in an array pointer
However, I have been trying to use glTexSubImage3D in order to avoid these access violation errors.
I have included glext.h in my project and since, glTexImage3D is not part of OpenGL libraries yet, I have used the function pointer PFNGLTEXIMAGE3DPROC glTexImage3D as provided for use here: http://content.gpwiki.org/index.php/OpenGL:Tutorials:3D_Textures
Code:
I have been following NeHe's Texture Mapping tutorial and volume rendering tutorial present here: http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering?msg=4729498
GLuint m_nTexId;
unsigned char *tex;
int h = 1024;
int w = 256;
int slices = 10;
PFNGLTEXIMAGE3DPROC glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
int LoadGLTextures()
{
glGenTextures(1,(GLuint*)&m_nTexId );
if(m_nTexId == 0)
return false;
glBindTexture( GL_TEXTURE_3D, m_nTexId );
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, w, h , slices, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
tex = (unsigned char *)SOIL_load_image("Data/PA_170090.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char*) SOIL_load_image("Data/PA_170091.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char *)SOIL_load_image("Data/PA_170092.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 2, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char *)SOIL_load_image("Data/PA_170093.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 3, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char *)SOIL_load_image("Data/PA_170094.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 4, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char *)SOIL_load_image("Data/PA_170095.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 5, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char*) SOIL_load_image("Data/PA_170096.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 6, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char*) SOIL_load_image("Data/PA_170097.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 7, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char*) SOIL_load_image("Data/PA_170098.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 8, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
tex = (unsigned char*) SOIL_load_image("Data/PA_170099.png", &w, &h, NULL, 0);
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 9, h, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) tex);
//glBindTexture( GL_TEXTURE_3D, 0 );
return true;
}
The problem is the same as you had when you originally tried to use glTexImage3D (...). Namely, 3D textures are a feature of OpenGL 1.2 and Windows only gives you OpenGL 1.1 without run-time extension.
You need to load the glTexSubImage3D (...) function the same as you did glTexImage3D (...).
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D =
(PFNGLTEXSUBIMAGE3DPROC) wglGetProcAddress("glTexSubImage3D");
Update 2 works, it was a wrong allert
Update 2 (using vbo vertex- and fragment-shaders) but it still don't works
#include "GL/glxew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <iostream>
GLint attribute;
GLuint program;
void gen_texture(GLuint &texture, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &texture);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glEnableVertexAttribArray(attribute);
GLfloat vertex_data[]
{
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
glVertexAttribPointer(
attribute,
2,
GL_FLOAT,
GL_FALSE,
0,
vertex_data
);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(attribute);
}
void init_layout()
{
GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
GLuint vs, fs;
vs = glCreateShader(GL_VERTEX_SHADER);
const char *vs_source =
"#version 120\n" // OpenGL 2.1
"attribute vec2 coord2d; "
"void main(void) { "
" gl_Position = vec4(coord2d, 0.0, 1.0); "
"}";
glShaderSource(vs, 1, &vs_source, 0);
glCompileShader(vs);
glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
if (0 == compile_ok)
{
std::cerr << "[texture_layout/init_layout] fehler im vertex shader\n";
exit(1);
}
fs = glCreateShader(GL_FRAGMENT_SHADER);
const char *fs_source =
"#version 120\n" // OpenGL 2.1
"void main(void) { "
" gl_FragColor[0] = 0.8f; "
" gl_FragColor[1] = 0.5f;"
" gl_FragColor[2] = 0.0f; "
"}";
glShaderSource(fs, 1, &fs_source, 0);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
if (0 == compile_ok)
{
std::cerr << "[texture_layout/init_layout] fehler im fragment shader\n";
exit(1);
}
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok)
{
std::cerr << "[texture_layout/init_layout] fehler in glLinkProgram\n";
exit(1);
}
const char* attribute_name = "coord2d";
attribute = glGetAttribLocation(program, attribute_name);
if (attribute == -1) {
std::cerr << "Could not bind attribute " << attribute_name << "\n";
exit(1);
}
}
int main(int argc, char **argv)
{
glutInit (&argc, argv);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutCreateWindow ("");
glewExperimental=GL_TRUE;
GLenum err=glewInit();
if(err!=0)
{
std::cerr << glewGetErrorString(err) << std::endl;
exit(1);
}
GLenum error;
GLuint texture;
while ( ( error = glGetError() ) != GL_NO_ERROR)
{
std::cerr << std::hex << error << "\n";
}
init_layout();
gen_texture(texture, 200, 200);
GLvoid *tex_data = new GLubyte[4*200*200];
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
return 0;
}
Update 1 (using vbo instead of glBegin)
now my code should draw a red triangle using vbo, but it doesn't
void gen_texture(GLuint &color, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
glColor3f(1.f, .0f, .0f);
GLfloat vertices[6] =
{
0, 0,
0, (GLfloat)height,
(GLfloat)width, (GLfloat)height,
};
unsigned short indices[] = {0, 1, 2};
GLuint vbo;
glGenBuffersARB(1, &vbo);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, 6*sizeof(GLfloat), vertices, GL_STATIC_DRAW_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, vertices);
}
Original 2:
I have a function that should draw a red square into a texture with the glBegin directive. But the only thing I got to work is
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
I've tested it with multiple colors. But that part do not work:
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
glColor3f(1.f, .0f, .0f);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(0, height);
glVertex2f(width, height);
glVertex2f(width, 0);
glEnd();
Here is the full function:
void gen_texture(GLuint &color, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glBindTexture(GL_TEXTURE_2D, color);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glViewport(0,0,width,height);
glOrtho(0,width,0,height,0,128);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
//glDisable(GL_CULL_FACE);
glColor3f(1.f, .0f, .0f);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(0, height);
glVertex2f(width, height);
glVertex2f(width, 0);
glEnd();
}
Original Post:
I have a function that should draw a red square into a texture, but when I call the function for generating the texture and then I want to check the generated texture data, with the glGetTexImage function, I get a null-pointer.
#include "GL/glxew.h"
#include "GL/glext.h"
#include "GL/glu.h"
#include "GL/freeglut.h"
#include <iostream>
GLuint texture;
GLvoid *tex_data;
void gen_texture(GLuint &color, int width, int height)
{
GLuint fb;
glGenFramebuffers(1, &fb);
glGenTextures(1, &color);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
width, height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, fb);
glViewport(0, 0, width, height);
glClearColor(1,1,1,0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, width, height, 0, 0, 1);
glMatrixMode (GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glColor4f(1.f, .0f, .0f, .5f);
glBegin(GL_QUADS);
glVertex2f(0, 0);
glVertex2f(0, height);
glVertex2f(width, height);
glVertex2f(width, 0);
glEnd();
}
int main(int argc, char **argv)
{
glutInit (&argc, argv);
glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize (500, 500);
glutCreateWindow ("");
glewExperimental=GL_TRUE;
GLenum err=glewInit();
if(err!=0)
{
std::cerr << glewGetErrorString(err) << std::endl;
exit(1);
}
GLenum error;
while ( ( error = glGetError() ) != GL_NO_ERROR)
{
std::cerr << std::hex << error << "\n";
}
gen_texture(texture, 200, 200);
glBindTexture(GL_TEXTURE_2D, texture);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
if (tex_data == 0)
std::cerr << "Captain, eine Null an Board!\n";
return 0;
}
the tex_data is now a null-pointer
what am I doing wrong???
glutInitContextVersion(3, 2);
glutInitContextProfile(GLUT_CORE_PROFILE);
^^^^^^^^^^^^^^^^^ ok...
....
glBegin(GL_QUADS);
^^^^^^^^ wat
glBegin() and friends aren't valid calls in a Core context.
You'll have to get spun up on shaders and VBOs if you insist on Core.
I'm trying to draw some texture with CAOpenGLLayer, but receiving GL_INVALID_OPERATION when i try to call glTexSubImage2d. According to this document : http://www.opengl.org/sdk/docs/man/xhtml/glTexSubImage2D.xml it's one of the errors described there. But seems i'm not breaking any rule described there and i don't understand what i'm doing wrong. Here is a code that i'm trying to run:
- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
{
uint32_t plugin_width = 32, plugin_height = 32;
texture_data = new uint8_t[plugin_width * plugin_height * 4];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0f, -1.0f, 1.0f);
glOrtho(0, plugin_width , 0, plugin_height , -1.0, 1.0);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glGenTextures(1, &textureName);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, plugin_width * plugin_height * 4, texture_data);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, plugin_width, plugin_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, texture_data);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
return [super copyCGLContextForPixelFormat:pixelFormat];
}
- (void)drawInCGLContext:(CGLContextObj)ctx pixelFormat:(CGLPixelFormatObj)pf forLayerTime:(CFTimeInterval)t displayTime:(const CVTimeStamp *)ts
{
uint32_t plugin_width = 32, plugin_height = 32;
uint32_t width = plugin_width;
uint32_t height = plugin_height;
srand(time(NULL));
for (int i = 0; i < 32*32*4; i ++)
texture_data[i] = rand() % 255;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
glTexSubImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, width, height,GL_BGRA, GL_UNSIGNED_INT_8_8_8_8 ,texture_data);
assert(glGetError() == GL_NO_ERROR); // here i'm getting GL_INVALID_OPERATION
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0.0f,0.0f);
glVertex2f(0.0f, 0.0f);
glTexCoord2f(1.0f,0.0f);
glVertex2f(width, 0);
glTexCoord2f(0.0f,1.0f);
glVertex2f(0, height);
glTexCoord2f(1.0f,1.0f);
glVertex2f(width, height);
glEnd();
[super drawInCGLContext:ctx pixelFormat:pf forLayerTime:t displayTime:ts];
}
Did you try to replace the external format GL_UNSIGNED_INT_8_8_8_8 with GL_UNSIGNED_BYTE in both calls (glTexImage2D and glTexSubImage2D)?
That might help.