OpenGL binding several 2D textures - c++

I've trying to load different textures to the GL_TEXTUREX variables and then assign them to different spheres. but so far I've having problems. I tried some of the suggestions in post like this and this
but couldnt solve it.
This is part of my code:
GLuint textures[2];
void LoadTextures(std::string const& dirname)
{
glGenTextures(2, textures);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
Image_t sun = loadPNG(std::string(dirname + "/sun.png"));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, &(sun.data[0]));
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
Image_t mercury = loadPNG(std::string(dirname + "/mercury.png"));
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1024, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, &(mercury.data[0]));
}
and
void draw(void)
{
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, textures[0]);
glPushMatrix();
glTranslatef(0.4,0,0);
gluSphere(sun, 0.5, 36, 36); //I want this sphere to use the texture GL_TEXTURE0
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}

You need to call glBindTexture just before performing a draw call:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
draw_things();
In the above example, whatever you draw with draw_things will have access to both textures 0 and 1 (GL_TEXTURE0 and GL_TEXTURE1).
Now, if what you want is to draw many things, but each with a different texture, then you need to:
glActiveTexture(GL_TEXTURE0); // activate any texture unit
glEnable(GL_TEXTURE_2D); // make sure texturing is enabled
glBindTexture(GL_TEXTURE_2D, thing1_texture);
draw_thing1();
glBindTexture(GL_TEXTURE_2D, thing2_texture);
draw_thing2();
// etecetera

Related

Render fonts with freetype

I made opengl rendering engine, and i can render shapes, 3d shapesand textures. Then i wanted to render fonts. I used freetype library to do this. But i have one serious problem with it. When i render font it looks terrible. First i will explain how i initialized freetype, and loaded font, then how i render textures, so you will be able to see itf there are any mistakes.
I initialize freetype and load font like this:
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Init_FreeType(&library);
FT_New_Face(library, "arial.ttf", 0, &face);
FT_Set_Char_Size(face, 0, 20 * 64, 300, 300);
slot = face->glyph;
FT_Load_Char(face, 'a', FT_LOAD_RENDER);
Then i load it into my texture:
this->tex.LoadFromBuffer(slot->bitmap.buffer, slot->bitmap.width, slot->bitmap.rows);
The tex object is just texture container which looks like this:
class Texture
{
public:
void LoadFromBuffer(unsigned char* buf, int w, int h);
float sizex, sizey;
GLuint texName;
};
And load from buffer function looks like this:
void Texture::LoadFromBuffer(unsigned char* buf, int w, int h)
{
this->sizex = w;
this->sizey = h;
glGenTextures(1, &this->texName);
glBindTexture(GL_TEXTURE_2D, this->texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(buf);
}
Then texture is created and i render it just normaly with opengl on squad:
void Renderer::Render(Quad& quadv)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, quadv.texture->texName);
glBegin(GL_QUADS);
glColor3f(quadv.color.r, quadv.color.g, quadv.color.b);
glTexCoord2f(0.0, 0.0); glVertex2f(quadv.vertices[0].x, quadv.vertices[0].y);
glTexCoord2f(1.0, 0.0); glVertex2f(quadv.vertices[1].x, quadv.vertices[1].y);
glTexCoord2f(1.0, 1.0); glVertex2f(quadv.vertices[2].x, quadv.vertices[2].y);
glTexCoord2f(0.0, 1.0); glVertex2f(quadv.vertices[3].x, quadv.vertices[3].y);
glEnd();
glDisable(GL_TEXTURE_2D);
}
Quadv is object which contains vertices of quad, but its not important here.
Texture in quadv is the texture with letter a, that i loaded before.
Code looks just normal to me, but when i run it, the texture looks like this:
A letter is triple no matter what size texture is or size of quad.
And whole image is terrible.
I don't recall what is the default PixelMode when using FT.
But it looks to me like you are assuming that the bitmap provided by FT comes as a 32-bit RGBA color, which is probably not the case.
I'm gonna assume it comes as an 8-bit color. Try changing:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
to
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, buf);
We replaced GL_RGB which was the input format to GL_RED such that the tex image function expects 1 component per pixel. FT2 Documentation for further information
The bitmap contains 1 channel per pixel, encoded in a single byte. Since you're using legacy OpenGL, I recommend using the internal texture format GL_ALPHA. Therefore each element of the texture is treated as a single alpha component.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, buf);
Enable Blending to show only the opaque part of the glyphs:
void Renderer::Render(Quad& quadv)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, quadv.texture->texName);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
glColor3f(quadv.color.r, quadv.color.g, quadv.color.b);
glTexCoord2f(0.0, 0.0); glVertex2f(quadv.vertices[0].x, quadv.vertices[0].y);
glTexCoord2f(1.0, 0.0); glVertex2f(quadv.vertices[1].x, quadv.vertices[1].y);
glTexCoord2f(1.0, 1.0); glVertex2f(quadv.vertices[2].x, quadv.vertices[2].y);
glTexCoord2f(0.0, 1.0); glVertex2f(quadv.vertices[3].x, quadv.vertices[3].y);
glEnd();
glDisable(GL_TEXTURE_2D);
}

