How to draw SDL 2D rectangles over a 3D OpenGL scene? - c++

I'm trying to overlay small interactive info rectangles drawn with SDL 2D over a 3D scene drawn with OpenGL. Each of itself works, but not together. The 3D model is then hidden.
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_CreateWindowAndRenderer(m_width, m_height, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE, &m_window, &m_renderer);
SDL_GLContext context = SDL_GL_CreateContext(m_window);
SDL_RenderClear(m_renderer);
SDL_RenderPresent(m_renderer);
// load vertex, fragmend shader...
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, m_indicesSize, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
SDL_Rect rect;
rect.w = 50;
rect.h = 50;
rect.x = 100;
rect.y = 100;
SDL_SetRenderDrawColor(m_renderer, 255, 0, 0, 255);
SDL_RenderFillRect(m_renderer, &rect);
SDL_RenderPresent(m_renderer);
How can I solve this problem? Thxs..

You don't, at least for now.
Here's the (open) bug about adding backend API state getters/setters to SDL_Renderer..
Alternatively, create a SDL_Renderer instance that uses the software renderer & upload the bitmaps coming out of that into a OpenGL texture & composite that into your scene.

Related

opengl Color & Cube is not working properly

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<GL/glut.h>
double cameraAngle;
void grid_and_axes() {
// draw the three major AXES
glBegin(GL_LINES);
//X axis
glColor3f(0, 1, 0); //100% Green
glVertex3f(-150, 0, 0);
glVertex3f(150, 0, 0);
//Y axis
glColor3f(0, 0, 1); //100% Blue
glVertex3f(0, -150, 0); // intentionally extended to -150 to 150, no big deal
glVertex3f(0, 150, 0);
//Z axis
glColor3f(1, 1, 1); //100% White
glVertex3f(0, 0, -150);
glVertex3f(0, 0, 150);
glEnd();
//some gridlines along the field
int i;
glColor3f(0.5, 0.5, 0.5); //grey
glBegin(GL_LINES);
for (i = -10; i <= 10; i++) {
if (i == 0)
continue; //SKIP the MAIN axes
//lines parallel to Y-axis
glVertex3f(i * 10, -100, 0);
glVertex3f(i * 10, 100, 0);
//lines parallel to X-axis
glVertex3f(-100, i * 10, 0);
glVertex3f(100, i * 10, 0);
}
glEnd();
}
void display() {
//codes for Models, Camera
//clear the display
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 0); //color black
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear buffers to preset values
/***************************
/ set-up camera (view) here
****************************/
//load the correct matrix -- MODEL-VIEW matrix
glMatrixMode(GL_MODELVIEW); //specify which matrix is the current matrix
//initialize the matrix
glLoadIdentity(); //replace the current matrix with the identity matrix [Diagonals have 1, others have 0]
//now give three info
//1. where is the camera (viewer)?
//2. where is the camera looking?
//3. Which direction is the camera's UP direction?
//gluLookAt(0,-150,20, 0,0,0, 0,0,1);
gluLookAt(150 * sin(cameraAngle), -150 * cos(cameraAngle), 50, 0, 0, 0, 0, 0, 1);
/*************************
/ Grid and axes Lines
**************************/
grid_and_axes();
/****************************
/ Add your objects from here
****************************/
/*glColor3f(1, 0, 0);
glutSolidCone(20, 20, 20, 20);
glColor3f(0, 0, 1);
GLUquadricObj *cyl = gluNewQuadric();
gluCylinder(cyl, 10, 10, 50, 20, 20);
glTranslatef(0, 0, 50);
glColor3f(1, 0, 0);
glutSolidCone(10, 20, 20, 20);
*/
glColor3f(1, 0, 0);
glutSolidCube(1);
I am not getting any cube here.
However if I use any transformation property like scaling or rotate then I get the desired cube like
glColor3f(1, 0, 0);
glScalef(50,5,60);
glutSolidCube(1);
what is the problem?
Another problem I am facing that color doesn't work if i don't use transformation property like above mentioned. If I write:
glColor3f(1, 0, 0);
glutSolidCone(20, 20, 20, 20);
For above codes color doesn't work; i get the default colored cone
However if I change this two lines to these 3 lines then color works perfectly:
glColor3f(1,0,0);
glTranslatef(0, 0, 50);
glutSolidCone(10,20,20,20);
then color works; what is the problem? Please help
//ADD this line in the end --- if you use double buffer (i.e. GL_DOUBLE)
glutSwapBuffers();
}
void animate() {
//codes for any changes in Models, Camera
cameraAngle += 0.001; // camera will rotate at 0.002 radians per frame.
//codes for any changes in Models
//MISSING SOMETHING? -- YES: add the following
glutPostRedisplay(); //this will call the display AGAIN
}
void init() {
//codes for initialization
cameraAngle = 0; //angle in radian
//clear the screen
glClearColor(0, 0, 0, 0);
/************************
/ set-up projection here
************************/
//load the PROJECTION matrix
glMatrixMode(GL_PROJECTION);
//initialize the matrix
glLoadIdentity();
/*
gluPerspective() — set up a perspective projection matrix
fovy - Specifies the field of view angle, in degrees, in the y direction.
aspect ratio - Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
zNear - Specifies the distance from the viewer to the near clipping plane (always positive).
zFar - Specifies the distance from the viewer to the far clipping plane (always positive).
*/
gluPerspective(70, 1, 0.1, 10000.0);
}
int main(int argc, char **argv) {
glutInit(&argc, argv); //initialize the GLUT library
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
/*
glutInitDisplayMode - inits display mode
GLUT_DOUBLE - allows for display on the double buffer window
GLUT_RGBA - shows color (Red, green, blue) and an alpha
GLUT_DEPTH - allows for depth buffer
*/
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Some Title");
init(); //codes for initialization
glEnable(GL_DEPTH_TEST); //enable Depth Testing
glutDisplayFunc(display); //display callback function
glutIdleFunc(animate); //what you want to do in the idle time (when no drawing is occuring)
glutMainLoop(); //The main loop of OpenGL
return 0;
}
I am not getting any cube here.
You do get a cube. It is just that tiny speck where the axis intersect. What else would you expect to see when you draw something 2 units big, ~160 units away, with a 70 degree field of view?
Another problem I am facing that color doesn't work if i don't use transformation property like above mentioned.
[...] I get the default colored cone.
I've no idea what you even mean by that. The "default color" would be the initial value of GL's builtin color attribute - which is (1, 1, 1, 1) - white. With the code you have set up, you will get the color which you set before. So the only guess I can make here is that you confused yourself by not properly taking GL's state machine into account.
But besides all that, you should not use that code at all - this is using the fixed function pipeline and immediate mode drawing - features which are deprecated since a decade now, and not supported at all by modern core profiles of OpenGL. Trying to learn that stuff in 2017 is a waste of time. And btw:
glutMainLoop(); //The main loop of OpenGL
Nope. Just NO!!!. OpenGL does not have a "main loop". GLUT is not OpenGL. Honestly, this is all just horrible.

