I cant seem to load an image and use it as a texture to my program: the image is 512*512 in size and i dont know what im doing wrong, can someone help me?
Main function:
int main(int argc, char** argv)
{
glutInit (&argc, argv);
glutInitWindowSize (800,600);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutCreateWindow ("CS248 GLUT example");
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutMainLoop ();
return 0;
}
The display function:
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glColor3f(1.0f,1.0f,1.0f);
texture = LoadTexture("space.bmp");
glBindTexture(GL_TEXTURE_2D, texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-20.0,-20.0,0);
glTexCoord2f(0.0, 1.0); glVertex3f(-20.0, 20.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(20.0, 20.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(20.0, -20.0, 0.0);
glEnd();
glFlush();
}
So, i call here the loadtexture function to an GLuint texture, this way:
GLuint LoadTexture( const char* texture )
{
GLuint textureID = SOIL_load_OGL_texture( texture, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS );
glGenTextures(1,&textureID);
glBindTexture( GL_TEXTURE_2D, textureID );
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_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
return textureID;
}
Reshape function:
void reshape(GLsizei w, GLsizei h) {
glViewport(0, 0, 800, 600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-20.0f, 20.0f, -20.0f, 20.0f, -20.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
Includes,etc:
#include <glut.h>
#include <SOIL.h>
GLuint texture;
GLuint textureID = SOIL_load_OGL_texture( texture, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS );
glGenTextures(1,&textureID);
SOIL_load_OGL_texture creates an OpenGL texture object. Generating a new one (which is what glGenTextures does) after already creating one is counter-productive.
Ditch that line, and you'll probably be OK.
However, you should not be reloading the texture on every display. You should be creating that texture once, during initialization, then just using the texture with a glBindTexture call.
Related
I'm working on building a basketball game in openGL, however i'm taking baby steps and dividing my work into sections. I'm currently focusing on texturing, attempting to build a house using the SOIL library.
I'm extremely new to all of this so i've probably set things up wrong but my main problem is that textures are acting as if they are clamped to edge from what i can see.
Currently the project is a singular wall meant to be textured by bricks, here's an image of the output i'm getting:
Texture Fail
Here is the source code:
#include <stdlib.h>
#include <GL/glut.h>
#include <SOIL.h>
#include <stdio.h>
float _angle = 0.0;
GLuint _textureBrick;
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
// Front side brick wall
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, _textureBrick);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTranslatef(0,0,-6);
glRotatef(_angle, 0.0, 1.0, 0.0);
glBegin(GL_QUADS); // Wall
glTexCoord3f(-50.0,2.0,0.1); glVertex3f(-50,0,1);
glTexCoord3f(50.0,2.0,0.1); glVertex3f(50,0,1);
glTexCoord3f(50.0,0.0,0.1); glVertex3f(50,-1.5,1);
glTexCoord3f(-50.0,0.0,0.1); glVertex3f(-50,-1.5,1);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void mySpecialFunc(int key, int x, int y){
switch (key) {
case GLUT_KEY_RIGHT:
_angle += 1;
if (_angle > 360) _angle = 0.0;
break;
case GLUT_KEY_LEFT:
_angle -= 1;
if (_angle > 360) _angle = 0.0;
break;
}
glutPostRedisplay();
}
GLuint loadTex(const char* texname)
{
GLuint texture = SOIL_load_OGL_texture
(
texname,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_INVERT_Y
);
if( 0 == texture )
{
printf( "SOIL loading error: '%s'\n", SOIL_last_result() );
}
//glBindTexture(GL_TEXTURE_2D, texture);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return texture;
}
void Initialize() {
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0, 100.0, -100.0, 100.0, -100.0, 100.0);
//_textureFloor = loadTex("C:\\Users\\Mikle\\OneDrive\\Uni work\\Second Year\\Projects\\3D-House-using-OpenGL-and-C--master\\court.png");
_textureBrick = loadTex("C:\\Users\\Mikle\\OneDrive\\Uni work\\Second Year\\Projects\\3D-House-using-OpenGL-and-C--master\\bricks.bmp");
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(0,0);
glutInitWindowSize(600,600);
glutCreateWindow("Textured House");
glEnable(GL_DEPTH_TEST);
glutReshapeFunc(resize);
glutSpecialFunc(mySpecialFunc);
glutDisplayFunc(renderScene);
Initialize();
glutMainLoop();
return 0;
}
Any help would be appreciated, thankyou!
Michael. In order to generate mipmaps and possibly fix the texture, you should change the parameters of the soil loading function to
GLuint texture = SOIL_load_OGL_texture
(
texname,
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
);
This will automatically generate mipmaps from the OpenGL library, as you did not call afterwards to glGenerateMipmaps(). It also saves on the memory needed to store the textures. Another suggestion for the texture clamping and wrapping is to use
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
after you use the load function. Good luck with your OpenGL learning experience. I hope this helped you in some way.
EDIT:
You also shouldn't repeat the glTexParameteri every single frame. This puts excess and unnecessary strain on your (or the user's) CPU.
I have been reading for a while the different techniques used to texture terrains and came across texture splatting. I have found a lot of articles that discuss how to do this in OpenGL, but most only discuss it theoretically and provide little to no code that I can study. Does anyone know/have some code that illustrates this in OpenGL?
Just to clarify, I want to be able to load four different textures, and based on the height of the quad/vertices, change the texture from one gradually to the next.
Edit: Below is a quick bit of code to help show what I want to know
#include <windows.h>
#include <SFML/Graphics.hpp>
#include <gl/gl.h>
#include <gl/glu.h>
#define GL_CLAMP_TO_EDGE 0x812F
class Scene {
public:
void resize( int w, int h ) {
// OpenGL Reshape
glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 120.0, (GLdouble)w/(GLdouble)h, 0.5, 500.0 );
glMatrixMode( GL_MODELVIEW );
}
};
int main() {
sf::RenderWindow window(sf::VideoMode(800, 600, 32), "Test");
///Setup the scene, materials, lighting
Scene scene;
scene.resize(800,600);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION);
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LIGHT0);
float XL = .5, YL = .1, ZL = 1;
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat lightpos[] = {XL, YL, ZL, 0.};
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
///Test terrain texture splatting
///Load the textures
sf::Image tex1;
tex1.loadFromFile("texture1.png");
sf::Image tex2;
tex2.loadFromFile("texture2.png");
///Set the first texture
GLuint grass;
glGenTextures(1, &grass);
glBindTexture(GL_TEXTURE_2D, grass);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tex1.getSize().x, tex1.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)tex1.getPixelsPtr() );
///Set the second texture
GLuint dirt;
glGenTextures(1, &dirt);
glBindTexture(GL_TEXTURE_2D, dirt);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tex2.getSize().x, tex2.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)tex2.getPixelsPtr() );
///Start loop
while( window.isOpen() ) {
sf::Event event;
while( window.pollEvent( event ) ) {
if( event.type == sf::Event::Closed )
window.close();
}
///Clear buffer and set camera
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, 1.0, 1.0, 50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(1, 0, 1, 0, 0, 0, 0, 1, 0);
///Begin rendering quad
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, grass);
///I know that around here I should enable blending in order to get my two textures to mix, but I am not certain
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3f(-0.5, -0.5, 0.0);
glTexCoord2f(1, 0);
glVertex3f(-0.5, 0.5, 0.0);
glTexCoord2f(1, 1);
glVertex3f(0.5, 0.5, 0.0);
glTexCoord2f(0, 1);
glVertex3f(0.5, -0.5, 0.0);
glEnd();
///Reset env settings for SFML
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
window.display();
}
return 1;
}
As people mentioned above, use programmable pipeline, use shaders. In the fragment shader you can pass all the textures and interpolate between them based on vertex data you receive from the vertex shader.
Quick search gave me this result. I am sure that is what you need. Also take a look at this post. And this paper explains the technique very well.
I want to set a background for an openGL window for mac. background will take a jpg or png file.
Here is my code..
GLuint texture; //the array for our texture
GLfloat angle = 0.0;
GLuint LoadTexture (const char * filename, int width, int height ){
// GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// // when texture area is small, bilinear filter the closest mipmap
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
// GL_LINEAR_MIPMAP_NEAREST );
// // when texture area is large, bilinear filter the original
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
//
// // the texture wraps over at the edges (repeat)
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
// glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
//
// //Generate the texture
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,GL_RGB, GL_UNSIGNED_BYTE, data);
// select modulate to mix texture with color for shading
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// when texture area is small, bilinear filter the closest mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST );
// when texture area is large, bilinear filter the first mipmap
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// // the texture wraps over at the edges (repeat)
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
// build our texture mipmaps
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, data );
free(data);
return texture; //return whether it was successful
}
void FreeTexture( GLuint texture ){
glDeleteTextures( 1, &texture );
}
void cube () {
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture ); //bind the texture
glPushMatrix();
glRotatef( angle, 0.0f, 0.0f, 1.0f );
glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0);
glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0);
glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);
glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);
glEnd();
glPopMatrix();
glutSwapBuffers();
//glutSolidCube(2);
}
void display () {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
texture = LoadTexture( "/Users/macbook/MatrixEngineClientSample/Fighters/Sunset03.jpg", 256, 256 ); //load the texture
glEnable( GL_TEXTURE_2D ); //enable 2D texturing
// glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
// glEnable(GL_TEXTURE_GEN_T);
cube();
FreeTexture( texture );
//glutSwapBuffers();
//angle ++;
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
//glLoadIdentity ();
gluPerspective (50, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutMainLoop ();
return 0;
}
EDIT
I want to see this image as a background of the openGL window...image is below..
but it showing this...
I consulted this Apple guide.
The problem is that the file is compressed AND has a header, and with your code you are even using part of the file header as an image source.
I would replace this code:
// GLuint texture;
unsigned char * data;
FILE * file;
//The following code will read in our RAW file
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );
With something more similar to this:
CFURLRef urlRef = (CFURLRef)[NSURL fileURLWithPath:#"/Users/macbook/MatrixEngineClientSample/Fighters/Sunset03.jpg"];
CGImageSourceRef myImageSourceRef = CGImageSourceCreateWithURL(url, NULL);
CGImageRef myImageRef = CGImageSourceCreateImageAtIndex(myImageSourceRef, 0, NULL);
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(myImageRef));
unsigned char *data = CFDataGetBytePtr(data);
You may need to add Core Graphics and Core Foundation to the list of your linked frameworks.
PNG and JPG images (as with most other image formats) require some form of decompression/decoding, so loading them raw from a file wont produce expected results. It should work with bmp or uncompressed tga images after reading the file header though :/ . Anyway, here are a few image loading libraries that should make loading images easy:
SOIL
DevIL
FreeImage
GLI
I'm currently trying to implement in OpenGL image processing algorithms.
I would like to successively use several shaders in order to perform several filters (Sobel Gaussian,...).
I understood that to do this I had to render to texture thanks to a FBO. I read a lot of things about that, and wrote a code. But I'm not getting the result I expected.
For the moment, I'm just trying to use two shaders. So, I have an original image which is the input of my first shader. Then, I want to render the output of the shader to a texture which will then be the input of my second shader (ping-pong technique). And finally, I want to display the output of the second shader.
But as result, I'm getting the original image.
My code is the following:
/******************** Shaders Function *******************************/
void setupShaders(char *vert, char *frag, GLuint p) {
GLuint v, f;
char *vs = NULL,*fs = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead(vert);
fs = textFileRead(frag);
const char * ff = fs;
const char * vv = vs;
glShaderSource(v, 1, &vv, NULL);
glShaderSource(f, 1, &ff, NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,v);
glLinkProgram(p);
glUseProgram(p);
}
/******************** Texture Function ***********************************/
void setupTexture(void) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
/******************** Quad Drawing Function ******************************/
void ShaderDraw(void){
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.0, height, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(width, height, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(width, height, 0.0);
glEnd();
}
/******************** Initialization Function ***************************/
void init(void)
{
//Checking GLSL
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else {
printf("OpenGL 2.0 not supported\n");
exit(1);
}
// Init
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
}
/******************** Display Function **********************************/
void display(void)
{
glEnable(GL_TEXTURE_2D);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(-4.0, -4.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-4.0, 4.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(4.0, 4.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(4.0, -4.0, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
/******************** Reshape Function *********************************/
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -7.0);
}
/******************** Main Function *************************************/
int main(int argc, char** argv)
{
// Glut Initialisation
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
// Window Generation
glutInitWindowSize(1000,800);
glutInitWindowPosition(100, 100);
glutCreateWindow("Night Vision");
// Initialisation Function
init();
// Downloading Image
data = cLoadBitmap("lena.bmp", &height, &width);
checkGLErrors ("Downloading Image");
int read_tex = 0;
int write_tex = 1;
// Generating Texture
glEnable(GL_TEXTURE_2D);
glGenTextures(2, texImg);
// Init Texture0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texImg[read_tex]);
setupTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
checkGLErrors ("InitTexture0");
// Init Texture1
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texImg[write_tex]);
setupTexture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
checkGLErrors ("InitTexture1");
// Setup Framebuffer Object
GLuint fb;
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
checkGLErrors ("Framebuffer->fb");
GLenum att_point[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
glBindTexture(GL_TEXTURE_2D, texImg[read_tex]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[read_tex], GL_TEXTURE_2D, texImg[read_tex], 0);
glBindTexture(GL_TEXTURE_2D, texImg[write_tex]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, att_point[write_tex], GL_TEXTURE_2D, texImg[write_tex], 0);
checkFramebufferStatus();
//set the write texture as output buffer for the shader
glDrawBuffer(att_point[write_tex]);
// create, init and enable the shader
setupShaders("filter.vert", "sobel_filter_3.frag", p1);
checkGLErrors ("Shaders 1");
// attach the input texture(read texture) to the first texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texImg[read_tex]);
GLuint texLoc;
texLoc = glGetUniformLocation(p1,"tex");
glUniform1i(texLoc, 0);
// draw a square with the texture on it so to perform the computation
ShaderDraw();
// swap the buffers
read_tex = 1;
write_tex = 0;
// Delete program 1
glDeleteProgram(p1);
// set the write texture as output buffer for the shader
glDrawBuffer(att_point[write_tex]);
// create, init and enable the shaders
setupShaders("filter.vert", "gaussian7.frag", p2);
checkGLErrors ("Shaders 2");
// attach the input texture(read texture) to the first texture unit
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texImg[read_tex]);
texLoc = glGetUniformLocation(p2,"tex");
glUniform1i(texLoc, 0);
// draw a square with the texture on it so to perform the computation
ShaderDraw();
// Delete program 2 & disable the FBO
glDeleteProgram(p2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glUseProgram(0);
// Bind the texture to display
glBindTexture(GL_TEXTURE_2D,texImg[0]);
// Glut Functions: Display, Reshape, Keyboard
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
// Calling Main
glutMainLoop();
return 0;
}
Does someone have an idea of what is wrong???
You are trying to simultaneously use the FBO as render source and render target. Afaik you cannot do that - if you want to use a texture bound to an FBO as render source, you need to unbind the FBO (either by calling glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); or by binding another FBO).
It looks like you are trying to save memory that way by using your start texture as the FBO's color buffer there. I am not sure whether this is possible as well.
So you may want try to create two FBOs, each with a single color buffer, and swap the entire FBOs, and start with rendering your texture to the first FBO. Also, don't use your start texture as a color buffer for an FBO, but create a separate color buffer for each FBO instead.
You also don't need to bind a texture to a texture unit before attaching it to an FBO.
Alright, so I'm using cairo to turn an SVG into image data for openGL textures.
That part works.
But now the texture I'm using won't map to the quad I'm making. It's just showing up as a blank square.
Is there something up with the order I'm calling things in or is there some secret function I forgot to use?
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 720;
const int SCREEN_BPP = 32;
int frame = 0;
SDL_Event event;
bool quit;
GLuint texture[1];
int main(int argc, char *argv[]) {
g_type_init();
rsvg_init();
SDL_Surface *screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL );
SDL_WM_SetCaption ("Cairo", NULL);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
/*2D stuff - it worked here
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glEnable (GL_BLEND);
glEnable (GL_TEXTURE_2D);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
*/
//An attempt at setting up 3D stuff
glEnable(GL_TEXTURE_2D);
glMatrixMode( GL_MODELVIEW );
glMatrixMode( GL_PROJECTION );
glViewport(0,0,SCREEN_WIDTH, SCREEN_HEIGHT);
glShadeModel(GL_SMOOTH);
glClearColor(0.0,0.0,0.0,0.0);
glClearDepth(1.0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);
//glLoadIdentity();
float FlowerWidth = .5;
float FlowerHeight = .5;
float FlowerTextureWidth = 80;
float FlowerTextureHeight = 80;
float FlowerScaleWidth = 1;
float FlowerScaleHeight = 1;
cairo_surface_t* Flower;
cairo_t* context;
Flower = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, FlowerTextureWidth, FlowerTextureHeight);
context = cairo_create(Flower);
const gchar* Filename = "resources/area/haneda/lavender.svg";
RsvgHandle* SvgData = rsvg_handle_new_from_file(Filename, NULL);
rsvg_handle_render_cairo_sub(SvgData, context,"#1000");
unsigned char *buffer = cairo_image_surface_get_data(Flower);
cairo_surface_write_to_png(Flower,"flower.png");
//Make a texture
glGenTextures(1, &texture[1]);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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_MODULATE);
glGetError();
//or am I supposed to use GL_TEXTURE_2D?
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
FlowerHeight,
FlowerWidth,
0,
GL_BGRA,
GL_UNSIGNED_BYTE,
buffer);
//done
while (quit==false) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
quit = true;
}
}
/*
FlowerScaleWidth+=.001;
FlowerScaleHeight+=.001;
cairo_scale(context,FlowerScaleWidth,FlowerScaleHeight);
*/
glBindTexture (GL_TEXTURE_2D, texture[1]);
glBegin (GL_QUADS);
glTexCoord2f (0.0, 0.0);
glVertex3f (0.0, 0.0, 0.0);
glTexCoord2f (FlowerWidth, 0.0);
glVertex3f (FlowerWidth, 0.0, 0.0);
glTexCoord2f (FlowerWidth, FlowerHeight);
glVertex3f (FlowerWidth, FlowerHeight, 0.0);
glTexCoord2f (0.0, FlowerHeight);
glVertex3f (0.0, FlowerHeight, 0.0);
glEnd ();
glDeleteTextures(1, &texture[1]);
cairo_save (context);
cairo_set_source_rgba (context, 0, 0, 0, 0);
cairo_set_operator (context, CAIRO_OPERATOR_SOURCE);
cairo_paint (context);
cairo_restore (context);
SDL_GL_SwapBuffers();
//glClear( GL_COLOR_BUFFER_BIT );
//SDL_Delay(100);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glGetError();
SDL_Delay(400);
}
}
For some reason, you've made an int array of length 1, but you pass the (non-existing) element 2 to glGenTextures. That reads beyond the array bounds and is undefined behavior. You also seem to delete the texture name inside your rendering loop. The same illegal indexing is used there too, as well in your call to glBindTexture.