Frame buffer not rendering depth into depth texture

So, i have this assignment about double pass rendering to compute shadows and I am trying to store the depth value of each of the objects of a scene and rendering them as a texture in another object.
I am using OpenGL, I don't really know where the error could be, but when analyzing a capture with RenderDoc, it says that the FBO (FrameBufferObject) is unused and also interprets what should be my 1st pass, a depth only pass, as a color pass.
/*-This is how I create the FBO and the texture to render the depth-*/
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Create texture for Depth image (first pass)
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
// Give pixel data to opengl
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr);
// WITH PCF for anti-aliasing shadow edges
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
depthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
/*---------------------------END------------------------------------*/
/*---This is how I render all the objects (1st and second pass)-----*/
glViewport(0, 0, 1024, 1024);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cube.FirstPass(light.getPos());
plane.FirstPass(light.getPos());
cone1.FirstPass(light.getPos());
cone2.FirstPass(light.getPos());
glFlush();
glFinish();
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cube.display(&cam, light.getPos());
plane.display(&cam, light.getPos());
viewport.display(&cam, light.getPos());
cone1.display(&cam, light.getPos());
cone2.display(&cam, light.getPos());
/*---------------------------END------------------------------------*/
/*---------This is how I do First Pass---------*/
//Here goes first pass
glBindFramebuffer(GL_FRAMEBUFFER, sceneManager.getFBO());
glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(DepthPass.shader);
glm::mat4 mtx = glm::perspective(glm::radians(60.0f), 1024.0f / 1024.0f, 5.0f, 40.0f);
DepthPass.setMat("M", mtx * glm::lookAt(glm::vec3(lightPos.x, lightPos.y, lightPos.z), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0)) *
getModelToWorld());
glBindVertexArray(vao);
// Draw
glDrawArrays(GL_TRIANGLES, 0, ModelVertices.size());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
/*---------------------------END------------------------------------*/
/*--This is what I pass to the shader that shows the depth texture--*/
DepthPass.setFloat("near", 5.0f);
DepthPass.setFloat("far", 40.0);
DepthPass.setInt("IsViewport", 1);
glActiveTexture(GL_TEXTURE0);
//GetDepthTexture() returns a handle of the texture created before
glBindTexture(GL_TEXTURE_2D, sceneManager.GetDepthTexture());
std::string textureName = "depthTexture";
DepthPass.setInt(textureName.c_str(), sceneManager.GetDepthTexture());
/*---------------------------END------------------------------------*/

What's wrong with my Depth Texture?