Can i draw QRect with QPainter and draw something with OpenGL together?

Qt 5.8.0. MinGW 32 bit.
I need to draw objects of different shapes on the screen. I use OpenGL to speed up and draw different shapes, but I also need to draw in QPaint.
I try to draw Rect with Qpainter (drawText function). Text show on screen, but rect not show on screen.
Example
How do I draw a rectangle with QPainter, not with OpenGL? I want to draw 3 shapes: a triangle and a rectangle using OpenGL, a rectangle using QPainter. My app should to draw any shapes (using QPainter) and sometimes draw particles with OpenGL acceleration. How can I combine this in one widget?
part of DrawingWidget.cpp:
void DrawingWidget::paintGL()
{
m_painter = new QPainter(this);
m_painter->beginNativePainting();
m_program->bind();
m_modelView.setToIdentity();
m_modelView.translate(-1.5f, 0.0f, -6.0f);
m_program->setUniformValue("mvpMatrix", m_projection * m_modelView);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
m_program->enableAttributeArray(m_posAttr);
m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
m_program->enableAttributeArray(m_colAttr);
m_program->setAttributeBuffer(m_colAttr, GL_FLOAT, 0, 3);
glDrawArrays(GL_TRIANGLES, 0, 3);
m_modelView.translate(3.0f, 0.0f, 0.0f);
m_program->setUniformValue("mvpMatrix", m_projection * m_modelView);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
m_program->enableAttributeArray(m_posAttr);
m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[3]);
m_program->enableAttributeArray(m_colAttr);
m_program->setAttributeBuffer(m_colAttr, GL_FLOAT, 0, 3);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
m_program->release();
m_painter->endNativePainting();
drawText();
m_painter->end();
}
void DrawingWidget::drawText()
{
m_painter->setPen(QColor(Qt::green));
m_painter->setBrush(QBrush(QColor(Qt::red)));
m_painter->drawRect(QRect(QPoint(10, 10), QPoint(50, 44)));
m_painter->drawText(0, 40, QString("TEST"));
}
main:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QSurfaceFormat format;
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile);
DrawingWidget GLWidget;
GLWidget.setFormat(format);
GLWidget.resize(800, 600);
GLWidget.show();
return app.exec();
}
18.04.17
ahaha, so, when i will draw to rect after draw text app is working, but not working if i try draw text after rect or try draw rect without text
m_painter->setPen(QColor(Qt::green));
m_painter->setBrush(QBrush(QColor(Qt::red)));
m_painter->drawText(0, 40, QString("TEST"));
for (int i = 0; i < 6; i++) {
int x = rand() % this->width();
int y = rand() % this->height();
m_painter->drawRect(QRect(QPoint(x, y), QPoint(x + 15, y + 15)));
}

