This is the code:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mFont->mTexId);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Bind our vertex data
glVertexPointer(2, GL_FLOAT, 0, mVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, mUVs);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Draw the text
glDrawElements(GL_TRIANGLES, 6 * mNumberOfQuads, GL_UNSIGNED_BYTE, mIndices);
I tried with the next code, but it is not working, the problem is that I´m beginning to learn Opengl Es and I don´t understand a lot of things.
// Enable texturing, bind the font's texture and set up blending
//glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mFont->mTexId);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Bind our vertex data
//glVertexPointer(2, GL_FLOAT, 0, mVertices);
//void VertexPointer(int size,enum type,sizei stride, void *pointer );
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 20, mVertices);
//void VertexAttribPointer( uint index, int size, enum type, boolean normalized, sizei stride, const void *pointer );
//glEnableClientState(GL_VERTEX_ARRAY);
//glEnableVertexAttribArray(VERTEX_ARRAY);
// glTexCoordPointer(2, GL_FLOAT, 0, mUVs);
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// Bind the VBO so we can fill it with data
glBindBuffer(GL_ARRAY_BUFFER, 2);
// Draw the text
glDrawArrays(GL_TRIANGLES, 0, 6 * mNumberOfQuads);
//void DrawArrays( enum mode, int first, sizei count );
//glDrawElements(GL_TRIANGLES, , GL_UNSIGNED_BYTE, );
//void DrawElements(enummode,sizeicount,enumtype, void *indices );*/
Try compiling and binding a vertex and pixel shader before you submit your geometry. There's no fixed-function pipeline at all in ES 2.0.
Related
I'm trying to hook IDirect3DDevice9::Present or ::EndScene and render my own overlay (which, for now, is just a simple rectangle) on top of everything else in a D3D9 application, but my overlay seems to be appearing and disappearing quite randomly. The drawing code I'm currently using is:
typedef struct CUSTOMVERTEX {
float x, y, z, rwh;
DWORD color;
};
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
void draw() {
// the positions are just for testing purposes, so they don't really make sense
CUSTOMVERTEX vertices[] = {
{ 0, 0, 0, 1.0f, D3DCOLOR_XRGB(255, 255, 255) },
{ 0, cursor_pos.y+500, 0, 1.0f, D3DCOLOR_XRGB(127, 255, 255) },
{ cursor_pos.x, cursor_pos.y, 0, 1.0f, D3DCOLOR_XRGB(255,255, 255) },
{ cursor_pos.x, 600, 0, 1.0f, D3DCOLOR_XRGB(127, 0, 0) }
};
if (vBuffer == 0) return;
VOID* pVoid;
vBuffer->Lock(0, 0, &pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
vBuffer->Unlock();
d3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
d3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
D3DMATRIX orthographicMatrix;
D3DMATRIX identityMatrix;
// MAKE_D3DMATRIX should be equivalent to D3DXMATRIX constructor
D3DMATRIX viewMatrix = MAKE_D3DMATRIX(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
((float)-(get_window_width()/2)), ((float)-(get_window_height()/ 2)), 0, 1
);
// MAKE_ORTHO_LH is equivalent to D3DMatrixOrthoLH
MAKE_ORTHO_LH(&orthographicMatrix, (FLOAT)get_window_width(), (FLOAT)get_window_height(), -1.0, 1.0);
// and this to D3DMatrixIdentity
MAKE_IDENTITY(&identityMatrix); // and this to D3DMatrixIdentity
d3dDevice->SetTransform(D3DTS_PROJECTION, &orthographicMatrix);
d3dDevice->SetTransform(D3DTS_WORLD, &identityMatrix);
d3dDevice->SetTransform(D3DTS_VIEW, &viewMatrix);
d3dDevice->SetRenderState(D3DRS_ZENABLE, false);
d3dDevice->SetFVF(CUSTOMFVF);
d3dDevice->SetStreamSource(0, vBuffer, 0, sizeof(CUSTOMVERTEX));
d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
d3dDevice->SetRenderState(D3DRS_ZENABLE, true);
}
I can't seem to figure out why this would cause the overlay to pop in and out of existence at seemingly random points in time.. What am I missing?
I found a foolproof method to render my stuff directly to the backbuffer (on CPU):
IDirect3DSwapChain9 *sc;
if (FAILED(d3dDevice->GetSwapChain(0, &sc))) {
PRINT("GetSwapChain failed\n");
return;
}
IDirect3DSurface9 *s;
if (FAILED(sc->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &s))) {
PRINT("GetBackBuffer failed\n");
return;
}
D3DLOCKED_RECT r;
if (FAILED(s->LockRect(&r, NULL, D3DLOCK_DONOTWAIT))) {
PRINT("LockRect failed\n");
return;
}
// here, find out pixel format and manipulate
// pixel buffer through r->pBits, using r->Pitch accordingly
s->UnlockRect();
s->Release();
sc->Release();
Will most probably incur a performance penalty, but in my application this doesn't really make a difference. A more optimal way would be to harness the GPU's hwacceled rendering capabilities, but I currently lack the D3D knowledge to do so.
I'm using the Quadro SDI SDK along with my Quadro K6000+ SDI Input & output cards and have converted the included cudaDVP SDK sample to send raw image buffers directly to the GPU from the SDI input card.
In the next step I display the data via opengl bindings. Finally I want to output the same identical data to my output card, and this is where I'm having troubles.
I am getting correct input data and I do manage to output to the screen but there appears to be some data modifications happening in the SDI output pipeline as the outgoing image is not quite correct (wrong colors etc). I'm passing the raw input buffer as can be seen below.
Which output card configuration should I use to match my input settings (see below)?
Which if any modifications to the OpenGL output texture configuration are required (see below)?
Input/output Capture/receive options & GL bindings in order of being called in the application:
........
Display *dpy = XOpenDisplay(NULL);
//scan the systems for GPUs
int num_gpus = ScanHW(dpy,gpuList);
if(num_gpus < 1)
exit(1);
//grab the first GPU for now for DVP
HGPUNV *g = &gpuList[0];
////////////////////////////////////////////////////////////////////////////////////////////////
/// Input related SDI settings and OpenGL settings
// Query input , in our case Video format: NV_CTRL_GVIO_VIDEO_FORMAT_576I_50_00_SMPTE259_PAL
XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, &m_videoFormat);
//
// Set desired parameters
//
// Signal format.
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, m_videoFormat);
//Bits per component - 10 bits
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT, NV_CTRL_GVI_BITS_PER_COMPONENT_10);
// Component sampling -422
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING, NV_CTRL_GVI_COMPONENT_SAMPLING_422);
// Chroma expansion OFF
XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, 0, 0, NV_CTRL_GVI_REQUESTED_STREAM_CHROMA_EXPAND, NV_CTRL_GVI_CHROMA_EXPAND_FALSE);
// Query the width and height of the input signal format
XNVCTRLQueryAttribute(dpy, g->deviceXScreen, value, NV_CTRL_GVIO_VIDEO_FORMAT_WIDTH, &m_videoWidth);
XNVCTRLQueryAttribute(dpy, g->deviceXScreen, value, NV_CTRL_GVIO_VIDEO_FORMAT_HEIGHT, &m_videoHeight);
....
GLuint m_videoSlot; // Video slot number
GLuint m_vidBuf; // Video capture buffers
GLint m_bufPitch; // Buffer pitch
GLuint m_vidTex; // Video capture textures
m_videoSlot = 1;
//////////////////////////////////////
////////// OpenGL related settings
// No video color conversion desired ( we want the raw data, NULL )
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0, GL_VIDEO_COLOR_CONVERSION_MATRIX_NV, NULL);
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0,GL_VIDEO_COLOR_CONVERSION_MAX_NV, NULL);
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0,GL_VIDEO_COLOR_CONVERSION_MIN_NV, NULL);
glVideoCaptureStreamParameterfvNV(m_videoSlot, 0,GL_VIDEO_COLOR_CONVERSION_OFFSET_NV, NULL);
// Set the buffer object capture data format. - IE number of components in a pixel
glVideoCaptureStreamParameterivNV(m_videoSlot, 0, GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV, &GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV);
// Get the video buffer pitch
glGetVideoCaptureStreamivNV(m_videoSlot, 0, GL_VIDEO_BUFFER_PITCH_NV, &m_bufPitch);
// Bind the buffer
glBindBufferARB(GL_VIDEO_BUFFER_NV, m_vidBuf);
// Allocate required space in video capture buffer
glBufferDataARB(GL_VIDEO_BUFFER_NV, m_bufPitch * m_videoHeight, NULL, GL_STREAM_READ_ARB);
// Bind the buffer to the video capture device.
glBindVideoCaptureStreamBufferNV(m_videoSlot, 0, GL_FRAME_NV, 0);
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
/// SDI Output card settings
GLuint m_CudaOutTexture; // Texture to send to the output device
GLuint m_CudaOutBuffer; // Texture to send to the output device
GLuint m_OutTexture;
// Set video format - same as input - NV_CTRL_GVIO_VIDEO_FORMAT_576I_50_00_SMPTE259_PAL
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT, m_videoFormat);
// Set data format format.
// Attempted several different settings here....
data_format = NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB422;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X10X10X10_422_PASSTHRU;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X8X8X8_422_PASSTHRU;
//data_format = NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB422;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X12X12X12_422_PASSTHRU;
//data_format = NV_CTRL_GVO_DATA_FORMAT_Y10CR10CB10_TO_YCRCB444;
//data_format = NV_CTRL_GVO_DATA_FORMAT_X10X8X8_422_PASSTHRU;
//data_format = NV_CTRL_GVO_ENABLE_RGB_DATA_DISABLE
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_DATA_FORMAT, data_format);
// Set sync mode
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_SYNC_MODE, NV_CTRL_GVO_SYNC_MODE_FREE_RUNNING);
// Set sync source
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_SYNC_SOURCE, NV_CTRL_GVO_SYNC_SOURCE_SDI);
// Set flip queue length
XNVCTRLSetAttribute(dpy, m_outputOptions.xscreen, 0, NV_CTRL_GVO_FLIP_QUEUE_SIZE, 5);
.....
///////////////////////////////////////////////////////////////////
// OpenGL related settings for output
//Setup the output after the capture is configured.
glGenTextures(1, &m_OutTexture);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_OutTexture);
glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
////////////////////////////////////////////////////////
//Setup GL output from cuda
// Create and initialize a texture objects.
glGenBuffersARB(1, &m_CudaOutBuffer);
assert(glGetError() == GL_NO_ERROR);
glBindBufferARB(GL_VIDEO_BUFFER_NV, m_CudaOutBuffer);
assert(glGetError() == GL_NO_ERROR);
// Allocate required space in video capture buffer
glBufferDataARB(GL_VIDEO_BUFFER_NV, pitch * height, NULL, GL_STREAM_COPY);
glGenTextures(1, &m_CudaOutTexture);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_CudaOutTexture);
glTexParameterf(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
assert(glGetError() == GL_NO_ERROR);
glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA8, width,height,
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
//register the buffer objects
cudaRegisterBuffers();
....
////////////////////////////////////////////////////////////////
/////////// Data transfer from GPU to output device buffer (to be outputted to the SDI output card)
GLint inBuf = m_vidBuf;
// Map buffer(s) into CUDA
cudaError_t cerr;
unsigned char *inDevicePtr;
cerr = cudaGLMapBufferObject((void**)&inDevicePtr, inBuf);
cudaCheckErrors("map");
unsigned char *outDevicePtr;
cerr = cudaGLMapBufferObject((void**)&outDevicePtr, m_CudaOutBuffer);
cudaCheckErrors("map");
//
// Dummy CUDA operation:
// Perform CUDA Operations here such as a kernel call with outDevicePtr and inDevicePtr.
//
unsigned int pitch = m_SDIin.getBufferObjectPitch(0);
unsigned int height = m_SDIin.getHeight();
cudaMemcpy(outDevicePtr,inDevicePtr,pitch*height,cudaMemcpyDeviceToDevice);
////////////////////////////////////////////////////////
/////// output
GLboolean C_cudaDVP::OutputVideo()
{
if(!m_SDIoutEnabled)
return GL_FALSE;
//send the texture to SDI out.
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_OutTexture);
glEnable(GL_TEXTURE_RECTANGLE_NV);
glPresentFrameKeyedNV(1, 0,
0, 0,
GL_FRAME_NV,
GL_TEXTURE_RECTANGLE_NV, m_OutTexture, 0,
GL_NONE, 0, 0);
GLenum l_eVal = glGetError();
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
if (l_eVal != GL_NO_ERROR) {
fprintf(stderr, "glPresentFameKeyedNV returned error: %s\n", gluErrorString(l_eVal));
return FALSE;
}
return GL_TRUE;
}
.....
// After which we call:
// To skip a costly data copy from video buffer to texture we
// can just bind a video buffer to GL_PIXEL_UNPACK_BUFFER_ARB and call
// glTexSubImage2D referencing into the buffer with the PixelData pointer
// set to 0.
glBindTexture(GL_TEXTURE_RECTANGLE_NV, m_CudaOutTexture);
//glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_SDIin.getBufferObjectHandle(0));
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_CudaOutBuffer);
glPixelStorei(GL_UNPACK_ROW_LENGTH,pitch/4);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_RECTANGLE_NV, 0);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
//////////////////////////////////////////////////////
I'm testing out several of Sumantha Guha's code and there's something that isn't working quite right... All of the sample code where he uses GLUT_DOUBLE and glutSwapBuffers() does not work on my ubuntu machine, but works on my Windows machine. More accurately the window that pops out simply traces the background.
I've had this issue before on Windows where Flush and single buffers don't work, but now this is happening on Linux where Double buffers and glutSwapBuffers do not work. Any idea as to what may be causing this?
Sample of code that I tried loading. Compiles fine, just get a window that traces the background.
///////////////////////////////////////////////////////////////////////////////////////////////////////
// loadTextures.cpp
//
// This stripped-down program shows how to load both external and program-generated images as textures.
//
// NOTE: The Textures folder must be in the same one as this program.
//
// Interaction:
// Press the left and right arrow keys to rotate the square.
// Press space to toggle between textures.
// Press delete to reset.
//
// Sumanta Guha
///////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////
// TEXTURE GREDITS:
// canLabel.bmp, thanks anonymous.
// canTop.bmp, thanks www.acoustica.com.
// cray2.bmp, thanks NASA website www.nasa.gov.
// grass.bmp, thanks www.amazingtextures.com.
// launch.bmp, thanks NASA website www.nasa.gov.
// nightsky.bmp, thanks anonymous.
// sky.bmp, thanks www.mega-tex.nl.
// trees.bmp, thanks anonymous.
////////////////////////////////////////////////
#include <cstdlib>
#include <iostream>
#include <fstream>
#ifdef __APPLE__
# include <GLUT/glut.h>
# include <OpenGL/glext.h>
#else
# include <GL/glut.h>
# include <GL/glext.h>
#endif
using namespace std;
// Globals.
static unsigned int texture[2]; // Array of texture indices.
static unsigned char chessboard[64][64][3]; // Storage for chessboard image.
static float angle = 0.0; // Angle to rotate textured square.
static int id = 0; // Currently displayed texture id.
// Struct of bitmap file.
struct BitMapFile
{
int sizeX;
int sizeY;
unsigned char *data;
};
// Routine to read a bitmap file.
// Works only for uncompressed bmp files of 24-bit color.
BitMapFile *getBMPData(string filename)
{
BitMapFile *bmp = new BitMapFile;
unsigned int size, offset, headerSize;
// Read input file name.
ifstream infile(filename.c_str(), ios::binary);
// Get the starting point of the image data.
infile.seekg(10);
infile.read((char *) &offset, 4);
// Get the header size of the bitmap.
infile.read((char *) &headerSize,4);
// Get width and height values in the bitmap header.
infile.seekg(18);
infile.read( (char *) &bmp->sizeX, 4);
infile.read( (char *) &bmp->sizeY, 4);
// Allocate buffer for the image.
size = bmp->sizeX * bmp->sizeY * 24;
bmp->data = new unsigned char[size];
// Read bitmap data.
infile.seekg(offset);
infile.read((char *) bmp->data , size);
// Reverse color from bgr to rgb.
int temp;
for (int i = 0; i < size; i += 3)
{
temp = bmp->data[i];
bmp->data[i] = bmp->data[i+2];
bmp->data[i+2] = temp;
}
return bmp;
}
// Load external textures.
void loadExternalTextures()
{
// Local storage for bmp image data.
BitMapFile *image[1];
// Load the texture.
image[0] = getBMPData("Textures/launch.bmp");
// Activate texture index texture[0].
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Set texture parameters for wrapping.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture parameters for filtering.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Specify an image as the texture to be bound with the currently active texture index.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image[0]->sizeX, image[0]->sizeY, 0,
GL_RGB, GL_UNSIGNED_BYTE, image[0]->data);
}
// Routine to load a program-generated image as a texture.
void loadProceduralTextures()
{
// Activate texture index texture[1].
glBindTexture(GL_TEXTURE_2D, texture[1]);
// Set texture parameters for wrapping.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture parameters for filtering.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Specify an image as the texture to be bound with the currently active texture index.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, chessboard);
}
// Create 64 x 64 RGB image of a chessboard.
void createChessboard(void)
{
int i, j;
for (i = 0; i < 64; i++)
for (j = 0; j < 64; j++)
if ( ( ((i/8)%2) && ((j/8)%2) ) || ( !((i/8)%2) && !((j/8)%2) ) )
{
chessboard[i][j][0] = 0x00;
chessboard[i][j][1] = 0x00;
chessboard[i][j][2] = 0x00;
}
else
{
chessboard[i][j][0] = 0xFF;
chessboard[i][j][1] = 0xFF;
chessboard[i][j][2] = 0xFF;
}
}
// Initialization routine.
void setup(void)
{
glClearColor(0.8, 0.8, 0.8, 0.0);
// Create texture index array.
glGenTextures(2, texture);
// Load external texture and generate and load procedural texture.
loadExternalTextures();
createChessboard();
loadProceduralTextures();
// Turn on OpenGL texturing.
glEnable(GL_TEXTURE_2D);
// Specify how texture values combine with current surface color values.
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
// Drawing routine.
void drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
// Activate a texture.
glBindTexture(GL_TEXTURE_2D, texture[id]);
// Map the texture onto a square polygon.
glBegin(GL_POLYGON);
glTexCoord2f(0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(10.0, -10.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(10.0, 10.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
glEnd();
glutSwapBuffers();
}
// OpenGL window reshape routine.
void resize(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-5.0, 5.0, -5.0, 5.0, 5.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
break;
case ' ':
id++;
if (id == 2) id = 0;
glutPostRedisplay();
break;
case 127:
angle = 0.0;
glutPostRedisplay();
break;
default:
break;
}
}
// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
if (key == GLUT_KEY_LEFT)
{
angle -= 5.0;
if (angle < 0.0) angle += 360.0;
}
if (key == GLUT_KEY_RIGHT)
{
angle += 5.0;
if (angle > 360.0) angle -= 360.0;
}
glutPostRedisplay();
}
// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
cout << "Interaction:" << endl;
cout << "Press the left and right arrow keys to rotate the square." << endl
<< "Press space to toggle between textures." << endl
<< "Press delete to reset." << endl;
}
// Main routine.
int main(int argc, char **argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("loadTextures.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyInput);
glutMainLoop();
return 0;
}
The Light, I added, looks on objects weak? I want it brighter and I don't want to give the Light position. I mean, I want a bright Light on all the screen with same brightness in the middle or at the corners?
float[] lightColor = {1, 1, 1, 0};
float[] lightPosition = {0, 0, 10, 0};
#Override
public void render () {
...
gl.glEnable(GL10.GL_LIGHTING);
...
gl.glEnable(GL10.GL_LIGHT0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightColor, 0);
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosition, 0);
}
I've been working on ping pong shading and had thought that I had cracked it after my previous question. However, with further shader knowledge it looks like while I'm able to run the shader on FBO A and on FBO B, the output from A is not used as the source to B. In other words I'm not binding it correctly.
The code I'm using is below. The output of the second shader is showing colour based output but the first shader sets the data to grayscale. So consquently I know this isn't working as required.
I'd be grateful for any (yet further!!) assistance.
Code below,
Cheers,
Simon
- (void) PingPong:(CVImageBufferRef)cameraframe;
{
// Standard texture coords for the rendering pipeline
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat textureVertices[] = {
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
};
if (context)
{
[EAGLContext setCurrentContext:context];
}
// Create two textures with the same configuration
int bufferHeight = CVPixelBufferGetHeight(cameraframe);
int bufferWidth = CVPixelBufferGetWidth(cameraframe);
// texture 1
glGenTextures(1, &tex_A);
glBindTexture(GL_TEXTURE_2D, tex_A);
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);
// Using BGRA extension to pull in video frame data directly
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, CVPixelBufferGetBaseAddress(cameraframe));
// Texture 2
glGenTextures(1, &tex_B);
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);
// Bind framebuffer A
glBindFramebuffer(GL_FRAMEBUFFER, fbo_A);
glViewport(0, 0, backingWidth, backingHeight);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_A);
// Update uniform values
glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);
// Update attribute values.
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
// Use the first shader
glUseProgram(greyscaleProgram);
// Render a quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Use the second shader
glUseProgram(program);
// Bind framebuffer B
glBindFramebuffer(GL_FRAMEBUFFER, fbo_B);
// Bind texture A and setup texture units for the shader
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_A);
// Render output of FBO b is texture B
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_B, 0);
// Update uniform values
glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);
// Update attribute values.
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);
// Render a quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Render the whole thing
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];
glDeleteTextures(1, &tex_A);
glDeleteTextures(1, &tex_B);
}
I think what might be happening is that you are still rendering into frame buffer memory and not texture memory. iirc glFramebufferTexture2D does not act as a resolve/copy but instead binds the framebuffer to the texture so that future render operations get written to the texture. You could have more problems however I'm pretty sure that your call to glFramebufferTexture2D should happen directly after your first call to glBindFramebuffer. This may not be your only problem, but it seems to be a significant one.