Integer literals in C++ are of type (signed) int. If int is 32 bits on your platform then the maximum value is 2^31 = 2147483648. 8000000000 and 9000000000 are going to overflow. Why it still prints it fine, I don't know. Maybe the compiler silently fixes this and this is not the cause at all.
You can specify that you want a long integer literal by appending L (or l), so 8000000000L and 9000000000L. More specifically you could also use UL or uL (or Ul, ...) for an unsigned long.
Assuming this is the cause, try ramping up the compiler warning settings. I'm pretty sure MSVC can warn about this. Even if not, warnings in general are useful.
[editline]9th January 2014[/editline]
Note a long is not guaranteed 64 bits, only 32 bits (minimum though). In C++11 you also have a long long, that is guaranteed to be at least 64 bits.
MSVC might have a special suffix for __int64 literal constants though.
I want to code a simple assembly compiler for a VM, how do I go about reference resolving? Is it a table? How do I optimize 16bit/32bit addresses (LI will only do 16bit, then I need to shift & ORI for a 32bit value)?
Anything on the matter would help.
Reference resolving? You mean labels and named constants? Sure, a table works fine.
Also, what do you mean by optimize 16bit/32bit addresses? You example sounds like you're trying to process a 32-bit value with a 16-bit processor. I don't think assemblers generally deal with that, instead the programmer is expected to solve this issue.
Is there any way I can limit a LookAt matrix so that it never looks directly Up/Down? Assuming I have the position, the lookat and the up vectors
[CODE] public static void main(String[] args) {
String word = getPlayerOnesWord();
int wordLength = word.length();
boolean gameFinished = false;
int incorrectGuesses = 0;
String matchWord = null;
boolean[] hiddenWord = new boolean[wordLength];
String[] correctGuesses = new String[wordLength];
for (int k = 0; k < correctGuesses.length; k++) {
correctGuesses[k] = "-";
}[/CODE]
[CODE]int pos = word.indexOf(matchWord);
if (word.contains(matchWord)) {
hiddenWord[pos] = true;
}
for (int j = pos; j < correctGuesses.length; j++) {
for (int i = pos; i < hiddenWord.length; i++) {
if (hiddenWord[i] == true) {
correctGuesses[j] = matchWord;
} else {
}
}
break;[/CODE]
The full code: [url]http://pastebin.com/Zmk0HMhF[/url]
So I came back to finish my hangman program finally after the busy holiday. My issue right now is filling the array with the same letter twice.
I can get a full word! As long as the word doesn't have any repeating letters... How do I have it fill the array twice with two of the same letters in different positions?
For example - the word is beer
What is expected if I type in 'e':
-ee-
What my program does when I type in e:
-e--
[QUOTE=Richy19;43477822]Is there any way I can limit a LookAt matrix so that it never looks directly Up/Down? Assuming I have the position, the lookat and the up vectors[/QUOTE]
Yes, you can dot the look at direction (lookat - position, assuming lookat is a position and not a direction already) and up vector. Make sure they're both normalized. This will give you a cosine between -1 and 1. If you want to limit it to a specific degrees you're going to need to convert it. Otherwise just check if it's close to 1 or -1.
[QUOTE=blacksam;43478939][CODE] public static void main(String[] args) {
String word = getPlayerOnesWord();
int wordLength = word.length();
boolean gameFinished = false;
int incorrectGuesses = 0;
String matchWord = null;
boolean[] hiddenWord = new boolean[wordLength];
String[] correctGuesses = new String[wordLength];
for (int k = 0; k < correctGuesses.length; k++) {
correctGuesses[k] = "-";
}[/CODE]
[CODE]int pos = word.indexOf(matchWord);
if (word.contains(matchWord)) {
hiddenWord[pos] = true;
}
for (int j = pos; j < correctGuesses.length; j++) {
for (int i = pos; i < hiddenWord.length; i++) {
if (hiddenWord[i] == true) {
correctGuesses[j] = matchWord;
} else {
}
}
break;[/CODE]
The full code: [url]http://pastebin.com/Zmk0HMhF[/url]
So I came back to finish my hangman program finally after the busy holiday. My issue right now is filling the array with the same letter twice.
I can get a full word! As long as the word doesn't have any repeating letters... How do I have it fill the array twice with two of the same letters in different positions?
For example - the word is beer
What is expected if I type in 'e':
-ee-
What my program does when I type in e:
-e--[/QUOTE]
You are overcomplicating things. Don't use indexOf() and contains(). Instead, just have one single for loop over the word length, check each position for the guessed character and if it matches, insert it in the solution at the same position.
[QUOTE=P1raten;43478582][CODE] if (!isGrounded)
{
Time elapsed = frameClock.getElapsedTime();
double d_velocity = velocity.y;
float tempJump = jumpSpeed * elapsed.asSeconds();
jumpPosition = jumpPosition + elapsed.asSeconds() * (d_velocity + tempJump / 2) * 2;
velocity.y = d_velocity + tempJump * 1.2;
if (m_grounded.y <= mSprite.getPosition().y)
isGrounded = true;
}[/CODE]
Silly, character. Why wont you jump? :(
[IMG]http://i.imgur.com/I7siA2P.gif[/IMG][/QUOTE]
Think my question got buried or some shit, so quoting it.
Can anyone with a good GPU tell me how much FPS they get on this (Using Fraps or something): [URL="http://www.mediafire.com/download/aa7gau1pddr2pqi/TEST.exe"]TEST.exe[/URL]
[QUOTE=HiredK;43505860]Can anyone with a good GPU tell me how much FPS they get on this (Using Fraps or something): [URL="http://www.mediafire.com/download/aa7gau1pddr2pqi/TEST.exe"]TEST.exe[/URL][/QUOTE]
It killed my graphics driver, i'm on HP ProBook 4535s.
[QUOTE=cartman300;43506037]It killed my graphics driver, i'm on HP ProBook 4535s.[/QUOTE]
Ahah I can't seem to get VBO batching working properly :v:
[QUOTE=HiredK;43505860]Can anyone with a good GPU tell me how much FPS they get on this (Using Fraps or something): [URL="http://www.mediafire.com/download/aa7gau1pddr2pqi/TEST.exe"]TEST.exe[/URL][/QUOTE]
It's not that I don't trust you, it's just that as a general rule of thumb I don't download and run random executables off the internet. Source or something would be nice. :)
[QUOTE=Chris220;43506238]It's not that I don't trust you, it's just that as a general rule of thumb I don't download and run random executables off the internet. Source or something would be nice. :)[/QUOTE]
It's just a modified version of an Overv tutorial:
[code]// Link statically with SFML
#define SFML_STATIC
// Link statically with GLEW
#define GLEW_STATIC
// Headers
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <iostream>
const int TEST = 100000;
// Shader sources
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec3 color;"
"out vec3 Color;"
"void main() {"
" Color = color;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec3 Color;"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(Color, 1.0);"
"}";
int main()
{
sf::Window window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close);
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
/*GLfloat vertices[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};*/
std::vector<float> vertices;
for(unsigned int i=0; i<TEST; i++) {
vertices.push_back(-0.5f); vertices.push_back( 0.5f); vertices.push_back( 1.0f); vertices.push_back( 0.0f); vertices.push_back( 0.0f);
vertices.push_back( 0.5f); vertices.push_back( 0.5f); vertices.push_back( 0.0f); vertices.push_back( 1.0f); vertices.push_back( 0.0f);
vertices.push_back( 0.5f); vertices.push_back(-0.5f); vertices.push_back( 0.0f); vertices.push_back( 0.0f); vertices.push_back( 1.0f);
vertices.push_back(-0.5f); vertices.push_back(-0.5f); vertices.push_back( 1.0f); vertices.push_back( 1.0f); vertices.push_back( 1.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
vertices.clear();
// Create an element array
GLuint ebo;
glGenBuffers(1, &ebo);
/*GLuint elements[] = {
0, 1, 2,
2, 3, 0
};*/
std::vector<GLuint> elements;
for(unsigned int i=0; i<TEST; i++) {
elements.push_back(0); elements.push_back(1); elements.push_back(2);
elements.push_back(2); elements.push_back(3); elements.push_back(0);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(GLuint), &elements[0], GL_STATIC_DRAW);
elements.clear();
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
while (window.isOpen())
{
sf::Event windowEvent;
while (window.pollEvent(windowEvent))
{
switch (windowEvent.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6 * TEST, GL_UNSIGNED_INT, 0);
/*for(unsigned int i=0; i<TEST; i++) {
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}*/
// Swap buffers
window.display();
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}[/code]
Made my computer nearly freeze :v:
[editline]11th January 2014[/editline]
You might want to check your TEST value (100000) and how you're using it in this line:
[CODE]glDrawElements(GL_TRIANGLES, 6 * TEST, GL_UNSIGNED_INT, 0);[/CODE]
[QUOTE=Bumrang;43506524]Made my computer nearly freeze :v:
[editline]11th January 2014[/editline]
You might want to check your TEST value (100000) and how you're using it in this line:
[CODE]glDrawElements(GL_TRIANGLES, 6 * TEST, GL_UNSIGNED_INT, 0);[/CODE][/QUOTE]
I'm really just looking for a way to draw as much polygons as possible using a single VBO, I changed the line to:
[code]glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);[/code]
But I still get around 1FPS... Is 100K quads too much for a 650GT? If so I really thought I could render more polys before hitting the FPS limit. I'll investigate this more tomorrow, I just needed to know if it was hardware related.
Built and ran it, it was so bad it lagged my mouse cursor so I closed it. Then I opened FRAPs and apparently my installation is corrupted so there's that. :v:
[QUOTE=HiredK;43506362]It's just a modified version of an Overv tutorial:
[code]// Link statically with SFML
#define SFML_STATIC
// Link statically with GLEW
#define GLEW_STATIC
// Headers
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <iostream>
const int TEST = 100000;
// Shader sources
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec3 color;"
"out vec3 Color;"
"void main() {"
" Color = color;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec3 Color;"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(Color, 1.0);"
"}";
int main()
{
sf::Window window(sf::VideoMode(800, 600, 32), "OpenGL", sf::Style::Titlebar | sf::Style::Close);
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
/*GLfloat vertices[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};*/
std::vector<float> vertices;
for(unsigned int i=0; i<TEST; i++) {
vertices.push_back(-0.5f); vertices.push_back( 0.5f); vertices.push_back( 1.0f); vertices.push_back( 0.0f); vertices.push_back( 0.0f);
vertices.push_back( 0.5f); vertices.push_back( 0.5f); vertices.push_back( 0.0f); vertices.push_back( 1.0f); vertices.push_back( 0.0f);
vertices.push_back( 0.5f); vertices.push_back(-0.5f); vertices.push_back( 0.0f); vertices.push_back( 0.0f); vertices.push_back( 1.0f);
vertices.push_back(-0.5f); vertices.push_back(-0.5f); vertices.push_back( 1.0f); vertices.push_back( 1.0f); vertices.push_back( 1.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
vertices.clear();
// Create an element array
GLuint ebo;
glGenBuffers(1, &ebo);
/*GLuint elements[] = {
0, 1, 2,
2, 3, 0
};*/
std::vector<GLuint> elements;
for(unsigned int i=0; i<TEST; i++) {
elements.push_back(0); elements.push_back(1); elements.push_back(2);
elements.push_back(2); elements.push_back(3); elements.push_back(0);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elements.size() * sizeof(GLuint), &elements[0], GL_STATIC_DRAW);
elements.clear();
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
while (window.isOpen())
{
sf::Event windowEvent;
while (window.pollEvent(windowEvent))
{
switch (windowEvent.type)
{
case sf::Event::Closed:
window.close();
break;
}
}
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6 * TEST, GL_UNSIGNED_INT, 0);
/*for(unsigned int i=0; i<TEST; i++) {
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}*/
// Swap buffers
window.display();
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}[/code][/QUOTE]
So 100k quads are typically going to run pretty well on modern cards. The problem is that what you're rendering isn't typical. Your glDepthFunc is probably defaulting to GL_LEQUAL, which is usually what you want, but in this case it's sabotaging your performance.
In this case, you're rendering the exact same quad over and over again. This means that the GPU will be generating the same depth values every time. Since GL_LEQUAL means "continue drawing if the depth value is less than OR EQUAL TO the existing depth value", you're doing the full fragment shader for the full quad 100k times every frame. You're likely fillrate bound. Let's do the math to see if that's the case:
Your framebuffer is 800x600.
The quad you're rendering takes up half of each axis, so 1/4 of the screen.
You're filling that many fragments 100,000 times per frame.
((800 * 600) / 4) * 100000 - or 12 billion pixels per frame.
Assuming that by "GT650" you're referring to a GeForce GT 650M, the pixel fillrate is [url=http://en.wikipedia.org/wiki/Comparison_of_Nvidia_graphics_processing_units#GeForce_600M_.286xxM.29_Series]13.4, 11.9, or 14.4[/url] billion pixels PER SECOND. So 1FPS sounds about right.
Even if you're talking about a GeForce GTX 650, it's pixel fillrate is 16.9 billion, so you're still going to get horrible performance.
Add "glDepthFunc(GL_LESS);" somewhere in initialization and you should (hopefully) see significantly better performance.
Also, a side note - you're creating a massive vertex buffer but only referring to the first 4 elements in your index buffer. If you want to see how long it takes to go through that enormous buffer, create your indices as i * 4 + 0, i * 4 + 1, i * 4 + 2, etc (instead of just 0, 1, 2...).
[QUOTE=robmaister12;43507267]So 100k quads are typically going to run pretty well on modern cards. The problem is that what you're rendering isn't typical. Your glDepthFunc is probably defaulting to GL_LEQUAL, which is usually what you want, but in this case it's sabotaging your performance.
In this case, you're rendering the exact same quad over and over again. This means that the GPU will be generating the same depth values every time. Since GL_LEQUAL means "continue drawing if the depth value is less than OR EQUAL TO the existing depth value", you're doing the full fragment shader for the full quad 100k times every frame. You're likely fillrate bound. Let's do the math to see if that's the case:
Your framebuffer is 800x600.
The quad you're rendering takes up half of each axis, so 1/4 of the screen.
You're filling that many fragments 100,000 times per frame.
((800 * 600) / 4) * 100000 - or 12 billion pixels per frame.
Assuming that by "GT650" you're referring to a GeForce GT 650M, the pixel fillrate is [url=http://en.wikipedia.org/wiki/Comparison_of_Nvidia_graphics_processing_units#GeForce_600M_.286xxM.29_Series]13.4, 11.9, or 14.4[/url] billion pixels PER SECOND. So 1FPS sounds about right.
Even if you're talking about a GeForce GTX 650, it's pixel fillrate is 16.9 billion, so you're still going to get horrible performance.
Add "glDepthFunc(GL_LESS);" somewhere in initialization and you should (hopefully) see significantly better performance.
Also, a side note - you're creating a massive vertex buffer but only referring to the first 4 elements in your index buffer. If you want to see how long it takes to go through that enormous buffer, create your indices as i * 4 + 0, i * 4 + 1, i * 4 + 2, etc (instead of just 0, 1, 2...).[/QUOTE]
Thanks a lot, I added what you said and went up to ~200FPS in 720p for 100K quads (so 200K triangles :dance:). Now the next step is to figure out how to properly use glMapBuffer to update the quads position/size.
[QUOTE=HiredK;43507435]Thanks a lot, I added what you said and went up to ~200FPS in 720p for 100K quads (so 200K triangles :dance:). Now the next step is to figure out how to properly use glMapBuffer to update the quads position/size.[/QUOTE]
So what's happening now is that the first quad gets drawn fully, then the other 99,999 do the vertex shader, but fail the z-test and therefore skip the fragment shader.
If you want a more accurate representation of performance compared to number of triangles rendered, I would recommend trying to write either a .ply or .obj parser and load in an actual model to mess around with (and change the depth function back to GL_LEQUAL).
With any model, about half the triangles will be backface culled, and a decent portion of them will be rejected in the z-test. Plus those triangles are typically not taking up 1/4 of the screen each, so you won't be anywhere near fillrate bound with a normal model.
When I started learning graphics, after I got a rectangle on screen I started messing around with models from the Stanford 3d scanning repository:
[url]http://graphics.stanford.edu/data/3Dscanrep/[/url]
Does anybody know why this C++ delegate
C++
[code]
public delegate int CFunc(GarrysMod::Lua::lua_State* S);
[/code]
passed from C# to C++ and then marshaled to a unmanaged function pointer and then passed to lua crash GMod instantly with access violation exception when it returns from call?
C#
[code]
[DllExport("gmod13_open", CallingConvention.Cdecl)]
public static int Open(lua_State* L) {
GLua LUA = new GLua(L);
LUA.PushSpecial(0);
LUA.PushString("TEST", 0);
LUA.PushCSFunction((l) => {
//Info("TEST WAS CALLED! WEE!");
return 0;
});
LUA.SetTable(-3);
MessageBox.Show("C# Module loaded!", "Kekeke", MessageBoxButtons.OK);
return 0;
}
[/code]
C++
[code]
void PushCFunction(GarrysMod::Lua::CFunc val) {
this->S->luabase->PushCFunction(val);
}
void PushCSFunction(CFunc^ val) {
this->PushCFunction((GarrysMod::Lua::CFunc)Marshal::GetFunctionPointerForDelegate(val).ToPointer());
}
[/code]
What i'm doing here is ducttaping C# onto C++ and Lua.
[QUOTE=robmaister12;43507517]So what's happening now is that the first quad gets drawn fully, then the other 99,999 do the vertex shader, but fail the z-test and therefore skip the fragment shader.
If you want a more accurate representation of performance compared to number of triangles rendered, I would recommend trying to write either a .ply or .obj parser and load in an actual model to mess around with (and change the depth function back to GL_LEQUAL).
With any model, about half the triangles will be backface culled, and a decent portion of them will be rejected in the z-test. Plus those triangles are typically not taking up 1/4 of the screen each, so you won't be anywhere near fillrate bound with a normal model.
When I started learning graphics, after I got a rectangle on screen I started messing around with models from the Stanford 3d scanning repository:
[URL]http://graphics.stanford.edu/data/3Dscanrep/[/URL][/QUOTE]
I actually wrote an model loader before and even implemented frustum/depth occlusion culling on large mesh (the [URL="http://graphics.cs.williams.edu/data/meshes.xml"]sponza[/URL] in that case). I'm actually trying to implement a GUI system and it's the first time using a single VBO for batching really made sense so I'm still kinda used to have a single VBO per mesh, plus before I was simply doing this:
[code]void root::Mesh::draw(unsigned int ptype)
{
if(m_pos.size()>0) {
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(4,GL_FLOAT,0,&m_pos[0]);
}
if(m_uvs.size()>0) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2,GL_FLOAT,0,&m_uvs[0]);
}
if(m_nor.size()>0) {
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0,&m_nor[0]);
}
glDrawElements(ptype,m_ind.size(),GL_UNSIGNED_SHORT,&m_ind[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}[/code]
Also if the a failed z-test skips the frag shader, I guess implementing a simple recursive occlusion pass before rendering the quads would skip the vertex shader thus speeding the process even more... Also is there a way to use glScissor for a batch rendering approach?
Yup, avoiding sending unnecessary draw calls to OpenGL is always a good thing.
glScissor is a state change, you're going to have to issue different glDrawElements calls between them as far as I'm aware.
You could also try drawing the areas that you'd scissor into framebuffers and only redraw them when something changes. I can't remember his username off the top of my head, but there was someone here who was trying to do that a little while ago and ran into a bunch of issues with alpha blending, so if you want transparency you're probably going to run into those same issues.
[QUOTE=cartman300;43507545]Does anybody know why this C++ delegate
C++
[code]
public delegate int CFunc(GarrysMod::Lua::lua_State* S);
[/code]
passed from C# to C++ and then marshaled to a unmanaged function pointer and then passed to lua crash GMod instantly with access violation exception when it returns from call?
C#
[code]
[DllExport("gmod13_open", CallingConvention.Cdecl)]
public static int Open(lua_State* L) {
GLua LUA = new GLua(L);
LUA.PushSpecial(0);
LUA.PushString("TEST", 0);
LUA.PushCSFunction((l) => {
//Info("TEST WAS CALLED! WEE!");
return 0;
});
LUA.SetTable(-3);
MessageBox.Show("C# Module loaded!", "Kekeke", MessageBoxButtons.OK);
return 0;
}
[/code]
C++
[code]
void PushCFunction(GarrysMod::Lua::CFunc val) {
this->S->luabase->PushCFunction(val);
}
void PushCSFunction(CFunc^ val) {
this->PushCFunction((GarrysMod::Lua::CFunc)Marshal::GetFunctionPointerForDelegate(val).ToPointer());
}
[/code]
What i'm doing here is ducttaping C# onto C++ and Lua.[/QUOTE]
I guess the delegate gets garbage collected.
[QUOTE=robmaister12;43508244]Yup, avoiding sending unnecessary draw calls to OpenGL is always a good thing.
glScissor is a state change, you're going to have to issue different glDrawElements calls between them as far as I'm aware.
You could also try drawing the areas that you'd scissor into framebuffers and only redraw them when something changes. I can't remember his username off the top of my head, but there was someone here who was trying to do that a little while ago and ran into a bunch of issues with alpha blending, so if you want transparency you're probably going to run into those same issues.[/QUOTE]
[URL="http://stackoverflow.com/questions/2171085/opengl-blending-with-previous-contents-of-framebuffer/18497511#18497511"]Here's how to solve the transparency/blending issue.[/URL]
I'm not sure if you can draw front-to-back like that too, it's possible that it works with a different blend function though.
[QUOTE=cartman300;43507545]Does anybody know why this C++ delegate
C++
passed from C# to C++ and then marshaled to a unmanaged function pointer and then passed to lua crash GMod instantly with access violation exception when it returns from call?
What i'm doing here is ducttaping C# onto C++ and Lua.[/QUOTE]
Make sure to verify that C++ is treating the delegate as a Cdecl as the defualt calling conversion is Stdcall it might be using that. Try doing the delegate like:
[code]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CFunc(GarrysMod::Lua::lua_State* S);
[/code]
Or however you define the Calling Conversion in C++ side since I'm not entirely sure.
Also like ZeekyHBomb said make sure it's not getting GC'd.
[QUOTE=anthonywolfe;43510320]Make sure to verify that C++ is treating the delegate as a Cdecl as the defualt calling conversion is Stdcall it might be using that. Try doing the delegate like:[code]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CFunc(GarrysMod::Lua::lua_State* S);
[/code]
Or however you define the Calling Conversion in C++ side since I'm not entirely sure.[/QUOTE]
__cdecl
The default calling convention in C++ is cdecl, I would assume this does not change in C++/CLI or it would be hard to use external header files.
You are probably confusing it with the WinAPI, in which all (?) functions are declared as __stdcall; this is done in the header however and not through any compiler setting or anything like that.
[QUOTE=ZeekyHBomb;43510363]__cdecl
The default calling convention in C++ is cdecl, I would assume this does not change in C++/CLI or it would be hard to use external header files.
You are probably confusing it with the WinAPI, in which all (?) functions are declared as __stdcall; this is done in the header however and not through any compiler setting or anything like that.[/QUOTE]
My bad, I was thinking he would be using [URL="http://msdn.microsoft.com/en-us/library/zdx6dyyh(v=vs.110).aspx"]GetDelegateForFunctionPointer[/URL] to load the function into the delegate which uses __Stdcall as the default calling conversion. Though now thinking about it, him being in C++ there would probably be a easier way to do so and I'm just being silly. I just know most if not all of my access violations come from mucking up the CallingConversion.
Class functions aren't cdecl - they use the "thiscall" convention on Windows. The pointer to the class is transparently passed as the first argument to the function and the callee cleans the stack (as opposed to cdecl, where the caller cleans it). Confusing them will muck up your stack.
I haven't used C++ with C# so I can't help much.
[QUOTE=anthonywolfe;43510320]Make sure to verify that C++ is treating the delegate as a Cdecl as the defualt calling conversion is Stdcall it might be using that. Try doing the delegate like:
[code]
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int CFunc(GarrysMod::Lua::lua_State* S);
[/code]
Or however you define the Calling Conversion in C++ side since I'm not entirely sure.
Also like ZeekyHBomb said make sure it's not getting GC'd.[/QUOTE]
You are right, this does indeed fix it. However a bit too late, [URL="http://facepunch.com/showthread.php?t=1341204&p=43510069&viewfull=1#post43510069"]i figured it out on my own[/URL].
I'm gonna release this soon if anybody is interested in source code.
Sorry, you need to Log In to post a reply to this thread.