SDL Rendering transparent rectangle using SDL_Rect

I could find nothing about rendering transparent rectangles in SDL2 documentaries. I want to render SDL_Rect as transparent texture/surface/anything used as "fog of war". Maybe you know any way to make surface or texture from SDL_Rect or just render it transparent. I don't want new texture in game files because player could just delete file and he would not have that fog of war.
Ok I managed to do it by myself and if anyone else will have same question thats the answer:
SDL_Surface* Fog = NULL;
SDL_Texture* gFog = NULL;
Fog = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);
if (Fog == NULL)std::cout << SDL_GetError();
gFog = SDL_CreateTextureFromSurface(gRenderer, Fog);
if (gFog == NULL)std::cout<<SDL_GetError();
SDL_SetTextureBlendMode(gFog, SDL_BLENDMODE_BLEND);
SDL_SetTextureAlphaMod(gFog, 150);

opengl: Trouble setting up viewport and glortho

I am trying to setup my OpenGL views for some texture rendering. Following some advice on the forum, I set up my viewport and ortho matrix as follows:
First I try to compute the screen width and height that I can use while maintaining the aspect ratio of my image:
void resize(int w, int h)
{
float target_aspect_ratio = image_width / image_height;
width = w;
height = (int)(width / target_aspect_ratio + 0.5f);
if (height > h) {
height = h;
width = (int)(height * target_aspect_ratio + 0.5f);
}
off_x = (w - width)/2.f;
off_y = (h - height)/2;
// I want to center my image. So I have these offsets
glViewport(off_x, off_y, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, 0.0f, 1.0f);
Now when I want to render my texture I do:
void paint()
{
// texture binding etc.
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(width, 0);
glTexCoord2f(1, 1); glVertex2f(width, height);
glTexCoord2f(0, 1); glVertex2f(0, height);
}
However, this does not show the image as expected. It does not maintain the aspect ratio as I size the screen. It is almost like the glViewport has no effect and I can verify this function gets called every time my window is resized.
Update:
It is strange. Almost as if these calls have no effect. I even did something as:
_off_x = _off_y = 0;
_width = 500;
_height = 500;
So I expected the viewport to be lower left box of my screen but the image is being drawn as before basically using the whole screen as the viewport.
Update 2:
Ok, so if I call
glViewport(_off_x, _off_y, _width, _height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, _width, 0, _height, 0, 1);
in my paint events, it works as expected! However, I thought it was enough to put this in the resize event handler.
Before start drawing, you need to switch your Matrix mode to GL_MODELVIEW. You don't need to set your projection matrix inside your render function at each frame.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Here is a detailed analysis that I wrote about glMatrixMode() function modes :
OpenGL glMatrixMode(GL_PROJECTION) vs glMatrixMode(GL_MODELVIEW)

C++ OpenGL (with SOIL addon) - Texture coming out shaded

I'm trying to learn OpenGL but I've not yet got the hang of it, as I encountered a problem at the first hurdle where I try to display a bright red square, but the image comes out as a maroon coloured square. (I apologize but I cannot post pictures due to not having enough reputation :( )
I've been using the SOIL library (http://www.lonesock.net/soil.html) to make the task of loading textures simpler, and I am fairly sure that this is where the problem lies.
I understand the most obvious answer is to not use SOIL, and to learn raw OGL first before I try using extensions, and I do intend to do this. However I would still like this problem solving for peace of mind.
My personal assumption is I have probably enabled some sort of shading somewhere, or there is some quirk of OGL or SOIL that forces the shade of the texture to change, however I am not experienced enough to solve this.
Below is what I believe to be the relevant code.
void displayBackground()
{
GetTexture("resources/red.png");
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(480, 0); glVertex2f( 480, 0);
glTexCoord2f(480, 480); glVertex2f( 480, 480);
glTexCoord2f(0, 480); glVertex2f(0, 480);
glEnd();
glDisable(GL_TEXTURE_2D);
}
And below is the SOIL-specific code which as far as I can tell should load a solid red texture into the active OGL texture
GLuint GetTexture(std::string Filename)
{
GLuint tex_ID;
tex_ID = SOIL_load_OGL_texture(
Filename.c_str(),
SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID,
SOIL_FLAG_POWER_OF_TWO
| SOIL_FLAG_MIPMAPS
| SOIL_FLAG_COMPRESS_TO_DXT
| SOIL_FLAG_DDS_LOAD_DIRECT
);
if( tex_ID > 0 )
{
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, tex_ID );
return tex_ID;
}
else
return 0;
}
Thank you in advance for anyone insight into where I have possibly gone wrong.
#Nazar554
I'm assuming this is what you mean by the view port? Sorry, I'm aware this is very basic OGL stuff and I probably sound rather stupid, but you've got to start somewhere right? :P
/** OpenGL Initial Setup**/
//pixel format descriptor to describe pixel layout of a given surface
PIXELFORMATDESCRIPTOR pfd;
std::memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER_DONTCARE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
HDC hdc = GetDC(hwnd); //gets device context of hwnd. Device context is a set of graphics objects that define how to draw to the given device
int format = ChoosePixelFormat(hdc, &pfd); //chooses best pixel format for device context given the pfd to be used
SetPixelFormat(hdc, format, &pfd);
HGLRC hglrc;
hglrc = wglCreateContext(hdc); //creates OGL rendering context suitable for drawing on the device specified by hdc
wglMakeCurrent(hdc, hglrc); //makes hglrc the thread's current context. subsequent OGL calls made on hdc
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Red, Green, Blue, Alpha. (Additive color) Does not need to be updated every cycle
glOrtho(0, 900, 600, 1.0, -1.0, 1.0); //sets co-ordinates system
Put glOrtho before glClearColor. Also you need to select projection matrix before calling glOrtho.
Use this:
glMatrixMode(GL_PROJECTION); // select projection matrix
glLoadIdentity(); // clear it
glOrtho(0, w, h, 0, 0, 1); // compute projection matrix, and multiply identity matrix by it
// w, h is your window size if you are doing 2D
glMatrixMode(GL_MODELVIEW); // select model matrix
Also, if you are studying OpenGL better begin with modern versions (3.3+, or 2.1 without old stuff), not 1.2. They have a lot of differences and it will be hard to forget everything you studied before. For beginners freeglut or GLFW is more simple and portable than pure Win32.