At the moment I'm playing with FBO, which I don't really master. I have no problems with color atachments, but I can't figure out how to use depth textures in my render.
At the moment, I render my scene on a FBO (color+depth), then I draw a textured quad using the depth texture... But it doesn't work, my screen stays black (everyhting is 0 : even if i multiply by 1000 it stays at 0). (Depth test works : if I render the color texture instead of the depth, depth test works correctly)
Rendering loop :
///Render to FBO
glEnable(GL_DEPTH_TEST);
FBO.Bind(); //Do I really need to explain what it does ?
glUseProgram(ShaderProgram->getProgramID());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
///Setting uniforms etc
mainScene.drawAll();
//draw the quad
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, m_window.getSize().x, m_window.getSize().y);
glUseProgram(2DShader.getProgramID());
quadModel.bindVAO();
glBindTexture(GL_TEXTURE_2D, FBO.DepthTexureID);
glDrawArrays(GL_TRIANGLES, 0, 6);
And FBO creation :
glGenFramebuffers(1, &FBO_ID);
glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);
glGenTextures(1, &ColorBufferID);
glBindTexture(GL_TEXTURE_2D, ColorBufferID);
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_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorBufferID, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &DepthTexture);
glBindTexture(GL_TEXTURE_2D, DepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthTexture, 0);
glBindTexture(GL_TEXTURE_2D, 0);
Any idea ?
Your depth texture is not mipmap-complete, but you are using the default mipmap filtering, so sampling will fail. Just specify some non-mipmapping filters like GL_NEAREST or LINEAR for sampling that texture.

Cannot render to texture with multisampling

