Related
I'm trying to render 2D text over a 3D scene. The 2D text is loaded using freetype from a TTF font and uses an orthographic projection to render and the scene uses a perspective projection using my camera. I have modified the code from this Learn OpenGL tutorial for text rendering. I can render the text by itself and the 3D scene separately however the 2D text does not appear when drawing them together.
My render function:
void Engine::render()
{
std::string fpsStr = std::to_string(fps).substr(0, std::to_string(fps).find(".") + 3);
glViewport(0, 0, surface_width, surface_height);
glClearColor(0.53f, 0.8f, 0.92f, 1.0f);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 3D scene gets rendered here
scene->render(display, surface, deltaTime);
//
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Text gets rendered here
debugText.renderText(fpsStr,25.0f, 25.0f, 1.0f, glm::vec3(0.0, 0.0, 0.0));
//
glDisable(GL_BLEND);
eglSwapBuffers(display, surface);
}
The text projection is a member variable (glm::mat4) that is initialized during creation of the text rendering class like so:
...
projection = glm::ortho(0.0f, static_cast<float>(screenWidth), 0.0f, static_cast<float>(screenHeight));
...
My render text function:
void Font::renderText(std::string text, float x, float y, float scale, glm::vec3 colour)
{
// activate corresponding render state
textShader.use();
textShader.setMat4("projection", projection);
textShader.setVec3("textColor", colour);
glActiveTexture(GL_TEXTURE0);
// iterate through all characters
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
Character ch = characters[*c];
float xpos = x + ch.bearing.x * scale;
float ypos = y - (ch.size.y - ch.bearing.y) * scale;
float w = ch.size.x * scale;
float h = ch.size.y * scale;
// update VBO for each character
float vertices[6][4] = {
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos, ypos, 0.0f, 1.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos, ypos + h, 0.0f, 0.0f },
{ xpos + w, ypos, 1.0f, 1.0f },
{ xpos + w, ypos + h, 1.0f, 0.0f }
};
// render glyph texture over quad
glBindTexture(GL_TEXTURE_2D, ch.textureID);
// update content of VBO memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// render quad
glDrawArrays(GL_TRIANGLES, 0, 6);
// now advance cursors for next glyph (note that advance is number of 1/64 pixels)
x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in pixels (2^6 = 64)
}
glBindTexture(GL_TEXTURE_2D, 0);
}
Here are two images, in this one I'm only rendering the text and in this one I've enabled both the 3D scene and the text, however only the 3D scene is displayed.
How can I overlay this 2D perspective over the 3D scene so they both get rendered?
You have said that rendering them (the 2D quad and 3D scene) separately works fine but rendering them together works causes the 2D quad not to render. Hmmm, try checking your rendering order of the objects; make sure you are binding and unbinding your shaders correctly.
Is there a particular reason you have disabled depth testing for the text (try enabling it and see if that fixes the problem) ?
I succesfully managed to rotate my object but I need to right click on the object to stop its rotation. I don't know how to make the object to rotate just around its center and then stop, I'll attach the code to see exactly what's happening with this shape. The problem, I think, is with the spinDisplay() function... the thing is that I need to rotate around its center on left mouse click and on the right mouse click I should change the color of the object....
#include <stdlib.h>
#include <math.h>
#include "dependente\freeglut\freeglut.h"
#include "dependente\glfw\glfw3.h"
#include <stdio.h> //incluziuni librarii
float ORG[3] = { 0,0,0 };
static GLfloat spin = 0.0;
GLfloat viewangle = 0, tippangle = 0, traj[120][3]; //variabila pentru unghi camera
GLfloat d[3] = { 0.1, 0.1, 0.1 }; //vector directie
GLfloat xAngle = 0.0, yAngle = 0.0, zAngle = 0.0;
bool draw_triangle = false; //variabila desenat figuri
bool draw_square = false;
bool draw_decagon = false;
void Triangle(void) //draw the triangle shape
{
glBegin(GL_TRIANGLE_FAN);//triangles have a common vertex, which is the central vertex
glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(0.0f, 1.0f, 0.0f); //V0(red)
glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); //V1(green)
glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); //V2(blue)
glEnd();
}
void Square(void) {
glBegin(GL_QUADS);
glVertex2f(-1.0f, 1.0f); // top left
glVertex2f(1.0f, 1.0f); // top right
glVertex2f(1.0f, -1.0f); // bottom right
glVertex2f(-1.0f, -1.0f); // bottom left
glEnd();
}
void Decagon(void) //draw the decagon shape
{
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.72f,0.8f, 0.0f); //a1
glVertex3f(0.52f, 0.8f,0.0f); //z
glVertex3f(0.35f, 0.64f, 0.0f); //b1
glVertex3f(0.3f, 0.48f, 0.0f); //d1
glVertex3f(0.35f, 0.3f, 0.0f); //e1
glVertex3f(0.52f, 0.16f, 0.0f); //l1
glVertex3f(0.72f, 0.16f, 0.0f); //m1
glVertex3f(0.9f, 0.3f, 0.0f); //o1
glVertex3f(0.95f, 0.48f, 0.0f); //p1
glVertex3f(0.9f, 0.64f, 0.0f); //c1
glScalef(10, 10, 10);
glTranslatef(1, 2, 3);
glEnd();
}
void Keyboard(unsigned char key, int x, int y) //press a key to perform actions
{
switch (key) {
case 'd': d[0] += 0.1; break; //camera right
case 'a': d[0] -= 0.1; break; //camera left
case 'w': d[1] += 0.1; break; //camera up
case 's': d[1] -= 0.1; break; //camera down
case 'm': d[2] += 0.1; break; //magnify
case 'n': d[2] -= 0.1; break; //minify
case 't': draw_triangle = true; draw_decagon = false; break; //draw pyramid when key is pressed
case 'q': draw_square = true; draw_decagon = false; draw_triangle = false; break; //draw cube when key is pressed
case 'l': draw_decagon = true; draw_triangle = false; draw_square = false; break; //draw prism when key is pressed
case 'x': xAngle += 5; break; //modify x axis angle
case 'y': yAngle += 5; break; //modify y axis angle
case 'z': zAngle += 5; break; //modify z axis angle
default: printf(" Keyboard %c == %d", key, key); //see what key it's pressed
}
glutPostRedisplay();
}
void spinDisplay() //here it's the problematic function
{
spin = spin + 0.1;
if (spin > 360.0)
{
spin = 0.0;
}
glutPostRedisplay();
}
void mouse(int buton, int state, int x, int y)
{
switch (buton) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN)
glutIdleFunc(spinDisplay);
break;
case GLUT_RIGHT_BUTTON: //here I don't know how to change the color of the shape
glutIdleFunc(NULL);
default:glutIdleFunc(NULL);
break;
}
}
void redraw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
glTranslatef(0, 0, -3);
glRotatef(tippangle, 1, 0, 0); // Up and down arrow keys 'tip' view.
glRotatef(viewangle, 0, 1, 0); // Right/left arrow keys 'turn' view.
glDisable(GL_LIGHTING);
glPushMatrix();
glTranslatef(d[0], d[1], d[2]); // Move box down X axis.
glScalef(0.7f, 0.7f, 0.7f); //increase the object size
glRotatef(zAngle, 0, 0, 1);
glRotatef(yAngle, 0, 1, 0);
glRotatef(xAngle, 1, 0, 0);
glRotatef(spin, 0.0, 0.0, 1.0);
if (draw_triangle)
Triangle();
if (draw_decagon)
Decagon();
if (draw_square)
Square();
glPopMatrix();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(900, 600);
glutInitWindowPosition(300, 300);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("Figure Rotation");
glutDisplayFunc(redraw);
glutKeyboardFunc(Keyboard);
glutMouseFunc(mouse);
glClearColor(0.1, 0.0, 0.1, 1.0);
glMatrixMode(GL_PROJECTION);//specify which matrix is the current matrix, matrix that represents your camera's lens (aperture, far-field, near-field, etc).
gluPerspective(60, 1.5, 1, 10); //set up a perspective projection matrix
glMatrixMode(GL_MODELVIEW); //specify which matrix is the current matrix,matrix that represents your camera (position, pointing, and up vector).
glutMainLoop();
return 1;
}
Solely based on your code, the main problem is at Decagon() for its shape vertices definition.
As such vertices are defined not at the center of the shape itself but defined towards the top right, thus it won't rotate around itself but seem to orbit around the center although your sequence of matrix multiplications are working ok.
For simplicity, I would visualize centering it at 0,0 along xy plane, then define right half of its shape then mirror it back to the left one. You can take advantage of - minus sign. Implicitly take advantage of defining shape in NDC (Normalizd Device Coordinate) space.
Note: not exactly the same ratio as per your original definition, but to get you an idea. You can try swapping the following into yours, then it should rotate around itself.
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.25f, 0.5f, 0.0f);
glVertex3f(0.45f, 0.30f, 0.0f);
glVertex3f(0.55f, 0.0f, 0.0f);
glVertex3f(0.45f, -0.30f, 0.0f);
glVertex3f(0.25f, -0.5f, 0.0f);
glVertex3f(-0.25f, -0.5f, 0.0f);
glVertex3f(-0.45f, -0.30f, 0.0f);
glVertex3f(-0.55f, 0.0f, 0.0f);
glVertex3f(-0.45f, 0.30f, 0.0f);
glVertex3f(-0.25f, 0.5f, 0.0f);
//glScalef(10, 10, 10); // this won't have any effect on result
//glTranslatef(1, 2, -3);// the same
glEnd();
You have 2 options here
Completely change the vertices definition (only with Decagon to be similar to above relative to the origin). Other shapes are already good, it's defined relative to the origin.
Carefully determine the origin of the shape regardless of how your defined shape's vertices. Use such position to translate back the shape as part of matrix operation firstly before all other operations (please read on to know why).
Concept of rotation around itself
The concept of rotation around itself is that we need to do the following operations in order
Scale (in this case we don't have)
Rotation
Translation
Scaling although we don't have in this case, should be last otherwise it might affect other two operations.
If we translate first to the arbitrary position, then the rotation will happen around such point. In fact, rotation works relatively to the origin 0,0, thus we just need to do by any means to place the object back to origin first before we proceed, then we can rotate, translate to desire position it should be, and scale.
Let's see your matrix multiplication order
glScalef(0.7f, 0.7f, 0.7f); //increase the object size
glTranslatef(d[0], d[1], d[2]); // Move box down X axis.
glRotatef(zAngle, 0, 0, 1);
glRotatef(yAngle, 0, 1, 0);
glRotatef(xAngle, 1, 0, 0);
glRotatef(spin, 0.0, 0.0, 1.0);
This means we do the following in order
rotate around z-axis with spin angle
rotate around x-axis with xAngle angle
rotate around y-axis with yAngle angle
rotate around z-axis with zAngle angle
Although we could possibly combine the first and last together, but anyway it's ok.
Also you might want to further look at Euler Angles when we rotate around 3 cardinal axes like this, it can lead to Gimbal lock problem but it can be solved by limiting angles user can rotate around a certain axis.
The order is right. This is translated into mathematics terms as S * T * Rz * Ry * Rx * Rspin in which you can see it's inverse of the order in code. Rspin happen first, then Rx then so on.
Now what happen if Decagon shape is defined not relative to the origin, but defined to in the way that it translated to the right.
Take my vertices definition, but + 0.55f for all x position, we will have
glBegin(GL_POLYGON);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.80f, 0.5f, 0.0f);
glVertex3f(1.0f, 0.30f, 0.0f);
glVertex3f(1.10f, 0.0f, 0.0f);
glVertex3f(1.0f, -0.30f, 0.0f);
glVertex3f(0.80f, -0.5f, 0.0f);
glVertex3f(0.30f, -0.5f, 0.0f);
glVertex3f(0.10f, -0.30f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.1f, 0.30f, 0.0f);
glVertex3f(0.30f, 0.5f, 0.0f);
glEnd();
If you swap above code to your vertices definition, then it won't rotate around itself anymore. But we know that it takes -0.55f in x-axis to bring this shape back to origin, thus if we add glTranslatef(-0.55f, 0.0f, 0.0f) to be the first operation to execute then it will work the same.
We'd have
glScalef(0.7f, 0.7f, 0.7f);
glTranslatef(d[0], d[1], d[2]);
glRotatef(zAngle, 0, 0, 1);
glRotatef(yAngle, 0, 1, 0);
glRotatef(xAngle, 1, 0, 0);
glRotatef(spin, 0.0, 0.0, 1.0);
glTranslatef(-0.55f, 0.0f, 0.0f); // <------ add this
In short, translate target object to be at origin first before rotating (around itself), then proceed proper sequence as before.
If you desire to have such object to be located at the location you've defined the shape's vertices i.e. it's to the right +0.55f along x-axis and still rotate around itself. Then you use glTranslatef(d[0] + 0.55f, d[1], d[2]) instead.
Further Notes
The last two gl operations glScalef() and glTranslatef() won't have any effect as you already drew the shape. These two operations get discarded every frame when you call glLoadIdentity().
Just note that source code is still based on fixed-function pipeline of OpenGL. You might want to also take a look at modern programmable pipeline. This will allows you more flexibility in controlling virtual camera thus matrix operations are more clear cut and separated to the object itself whenever we need to move around. So this will make matrix operations easier to grasp, and to understand.
Edit
For additional control and satisfy application requirement as follows
Left click to rotate indefinitely, then left click again to stop
Right click to cycle through the color for rendered shape
We have to have control flags, and information for us to change at any frame time as follows.
bool isSpinning = false;
#define NUM_COLOR 4
int sCurrColor = 0;
GLfloat sColor[NUM_COLOR][3] = {
{1.0f, 1.0f, 1.0f},
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f}
};
So for colors, we have white, red, blue, and green. Total in 4 colors, each color has 3 component values for RGB. We start with white color as seen in sCurrColor for our index.
Now your mouse() function would looks like this
void mouse(int buton, int state, int x, int y)
{
switch (buton) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN && !isSpinning)
isSpinning = true;
else if (state == GLUT_DOWN && isSpinning)
isSpinning = false;
break;
case GLUT_RIGHT_BUTTON: //here I don't know how to change the color of the shape
if (state == GLUT_DOWN)
sCurrColor = (sCurrColor + 1) % NUM_COLOR;
break;
default:glutIdleFunc(NULL);
break;
}
}
We optimized moving glutIdleFunc(spinDisplay); to be called inside main() function just before glutMainLoop(). As your requirements, we don't have to change it every frame.
Thus, spinDisplay() is now changed to be
void spinDisplay() //here it's the problematic function
{
if (isSpinning)
{
spin = spin + 3.0;
if (spin > 360.0)
{
spin = 0.0;
}
}
glutPostRedisplay();
}
Probably better to change the name of function to something like display() as it's more generic to not confuse that we have to spin everytime. Anyway, I didn't change this for the sake of brevity and consistency of your code.
Now the last part is to plug in sColor to be used by all those shapes in rendering. For example for Decagon you can do this
glColor3f(sColor[sCurrColor][0], sColor[sCurrColor][1], sColor[sCurrColor][2]);
This will be the same for other shapes if you like to have the same effect by right clicking to cycle through the color.
I'm doing something with DirectX 11 and came to a rectagle drawing (empty, non-colored), seemed simple for me at start (linelist_topology, 8 indices) but when I have it on the screen I see that my rectangle is kinda incomleted at left-top coordinate, there is a point of a background color there, the code is not complicated at all, vertices are 2D space:
SIMPLEVERTEX gvFrameVertices[4]=
{XMFLOAT3(0.0f,0.0f,1.0f),XMFLOAT2(0.0f, 0.0f),
XMFLOAT3(1.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f),
XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f),
XMFLOAT3(0.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f)};
indices:
WORD gvRectangularIndices[8] = { 0, 1, 1, 2, 2, 3, 3, 0 };
Shader just returns given color in constant buffer:
float4 PS_PANEL(PS_INPUT input) : SV_Target
{
return fontcolor;
}
Function code itself:
VOID rectangle(INT _left, INT _top, INT _width, INT _height, XMFLOAT4 _color)
{
XMMATRIX scale;
XMMATRIX translate;
XMMATRIX world;
scale = XMMatrixScaling( _width, _height, 1.0f );
translate = XMMatrixTranslation(_left, gvHeight - _top, 1.0f);
world = scale * translate;
gvConstantBufferData.world = XMMatrixTranspose(world);
gvConstantBufferData.index = 1.0f;
gvConstantBufferData.color = _color;
gvContext->PSSetShader(gvPanelPixelshader, NULL, 0);
gvContext->UpdateSubresource(gvConstantBuffer, 0, NULL, &gvConstantBufferData, 0, 0 );
gvContext->IASetIndexBuffer(gvLinelistIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
gvContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST );
gvContext->DrawIndexed(8, 0, 0);
gvContext->IASetIndexBuffer(gvTriangleslistIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
gvContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
};
gvHeight - _top - I'm using orthographic matrix for projection, so the coordinate center is at left-bottom, that why need to substract for proper Y coordinate.
gvOrthographicProjection = XMMatrixOrthographicOffCenterLH( 0.0f, gvWidth, 0.0f, gvHeight, 0.01f, 100.0f );
Do you have any idea what can cause this pointal incompletness of a rectangle in my case or I need to supply more code info (don't really want to link lines of the whole initializations cause they seem very obvious and simple for me, done for /at c++ and directx amateur level :)
Thank you:)
This is a simple program that draws a 3d cube with a texture. The problem is I can not see the texture because the lights are not working.I have turned off the lights just to make sure the texture is there and it is.So if any one can help me figure out why the lights are not working I would greatly appreciate it.
#include "DirectXGame.h"
DirectXGame::DirectXGame(void)
{
//init to zero good pratice
m_pD3DObject=0;
m_pD3DDevice=0;
m_currTime=0;
m_prevTime=0;
ZeroMemory(&m_D3Dpp,sizeof(m_D3Dpp));
FOV=D3DXToRadian(65.0f);
aspectRatio=800/600;
nearPlane=1.0f;
farPlane=1000.0f;
}
DirectXGame::~DirectXGame(void)
{
}
//create class for input
DirectXInput DXClass;
void DirectXGame::Initialize(HWND hWnd ,HINSTANCE hInst,bool bWindowed) // create the material struct)//
{
// grab the window width and height fronm the HWND
RECT r;
GetWindowRect(hWnd, &r);
m_nWidth = r.right - r.left;
m_nHeight = r.bottom - r.top;
m_bVSync = false;
// Create the D3D Object
m_pD3DObject = Direct3DCreate9(D3D_SDK_VERSION);
// Create our presentation parameters for our D3D Device
m_D3Dpp.hDeviceWindow = hWnd; // Handle to the window
m_D3Dpp.Windowed = bWindowed; // Windowed or Full-screen?
m_D3Dpp.BackBufferCount = 1; // Number of back-buffers
m_D3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // Back-buffer pixel format
m_D3Dpp.BackBufferWidth = m_nWidth; // Back-buffer width
m_D3Dpp.BackBufferHeight = m_nHeight; // Back-buffer height
m_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Swap effectm_bVSync ? D3DPRESENT_INTERVAL_DEFAULT :
m_D3Dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
m_D3Dpp.FullScreen_RefreshRateInHz = bWindowed ? 0 : D3DPRESENT_RATE_DEFAULT;
m_D3Dpp.EnableAutoDepthStencil = TRUE; // Enable depth and stencil buffer
m_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // Depth/Stencil buffer bit format
m_D3Dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; // Discard the depth/stencil buffer upon Present()
m_D3Dpp.MultiSampleQuality = 0; // MSAA quality
m_D3Dpp.MultiSampleType = D3DMULTISAMPLE_NONE; // MSAA type
// Check the device's capabilities
DWORD deviceBehaviorFlags = 0;
m_pD3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_D3DCaps);
// Determine vertex processing mode
if(m_D3DCaps.DevCaps & D3DCREATE_HARDWARE_VERTEXPROCESSING)
{
deviceBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
deviceBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
// if hardware vertex processing is on, check for pure
if(m_D3DCaps.DevCaps & D3DCREATE_PUREDEVICE && deviceBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING)
{
deviceBehaviorFlags |= D3DCREATE_PUREDEVICE;
}
// Create D3D Device
m_pD3DObject->CreateDevice(
D3DADAPTER_DEFAULT, // Default display adapter
D3DDEVTYPE_HAL, // Device type to use
hWnd, // Handle to our window
deviceBehaviorFlags, // D3DCREATE_HARDWARE_VERTEXPROCESSINGVertex Processing Behavior Flags (PUREDEVICE, HARDWARE_VERTEXPROCESSING, SOFTWARE_VERTEXPROCESSING)
&m_D3Dpp, // Presentation parameters
&m_pD3DDevice); // Return a created D3D Device
//=================================================================//
// Create/Load Sprite & Font D3D and COM objects
//Create font
D3DXCreateFont(m_pD3DDevice, 23, 0, FW_BOLD, 0, true,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"),
&m_pD3DFont);
//for font 1 "Name"
RECT rct;
rct.left=2;
rct.right=780;
rct.top=10;
rct.bottom=rct.top+20;
//MATRIX
eyePos.x = 0;
eyePos.y = 2;
eyePos.z = -10;
lookAt.x = 0;
lookAt.y = 0;
lookAt.z = 0;
upVec.x = 0;
upVec.y = 1;
upVec.z = 0;
D3DXMatrixLookAtLH( &view_Matrix, &eyePos, &lookAt, &upVec);
m_pD3DDevice->SetTransform( D3DTS_VIEW, &view_Matrix);
// projection matrix
D3DXMatrixPerspectiveFovLH( &pro_Matrix, FOV, aspectRatio, nearPlane, farPlane);
m_pD3DDevice->SetTransform( D3DTS_PROJECTION, &pro_Matrix);
// MATRIX: VertexElement Declaration
D3DVERTEXELEMENT9 declaration[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END()
};
//LPDIRECT3DVERTEXDECLARATION9 m_pVtxDeclObject;
// Create vertex declaration
m_pD3DDevice->CreateVertexDeclaration(declaration,&vertDec);
///---CUBE: Vertex and Indicies :START---///
// Load vertex info, listed per cube face quads
// Front
m_cubeVerts[0].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
m_cubeVerts[1].position = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
m_cubeVerts[2].position = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
m_cubeVerts[3].position = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
D3DXVec3Normalize(&m_cubeVerts[0].normal, &D3DXVECTOR3(0.0f, 0.0f, -1.0f));
D3DXVec3Normalize(&m_cubeVerts[1].normal, &D3DXVECTOR3(0.0f, 0.0f, -1.0f));
D3DXVec3Normalize(&m_cubeVerts[2].normal, &D3DXVECTOR3(0.0f, 0.0f, -1.0f));
D3DXVec3Normalize(&m_cubeVerts[3].normal, &D3DXVECTOR3(0.0f, 0.0f, -1.0f));
m_cubeVerts[0].uv = D3DXVECTOR2(0.0f, 1.0f);
m_cubeVerts[1].uv = D3DXVECTOR2(0.0f, 0.0f);
m_cubeVerts[2].uv = D3DXVECTOR2(1.0f, 0.0f);
m_cubeVerts[3].uv = D3DXVECTOR2(1.0f, 1.0f);
// Back
m_cubeVerts[4].position = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
m_cubeVerts[5].position = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
m_cubeVerts[6].position = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
m_cubeVerts[7].position = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
D3DXVec3Normalize(&m_cubeVerts[4].normal, &D3DXVECTOR3(0.0f, 0.0f, 1.0f));
D3DXVec3Normalize(&m_cubeVerts[5].normal, &D3DXVECTOR3(0.0f, 0.0f, 1.0f));
D3DXVec3Normalize(&m_cubeVerts[6].normal, &D3DXVECTOR3(0.0f, 0.0f, 1.0f));
D3DXVec3Normalize(&m_cubeVerts[7].normal, &D3DXVECTOR3(0.0f, 0.0f, 1.0f));
m_cubeVerts[4].uv = D3DXVECTOR2(1.0f, 1.0f);
m_cubeVerts[5].uv = D3DXVECTOR2(0.0f, 1.0f);
m_cubeVerts[6].uv = D3DXVECTOR2(0.0f, 0.0f);
m_cubeVerts[7].uv = D3DXVECTOR2(1.0f, 0.0f);
// Top
m_cubeVerts[8].position = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
m_cubeVerts[9].position = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
m_cubeVerts[10].position = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
m_cubeVerts[11].position = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
D3DXVec3Normalize(&m_cubeVerts[8].normal, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[9].normal, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[10].normal, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[11].normal, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
m_cubeVerts[8].uv = D3DXVECTOR2(0.0f, 1.0f);
m_cubeVerts[9].uv = D3DXVECTOR2(0.0f, 0.0f);
m_cubeVerts[10].uv = D3DXVECTOR2(1.0f, 0.0f);
m_cubeVerts[11].uv = D3DXVECTOR2(1.0f, 1.0f);
// Bottom
m_cubeVerts[12].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
m_cubeVerts[13].position = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
m_cubeVerts[14].position = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
m_cubeVerts[15].position = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
D3DXVec3Normalize(&m_cubeVerts[12].normal, &D3DXVECTOR3(0.0f, -1.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[13].normal, &D3DXVECTOR3(0.0f, -1.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[14].normal, &D3DXVECTOR3(0.0f, -1.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[15].normal, &D3DXVECTOR3(0.0f, -1.0f, 0.0f));
m_cubeVerts[12].uv = D3DXVECTOR2(1.0f, 1.0f);
m_cubeVerts[13].uv = D3DXVECTOR2(0.0f, 1.0f);
m_cubeVerts[14].uv = D3DXVECTOR2(0.0f, 0.0f);
m_cubeVerts[15].uv = D3DXVECTOR2(1.0f, 0.0f);
// Left
m_cubeVerts[16].position = D3DXVECTOR3(-1.0f, -1.0f, 1.0f);
m_cubeVerts[17].position = D3DXVECTOR3(-1.0f, 1.0f, 1.0f);
m_cubeVerts[18].position = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);
m_cubeVerts[19].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
D3DXVec3Normalize(&m_cubeVerts[16].normal, &D3DXVECTOR3(-1.0f, 0.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[17].normal, &D3DXVECTOR3(-1.0f, 0.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[18].normal, &D3DXVECTOR3(-1.0f, 0.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[19].normal, &D3DXVECTOR3(-1.0f, 0.0f, 0.0f));
m_cubeVerts[16].uv = D3DXVECTOR2(0.0f, 1.0f);
m_cubeVerts[17].uv = D3DXVECTOR2(0.0f, 0.0f);
m_cubeVerts[18].uv = D3DXVECTOR2(1.0f, 0.0f);
m_cubeVerts[19].uv = D3DXVECTOR2(1.0f, 1.0f);
// Right
m_cubeVerts[20].position = D3DXVECTOR3(1.0f, -1.0f, -1.0f);
m_cubeVerts[21].position = D3DXVECTOR3(1.0f, 1.0f, -1.0f);
m_cubeVerts[22].position = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
m_cubeVerts[23].position = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
D3DXVec3Normalize(&m_cubeVerts[20].normal, &D3DXVECTOR3(1.0f, 0.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[21].normal, &D3DXVECTOR3(1.0f, 0.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[22].normal, &D3DXVECTOR3(1.0f, 0.0f, 0.0f));
D3DXVec3Normalize(&m_cubeVerts[23].normal, &D3DXVECTOR3(1.0f, 0.0f, 0.0f));
m_cubeVerts[20].uv = D3DXVECTOR2(0.0f, 1.0f);
m_cubeVerts[21].uv = D3DXVECTOR2(0.0f, 0.0f);
m_cubeVerts[22].uv = D3DXVECTOR2(1.0f, 0.0f);
m_cubeVerts[23].uv = D3DXVECTOR2(1.0f, 1.0f);
// Load index info, refers into index into verts array to compose triangles
// Note: A clockwise winding order of verts will show the front face.
// Front
m_cubeIndices[0] = 0; m_cubeIndices[1] = 1; m_cubeIndices[2] = 2; // Triangle 0
m_cubeIndices[3] = 0; m_cubeIndices[4] = 2; m_cubeIndices[5] = 3; // Triangle 1
// Back
m_cubeIndices[6] = 4; m_cubeIndices[7] = 5; m_cubeIndices[8] = 6; // Triangle 2
m_cubeIndices[9] = 4; m_cubeIndices[10] = 6; m_cubeIndices[11] = 7; // Triangle 3
// Top
m_cubeIndices[12] = 8; m_cubeIndices[13] = 9; m_cubeIndices[14] = 10; // Triangle 4
m_cubeIndices[15] = 8; m_cubeIndices[16] = 10; m_cubeIndices[17] = 11; // Triangle 5
// Bottom
m_cubeIndices[18] = 12; m_cubeIndices[19] = 13; m_cubeIndices[20] = 14; // Triangle 6
m_cubeIndices[21] = 12; m_cubeIndices[22] = 14; m_cubeIndices[23] = 15; // Triangle 7
// Left
m_cubeIndices[24] = 16; m_cubeIndices[25] = 17; m_cubeIndices[26] = 18; // Triangle 8
m_cubeIndices[27] = 16; m_cubeIndices[28] = 18; m_cubeIndices[29] = 19; // Triangle 9
// Right
m_cubeIndices[30] = 20; m_cubeIndices[31] = 21; m_cubeIndices[32] = 22; // Triangle 10
m_cubeIndices[33] = 20; m_cubeIndices[34] = 22; m_cubeIndices[35] = 23; // Triangle 11
///---CUBE: Vertex and Indicies :END---///
//create buffers
// create a vertex buffer interface called i_buffer
m_pD3DDevice->CreateVertexBuffer(4*6*sizeof(Vertex),
D3DUSAGE_WRITEONLY,
0,
D3DPOOL_MANAGED,
&VB,
NULL);
void* pVertices;
// lock VB and load the vertices into it
VB->Lock(0, 0,&pVertices, 0);
// send array
memcpy(pVertices, m_cubeVerts, 4*6*sizeof(Vertex));
//unlock
VB->Unlock();
///////////////////////////////////////////////////
m_pD3DDevice->CreateIndexBuffer(3*12*sizeof(WORD), // 3 and 12
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&IB,
NULL);
void* pIndices;
// lock index
IB->Lock(0,0,&pIndices,0);
//send array of indices to vram
memcpy(pIndices, m_cubeIndices, 3*12*sizeof(WORD));
//unlock index
IB->Unlock();
D3DLIGHT9 light;
D3DMATERIAL9 m_Mat;
ZeroMemory(&light, sizeof(light));
// clear out the light struct for use
light.Type = D3DLIGHT_POINT;
// make the light type 'directional light'
light.Diffuse.r = 0.5f;
light.Diffuse.g = 0.5f;
light.Diffuse.b = 0.5f;
light.Diffuse.a = 1.0f;
light.Ambient.r = 0.2f;
light.Ambient.g = 0.2f;
light.Ambient.b = 1.0f;
light.Specular.r = 1.0f;
light.Specular.g = 1.0f;
light.Specular.b = 1.0f;
// set the lighting position
light.Position.x = 30;
light.Position.y = 10;
light.Position.z = -10;
light.Range = 900.0f;
light.Attenuation0 = 0.0f;
light.Attenuation1 = 0.125f;
light.Attenuation2 = 0.0f;
m_pD3DDevice->SetLight(0, &light);
// send the light struct properties to light #0
m_pD3DDevice->LightEnable(0, TRUE);
// turn on light #0
ZeroMemory(&m_Mat, sizeof(m_Mat));
// clear out the struct for use
m_Mat.Diffuse.r = 1.0f;
m_Mat.Diffuse.g = 0.0f;
m_Mat.Diffuse.b = 0.0f;
m_Mat.Diffuse.a = 0.0f;
// set diffuse color to white
m_Mat.Ambient.r = 0.2f;
m_Mat.Ambient.g = 0.2f;
m_Mat.Ambient.b = 0.2f;
m_Mat.Ambient.a = 1.0f;
// set ambient color to white
m_Mat.Specular.r = 1.0f;
m_Mat.Specular.g =1.0f;
m_Mat.Specular.b =1.0f;
m_Mat.Specular.a =1.0f;
m_Mat.Power = 100.0f;
m_pD3DDevice->SetMaterial(&m_Mat);
// Create a texture using the with "test.tga" from the sprite labs.
//Apply tri-linear filtering to the texture, by modifying the sampler states by calling the device's SetSamplerState().
D3DXCreateTextureFromFile(m_pD3DDevice, L"test.png",&m_Texture);
//Apply tri-linear filtering to the texture, by modifying the sampler states by calling the device's SetSamplerState().
m_pD3DDevice->SetSamplerState( 0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pD3DDevice->SetSamplerState( 0,D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
m_pD3DDevice->SetSamplerState( 0,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
}
void DirectXGame::Update(HWND hWnd, bool& bWindowed, double dt)
{
}
void DirectXGame::Render()
{
// if our d3d device was not craeted return
if(!m_pD3DDevice)
return;
m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(100,149,237), 1, 0); // 100,149,237 00255
// Begin the scene
if( SUCCEEDED( m_pD3DDevice->BeginScene() ) )
{
m_pD3DDevice->SetVertexDeclaration( vertDec);
//set cube postion
D3DXMATRIX translation, rotation, scale, world, position;
float index = 0.0f; index+=0.05f;
D3DXMatrixTranslation(&translation,0,0,0);
D3DXMatrixRotationY(&rotation, timeGetTime()/1000);
D3DXMatrixScaling(&scale,1,1, 1.0f);
world = scale*rotation*translation;
m_pD3DDevice->SetTransform(D3DTS_WORLD, &world);
// select the vertex and index buffers to use
m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
m_pD3DDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
m_pD3DDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(60,60,60));
m_pD3DDevice->SetStreamSource(0, VB, 0, sizeof(Vertex));
m_pD3DDevice->SetIndices(IB);
m_pD3DDevice->SetMaterial(&m_Mat);
m_pD3DDevice->SetTexture( 0,m_Texture);
m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,//D3DPRIMITIVETYPE Type
0,/*BaseVertexIndex*/
0, //* MinIndex*/
24, /*NumVertices*/
0, /*StartIndex*/
12);//PrimitiveCount
///////////////////////////////////////////////////////////////////////////
//Font 1 "Name"
RECT rct;
rct.bottom = m_nHeight;
rct.top=2;
rct.left=658;
rct.right=m_nWidth;
//for the font2 FPS
RECT rect;
rect.bottom = m_nHeight;
rect.top =2;
rect.left = 10;
rect.right = m_nWidth;
wchar_t buffer[64];
swprintf_s(buffer, 64,L"Frames Per Second: %d", m_FPS);
m_pD3DFont->DrawText(0, buffer, -1, &rect, DT_TOP | DT_NOCLIP, D3DCOLOR_ARGB(255,255,255,255));
// Create a colour for the text ( blue)
D3DCOLOR fontColor = D3DCOLOR_ARGB(255,0,0,255);
//draw the text
m_pD3DFont->DrawText(NULL, L"Mariana Serrato", -1, &rct, 0, fontColor ); // move test to far right
// End the scene
m_pD3DDevice->EndScene();
// present the back buffer to the screen
m_pD3DDevice->Present(NULL, NULL, NULL, NULL);
//calculate Frames Per Second
m_currTime = timeGetTime();
static int fspCounter = 0;
if(m_currTime - m_prevTime >= 1000.0f)
{
m_prevTime = m_currTime;
m_FPS = fspCounter;
fspCounter =0;
} else {
++fspCounter;
}
}
}
void DirectXGame::Shutdown()
{
SAFE_RELEASE(VB);
SAFE_RELEASE(IB);
SAFE_RELEASE(vertDec);
SAFE_RELEASE(m_pD3DFont);
SAFE_RELEASE(m_Texture);
SAFE_RELEASE(m_Sprite);
SAFE_RELEASE(m_pD3DDevice);
SAFE_RELEASE(m_pD3DObject);
}
//////////////////////////////////////////////////////////////////////////////////////////
.h header file
pragma once
include // for random nums
include
include
include
include
include
include "DirectXInput.h"
include
include
pragma comment (lib, "d3d9.lib")
pragma comment (lib, "d3dx9.lib")
pragma comment(lib, "winmm.lib")//for timeGetTime()
pragma comment(lib, "dinput8.lib")
pragma comment(lib, "dxguid.lib")
// Macro to Safely release com obejcts
define SAFE_RELEASE(x) if(x) {x->Release(); x = 0;}
// Direct Input version
define DIRECTINPUT_VERSION 0x0800
// Define window size
define SCREEN_WIDTH 800
define SCREEN_HEIGHT 600
//#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
class DirectXGame
{
struct Vertex
{
D3DXVECTOR3 position;
D3DXVECTOR3 normal;
D3DXVECTOR2 uv;
};
IDirect3D9* m_pD3DObject;
IDirect3DDevice9* m_pD3DDevice;
D3DPRESENT_PARAMETERS m_D3Dpp;
ID3DXFont* m_pD3DFont; //Font
LPDIRECT3DTEXTURE9 m_Texture;
ID3DXSprite* m_Sprite;//Sprite
D3DXVECTOR3 texCenter,eyePos,lookAt,upVec;
D3DCAPS9 m_D3DCaps; //D3D Device Caps
D3DLIGHT9 m_Light;
D3DMATERIAL9 m_Mat;
D3DVERTEXELEMENT9 m_Element;
D3DXMATRIX view_Matrix, pro_Matrix;
// cube
Vertex m_cubeVerts[24];
WORD m_cubeIndices[36];
IDirect3DVertexBuffer9* VB;
IDirect3DIndexBuffer9* IB;
IDirect3DVertexDeclaration9* vertDec;
bool m_bVSync;
char buffer [256];
int m_nWidth, m_nHeight;
int m_FPS,alfa[5],mFPS,mMilliSecPerFrame;
float m_currTime,m_prevTime,FOV, aspectRatio, nearPlane, farPlane;
DWORD D3DUSASE_DYNAMIC,D3DUSASE_WRITEONLY;
public:
DirectXGame(void);
~DirectXGame(void);
void Initialize(HWND hWnd,HINSTANCE hInst, bool bWindowed);
bool isDeviceLost();
void Update(HWND hWnd, bool& bWindowed, double dt);
void Render();
void CheckPosition();
void Shutdown();
};
You haven't enabled D3DRS_LIGHTING.
m_pD3DDevice->setRenderState(D3DRS_LIGHTING, TRUE);
So I have begun learning OpenGL, reading from the book "OpenGL Super Bible 5 ed.". It's explains things really well, and I have been able to create my first gl program myself! Just something simple, a rotating 3d pyramid.
Now for some reason one of the faces are not rendering. I checked the vertecies (plotted it on paper first) and it seemed to be right. Found out if I changed the shader to draw a line loop, it would render. However it would not render a triangle. Can anyone explain why?
void setupRC()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
shaderManager.InitializeStockShaders();
M3DVector3f vVerts1[] = {-0.5f,0.0f,-0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,-0.5f};
M3DVector3f vVerts2[] = {-0.5f,0.0f,-0.5f,0.0f,0.5f,0.0f,-0.5f,0.0f,0.5f};
M3DVector3f vVerts3[] = {-0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,0.5f};
M3DVector3f vVerts4[] = {0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,0.5f,0.0f,-0.5f};
triangleBatch1.Begin(GL_LINE_LOOP, 3);
triangleBatch1.CopyVertexData3f(vVerts1);
triangleBatch1.End();
triangleBatch2.Begin(GL_TRIANGLES, 3);
triangleBatch2.CopyVertexData3f(vVerts2);
triangleBatch2.End();
triangleBatch3.Begin(GL_TRIANGLES, 3);
triangleBatch3.CopyVertexData3f(vVerts3);
triangleBatch3.End();
triangleBatch4.Begin(GL_TRIANGLES, 3);
triangleBatch4.CopyVertexData3f(vVerts4);
triangleBatch4.End();
glEnable(GL_CULL_FACE);
}
float rot = 1;
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
GLfloat vRed[] = {1.0f, 0.0f, 0.0f, 0.5f};
GLfloat vBlue[] = {0.0f, 1.0f, 0.0f, 0.5f};
GLfloat vGreen[] = {0.0f, 0.0f, 1.0f, 0.5f};
GLfloat vWhite[] = {1.0f, 1.0f, 1.0f, 0.5f};
M3DMatrix44f transformMatrix;
if (rot >= 360)
rot = 0;
else
rot = rot + 1;
m3dRotationMatrix44(transformMatrix,m3dDegToRad(rot),0.0f,1.0f,0.0f);
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vRed);
triangleBatch1.Draw();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vBlue);
triangleBatch2.Draw();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vGreen);
triangleBatch3.Draw();
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformMatrix, vWhite);
triangleBatch4.Draw();
glutSwapBuffers();
glutPostRedisplay();
Sleep(10);
}
You've most likely defined the vertices in clockwise order for the triangle that isn't showing, and in counterclockwise order (normally the default) for those that are. Clockwise winding essentially creates an inward facing normal and thus OpenGL won't bother to render it when culling is enabled.
The easiest way to check this is to set glCullFace(GL_FRONT)--that should toggle it so you see the missing triangle and no longer see the other three.
The only thing I see that affects polygons here is glEnable(GL_CULL_FACE);.
You shouldn't have that, because if you plot your vertices backwards, the polygon won't render.
Remove it or actually call glDisable(GL_CULL_FACE); to be sure.
In your case, it's not likely that you want to draw a polygon that you can see from one side only.