I ran the framebuffers example in this page -original code- (using glfw3 and glew in xcode 4.6 in osx 10.8), it worked fine, then I wanted to add multisampling (to avoid jagged edges on cube edges and on the floor, glfwWindowHint (GLFW_SAMPLES, 4) was enough when rendering directly to the back-buffer), found some answers directing to opengl.org, tried to use glTexImage2DMultisample but it displayed nothing (black screen). The framebuffer settings and rendering loop is:
// Create frame buffer
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
// Create texture to hold color buffer
GLuint texColorBuffer;
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texColorBuffer);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, width, height, GL_FALSE);
/*
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texColorBuffer, 0);
// Create Renderbuffer Object to hold depth and stencil buffers
GLuint rboDepthStencil;
glGenRenderbuffers(1, &rboDepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil);
//glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glRenderbufferStorageMultisample (GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil);
// ...
while (!window->shouldClose()) {
static int rot = 0;
// Bind our framebuffer and draw 3D scene (spinning cube)
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
auto err_res = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(err_res != GL_FRAMEBUFFER_COMPLETE) {
ERR("Incomplete frameBuffer:%X!", err_res);
goto end;
}
glBindVertexArray(vaoCube);
glEnable(GL_DEPTH_TEST);
glUseProgram(sceneShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texKitten);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texPuppy);
// Clear the screen to white
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
// Draw cube
glEnable(GL_MULTISAMPLE);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_STENCIL_TEST);
// Draw floor
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0xFF);
glDepthMask(GL_FALSE);
glClear(GL_STENCIL_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 36, 6);
// Draw cube reflection
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilMask(0x00);
glDepthMask(GL_TRUE);
model = glm::scale(glm::translate(model, glm::vec3(0, 0, -1)), glm::vec3(1, 1, -1));
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glUniform3f(uniColor, 0.3f, 0.3f, 0.3f);
glDrawArrays(GL_TRIANGLES, 0, 36);
glUniform3f(uniColor, 1.0f, 1.0f, 1.0f);
glDisable(GL_STENCIL_TEST);
/*
// Bind default framebuffer and draw contents of our framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
glBindVertexArray(vaoQuad);
glDisable(GL_DEPTH_TEST);
glUseProgram(screenShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);
*/
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Make sure no FBO is set as the draw framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer); // Make sure your multisampled FBO is the read framebuffer
glDrawBuffer(GL_BACK); // Set the back buffer as the draw buffer
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Swap buffers
glfwSwapBuffers(window->getHandle());
glfwPollEvents();
}
glVersion: 3.2 NVIDIA-8.10.44 304.10.65f03
glRenderer: NVIDIA GeForce 9400M OpenGL Engine
The 'EXT' additions are probably unnecessary but I also tried to run without them before and the result was the same. What am I doing wrong?
EDIT: Now binding GL_TEXTURE_2D_MULTISAMPLE and getting GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE error!
If you checked your framebuffer object for completeness, you would probably have caught this by now... your depth/stencil buffer needs to be multisampled as well.
A framebuffer is considered multisample incomplete by both core and the EXT FBO extension if one attachment has a different number of samples than any other attachment. In your case, you have a color buffer attachment with 4 samples and a depth/stencil attachment with 1 sample.
Name
glCheckFramebufferStatus — check the completeness status of a framebuffer
Description
glCheckFramebufferStatus queries the completeness status of the framebuffer object currently bound to target. target must be GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER. GL_FRAMEBUFFER is equivalent to GL_DRAW_FRAMEBUFFER.
The return value is GL_FRAMEBUFFER_COMPLETE if the framebuffer bound to target is complete. Otherwise, the return value is determined as follows:
[...]
GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.
To fix this, you need to allocate a multisampled depth/stencil attachment with 4 samples:
glRenderbufferStorageMultisample (GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
By the way, since your implementation is >= 3.0, you do not need the EXT suffix on anything. All of the constants defined by the EXT extension are identical to ARB / core FBOs, but some of the EXT functions (such as glCheckFramebufferStatusEXT) have more restrictive behavior (requiring each attachment to have the same image dimensions, for instance).

OpenGL error 'invalid value' when calling glTexSubImage2D

I have a small application that I'm using for testing that is doing some post processing effects. My goal is to read the pixels using double PBO's and then render the pixels to a full screen texture quad and modify/add my effects in a fragment shader. Similar to here. The application is using OSG but I am using openGL calls to do the full screen texturing.
My problem is that when I copy the pixels to the texture each frame using glTexSubImage2D, I get an invalid value openGL error. I have verified with gDEBugger that this is the call generating the errors. The first time the error happens the pointer address is different than in all the subsequent frames. Also, by making the width and height parameters of the glTexSubImage2d 0 the error is not generated. So I'm not really sure what's going.
Here is the relevant code:
MyCallbackClass()
{
pImgData = (unsigned char*) malloc(1024*512*3);
setupTextureAndShaders();
}
void setupTextureAndShaders()
{
glGenTextures(1, &screenTexture);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
memset(pImgData, 0, 1024*512*3);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, pImgData);
glBindTexture(GL_TEXTURE_2D, 0);
}
//callback called every frame
virtual void operator () (osg::RenderInfo& renderInfo) const
{
// buffer and context stuff unchanged from the sample program
if(!shaderInit) // only executed once
{
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
const GLchar* vs_source = shaderLoadFile("vert.glsl");
glShaderSource(vs, 1, &vs_source, NULL);
glCompileShader(vs);
checkShader(&vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
const GLchar* fs_source = shaderLoadFile("frag.glsl");
glShaderSource(fs, 1, &fs_source, NULL);
glCompileShader(fs);
checkShader(&fs);
prog = glCreateProgram();
glAttachShader(prog, vs);
glAttachShader(prog, fs);
glLinkProgram(prog);
texLoc = glGetUniformLocation(prog, "screenTex");
shaderInit = true;
}
read(); // does the double pbo operations to read the image data into pImgData
glUseProgram(prog);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, screenTexture);
glUniform1i(texLoc, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, pImgData);
glBegin(GL_QUADS);
glTexCoord2f(0, 1);
glVertex2f(-1,-1);
glTexCoord2f(0, 0);
glVertex2f(-1,1);
glTexCoord2f(1,0);
glVertex2f(1,1);
glTexCoord2f(1,1);
glVertex2f(1,-1);
glEnd();
glDisable(GL_TEXTURE_2D);
glMatrixMode (GL_MODELVIEW);
glPopMatrix();
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
glUseProgram(0);
}
I looked into the state changing in the read() call, however the real problem was with my setupTexturesAndShaders() function being in a different context. I believe this resulted in the glTexSubImage2D being called without having called the glTexImage2D first in the same context which would make any size image be out of range. Thanks for getting me thinking on the right track